import type { AgentAdapter, DetectionResult, InstallOptions, InstallReport, InstallState, Scope } from "../types.js";
export interface RunResult {
    stdout: string;
    stderr: string;
    exitCode: number;
}
/**
 * Dependencies injected into the adapter. Default implementations use real
 * system calls; tests pass stubs. Keeping this as a plain interface (not a
 * class) avoids leaking test-only code into the runtime and keeps the adapter
 * cheap to instantiate.
 */
export interface ClaudeCodeDeps {
    /** Run a command and resolve with stdout/stderr/exitCode. Rejects on spawn failures (e.g., ENOENT). */
    run: (cmd: string, args: string[]) => Promise<RunResult>;
    existsSync: (p: string) => boolean;
    readFileSync: (p: string, encoding?: BufferEncoding) => string;
    readdirSync: (p: string) => string[];
    /** Write a file, creating parent directories as needed. Optional — defaults to fs. */
    writeFileSync?: (p: string, data: string) => void;
    /** Ensure a directory exists (recursive). Optional — defaults to fs.mkdirSync. */
    mkdirSync?: (p: string, options?: {
        recursive?: boolean;
    }) => void;
    /** Rename a file. Optional — defaults to fs.renameSync. Used for atomic writes. */
    renameSync?: (from: string, to: string) => void;
    homedir: () => string;
    cwd: () => string;
    /**
     * Best-effort fetch of the latest plugin version from GitHub. Returning
     * undefined or throwing is treated as "unknown" — never fatal.
     */
    fetchLatestVersion: () => Promise<string | undefined>;
}
export declare function defaultClaudeCodeDeps(): ClaudeCodeDeps;
export declare class ClaudeCodeAdapter implements AgentAdapter {
    readonly id = "claude";
    readonly displayName = "Claude Code";
    private deps;
    constructor(deps?: ClaudeCodeDeps);
    supportsScopes(): Scope[];
    detect(): Promise<DetectionResult>;
    getInstallState(scope: Scope): Promise<InstallState>;
    private queryLocalInstallState;
    private enrichWithLatest;
    /**
     * Invoke `claude plugin list --json` and find our plugin at the requested
     * scope. Returns binaryAvailable=false on spawn failure so callers can fall
     * back to the settings-file path; binaryAvailable=true otherwise, with
     * `installed` reflecting whether doc-detective@doc-detective is present at
     * the mapped Claude scope (`user` for our `global`, `project` for `project`).
     *
     * Note: `claude plugin marketplace list --json` returns the *marketplaces*,
     * not the installed plugins — a separate command (`plugin list`) is the
     * authoritative source for install state.
     */
    private queryMarketplaceList;
    private findInstalledVersionFromCache;
    private settingsPathFor;
    install(opts: InstallOptions): Promise<InstallReport>;
    /**
     * Path B: edit ~/.claude/settings.json (or ./.claude/settings.json) directly.
     * Claude Code will notice the extraKnownMarketplaces + enabledPlugins entries
     * on its next launch and prompt to trust + complete the install.
     */
    private installViaSettingsFile;
    private readSettingsFile;
    private mergeSettingsForDocDetective;
    private writeSettingsFile;
    /**
     * Path A: `claude plugin ...` subcommands. Assumes binary is available.
     */
    private installViaCli;
    private isClaudeAvailable;
}
export declare const claudeCodeAdapter: AgentAdapter;
//# sourceMappingURL=claude-code.d.ts.map