import { ChildProcess } from 'node:child_process';

/**
 *
 * Subprocess wrappers for the local coding-harness CLIs installed in the
 * sandbox image (claude-code, codex, opencode). Used by the in-process
 * delegation executor (`createInProcessExecutor`) so a delegated coding task
 * spawns a real harness on a real git worktree instead of provisioning a
 * sibling sandbox.
 *
 * All harness invocations:
 *   - run with `cwd` set to the worktree
 *   - inherit env from the parent (the MCP server inside the sandbox has
 *     the harness's auth already)
 *   - capture stdout/stderr
 *   - support cancellation via AbortSignal
 *   - enforce a wall-clock timeout
 *
 * @experimental
 */

/** Local coding harness available inside the sandbox. */
type LocalHarness = 'claude' | 'codex' | 'opencode';
/** @experimental */
interface RunLocalHarnessOptions {
    harness: LocalHarness;
    /** Working directory for the subprocess (typically a worktree path). */
    cwd: string;
    /** Prompt forwarded as the harness CLI's task argument. */
    taskPrompt: string;
    /**
     * Pre-built command + args (e.g. from `harnessInvocation` so the full authored
     * `AgentProfile` — systemPrompt + model — reaches the harness). When set it OVERRIDES the
     * default prompt-only `buildArgs(taskPrompt)` path; `command` defaults to the harness's
     * default binary when only `args` is supplied. When absent the legacy prompt-only shape
     * is used unchanged.
     */
    invocation?: {
        command?: string;
        args: ReadonlyArray<string>;
    };
    /** Wall-clock kill deadline (ms). Default 5 min. Subprocess SIGTERMed on expiry. */
    timeoutMs?: number;
    /** Caller cancellation. SIGTERM is sent on abort. */
    signal?: AbortSignal;
    /** Override env (defaults to inheriting from the parent). */
    env?: NodeJS.ProcessEnv;
    /**
     * Test seam — inject a custom spawner so unit tests can mock the
     * subprocess without touching the OS. Defaults to node's `child_process.spawn`.
     */
    spawn?: (command: string, args: ReadonlyArray<string>, opts: {
        cwd: string;
        env: NodeJS.ProcessEnv;
        stdio: 'pipe';
    }) => ChildProcess;
}
/** @experimental */
interface LocalHarnessResult {
    /** OS exit code. `null` when killed before exit. */
    exitCode: number | null;
    /** Concatenated stdout. */
    stdout: string;
    /** Concatenated stderr. */
    stderr: string;
    /** Set when the process exited via signal (timeout / abort). */
    killedBySignal: NodeJS.Signals | null;
    /** Wall-clock duration ms (spawn → exit). */
    durationMs: number;
    /** Set when timeoutMs elapsed before exit. */
    timedOut: boolean;
}
/**
 * Spawn a local coding harness CLI as a subprocess + collect its output.
 *
 * NOT responsible for parsing the harness's output or extracting a diff —
 * the in-process executor's `streamPrompt` orchestrates `git diff` against
 * the worktree after this resolves. This function is intentionally narrow:
 * spawn, wait, capture, return.
 *
 * Fails loud — throws when:
 *   - `cwd` doesn't exist (subprocess emits ENOENT; surfaced as Error)
 *   - the harness binary is not on PATH (ENOENT)
 *
 * Does NOT throw when:
 *   - the subprocess exits non-zero (`result.exitCode` carries the code)
 *   - the subprocess is aborted / timed out (`result.killedBySignal` /
 *     `result.timedOut` carries the reason)
 *
 * @experimental
 */
declare function runLocalHarness(options: RunLocalHarnessOptions): Promise<LocalHarnessResult>;

export { type LocalHarness as L, type RunLocalHarnessOptions as R, type LocalHarnessResult as a, runLocalHarness as r };
