import { type ChildProcess } from "node:child_process";
import fs from "node:fs";
import { Command } from "commander";
import { buildLocalDesktopModelEntry, mergeLocalAgentBackendUrlsIntoApplicationUser, mergeLocalDesktopModelsIntoApplicationUser } from "./cursorDesktopState.js";
export { buildLocalDesktopModelEntry, mergeLocalAgentBackendUrlsIntoApplicationUser, mergeLocalDesktopModelsIntoApplicationUser, };
import { type DesktopConnectProxy } from "./desktopConnectProxy.js";
export type CkCommand = "launch" | "test" | "doctor" | "cert" | "route" | "stop";
export type CkProfileMode = "isolated" | "default";
export type CkRouteMethod = "pf" | "direct";
export type CkRouteAction = "plan" | "status" | "rollback";
export interface CkArgs {
    command: CkCommand;
    dryRun: boolean;
    profileMode: CkProfileMode;
    timeoutMs: number;
    routeMethod: CkRouteMethod;
    routeAction: CkRouteAction;
    debugPort?: number;
    instanceId?: string;
    seedAuthFromDefault?: boolean;
}
export interface CommandSpec {
    executable: string;
    args: string[];
    env?: Record<string, string>;
}
export interface CkLaunchPlan {
    bridge: CommandSpec;
    cursor: CommandSpec;
    bridgePort: number;
    connectProxyPort?: number;
    agentHttpPort?: number;
    stateDir: string;
    statePath: string;
    logPath: string;
    connectProxyLogPath?: string;
    userDataDir: string | undefined;
    extensionsDir: string;
    workspacePath: string;
    profileMode: CkProfileMode;
    debugPort?: number;
    instanceId?: string;
    seedAuthFromDefault: boolean;
    authSeedStatus?: CursorAuthSeedStatus;
    localModelSeedStatus?: CursorLocalModelSeedStatus;
}
export type CursorAuthSeedStatus = "not-requested" | "not-isolated" | "sqlite-unavailable" | "source-missing" | "no-auth-rows" | "seeded";
export type CursorLocalModelSeedStatus = "not-isolated" | "sqlite-unavailable" | "state-missing" | "no-local-models" | "seeded";
export interface CkRoutePlan {
    method: CkRouteMethod;
    hostname: string;
    hostnames: string[];
    bridgePort: number;
    upstreamConnectHost: string | undefined;
    warnings: string[];
    setupCommands: CommandSpec[];
    verificationCommands: CommandSpec[];
    rollbackCommands: CommandSpec[];
}
export interface RouteInventoryObservation {
    method: string;
    path: string;
    contentType: string;
    status: number;
    framing: string;
    policy: string;
    outcome: string;
}
export interface RouteInventoryPathSummary {
    path: string;
    count: number;
    methods: string[];
    statuses: number[];
    framings: string[];
    policies: string[];
    outcomes: string[];
}
export type DesktopRouteCategory = "model-metadata" | "local-agent-candidate" | "pass-through" | "decoded-only" | "unsupported" | "unknown";
export interface DesktopRouteCategorySummary {
    path: string;
    category: DesktopRouteCategory;
    reason: string;
}
export interface DesktopTestReport {
    routeInventorySeen: boolean;
    modelRoutesSeen: string[];
    missingModelRoutes: string[];
    observedPaths: string[];
    routeSummary: RouteInventoryPathSummary[];
    routeCategories: DesktopRouteCategorySummary[];
    failedRoutes: RouteInventoryObservation[];
    passThroughRoutes: RouteInventoryObservation[];
    diagnosis: string[];
}
export interface CkProcessGroup {
    bridge: ChildProcess;
    log: fs.WriteStream;
    connectProxy?: DesktopConnectProxy;
}
interface CkState {
    bridgePid?: number;
    bridgeCommand?: string;
    bridgePort?: number;
    connectProxyPort?: number;
    agentHttpPort?: number;
    logPath?: string;
    connectProxyLogPath?: string;
    profileMode?: CkProfileMode;
    userDataDir?: string;
    extensionsDir?: string;
    workspacePath?: string;
    debugPort?: number;
    instanceId?: string;
    seedAuthFromDefault?: boolean;
    authSeedStatus?: CursorAuthSeedStatus;
    localModelSeedStatus?: CursorLocalModelSeedStatus;
    startedAt?: string;
}
export declare const CK_STATE_DIR: string;
export declare const CK_STATE_PATH: string;
/**
 * Build the commander program for `ck`. `dispatch` receives the resolved
 * {@link CkArgs}; the real binary runs the command while {@link parseCkArgs}
 * captures the args for tests.
 */
export declare function buildCkProgram(dispatch: (args: CkArgs) => void | Promise<void>): Command;
/**
 * Pure argument parser built on the commander program: returns the resolved
 * {@link CkArgs} (or throws on invalid input) without running the command.
 */
export declare function parseCkArgs(argv: string[]): CkArgs;
export declare function buildCkLaunchPlan(options: {
    env: NodeJS.ProcessEnv;
    bridgePort: number;
    connectProxyPort?: number;
    agentHttpPort?: number;
    profileMode?: CkProfileMode;
    debugPort?: number;
    instanceId?: string;
    seedAuthFromDefault?: boolean;
    cwd?: string;
}): CkLaunchPlan;
export declare function commandForDisplay(spec: CommandSpec): string;
export declare function buildCkRoutePlan(options?: {
    method?: CkRouteMethod;
    bridgePort?: number;
    upstreamConnectHost?: string;
    cwd?: string;
}): Promise<CkRoutePlan>;
export declare function containsPrivilegedCommand(spec: CommandSpec): boolean;
export declare function routeInventoryTimeoutDiagnosis(): string[];
export declare function analyzeRouteInventoryLog(logText: string): DesktopTestReport;
export declare function runCk(argv?: string[]): Promise<void>;
/** Attach the `ck` desktop launcher as a subcommand group of another program. */
export declare function registerCk(program: Command): void;
export declare function chooseBridgePort(): Promise<number>;
export declare function seedCursorAuthFromDefault(plan: Pick<CkLaunchPlan, "profileMode" | "userDataDir" | "seedAuthFromDefault">): CursorAuthSeedStatus;
export declare function seedLocalModelsIntoCursorState(plan: Pick<CkLaunchPlan, "agentHttpPort" | "bridge" | "profileMode" | "userDataDir">): CursorLocalModelSeedStatus;
export declare function cleanupIsolatedCursorProcesses(userDataDir: string): number[];
export declare function bridgeProcessMatchesState(command: string, state?: Pick<CkState, "bridgeCommand">): boolean;
