import type { HttpContext } from '@adonisjs/core/http';
import type { AgentGovernanceAuthorize } from '../governance-gate.js';
import type { Actor } from '../types.js';
import type { AccessDeniedOption as GenericAccessDeniedOption, AccessDeniedRenderer as GenericAccessDeniedRenderer } from './access_denied_page.js';
/**
 * The function form of {@link AgentDashboardConfig.accessDenied}: render (or answer) a refused
 * page navigation yourself. Receives the refusal ({@link AccessDeniedInfo}) and the AdonisJS
 * {@link HttpContext}. Return an HTML string to have it served; answer the request yourself (a
 * redirect, most commonly) and return nothing to make the provider stand down; return nothing
 * WITHOUT answering and the built-in page is served.
 */
export type AccessDeniedRenderer = GenericAccessDeniedRenderer<HttpContext>;
/** `accessDenied` in either form — an options object for the built-in page, or a renderer. */
export type AccessDeniedOption = GenericAccessDeniedOption<HttpContext>;
/**
 * An extra authorization gate for the dashboard, run AFTER the agent config's `actorResolver` has
 * resolved the caller. Return `false` (or throw) to deny — the request gets `403`. The governance
 * read-model the SPA serves spans EVERY actor's spend/usage, so most apps restrict the console beyond
 * mere authentication, e.g. `(actor) => actor.roles?.includes('ADMIN') ?? false`.
 */
export type AgentDashboardAuthorize = (actor: Actor, ctx: HttpContext) => boolean | Promise<boolean>;
/**
 * Runs when the agent config's `actorResolver` itself rejects the caller — no resolver configured, or
 * `resolve(ctx)` threw (e.g. `AuthActorResolver` over an anonymous `ctx.auth`) — so there is no
 * resolved {@link Actor} to hand to {@link AgentDashboardAuthorize}. Deliberately ctx-only, never a
 * fabricated actor: the resolver's whole contract is "never invent an identity", and this hook must
 * not undermine that.
 *
 * Called BEFORE the gate writes its default `401 { error }` JSON. To show something other than that
 * JSON — a redirect to the app's own login page, most commonly — set a response header inside this
 * hook (typically via `ctx.response.redirect(...)`); the gate detects the `location` header and skips
 * its own write. Anything else (return normally without touching the response) falls through to the
 * default JSON, so this is safe to omit or to use only for side effects (e.g. logging).
 */
export type AgentDashboardUnauthenticatedHook = (ctx: HttpContext) => void | Promise<void>;
/**
 * Optional `config('agent').dashboard` block. The dashboard reuses the agent config's `path` and
 * `actorResolver` (so it sits behind the SAME actor gating as the governance routes); this block
 * toggles it on/off, optionally overrides the mount path, and optionally adds an `authorize` gate.
 *
 * Shared by BOTH the embedded dashboard provider (`@adonis-agora/agent/dashboard_provider`, wired
 * automatically when you `node ace configure @adonis-agora/agent`) and the standalone
 * `@adonis-agora/agent-dashboard` package's provider — one config block controls whichever one is
 * registered.
 */
export interface AgentDashboardConfig {
    /**
     * Mount the SPA. Default `true` — set `false` to keep the routes off entirely. Note `true` is
     * necessary but not sufficient: the console also needs the agent's `governanceAuthorize` gate, see
     * {@link decideDashboardMount}.
     */
    enabled?: boolean;
    /** Override the mount path. Default `<agentPath>/dashboard`. */
    path?: string;
    /**
     * Extra authorization run after the actor resolves. Return `false` to deny (`403`). Omit to allow
     * any resolved actor (the default) — note this is only an EXTRA gate on the SPA shell; whether the
     * console mounts at all, and whether its data is readable, is decided by the agent config's
     * `governanceAuthorize`.
     */
    authorize?: AgentDashboardAuthorize;
    /**
     * Runs when the actor resolver itself rejects the caller (no resolver, or `resolve(ctx)` threw) —
     * the one denial `authorize` never sees, since there is no resolved actor to hand it. Set a
     * response header inside (e.g. `ctx.response.redirect('/login')`) to replace the default
     * `401 { error }` JSON with a custom page/redirect. See {@link AgentDashboardUnauthenticatedHook}.
     */
    onUnauthenticated?: AgentDashboardUnauthenticatedHook;
    /**
     * What a BROWSER sees when the gate refuses — the SPA shell or its assets (the console has no
     * JSON routes of its own; its data comes from the agent's `/agent/governance/*` routes, which are
     * unaffected). Omit it for the built-in page — a dark card in the console's own visual language
     * with the status, a sentence explaining the refusal and a "Back to app" link. Pass an object to
     * tweak that page (`brand`, `title`, `message`, `homeHref`, `accent`, …), or a function to
     * render/answer it yourself — see {@link AccessDeniedRenderer}. A redirect written by
     * `onUnauthenticated` or `authorize` still wins: the provider never overwrites a `location` header.
     */
    accessDenied?: AccessDeniedOption;
}
export interface ResolvedAgentDashboardConfig {
    enabled: boolean;
    path?: string;
    authorize?: AgentDashboardAuthorize;
    onUnauthenticated?: AgentDashboardUnauthenticatedHook;
    accessDenied?: AccessDeniedOption;
}
/** Fill defaults for the optional dashboard config block. */
export declare function resolveDashboardConfig(config: AgentDashboardConfig | undefined): ResolvedAgentDashboardConfig;
/** Whether the provider registers the console's routes, and (when it refuses) what to say about it. */
export type DashboardMountDecision = {
    mount: true;
} | {
    mount: false;
    reason: 'disabled';
} | {
    mount: false;
    reason: 'no-governance-gate';
    warning: string;
} | {
    mount: false;
    reason: 'no-governance-queries';
    warning: string;
};
/**
 * Decide whether to register the console's routes at all — the router-free core of the provider's
 * mount check, extracted so it can be unit tested without booting an app.
 *
 * The console is a pure consumer of the agent's cross-actor `/agent/governance/*` read routes, and
 * those routes are not mounted unless the agent config carries a `governanceAuthorize` gate. Serving
 * a shell that can only 404 its own data is worse than not serving it: the failure shows up as seven
 * dead panels at click time with nothing anywhere explaining why. So the console follows the same
 * fail-closed-by-omission rule one layer down — no gate, no routes — and says so at boot.
 *
 * This costs nothing that still works: every app affected is an app whose console is ALREADY dead in
 * every view but Quota. `dashboard.authorize` is deliberately NOT the trigger; it gates the shell,
 * not the data, and an app can set it and still have a console with nothing to render.
 */
export declare function decideDashboardMount(enabled: boolean, governanceAuthorize: AgentGovernanceAuthorize | undefined, governanceQueries?: unknown): DashboardMountDecision;
//# sourceMappingURL=define_config.d.ts.map