export interface HarnessRunOptions { maxBuffer?: number; /** Hard kill ceiling for TTY-routed runs (agy); minutes. */ timeoutMin?: number; /** Working directory the harness runs in (must match the MCP config cwd). */ cwd?: string; /** Extra env for the child (TTY path only; piped path merges via adapter). */ env?: NodeJS.ProcessEnv; /** * Route through a pseudo-terminal when the harness gates stdout on isatty * (mirrors the adapter's `needsTty`). When false, always piped. */ needsTty?: boolean; /** * Agent API key injected into a per-session opencode config so the * teamshare MCP server authenticates as THIS agent (never the global * config's key - shared keys made agents act as each other). */ opencodeAgentKey?: string; /** TeamShare API base URL for the MCP override (default: hosted API). */ opencodeMcpUrl?: string; /** Session mode header for the MCP override ('run' | 'build' | 'chat' | 'doc'). */ opencodeSessionMode?: string; /** TTY runs only: per-line transcript tap (tee agy output into session logs). */ onLine?: (line: string) => void; /** * When true, onLine receives formatted transcript lines instead of raw NDJSON. * Mirrors the adapter's `structuredOutput` flag — chat/doc reply loops pass * this so the live console shows human-readable text instead of JSON events. */ structuredOutput?: boolean; /** * Raw stdout line callback — fires with each unformatted line before * formatHarnessEvent processes it. Used by chat-reply/doc-reply to * capture raw output for parseHarnessOutput while reusing the same * spawn logic as run/build (via spawnHarness). */ onRawLine?: (line: string) => void; } export interface ResolvedBin { file: string; args?: string[]; } /** * Resolves a PATH command to something Node can spawn without a shell. * Windows npm shims (opencode.cmd / opencode.ps1, claude.cmd) cannot be * spawned directly (ENOENT) and shell-joining truncates multi-line args at * the first newline - so the shim's real target (opencode.exe or a JS entry * run via node) is extracted from the shim file instead. */ export declare function resolveBin(bin: string): ResolvedBin | null; /** * Writes a throwaway opencode config that overrides the teamshare MCP * server's API key for this run (project/`OPENCODE_CONFIG` scope wins over * the user's global config). Returns the config file path + cleanup. */ export declare function writeOpencodeMcpConfig(agentKey: string, apiBaseUrl: string, sessionMode?: string): { file: string; cleanup: () => void; }; /** * Runs a harness binary non-interactively and returns its stdout. * Spawned without a shell so multi-line prompts survive intact. */ export declare function runHarness(cmd: string, args: string[], opts?: HarnessRunOptions): string; export declare function hasBin(bin: string): boolean; /** * Async piped harness run with per-line tee. The sync execFileSync path in * runHarness buffers everything and cannot stream - chat/doc reply sessions * showed nothing but the CLI's own lines in the agent console, with no * harness work visible. This twin mirrors runHarness's contract exactly * (same opencode MCP env wiring, same error message format) and tees every * output line via opts.onLine as it arrives. */ export declare function runHarnessAsync(cmd: string, args: string[], opts?: HarnessRunOptions): Promise; /** * runHarness variant for TTY-gated harnesses (adapter `needsTty: true`): * routes the run through a pseudo-terminal so its isatty-gated stdout actually * emits, and returns the cleaned transcript as the reply text. Every other * binary keeps the plain piped path. Chat/doc callers should prefer this. */ export declare function runHarnessTtyAware(cmd: string, args: string[], opts?: HarnessRunOptions): Promise;