/** * Harness session continuation (resume) support. * * TeamShare spawns an AI harness (`opencode`, `claude`, `codex`, ...) for every * task/chat/doc run. Historically each spawn created a BRAND-NEW harness * session, so a retry, a build resume, or answering a question lost all prior * context. This module defines the per-harness resume capability so a run can * continue the previous conversation instead. * * IMPORTANT - sessions are MACHINE-LOCAL. The harness stores them on the * machine that ran them (`~/.local/share/opencode`, `~/.claude`, ...). A task * picked up by a daemon on ANOTHER PC has no session there, so the store is * keyed by agent+task+mode on THIS machine and a missing record simply means * "start fresh" - never an error. */ /** What the caller asks spawnHarness() to resume. */ export interface HarnessResumeRequest { /** Resume this specific session id/name (takes precedence over `latest`). */ id?: string; /** Resume the most recent session when no id is known. */ latest?: boolean; /** Branch (fork) instead of continuing in place, where supported. */ fork?: boolean; /** * Start a NEW session but bind it to this id/name so it can be resumed * deterministically later (only for harnesses with `resume.preassign`). */ preassignId?: string; } /** * Per-harness resume metadata. The actual argv is built by the adapter's * `headlessArgs()` (because flag-position and codex's subcommand differ per * harness); this describes capture + failure behaviour for the spawn layer. */ export interface ResumeSpec { /** How the harness addresses sessions. */ kind: 'flag' | 'subcommand' | 'history'; /** * Whether the harness can be handed a session id/name on the FIRST run * (so no capture is needed and continuation is deterministic). */ preassign?: 'uuid' | 'name'; /** How to learn the id of the run we just launched. */ capture: 'json-event' | 'session-list' | 'stdout' | 'none'; /** * Extra stderr/stdout signatures that mean a resume attempt failed (session * gone, unknown id, cwd mismatch). Falls back to the shared list. Match → * forget the record and start fresh. */ failureSignatures?: RegExp[]; /** * Resume-by-id needs the ORIGINAL working directory for some harnesses * (opencode/claude/gemini/cursor scope sessions per project/cwd). */ cwdScoped?: boolean; } /** * A resume is considered failed when the harness reports one of these. Kept * broad + tolerant: a false positive only costs a fresh run (safe), never a * broken task. */ export declare const RESUME_FAILURE_SIGNATURES: RegExp[]; /** True when a harness line looks like a resume failure. */ export declare function isResumeFailure(harness: string, line: string): boolean; /** * Best-effort session id extraction from a single structured-output line. * Returns undefined when the line carries no recognisable id. */ export declare function extractSessionId(harness: string, raw: string): string | undefined; /** * Extract a conversation/session id from plain stdout lines for harnesses that * print it (openhands: "Conversation ID: abc123"; copilot: "Session: "). */ export declare function extractSessionIdFromText(harness: string, line: string): string | undefined; /** Generate a session id we control (uuid-ish) for pre-assignment. */ export declare function newHarnessSessionId(): string;