/**
 * DaemonCliManager — CLI session creation, management, and command handling
 *
 * Separated from adhdev-daemon.ts.
 * CLI cases of createAdapter, startCliSession, stopCliSession, executeDaemonCommand extracted to independent module extract.
 */
import type { ProviderInstanceManager } from '../providers/provider-instance-manager.js';
import { ProviderLoader } from '../providers/provider-loader.js';
import { type MeshCoordinatorDelegatedWorkerIsolation, type ProviderModule, type ProviderResumeCapability } from '../providers/contracts.js';
import type { CliAdapter } from '../cli-adapter-types.js';
import type { PtyTransportFactory } from '../cli-adapters/pty-transport.js';
import type { SessionRegistry } from '../sessions/registry.js';
export interface CliManagerDeps {
    /** Server connection — injected into adapter */
    getServerConn(): any | null;
    /** P2P — PTY output transmit */
    getP2p(): {
        broadcastSessionOutput(key: string, data: string): void;
    } | null;
    /** StatusReporter callback */
    onStatusChange(): void;
    removeAgentTracking(key: string): void;
    /** InstanceManager — register in CLI unified status */
    getInstanceManager(): ProviderInstanceManager | null;
    getSessionRegistry?(): SessionRegistry | null;
    createPtyTransportFactory?: (params: CliTransportFactoryParams) => PtyTransportFactory | null;
    listHostedCliRuntimes?: () => Promise<HostedCliRuntimeDescriptor[]>;
    hostedRuntimeManagerTag?: string;
}
type CommandResult = {
    success: boolean;
    [key: string]: unknown;
};
export interface CliTransportFactoryParams {
    runtimeId: string;
    providerType: string;
    workspace: string;
    cliArgs?: string[];
    providerSessionId?: string;
    attachExisting?: boolean;
    /**
     * Launch-time record meta (meshNodeId / meshNodeFor / launchedByCoordinator /
     * autoLaunchedForQueueTaskId). Defense-in-depth for SESSION-ACCUMULATION-LEAK:
     * a session-host factory impl SHOULD seed the create_session record with this
     * so the node binding is present the instant the record exists, rather than
     * relying solely on the post-spawn updateRuntimeMeta round-trip. Optional and
     * additive — factory impls that ignore it keep the prior behavior; the
     * post-spawn WTDISPATCH stamp in register() still runs as the primary path.
     */
    initialMeta?: Record<string, unknown>;
}
export interface HostedCliRuntimeDescriptor {
    runtimeId: string;
    runtimeKey?: string;
    displayName?: string;
    workspaceLabel?: string;
    lifecycle?: 'starting' | 'running' | 'stopping' | 'stopped' | 'failed' | 'interrupted';
    recoveryState?: string | null;
    cliType: string;
    workspace: string;
    cliArgs?: string[];
    providerSessionId?: string;
    managedBy?: string;
    /**
     * Real spawn time (ms epoch) of the underlying session-host runtime — a PAST
     * timestamp recorded when the runtime first started. Threaded through so an
     * attach can restore the native-history session-floor to the runtime's actual
     * birth instead of collapsing spawnedAtMs to 0. Undefined when unrecoverable
     * (genuine post-restart-unknown), in which case the caller keeps the 0 fallback.
     */
    startedAtMs?: number;
}
type CliLaunchMode = 'new' | 'resume' | 'manual';
type CliSessionBinding = {
    cliArgs?: string[];
    providerSessionId?: string;
    launchMode: CliLaunchMode;
};
type CliStartOptions = {
    resumeSessionId?: string;
    settingsOverride?: Record<string, any>;
    extraEnv?: Record<string, string>;
    /** BRAIN-ROUTING thinking axis: standard level ('low'|'medium'|'high') applied
     *  at launch via the provider's thinkingLaunchArgs (CLI) or setConfigOption
     *  ('thought_level', ACP). Best-effort — ignored by providers with no support. */
    initialThinkingLevel?: string;
};
export interface CoordinatorDelegatedCliLaunchOptionsInput {
    cliType: string;
    workspace: string;
    cliArgs?: string[];
    env?: Record<string, string>;
    isolation?: MeshCoordinatorDelegatedWorkerIsolation;
}
export interface CoordinatorDelegatedCliLaunchOptions {
    cliArgs: string[];
    env: Record<string, string>;
}
/**
 * Decide the session-registry spawnedAtMs (the native-history session-floor) for a
 * newly registered CLI instance.
 *
 * - Fresh launch (attachExisting=false): now (nowMs). A real live spawn floor
 *   isolates a fresh session's own store and holds prior-session leak protection.
 * - Attach WITH a recoverable record startedAt (a PAST timestamp): that startedAt.
 *   Restoring a hosted runtime (coordinator / MAGI replica / hermes / claude /
 *   codex) after a daemon restart, the real spawn time is in the past. Using it
 *   restores each session's per-session birth-floor so co-located antigravity
 *   runtimes resolve their OWN conversation (ownerConfirmed) instead of the
 *   floor-less newest-by-mtime path that let a replica claim the coordinator's conv.
 * - Attach with NO recoverable startedAt: 0 — disables the floor for this session
 *   (recent_window_ms still bounds the look-back). NEVER use nowMs here: nowMs is in
 *   the FUTURE relative to existing transcripts and would push the floor past every
 *   transcript file, losing them (the ANTIGRAVITY-FINAL-MESSAGE-TAIL-GAP regression).
 */
export declare function resolveHostedSpawnedAtMs(attachExisting: boolean, attachStartedAtMs: number | undefined, nowMs: number): number;
export declare function buildCoordinatorDelegatedCliLaunchOptions(input: CoordinatorDelegatedCliLaunchOptionsInput): CoordinatorDelegatedCliLaunchOptions;
/**
 * Expand a provider's `modelLaunchArgs` template with the requested model, mirroring
 * expandResumeArgs. `{{model}}` → the trimmed model string. Returns undefined when
 * there is no template or no model (a model request without a template is a no-op —
 * see startSession, where the caller logs the skip). MAGI kind-panel model axis.
 */
export declare function expandModelLaunchArgs(template: string[] | undefined, model: string | undefined): string[] | undefined;
/**
 * Expand a provider's `thinkingLaunchArgs` template with the requested thinking
 * level, parallel to expandModelLaunchArgs. The standard level ('low'|'medium'|
 * 'high') is first mapped through the provider's `thinkingLevelMap` (a level absent
 * from the map passes through unchanged), then substituted into every `{{level}}`
 * token. Returns undefined when there is no template or no level (best-effort; a
 * thinking request without a template is a no-op). BRAIN-ROUTING thinking axis.
 */
export declare function expandThinkingLaunchArgs(template: string[] | undefined, level: string | undefined, levelMap: Partial<Record<string, string>> | undefined): string[] | undefined;
export declare function supportsExplicitSessionResume(resume?: ProviderResumeCapability): boolean;
export declare function resolveCliSessionBinding(provider: ProviderModule | undefined, normalizedType: string, cliArgs?: string[], requestedResumeSessionId?: string): CliSessionBinding;
export declare class DaemonCliManager {
    readonly adapters: Map<string, CliAdapter>;
    private deps;
    private providerLoader;
    constructor(deps: CliManagerDeps, providerLoader: ProviderLoader);
    getCliKey(cliType: string, dir: string): string;
    getSessionPresentationMode(sessionId: string): 'terminal' | 'chat' | null;
    isTerminalSession(sessionId: string): boolean;
    private persistRecentActivity;
    private getTransportFactory;
    private createAdapter;
    private startCliExitMonitor;
    private registerCliInstance;
    startSession(cliType: string, workingDir: string, cliArgs?: string[], initialModel?: string, options?: CliStartOptions): Promise<{
        runtimeSessionId: string;
        providerSessionId?: string;
    }>;
    stopSession(key: string): Promise<void>;
    stopSessionWithMode(key: string, mode: 'hard' | 'save'): Promise<void>;
    shutdownAll(): void;
    detachAll(): void;
    restoreHostedSessions(records?: HostedCliRuntimeDescriptor[]): Promise<number>;
    /**
    * Search for CLI adapter. Priority order:
    * 0. sessionId (UUID direct match)
    * 1. agentType + dir (iteration match)
    * 2. agentType fuzzy match (⚠ returns first match when multiple sessions exist)
    */
    findAdapter(agentType: string, opts?: {
        dir?: string;
        instanceKey?: string;
    }): {
        adapter: CliAdapter;
        key: string;
    } | null;
    private findAdapterBySessionId;
    /**
     * WTCLAIM (B): resolve the adapter for a mesh dispatch that named a node
     * (meshContext.nodeId) but carried no explicit session. Matches by the
     * instance's bound mesh node id (settings.meshNodeId, falling back to the
     * sticky meshLastNodeId) first, then by the node workspace (workingDir).
     *
     * Unlike findAdapter's step-2 fuzzy fallback, this NEVER degrades to a
     * provider-only first-match: on a daemon hosting BOTH a base node and a
     * cloned worktree node (same daemonId), that fuzzy match could land a
     * worktree-targeted task on the base session. Returns null when no session
     * is bound to this node so the caller fails closed.
     */
    private findMeshNodeAdapter;
    handleCliCommand(cmd: string, args: any): Promise<CommandResult | null>;
}
export {};
