/**
 * DaemonCommandHandler — unified command routing for CDP & CLI
 *
 * Routes incoming commands (from server WS, P2P, or local WS) to
 * the correct CDP manager or CLI adapter.
 *
 * Key concepts:
 *   - extractIdeType(): determines target IDE from targetSessionId or ideType
 *   - getCdp(): returns the DaemonCdpManager for current command
 *   - getProvider(): returns the ProviderModule for current command
 *   - handle(): main entry point, sets context then dispatches
 */
import type { DaemonCdpManager } from '../cdp/manager.js';
import { ProviderLoader } from '../providers/provider-loader.js';
import type { ProviderInstanceManager } from '../providers/provider-instance-manager.js';
import type { ProviderModule } from '../providers/contracts.js';
import type { DaemonAgentStreamManager } from '../agent-stream/index.js';
import type { CliAdapter } from '../cli-adapter-types.js';
import { ChatHistoryWriter } from '../config/chat-history.js';
import type { SessionRegistry, SessionRuntimeTarget } from '../sessions/registry.js';
import { type GitCommandServices } from '../git/git-commands.js';
export interface CommandResult {
    success: boolean;
    [key: string]: unknown;
}
export interface CommandContext {
    cdpManagers: Map<string, DaemonCdpManager>;
    ideType: string;
    adapters: Map<string, CliAdapter>;
    providerLoader?: ProviderLoader;
    /** ProviderInstanceManager — for runtime settings propagation */
    instanceManager?: ProviderInstanceManager;
    sessionRegistry?: SessionRegistry;
    onProviderSettingChanged?: (providerType: string, key: string, value: any) => Promise<void> | void;
    onProviderSourceConfigChanged?: () => Promise<void> | void;
    gitCommandServices?: GitCommandServices;
    /** Fired synchronously before send_chat is dispatched; fire-and-forget for callers */
    onBeforeSendChat?: (params: {
        workspace: string;
        sessionId: string;
    }) => void;
}
/**
 * Shared helpers interface — passed to sub-module command functions
 * for accessing CDP, providers, agent streams, and other handler-owned state.
 */
export interface CommandHelpers {
    getCdp(ideType?: string): DaemonCdpManager | null;
    getProvider(overrideType?: string): ProviderModule | undefined;
    getProviderScript(scriptName: string, params?: Record<string, string>, ideType?: string): string | null;
    evaluateProviderScript(scriptName: string, params?: Record<string, string>, timeout?: number): Promise<{
        result: any;
        category: string;
    } | null>;
    getCliAdapter(type?: string): CliAdapter | null;
    readonly currentManagerKey: string | undefined;
    readonly currentIdeType: string | undefined;
    readonly currentProviderType: string | undefined;
    readonly currentSession: SessionRuntimeTarget | undefined;
    readonly agentStream: DaemonAgentStreamManager | null;
    readonly ctx: CommandContext;
    readonly historyWriter: ChatHistoryWriter;
}
export declare class DaemonCommandHandler implements CommandHelpers {
    private _ctx;
    private _agentStream;
    private domHandlers;
    private _historyWriter;
    /** Current request route context */
    private _currentRoute;
    constructor(ctx: CommandContext);
    get ctx(): CommandContext;
    get agentStream(): DaemonAgentStreamManager | null;
    get historyWriter(): ChatHistoryWriter;
    get currentManagerKey(): string | undefined;
    get currentIdeType(): string | undefined;
    get currentProviderType(): string | undefined;
    get currentSession(): SessionRuntimeTarget | undefined;
    /** Get CDP manager for a specific session or manager key. */
    getCdp(ideType?: string): DaemonCdpManager | null;
    /**
     * Get provider module — _currentProviderType (agentType priority) use.
     */
    getProvider(overrideType?: string): ProviderModule | undefined;
    /** Get a provider script by name from ProviderLoader. */
    getProviderScript(scriptName: string, params?: Record<string, string>, ideType?: string): string | null;
    /**
     * per-category CDP script execute:
     * IDE → cdp.evaluate(script) (main window)
     * Extension → cdp.evaluateInSession(sessionId, script) (webview)
     */
    evaluateProviderScript(scriptName: string, params?: Record<string, string>, timeout?: number): Promise<{
        result: any;
        category: string;
    } | null>;
    /** CLI adapter search */
    getCliAdapter(type?: string): CliAdapter | null;
    private inferProviderType;
    private resolveRoute;
    /** Extract CDP scope key from target session or explicit ideType */
    private extractIdeType;
    private logCommandStart;
    private logCommandEnd;
    setAgentStreamManager(manager: DaemonAgentStreamManager): void;
    /**
     * When a command in the manual-attendance set arrives for a session this
     * daemon hosts, stamp the live instance so auto-approve holds while the user
     * drives the session by hand. Provider-common: the signal is the command
     * (foreground select_session / open_panel, controlbar invoke_provider_script
     * / set_mode / change_model / set_thought_level, manual resolve_action,
     * pty_input), never any CLI-specific modal text — so it works identically for
     * every CLI/ACP provider. send_chat is deliberately excluded because a
     * coordinator delegating a task to a worker also uses send_chat; counting it
     * would wrongly suppress the worker's delegated auto-approve. For a remote
     * mesh worker session the controlbar commands are forwarded to the owning
     * worker daemon, which runs this same hook there, so attendance is recorded
     * on the daemon that actually hosts the instance.
     */
    private noteManualAttendanceIfApplicable;
    handle(cmd: string, args: any): Promise<CommandResult>;
    private dispatch;
    /**
     * Reload providers from disk. Does NOT pull from the registry — the user
     * controls installs explicitly via install_provider_manifest. To upgrade
     * an installed provider, call install_provider_manifest again with the
     * desired version (or with no version to pick up the latest from
     * registry), or use check_provider_updates to see what is out of date.
     */
    private handleRefreshScripts;
    /**
     * Return per-provider availability so the dashboard's provider catalog
     * can show "Installed" badges. Reuses the existing detection state from
     * ProviderLoader.getMachineProviderStatus() — no probing is triggered.
     */
    private handleListProviderAvailability;
    /**
     * Compute the *upstream cache root*. install_provider_manifest writes
     * official-registry manifests here so the daemon's standard upstream
     * layer picks them up — no special handling needed at load time, and
     * the manifests inherit the official-trust badge instead of the
     * untrusted-external one.
     *
     * Path matches ProviderLoader.upstreamDir but we recompute it from
     * homedir() so this method stays usable in dev where userDir can
     * point at a sibling git checkout.
     */
    private getUpstreamInstallRoot;
    /**
     * Download a single provider manifest from the registry and write it to
     * ~/.adhdev/providers/.upstream/{category}/{type}/provider.json.
     *
     * Used by standalone onboarding to seed the upstream cache with the
     * default provider set on first launch. Verifies SHA-256 checksum
     * against the registry meta before persisting. Refuses to write
     * outside the upstream root.
     *
     * Args: { type: string, category?: string, version?: string }
     * If category/version are omitted, looks up the latest from the registry.
     */
    private handleInstallProviderManifest;
    /**
     * If `manifest.source = { type:'github', repo, ref, subdir? }` is set,
     * walk each script directory the manifest references and download every
     * file from the public GitHub raw endpoint. Returns a small summary so
     * the caller can report what was fetched.
     *
     * Best-effort: failures don't reject the install — the manifest itself is
     * usable for declarative-only providers, and the user still gets a clear
     * error string back if a needed script is missing.
     */
    private fetchProviderSources;
    /**
     * Remove a provider manifest from the upstream cache root
     * (~/.adhdev/providers/.upstream/{category}/{type}/). Refuses to touch
     * anything outside that root. Used by onboarding to opt out of a
     * provider the user doesn't want; the dashboard no longer exposes a
     * per-provider uninstall button (external sources are removed as a
     * whole via remove_provider_source).
     */
    private handleUninstallProviderManifest;
    /**
     * Return everything currently installed in the upstream cache with its
     * version. This is the "what does this daemon have" answer used both by
     * the UI and by the update checker.
     */
    private handleListInstalledProviders;
    /**
     * For each installed provider, ask the registry for its current latest
     * version and report whether an update is available. The user can then
     * call install_provider_manifest to upgrade (it overwrites the file).
     *
     * Returns { providers: [{ type, category, installedVersion, latestVersion,
     *   updateAvailable, error? }] }
     */
    private handleCheckProviderUpdates;
    /**
     * Register a new external provider source. The daemon clones the repo
     * to ~/.adhdev/external/<name>/, walks it once to detect provided
     * types, and surfaces any conflicts with already-installed types so
     * the dashboard can ask the user how to resolve them.
     *
     * Args: { url: string, ref?: string, name?: string }
     *   - url: https://, git@, or any git-cloneable URL
     *   - ref: branch/tag/commit (default "main")
     *   - name: short identifier (default derived from URL)
     *
     * Returns: { source, providers, conflicts }
     *   - conflicts: list of types this new source provides that another
     *     source already exposes. UI uses this to prompt for active-source
     *     selection before the load takes effect.
     */
    private handleAddProviderSource;
    /**
     * Remove a registered external source. Deletes the clone directory and
     * any active-source entry pointing to it.
     *
     * Args: { name: string }
     */
    private handleRemoveProviderSource;
    /**
     * List registered external sources + each source's currently installed
     * providers + the active selection for any conflicting types. Used by
     * the dashboard's "Sources" tab.
     */
    private handleListProviderSources;
    /**
     * Pick which source's copy of a conflicting provider type is active.
     * Other sources' copies stay on disk but the loader ignores them.
     *
     * Args: { type: string, sourceName: string }
     */
    private handleSetActiveProviderSource;
    private proxyDevServerPost;
    private proxyDevServerGet;
    private proxyDevServerScaffold;
}
