{"version":3,"sources":["../../src/types.ts","../../src/client/index.ts"],"names":["value"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * AIP-44 AcpDefinition + AcpHandle.\n *\n * Mirrors `resources/aip-44/draft/ACP.schema.json`. AIP-44 is an\n * agentproto profile of the Agent Client Protocol — top-level fields\n * declare role/transport/version, and AIP-44 extensions live under\n * `metadata.aip44.*`.\n *\n * `AcpHandle` is the readonly view of the same shape; tighten it by\n * hand for fields that get defaults applied in build().\n */\n\n/**\n * How a host resolves a `session/request_permission` request that was parked\n * by permission-hold mode. `{ optionId }` selects one of the offered options\n * (the allow- or reject-flavored one, chosen by the host); `{ cancelled: true }`\n * maps to ACP's `cancelled` outcome (used when the request offers no matching\n * option or the session is being torn down). Consumed by\n * `AcpClient.respondPermission` and the daemon's permission inbox.\n */\nexport type AcpPermissionResolution =\n  | { optionId: string; feedback?: string }\n  | { cancelled: true }\n\n/**\n * `_meta` key the daemon's respond path uses to carry the caller's free-text\n * feedback (e.g. \"reject, but do X instead\") on the `selected` outcome of a\n * held `session/request_permission` RPC. Defined once here so the acp client\n * and adapters agree on the convention.\n */\nexport const ACP_META_FEEDBACK = \"agentproto/feedback\"\n\nexport type AcpRole = \"client\" | \"server\" | \"bridge\"\nexport type AcpTransport = \"stdio\" | \"websocket\"\nexport type AcpTier = \"basic\" | \"governance-aware\" | \"sandboxed\"\n\n/** Mirror of upstream ACP `initialize` capabilities. */\nexport interface AcpCapabilities {\n  client?: {\n    fs?: {\n      readTextFile?: boolean\n      writeTextFile?: boolean\n    }\n    terminal?: boolean\n  }\n  agent?: {\n    loadSession?: boolean\n    promptCapabilities?: {\n      image?: boolean\n      audio?: boolean\n      embeddedContext?: boolean\n    }\n    mcpCapabilities?: {\n      http?: boolean\n      sse?: boolean\n    }\n  }\n}\n\nexport interface AcpAuditConfig {\n  ref?: string\n  kind?: \"governance\" | \"external\" | \"off\"\n}\n\nexport interface AcpMcpServer {\n  name: string\n  transport: \"stdio\" | \"http\" | \"sse\"\n  ref?: string\n  /** Static HTTP headers sent with every request to an `http` or `sse`\n   *  MCP server. Useful for fixed auth tokens or content-negotiation\n   *  headers that are safe to embed in config. */\n  headers?: Record<string, string>\n  /** Brokered credential path resolved at spawn time into additional\n   *  `headers` (typically an `Authorization` header). The path is passed\n   *  to the daemon's credential broker, so the actual secret never lives\n   *  in env or config. Mutually usable with `headers`; brokered headers\n   *  win on collision. */\n  credentialRef?: string\n  /** Extra argv for a `stdio` server (the command itself is `ref`).\n   *  Ignored for `http` / `sse`. */\n  args?: string[]\n  /** Extra environment for a `stdio` server, merged over the agent's own\n   *  env by the ACP agent when it launches the process. Ignored for\n   *  `http` / `sse`. */\n  env?: Record<string, string>\n}\n\n/** AIP-44 extensions on the agentskills.io baseline. Lives under `metadata.aip44`. */\nexport interface Aip44Extensions {\n  /** Commit SHA of upstream ACP repository this manifest validates against. */\n  acp_rev: string\n  /** Capability tier shorthand. */\n  tier: AcpTier\n  /** Optional explicit capability map; overrides tier defaults when present. */\n  capabilities?: AcpCapabilities\n  /** AIP-9 OPERATOR.md ref. REQUIRED when kind=server. */\n  operator?: string\n  /** AIP-7 GOVERNANCE.md ref. */\n  governance?: string\n  /** AIP-36 SANDBOX.md ref. REQUIRED when tier=sandboxed. */\n  sandbox?: string\n  /** Audit log target override. */\n  audit?: AcpAuditConfig\n  /** MCP servers to mount via session/new.mcpServers. */\n  mcp_servers?: AcpMcpServer[]\n  /** AIP-44 extensions stay open; vendors MAY add namespaced sub-keys. */\n  [extension: string]: unknown\n}\n\n/**\n * AIP-44 ACP.md frontmatter. Top-level fields are stable across upstream\n * ACP rev bumps; the AIP-44-specific binding layer lives in\n * `metadata.aip44`.\n */\nexport interface AcpDefinition {\n  /** Kebab id; MUST equal the parent directory name. */\n  name: string\n  /** Stable runtime id. */\n  id: string\n  /** One-paragraph purpose. */\n  description: string\n  /** Semver of this manifest. */\n  version: string\n  /** client = drives a subprocess; server = exposes an operator; bridge = both. */\n  kind: AcpRole\n  /** Transport(s) supported. stdio is REQUIRED; websocket is OPTIONAL. */\n  transport: AcpTransport | AcpTransport[]\n  /** Free-form metadata. AIP-44 extensions live under `metadata.aip44`. */\n  metadata: {\n    aip44: Aip44Extensions\n    [vendor: string]: unknown\n  }\n  /** Optional tags for catalog ergonomics. */\n  tags?: string[]\n  /** Top-level extension surface preserved for forward compatibility. */\n  [extension: string]: unknown\n}\n\nexport type AcpHandle = Readonly<AcpDefinition>\n\n/**\n * One background task as reported by the agent — see the `background-task`\n * {@link StreamEvent}. Only `taskId` is guaranteed; a `\"settled\"` edge carries\n * the terminal `status` and usually a `summary`.\n */\nexport interface BackgroundTaskInfo {\n  taskId: string\n  /** Friendly task type (`\"shell\"`, `\"monitor\"`, `\"workflow\"`, ...). */\n  taskKind?: string\n  description?: string\n  /** Where the task writes its output, when the agent says. */\n  outputFile?: string\n  status?: \"running\" | \"paused\" | \"completed\" | \"failed\" | \"stopped\"\n  summary?: string\n  /** The tool call that started the task, when the agent says. */\n  toolCallId?: string\n}\n\n/**\n * Canonical stream-event taxonomy emitted from `createAcpClient`. The\n * client maps upstream ACP `session/update` notifications and\n * `requestPermission` callbacks into this closed set so consumers\n * never see protocol-specific shapes.\n */\nexport type StreamEvent =\n  | { kind: \"text-delta\"; sessionId: string; text: string }\n  | {\n      kind: \"tool-call\"\n      sessionId: string\n      toolCallId: string\n      toolName: string\n      arguments: unknown\n      /**\n       * True when this event ENRICHES a call already announced under the same\n       * `toolCallId` rather than announcing a new one.\n       *\n       * ACP lets an agent announce a call before it knows the details and fill\n       * them in afterwards. The claude-code bridge does exactly that: its\n       * `tool_call` carries `title: \"Read File\"` with `rawInput: {}`, and the\n       * FOLLOWING `tool_call_update` carries `rawInput: {file_path: …}` plus a\n       * real title. Consumers must merge an update onto the existing call\n       * (keyed by `toolCallId`) rather than rendering a second card, and must\n       * not count it as a fresh call for logging or blocked-on purposes.\n       *\n       * `toolName` is `\"\"` when the update carried no title — merge only\n       * non-empty names so an untitled enrichment can't erase a good one.\n       */\n      isUpdate?: boolean\n    }\n  | { kind: \"tool-result\"; sessionId: string; toolCallId: string; result: unknown; isError?: boolean }\n  | { kind: \"thought\"; sessionId: string; text: string }\n  | {\n      kind: \"agent-prompt\"\n      sessionId: string\n      /**\n       * Correlation id for this prompt. In permission-hold mode this is the\n       * stable request id the host passes back to `respondPermission` to\n       * resolve the parked `session/request_permission` RPC — derived from the\n       * ACP `toolCall.toolCallId` plus a per-client counter so it stays unique\n       * even when an agent re-requests permission for the same tool call.\n       */\n      toolCallId: string\n      options: unknown\n      /** Human-readable \"Allow X?\" line, when derivable from the request. */\n      text?: string\n      /** Tool title/kind the agent is asking permission for, when present. */\n      toolName?: string\n      /**\n       * The tool call's raw input (ACP `ToolCallUpdate.rawInput`) — e.g. a\n       * Bash tool's command string — carried through unmodified so a host can\n       * see WHAT the agent is asking permission to run. Harness-shaped and\n       * untyped: normalize defensively per-adapter rather than assuming a\n       * stable schema.\n       */\n      rawInput?: unknown\n      /**\n       * The tool call's `_meta` (e.g. mastra-agent's\n       * `mastra-agent/suspendPayload` carrying a submit_plan's plan text),\n       * carried through unmodified. Harness-shaped and untyped — normalize\n       * defensively per-adapter rather than assuming a stable schema.\n       */\n      _meta?: unknown\n    }\n  | {\n      kind: \"turn-end\"\n      sessionId: string\n      /**\n       * `\"watchdog-timeout\"` is synthesized client-side (never sent by the\n       * agent) when `AcpClientOptions.turnIdleTimeoutMs` elapses with no\n       * activity signal during a turn and the underlying `prompt()` call\n       * still hasn't resolved — distinguishes an inferred completion from\n       * a real one so callers that care can tell the difference.\n       */\n      reason: \"completed\" | \"cancelled\" | \"max_turns\" | \"error\" | \"watchdog-timeout\"\n    }\n  | { kind: \"error\"; sessionId?: string; error: { code?: number; message: string; data?: unknown } }\n  | {\n      kind: \"plan\"\n      sessionId: string\n      title?: string\n      entries: Array<{\n        content: string\n        priority: \"high\" | \"medium\" | \"low\"\n        status: \"pending\" | \"in_progress\" | \"completed\"\n      }>\n    }\n  | {\n      kind: \"usage_update\"\n      sessionId: string\n      size: number\n      used: number\n      cost?: { amount: number; currency: string }\n      /** Cumulative input/output token counts, when the agent reports them\n       *  (some ACP agents send per-token usage alongside the context-window\n       *  `size`/`used`). Lets the daemon price a session that has tokens but\n       *  no adapter-reported `cost`. */\n      tokensIn?: number\n      tokensOut?: number\n      /** The model this usage belongs to, when the agent reports it\n       *  (claude-agent-acp: `_meta[\"_claude/model\"]`). */\n      model?: string\n      /** True when the agent's `size` is a guess it corrects later (the\n       *  claude-agent-acp wrapper's in-turn frames), not a known window. */\n      sizeInferred?: boolean\n      /** The context-window size the agent itself reported, kept by the\n       *  daemon when it corrects `size` (see runtime `context-window.ts`). */\n      reportedSize?: number\n      /**\n       * Who started the cycle this usage closes, when the agent says\n       * (claude-agent-acp: `_meta[\"_claude/origin\"].kind`). `\"task-notification\"`\n       * marks the end of an AUTONOMOUS cycle — the model woke on its own\n       * because a background task settled, with no `session/prompt` in flight.\n       */\n      origin?: string\n    }\n  | {\n      kind: \"background-task\"\n      sessionId: string\n      /**\n       * Lifecycle edge of a non-agent background task (a backgrounded Bash\n       * command, a monitor, ...), published over the AIR `asyncTasks`\n       * extension (`async_task_spawned` / `async_task_progress` /\n       * `async_task_state_update`). `\"started\"` announces the task,\n       * `\"updated\"` carries progress/metadata, `\"settled\"` is terminal.\n       */\n      phase: \"started\" | \"updated\" | \"settled\"\n      task: BackgroundTaskInfo\n    }\n  | {\n      kind: \"available-commands\"\n      sessionId: string\n      /**\n       * The full, current set of slash-commands/skills the agent supports —\n       * an `available_commands_update` REPLACES any previously reported list\n       * wholesale, it is not a delta.\n       */\n      commands: Array<{\n        name: string\n        description?: string\n        input?: { hint?: string } | null\n        _meta?: { scope?: string; path?: string; bareName?: string; qualifiedName?: string }\n      }>\n    }\n","/**\n * AIP-44 ACP client — drives a subprocess agent via stdio JSON-RPC.\n *\n * Wraps `@agentclientprotocol/sdk`'s `ClientSideConnection`. Owns the\n * connection lifecycle, runs `initialize` on construction, and exposes\n * a session API where each `prompt()` call returns an\n * `AsyncIterable<StreamEvent>` fed by the SDK's `session/update`\n * notification handler.\n */\n\nimport {\n  ClientSideConnection,\n  ndJsonStream,\n  type Client as AcpClientHandlers,\n  type SessionConfigOption,\n  type SessionConfigSelectGroup,\n  type SessionConfigSelectOption,\n  type SessionConfigSelectOptions,\n  type SessionMode,\n  type SessionModeState,\n  type Stream,\n} from \"@agentclientprotocol/sdk\"\nimport type {\n  AcpMcpServer,\n  AcpPermissionResolution,\n  BackgroundTaskInfo,\n  StreamEvent,\n} from \"../types.js\"\nimport { ACP_META_FEEDBACK } from \"../types.js\"\n\nexport type { SessionConfigOption, SessionMode }\n\nexport type { AcpPermissionResolution }\n\nconst PROTOCOL_VERSION_DEFAULT = 1\n\n/**\n * The doubly-nested `RequestPermissionResponse` shape the ACP SDK expects\n * back from a `session/request_permission` handler — see\n * `@agentproto/driver-agent-cli`'s `AcpPermissionOutcome` for the full\n * rationale on why the `outcome` field is nested.\n */\ntype RequestPermissionResponse =\n  | { outcome: { outcome: \"selected\"; optionId: string; _meta?: Record<string, unknown> } }\n  | { outcome: { outcome: \"cancelled\" } }\n\n/** A `session/request_permission` RPC parked by permission-hold mode. */\ninterface HeldPermission {\n  sessionId: string\n  resolve: (response: RequestPermissionResponse) => void\n}\n\n/**\n * Map our internal `AcpMcpServer` (`{ name, transport, ref, headers, credentialRef, args, env }`)\n * onto the `@agentclientprotocol/sdk` wire shape expected by\n * `session/new.mcpServers` (and `session/load.mcpServers`).\n *\n * The ACP `McpServer` union is transport-tagged and field-named\n * differently from our compact internal form:\n *   - http → `{ type: \"http\", name, url, headers: [{ name, value }, …] }`\n *   - sse  → `{ type: \"sse\",  name, url, headers: [{ name, value }, …] }`\n *   - stdio → `{ name, command, args, env: [{ name, value }, …] }` (untagged variant)\n *\n * Without this mapping the raw `{ transport, ref }` entry reaches the\n * agent verbatim and `session/new` rejects with `Invalid params` — the\n * symptom that broke orchestrator spawns (the auto-injected scoped\n * gateway is an `http` entry).\n *\n * Retro-compat: an entry that already carries an ACP-native discriminator\n * (`type`/`url`/`command`) is passed through untouched, so callers that\n * pre-shape their entries keep working.\n */\nexport function toAcpMcpServers(servers: readonly unknown[]): unknown[] {\n  return servers.map(toAcpMcpServer)\n}\n\nfunction toAcpMcpServer(server: unknown): unknown {\n  if (!server || typeof server !== \"object\") return server\n  const entry = server as Record<string, unknown>\n\n  // Already ACP-native (has a wire discriminator) → leave as-is.\n  if (\"type\" in entry || \"url\" in entry || \"command\" in entry) return entry\n\n  const transport = entry.transport\n  // Not our `{ name, transport, ref }` shape → nothing to map.\n  if (typeof transport !== \"string\") return entry\n\n  const name = entry.name\n  const ref = entry.ref\n  const headers = entry.headers\n\n  switch (transport) {\n    case \"http\":\n      return { type: \"http\", name, url: ref ?? \"\", headers: toAcpNameValues(headers) }\n    case \"sse\":\n      return { type: \"sse\", name, url: ref ?? \"\", headers: toAcpNameValues(headers) }\n    case \"stdio\":\n      return { name, command: ref ?? \"\", args: toAcpArgs(entry.args), env: toAcpNameValues(entry.env) }\n    default:\n      return entry\n  }\n}\n\nfunction toAcpArgs(args: unknown): string[] {\n  if (!Array.isArray(args)) return []\n  return args.map(a => (typeof a === \"string\" ? a : String(a)))\n}\n\n/** `Record<string,string>` → ACP's `[{ name, value }]` (http headers, stdio env). */\nfunction toAcpNameValues(record: unknown): Array<{ name: string; value: string }> {\n  if (!record || typeof record !== \"object\" || Array.isArray(record)) return []\n  return Object.entries(record).map(([name, value]) => ({\n    name,\n    value: typeof value === \"string\" ? value : String(value),\n  }))\n}\n\nexport interface AcpClientOptions {\n  /** Output bytes go here (subprocess stdin). */\n  output: WritableStream<Uint8Array>\n  /** Input bytes come from here (subprocess stdout). */\n  input: ReadableStream<Uint8Array>\n  /** Client identity advertised during `initialize`. */\n  clientInfo?: {\n    name: string\n    title?: string\n    version?: string\n  }\n  /** Client capabilities advertised during `initialize`. */\n  capabilities?: {\n    fs?: { readTextFile?: boolean; writeTextFile?: boolean }\n    terminal?: boolean\n    /**\n     * Advertise the AIR `asyncTasks` extension (default true), so an agent\n     * that implements it (claude-agent-acp) publishes its background tasks'\n     * lifecycle — surfaced as `background-task` StreamEvents. Pass `false`\n     * to opt out; an agent that doesn't know the extension ignores it.\n     */\n    asyncTasks?: boolean\n  }\n  /** Optional handlers for agent-initiated requests beyond fs / terminal. */\n  handlers?: Partial<AcpClientHandlers>\n  /**\n   * When true, every `session/request_permission` the agent raises is\n   * SURFACED (emitted as an `agent-prompt` StreamEvent on the session's\n   * stream) and HELD — the RPC does not resolve until the host calls\n   * `respondPermission(requestId, ...)`. `handlers.requestPermission` is\n   * bypassed while this is set. Undefined/false (the default) is unchanged:\n   * requests go straight to `handlers.requestPermission`. Used by the\n   * daemon's cross-session permission inbox.\n   */\n  permissionHold?: boolean\n  /** Protocol version to negotiate. Defaults to the SDK's current. */\n  protocolVersion?: number\n  /**\n   * Called on ANY JSON-RPC traffic with the child agent process — every\n   * incoming `session/update` notification (even ones that\n   * `translateSessionUpdate` maps to `null`, e.g. a `tool_call_update`\n   * still in progress) and every outbound RPC call this client makes\n   * (`newSession`, `loadSession`, `setSessionConfigOption`, `prompt`,\n   * `cancel`). Distinct from the `StreamEvent` stream: fires even\n   * during gaps where no event is produced, so a host can track\n   * liveness independent of what the agent actually says.\n   */\n  onActivity?: () => void\n  /**\n   * Turn-idle watchdog: if a `prompt()` call goes this many ms with NO\n   * activity signal (see `onActivity` above — incoming `session/update`\n   * notifications, outbound RPCs) and the underlying `connection.prompt()`\n   * promise still hasn't resolved, synthesize a `turn-end` event with\n   * `reason: \"watchdog-timeout\"` so the caller's async iterator completes\n   * instead of hanging forever. The timer resets on every activity signal\n   * observed DURING that turn, so a legitimately long tool-call chain\n   * (still producing activity, just no user-visible output) never\n   * false-positives — this is \"N ms of true silence,\" not \"N ms since the\n   * turn started.\"\n   *\n   * Undefined (the default) disables the watchdog entirely — existing\n   * callers see no behavior change. If the real `connection.prompt()`\n   * eventually settles after the synthetic turn-end was already emitted,\n   * the late result is logged and discarded (no crash, no duplicate\n   * turn-end for the same logical turn).\n   */\n  turnIdleTimeoutMs?: number\n  /**\n   * Orphaned-prompt recovery (default {@link DEFAULT_ORPHANED_PROMPT_TIMEOUT_MS};\n   * `0` disables). A prompt sent while the agent is mid-way through an\n   * AUTONOMOUS cycle (Claude Code's task-notification wake) can be folded\n   * into that cycle as a queued command: the model answers it, but the\n   * cycle's only result carries the autonomous origin, which claude-agent-acp\n   * keeps off the user-turn lane — so `session/prompt` never resolves (seen\n   * live: a finished session stayed \"busy\" ~50 min until a manual cancel).\n   * When an in-flight prompt sees an autonomous-origin result frame followed\n   * by this many ms of silence, the client cancels it — a real active turn\n   * on the agent side, so the cancel settles it — and reports the turn\n   * `completed`: its work was done inside the cycle.\n   */\n  orphanedPromptTimeoutMs?: number\n}\n\nexport const DEFAULT_ORPHANED_PROMPT_TIMEOUT_MS = 60_000\n\n/** Result origins claude-agent-acp routes to its autonomous lane\n *  (`AUTONOMOUS_RESULT_ORIGINS` in its acp-agent.js). */\nconst AUTONOMOUS_RESULT_ORIGINS = new Set([\n  \"task-notification\",\n  \"peer\",\n  \"coordinator\",\n  \"observer\",\n  \"observer-activity\",\n])\n\n/** The ACP steering extension request (claude-agent-acp, codex-acp):\n *  inject a follow-up into the turn that is currently running. */\nexport const ACP_STEER_METHOD = \"_session/steering\"\n\n/** What `AcpClientSession.steer` did:\n *  - `\"steered\"` — injected into the running turn;\n *  - `\"promptRequired\"` — no turn in flight (checked here first: we only\n *    steer while OUR `prompt()` is in flight, never during an agent's\n *    autonomous cycle), so nothing was sent — deliver it as a normal prompt;\n *  - `\"unsupported\"` — the agent doesn't advertise steering, or refused. */\nexport type SteerOutcome = \"steered\" | \"promptRequired\" | \"unsupported\"\n\nexport interface AcpClient {\n  readonly connection: ClientSideConnection\n  /**\n   * Whether the underlying JSON-RPC connection is still open. Reads the SDK\n   * connection's own abort signal (`ClientSideConnection.signal`), which is\n   * aborted synchronously the moment the transport closes — so this is a\n   * FRESH fact at call time, never a cached flag that can go stale.\n   *\n   * The pull counterpart to {@link AcpClient.onDisconnect}: a sweep (the\n   * daemon's crash-detect pass) can ask \"is this session's adapter actually\n   * reachable?\" without waiting for a prompt to fail.\n   */\n  isConnected(): boolean\n  /**\n   * Subscribe to transport death. `listener` fires at most once, when the\n   * JSON-RPC connection to the agent goes away — the subprocess's stdout\n   * ended, the transport errored, or the SDK closed the connection for any\n   * other reason — and fires SYNCHRONOUSLY if it's already gone by the time\n   * you subscribe (so there is no window where a late subscriber misses it).\n   *\n   * This is the only push signal for the failure mode a pid probe cannot\n   * see: the wrapper process is still alive (`process.kill(pid, 0)`\n   * succeeds) but its ACP stream is dead, so every subsequent RPC rejects\n   * with \"ACP connection closed\" while the host still believes the session\n   * is running.\n   *\n   * Also fires for an ORDERLY teardown (the host's own `close()` aborts the\n   * same controller), so a consumer that only cares about UNEXPECTED death\n   * must gate on its own \"did I ask for this?\" state — the daemon does that\n   * via the session's status (`markCrashed` only acts on a `running` row).\n   */\n  onDisconnect(listener: (err: Error) => void): void\n  /** Negotiated agent capabilities returned from `initialize`. */\n  readonly agentCapabilities: Record<string, unknown> | undefined\n  /** The TOP-LEVEL `_meta` of the `initialize` response (sibling of\n   *  `agentCapabilities`) — where extension capabilities such as\n   *  `steering.supported` are advertised. `undefined` when absent. */\n  readonly initMeta: Record<string, unknown> | undefined\n  /** True when the agent advertised `_meta.steering.supported` at\n   *  initialize — i.e. it accepts `_session/steering`. */\n  readonly steeringSupported: boolean\n  newSession(params: {\n    cwd: string\n    mcpServers?: unknown[]\n    /**\n     * Model to select via `session/set_config_option` immediately after\n     * `newSession`. The claude-agent-acp wrapper supports this as\n     * `configId:\"model\"`. Omit to keep the agent's own default.\n     *\n     * Best-effort: a value the agent can't resolve (a stale/gated/typo'd id)\n     * is warned about and dropped — the session still starts on the agent's\n     * default model rather than crashing the spawn. See the reject handler\n     * in `newSession` for the reasoning (agentproto#186).\n     */\n    model?: string\n    /**\n     * Effort level to select via `session/set_config_option` after\n     * `newSession`. Effort is model-dependent — same label ≠ same\n     * budget across models; defaults differ too (see AgentCliConnectOptions).\n     * Omit to keep the model's own default.\n     */\n    effort?: string\n    /**\n     * Mode to select via `session/set_config_option` after `newSession`,\n     * for ACP servers that model mode selection as a session config\n     * option (`configId:\"mode\"`) instead of a CLI flag — e.g. opencode.\n     * Best-effort, same as `model`/`effort`: a rejection is warned about\n     * and dropped rather than failing the spawn. Omit to keep the\n     * agent's own default mode.\n     */\n    mode?: string\n    /**\n     * Extra `_meta` for the `session/new` request (vendor-extension bag —\n     * e.g. claude-agent-acp's `_meta.systemPrompt = { append: text }`).\n     * Forwarded verbatim as the request's `_meta`, only when set. Omit to\n     * send no `_meta` at all (unchanged).\n     */\n    meta?: Record<string, unknown>\n  }): Promise<AcpClientSession>\n  /**\n   * Reattach to an existing session by id. Available only when the\n   * agent advertised `loadSession: true` in its capabilities (callers\n   * should check `agentCapabilities` first; we forward the SDK error\n   * verbatim if they don't).\n   *\n   * Drives the AIP-45 native-resume continuation strategy: the host\n   * persists the `sessionId` returned by `newSession`, then on a\n   * cold start (process restart, fresh sandbox, different machine)\n   * spawns a new subprocess and calls `loadSession` to pick up\n   * the conversation from the stored history.\n   */\n  loadSession(params: {\n    sessionId: string\n    cwd: string\n    mcpServers?: unknown[]\n    /**\n     * Model to re-assert via `session/set_config_option` immediately after\n     * `loadSession`. A native-resume spawns a fresh subprocess whose session\n     * config starts from the harness default; some harnesses (opencode)\n     * PERSIST and restore the session's own model, so a resumed session that\n     * omits this silently runs the harness default — a different provider on a\n     * different bill for a derived-from-model adapter. Same best-effort\n     * contract as {@link newSession}'s `model` (a rejection is recorded on\n     * `modelApplyRejection`, never fatal here). Omit to keep the resumed\n     * session's own model.\n     */\n    model?: string\n    /** Effort level to re-assert on the resumed session — same contract as\n     *  {@link newSession}'s `effort`. Omit to keep the model's own default. */\n    effort?: string\n    /** Mode to re-assert on the resumed session via\n     *  `session/set_config_option(configId:\"mode\")` — same contract as\n     *  {@link newSession}'s `mode`. Omit to keep the resumed session's own\n     *  mode. */\n    mode?: string\n    /**\n     * Extra `_meta` for the `session/load` request — same contract as\n     * {@link newSession}'s `meta` (claude-agent-acp re-reads e.g.\n     * `_meta.systemPrompt` on load too, so a channel-backed text must be\n     * re-sent every cold resume or it is lost after turn 1).\n     */\n    meta?: Record<string, unknown>\n  }): Promise<AcpClientSession>\n  /**\n   * Resolve a permission request parked by permission-hold mode. `requestId`\n   * is the `toolCallId` carried on the `agent-prompt` StreamEvent that\n   * surfaced the request. Returns true when a matching parked request was\n   * found and resolved, false when the id is unknown or already resolved\n   * (idempotent — a duplicate response is a no-op). No-op returning false\n   * when `permissionHold` was never enabled.\n   */\n  respondPermission(\n    requestId: string,\n    resolution: AcpPermissionResolution,\n  ): boolean\n  close(): Promise<void>\n}\n\n/**\n * Result of a mid-session `setConfigOption` call — mirrors the best-effort\n * contract `newSession`'s own `model`/`effort`/`mode` params already use\n * (see the reject handler below): a rejected config option is reported\n * structurally, never thrown, so a caller can surface \"didn't apply\" to a\n * human without the live session (or its in-flight turn) ever being at risk.\n */\nexport interface SetConfigOptionResult {\n  applied: boolean\n  /** Present only when `applied` is false — the server's rejection detail\n   *  (see `configOptionErrorDetail`), or a client-side reason. */\n  reason?: string\n}\n\nexport interface AcpClientSession {\n  readonly sessionId: string\n  /**\n   * Set when `newSession`'s connect-time `model` apply was REJECTED by the\n   * server — the session is live but running on the agent's own default\n   * model, not the requested one. The apply itself stays non-fatal here\n   * (agentproto#186: a rejected model must never crash the spawn with an\n   * opaque error), but silently-on-the-wrong-model is exactly the failure\n   * a caller may need to escalate: for a derived-from-model adapter\n   * (opencode & co.) the model IS the route, so \"kept the default\" means\n   * a different provider and a different bill. This field is the\n   * structural signal that lets the host decide — warn for free-routing\n   * adapters, fail loudly for derived-from-model ones. `undefined` when no\n   * model was requested, the apply succeeded, or the session was resumed\n   * (`loadSession` applies no model).\n   */\n  readonly modelApplyRejection?: { requested: string; reason: string }\n  /**\n   * The wrapper's advertised session configuration options (SDK\n   * `SessionConfigOption[]`), captured verbatim from `newSession`'s /\n   * `loadSession`'s response at connect time — the per-model value lists\n   * (e.g. which model/effort ids the wrapper will actually accept) that\n   * today are otherwise discoverable only by calling `setConfigOption`\n   * and catching a reject. A read surface so a caller can resolve what's\n   * offerable BEFORE attempting to apply it. Empty when the wrapper\n   * advertises nothing (`configOptions` absent/`null` on the wire) —\n   * never inferred or guessed. Snapshot at connect time; not live-updated\n   * by a later `setConfigOption`/`setSessionMode` call.\n   */\n  readonly availableConfigOptions: SessionConfigOption[]\n  /**\n   * The wrapper's advertised session modes (SDK `SessionModeState.\n   * availableModes`), captured from the same connect-time response.\n   * Empty when the wrapper has no native mode registry (`modes`\n   * absent/`null` on the wire) — the read-surface signal a caller uses to\n   * decide there's no native posture to switch, only a portable/\n   * prompt-injected one. Snapshot at connect time, same as\n   * `availableConfigOptions`.\n   */\n  readonly availableModes: SessionMode[]\n  /**\n   * The mode id the wrapper reported as active (`SessionModeState.\n   * currentModeId`) at connect time. `undefined` when the wrapper\n   * advertised no mode state at all.\n   */\n  readonly currentModeId: string | undefined\n  prompt(input: {\n    messages: unknown[]\n    signal?: AbortSignal\n  }): AsyncIterable<StreamEvent>\n  cancel(): Promise<void>\n  /**\n   * Apply a session config option (e.g. `configId:\"model\"`) on this LIVE,\n   * already-connected session — the mid-session counterpart to the\n   * `model`/`effort`/`mode` params `newSession` accepts at connect time.\n   * Same non-fatal contract: a server rejection resolves\n   * `{applied:false, reason}` instead of throwing, so a bad or gated model\n   * id can never kill an otherwise-healthy session.\n   */\n  setConfigOption(configId: string, value: string): Promise<SetConfigOptionResult>\n  /**\n   * Switch this session's mode on this LIVE, already-connected session via\n   * ACP `session/set_mode` (SDK `setSessionMode`) — the native-posture\n   * counterpart to `setConfigOption`, distinct axis (SDK models mode and\n   * config-option as separate RPCs). Same best-effort, non-fatal contract:\n   * a mode the wrapper doesn't recognize (not in `availableModes`, a stale\n   * offer, or a version mismatch) resolves `{applied:false, reason}`\n   * instead of throwing — a rejected mode switch must never kill an\n   * otherwise-healthy session, mirroring `setConfigOption`'s contract\n   * exactly.\n   */\n  setSessionMode(modeId: string): Promise<SetConfigOptionResult>\n  /**\n   * Receive the events the agent emits while NO `prompt()` is in flight.\n   *\n   * An agent can work without being prompted: Claude Code wakes the model on\n   * its own when a background task settles (an \"autonomous\" task-notification\n   * cycle) and streams that work as ordinary `session/update`s. With no turn\n   * iterator to land in, those events used to be dropped on the floor — the\n   * host saw an idle session while the agent kept working. They are delivered\n   * here instead (in-turn events keep flowing through `prompt()`'s iterator\n   * only). Returns an unsubscribe function. With no listener registered, an\n   * out-of-turn event is dropped, as before.\n   */\n  onOutOfTurnEvent(listener: (event: StreamEvent) => void): () => void\n  /** Whether this session's agent accepts `_session/steering` (see\n   *  `AcpClient.steeringSupported`). */\n  readonly steeringSupported: boolean\n  /**\n   * Steer the turn in flight: inject `content` into it (ACP steering\n   * extension, `_session/steering`) instead of queueing a new prompt.\n   * Always sends `idleBehavior:\"promptRequired\"`, and never sends at all\n   * unless OUR `prompt()` is in flight — so it can't start a detached turn\n   * the host never sees, or fold into an agent's autonomous cycle. Never\n   * throws; see {@link SteerOutcome}.\n   */\n  steer(content: unknown): Promise<SteerOutcome>\n  close(): Promise<void>\n}\n\ninterface SessionState {\n  events: StreamEvent[]\n  resolveNext: ((evt: StreamEvent | undefined) => void) | null\n  done: boolean\n  active: boolean\n  /**\n   * Set by `buildSession.prompt()` for the duration of an in-flight turn\n   * when a watchdog timer is armed; cleared once that turn settles. Lets\n   * the `sessionUpdate` handler (which only has a `sessionId`, not a\n   * closure over the turn's timer) bump the SAME timer an incoming\n   * notification is liveness evidence for.\n   */\n  resetWatchdogTimer?: () => void\n  /** Snapshot of `AcpClientSession.availableConfigOptions` — see there. */\n  configOptions: SessionConfigOption[]\n  /** Snapshot of `AcpClientSession.availableModes` — see there. */\n  modes: SessionMode[]\n  /** Snapshot of `AcpClientSession.currentModeId` — see there. */\n  currentModeId: string | undefined\n  /** Listeners registered via `AcpClientSession.onOutOfTurnEvent`. */\n  outOfTurnListeners: Set<(event: StreamEvent) => void>\n  /** See `AcpClientOptions.orphanedPromptTimeoutMs`. */\n  orphanedPromptTimeoutMs: number\n  /** Set by `prompt()` for the in-flight turn: sees every incoming update\n   *  (translated, or null) to drive orphaned-prompt recovery. */\n  observeTurnUpdate?: (event: StreamEvent | null) => void\n}\n\nexport async function createAcpClient(\n  options: AcpClientOptions,\n): Promise<AcpClient> {\n  const sessions = new Map<string, SessionState>()\n\n  // Permission-hold state: parked `session/request_permission` RPCs keyed by\n  // the stable request id we mint per request (and emit on the `agent-prompt`\n  // StreamEvent). Empty and untouched unless `permissionHold` is set.\n  const pendingPermissions = new Map<string, HeldPermission>()\n  let permissionSeq = 0\n\n  const respondPermission = (\n    requestId: string,\n    resolution: AcpPermissionResolution,\n  ): boolean => {\n    const held = pendingPermissions.get(requestId)\n    if (!held) return false\n    pendingPermissions.delete(requestId)\n    held.resolve(\n      \"cancelled\" in resolution\n        ? { outcome: { outcome: \"cancelled\" } }\n        : {\n            outcome: {\n              outcome: \"selected\",\n              optionId: resolution.optionId,\n              ...(resolution.feedback\n                ? { _meta: { [ACP_META_FEEDBACK]: resolution.feedback } }\n                : {}),\n            },\n          },\n    )\n    return true\n  }\n\n  // Resolve every request parked for a session as `cancelled` — used when a\n  // session (or the whole client) tears down so no held RPC dangles.\n  const cancelPermissionsForSession = (sessionId: string): void => {\n    // Collect the matching keys first, THEN delete + resolve — never mutate the\n    // map while iterating its entries.\n    const ids: string[] = []\n    for (const [id, held] of pendingPermissions) {\n      if (held.sessionId === sessionId) ids.push(id)\n    }\n    for (const id of ids) {\n      const held = pendingPermissions.get(id)\n      if (!held) continue\n      pendingPermissions.delete(id)\n      held.resolve({ outcome: { outcome: \"cancelled\" } })\n    }\n  }\n\n  const stream: Stream = withAirTaskUpdatesRerouted(\n    ndJsonStream(options.output, options.input),\n  )\n\n  const connection: ClientSideConnection = new ClientSideConnection(\n    () =>\n      buildClientHandlers(options.handlers ?? {}, sessions, options.onActivity, {\n        permissionHold: options.permissionHold ?? false,\n        pendingPermissions,\n        nextRequestId: () => `perm_${++permissionSeq}`,\n      }),\n    stream,\n  )\n\n  // Transport-death subscription. `connection.signal` is the SDK's own\n  // AbortController: `Connection.close()` aborts it with the close error\n  // (`new Error(\"ACP connection closed\")` when the stream simply ended), and\n  // that happens the instant the subprocess's stdout reader completes — long\n  // before anything else in the stack notices.\n  const onDisconnect = (listener: (err: Error) => void): void => {\n    const signal = connection.signal\n    const fire = (): void => {\n      const reason: unknown = signal.reason\n      listener(reason instanceof Error ? reason : new Error(\"ACP connection closed\"))\n    }\n    // Already dead by the time this subscriber arrived — `addEventListener`\n    // on an aborted signal never fires, so report it directly. This is what\n    // makes subscribing AFTER connect (the daemon does, once it has the\n    // session handle) race-free.\n    if (signal.aborted) fire()\n    else signal.addEventListener(\"abort\", fire, { once: true })\n  }\n\n  const initResponse = await connection.initialize({\n    protocolVersion: options.protocolVersion ?? PROTOCOL_VERSION_DEFAULT,\n    clientCapabilities: clientCapabilitiesFromOptions(options),\n    clientInfo: options.clientInfo\n      ? {\n          name: options.clientInfo.name,\n          title: options.clientInfo.title ?? options.clientInfo.name,\n          version: options.clientInfo.version ?? \"0.0.0\",\n        }\n      : undefined,\n  } as never)\n\n  const initMeta = (initResponse as { _meta?: Record<string, unknown> | null })._meta ?? undefined\n  const steeringSupported = isSteeringAdvertised(initMeta)\n\n  // Apply the operator's model/effort/mode over the freshly-created session's\n  // config options. Shared by newSession AND loadSession: loadSession used to\n  // apply NOTHING, so a resumed session silently kept the harness's own default\n  // model instead of the operator's. For a derived-from-model adapter\n  // (opencode & co.) that is a different provider on a different bill — and\n  // opencode's default `opencode/big-pickle` is a per-IP rate-limited free id,\n  // so the resumed session then failed \"Rate limit exceeded\" while its\n  // agentproto metadata still claimed the requested model/route. Model is\n  // applied FIRST (a model switch rebuilds the effort option list), then\n  // effort, then mode. A model rejection is recorded structurally for the\n  // driver's derived-from-model guard; effort/mode rejections stay best-effort\n  // (agentproto#186).\n  const applyConfigOptions = async (\n    sessionId: string,\n    params: { model?: string; effort?: string; mode?: string },\n  ): Promise<{ modelApplyRejection?: { requested: string; reason: string } }> => {\n    let modelApplyRejection: { requested: string; reason: string } | undefined\n    if (params.model) {\n      try {\n        await connection.setSessionConfigOption({\n          configId: \"model\",\n          value: params.model,\n          sessionId,\n        } as never)\n        options.onActivity?.()\n      } catch (err) {\n        const reason = configOptionErrorDetail(err)\n        modelApplyRejection = { requested: params.model, reason }\n        console.warn(\n          `[acp] set_config_option model=\"${params.model}\" rejected by server ` +\n            `— keeping the agent's default model. Reason: ${reason}`,\n        )\n      }\n    }\n    if (params.effort) {\n      try {\n        await connection.setSessionConfigOption({\n          configId: \"effort\",\n          value: params.effort,\n          sessionId,\n        } as never)\n        options.onActivity?.()\n      } catch (err) {\n        console.warn(\n          `[acp] set_config_option effort=\"${params.effort}\" rejected by server ` +\n            `(best-effort): ${configOptionErrorDetail(err)}`,\n        )\n      }\n    }\n    if (params.mode) {\n      try {\n        await connection.setSessionConfigOption({\n          configId: \"mode\",\n          value: params.mode,\n          sessionId,\n        } as never)\n        options.onActivity?.()\n      } catch (err) {\n        console.warn(\n          `[acp] set_config_option mode=\"${params.mode}\" rejected by server ` +\n            `(best-effort): ${configOptionErrorDetail(err)}`,\n        )\n      }\n    }\n    return modelApplyRejection ? { modelApplyRejection } : {}\n  }\n\n  return {\n    connection,\n    isConnected: () => !connection.signal.aborted,\n    onDisconnect,\n    agentCapabilities: (initResponse as { agentCapabilities?: Record<string, unknown> })\n      .agentCapabilities,\n    initMeta,\n    steeringSupported,\n    async newSession(params) {\n      let response: Awaited<ReturnType<ClientSideConnection[\"newSession\"]>>\n      try {\n        response = await connection.newSession({\n          cwd: params.cwd,\n          mcpServers: toAcpMcpServers(params.mcpServers ?? []) as never,\n          ...(params.meta ? { _meta: params.meta } : {}),\n        } as never)\n      } catch (err) {\n        // The detail travels in `error.data.details`, not the message —\n        // a refused spawn (bad repo source, missing credential, vendor\n        // API error) would otherwise surface as a bare \"Internal error\".\n        throw enrichInternalAcpError(err)\n      }\n      options.onActivity?.()\n      const sessionId = (response as { sessionId: string }).sessionId\n      const configOptions = response.configOptions ?? []\n      const { modes, currentModeId } = sessionModes(response.modes, configOptions)\n      const state: SessionState = {\n        events: [],\n        resolveNext: null,\n        done: false,\n        active: false,\n        configOptions,\n        modes,\n        currentModeId,\n        outOfTurnListeners: new Set(),\n        orphanedPromptTimeoutMs:\n          options.orphanedPromptTimeoutMs ?? DEFAULT_ORPHANED_PROMPT_TIMEOUT_MS,\n      }\n      sessions.set(sessionId, state)\n      const { modelApplyRejection } = await applyConfigOptions(sessionId, params)\n      return buildSession(\n        connection,\n        sessionId,\n        state,\n        sessions,\n        options.onActivity,\n        options.turnIdleTimeoutMs,\n        cancelPermissionsForSession,\n        modelApplyRejection,\n        steeringSupported,\n      )\n    },\n    async loadSession(params) {\n      // SDK returns `LoadSessionResponse` (no body fields we need); the\n      // sessionId is what the caller already provided. We register a\n      // fresh `SessionState` so subsequent `prompt` calls have a slot\n      // to flush events into — same lifecycle shape as a brand-new\n      // session.\n      let response: Awaited<ReturnType<ClientSideConnection[\"loadSession\"]>>\n      try {\n        response = await connection.loadSession({\n          sessionId: params.sessionId,\n          cwd: params.cwd,\n          mcpServers: toAcpMcpServers(params.mcpServers ?? []) as never,\n          ...(params.meta ? { _meta: params.meta } : {}),\n        } as never)\n      } catch (err) {\n        // Same as newSession: the real refusal (e.g. a cloud adapter naming\n        // the vendor id it cannot re-attach to) travels in data.details.\n        throw enrichInternalAcpError(err)\n      }\n      options.onActivity?.()\n      const configOptions = response.configOptions ?? []\n      const { modes, currentModeId } = sessionModes(response.modes, configOptions)\n      const state: SessionState = {\n        events: [],\n        resolveNext: null,\n        done: false,\n        active: false,\n        configOptions,\n        modes,\n        currentModeId,\n        outOfTurnListeners: new Set(),\n        orphanedPromptTimeoutMs:\n          options.orphanedPromptTimeoutMs ?? DEFAULT_ORPHANED_PROMPT_TIMEOUT_MS,\n      }\n      sessions.set(params.sessionId, state)\n      // Re-assert the operator's model/effort/mode on the RESUMED session — a\n      // native-resume spawns a fresh subprocess whose in-memory config starts\n      // from the harness default, and opencode (unlike claude-code) PERSISTS\n      // and restores the session's model. Without this the requested model is\n      // silently dropped and the resumed session runs the harness default\n      // (opencode: `opencode/big-pickle`, a rate-limited free id). The driver's\n      // derived-from-model guard consumes the returned rejection.\n      const { modelApplyRejection } = await applyConfigOptions(params.sessionId, params)\n      return buildSession(\n        connection,\n        params.sessionId,\n        state,\n        sessions,\n        options.onActivity,\n        options.turnIdleTimeoutMs,\n        cancelPermissionsForSession,\n        modelApplyRejection,\n        steeringSupported,\n      )\n    },\n    respondPermission,\n    async close() {\n      // Never leave a held permission RPC dangling — resolve all as cancelled.\n      for (const [, held] of pendingPermissions) {\n        held.resolve({ outcome: { outcome: \"cancelled\" } })\n      }\n      pendingPermissions.clear()\n      sessions.clear()\n    },\n  }\n}\n\n/**\n * The AIR extension's `_meta` shape, as claude-agent-acp reads it\n * (`air-extension.js` `clientSupportsAirCapability`): an integer `version`\n * >= 1 and a `capabilities` list, under `_meta.jetbrains.air`.\n */\nexport const AIR_ASYNC_TASKS_CAPABILITY = \"asyncTasks\"\nconst AIR_EXTENSION_VERSION = 1\n\nfunction clientCapabilitiesFromOptions(\n  options: AcpClientOptions,\n): Record<string, unknown> {\n  const caps = options.capabilities ?? {}\n  return {\n    fs: {\n      readTextFile: caps.fs?.readTextFile ?? false,\n      writeTextFile: caps.fs?.writeTextFile ?? false,\n    },\n    terminal: caps.terminal ?? false,\n    ...(caps.asyncTasks === false\n      ? {}\n      : {\n          _meta: {\n            jetbrains: {\n              air: {\n                version: AIR_EXTENSION_VERSION,\n                capabilities: [AIR_ASYNC_TASKS_CAPABILITY],\n              },\n            },\n          },\n        }),\n  }\n}\n\n/** `InitializeResponse._meta.steering.supported === true`. */\nexport function isSteeringAdvertised(initMeta: Record<string, unknown> | undefined): boolean {\n  const steering = initMeta?.steering\n  return (\n    typeof steering === \"object\" &&\n    steering !== null &&\n    (steering as { supported?: unknown }).supported === true\n  )\n}\n\n/** A raw string, one ContentBlock, or a block array → ContentBlock[]. */\nfunction toContentBlocks(content: unknown): unknown[] {\n  if (typeof content === \"string\") return content ? [{ type: \"text\", text: content }] : []\n  if (Array.isArray(content)) return content\n  if (content && typeof content === \"object\") return [content]\n  return []\n}\n\nfunction buildSession(\n  connection: ClientSideConnection,\n  sessionId: string,\n  state: SessionState,\n  sessions: Map<string, SessionState>,\n  onActivity: (() => void) | undefined,\n  turnIdleTimeoutMs: number | undefined,\n  cancelPermissionsForSession: (sessionId: string) => void,\n  modelApplyRejection?: { requested: string; reason: string },\n  steeringSupported = false,\n): AcpClientSession {\n  return {\n    sessionId,\n    steeringSupported,\n    ...(modelApplyRejection ? { modelApplyRejection } : {}),\n    availableConfigOptions: state.configOptions,\n    availableModes: state.modes,\n    currentModeId: state.currentModeId,\n    prompt(input) {\n      if (state.active) {\n        throw new Error(\n          `AcpClientSession.prompt: session ${sessionId} already has an in-flight prompt`,\n        )\n      }\n      state.active = true\n      state.done = false\n      state.events.length = 0\n\n      const iter = makeIterator(state)\n\n      // Turn-idle watchdog — undefined turnIdleTimeoutMs disables it\n      // entirely (existing callers see no behavior change). Armed below\n      // and re-armed on every activity signal observed during this turn\n      // (outbound send, resolve, and incoming session/update via\n      // `state.resetWatchdogTimer`); cleared once the turn settles.\n      let watchdogTimer: ReturnType<typeof setTimeout> | undefined\n      let watchdogFired = false\n      const clearWatchdogTimer = () => {\n        if (watchdogTimer) clearTimeout(watchdogTimer)\n        watchdogTimer = undefined\n      }\n      const armWatchdogTimer = () => {\n        if (turnIdleTimeoutMs === undefined) return\n        clearWatchdogTimer()\n        watchdogTimer = setTimeout(() => {\n          watchdogFired = true\n          state.done = true\n          enqueue(state, { kind: \"turn-end\", sessionId, reason: \"watchdog-timeout\" })\n        }, turnIdleTimeoutMs)\n      }\n      state.resetWatchdogTimer = armWatchdogTimer\n\n      // Orphaned-prompt recovery — see `AcpClientOptions.orphanedPromptTimeoutMs`.\n      // Armed by an autonomous-origin result frame, disarmed by ANY later\n      // update (the agent went on to run this prompt after all).\n      let orphanTimer: ReturnType<typeof setTimeout> | undefined\n      let orphanCancelled = false\n      const clearOrphanTimer = () => {\n        if (orphanTimer) clearTimeout(orphanTimer)\n        orphanTimer = undefined\n      }\n      state.observeTurnUpdate = event => {\n        clearOrphanTimer()\n        if (\n          state.orphanedPromptTimeoutMs > 0 &&\n          event?.kind === \"usage_update\" &&\n          event.cost &&\n          event.origin !== undefined &&\n          AUTONOMOUS_RESULT_ORIGINS.has(event.origin)\n        ) {\n          orphanTimer = setTimeout(() => {\n            orphanCancelled = true\n            console.warn(\n              `[acp] session ${sessionId}: prompt still unresolved ` +\n                `${state.orphanedPromptTimeoutMs}ms after an autonomous (${event.origin}) ` +\n                `result — it was folded into that cycle; cancelling to settle it.`,\n            )\n            void connection.cancel({ sessionId } as never)\n          }, state.orphanedPromptTimeoutMs)\n        }\n      }\n\n      // Outbound send — proves the daemon is still driving this turn,\n      // independent of whatever StreamEvents come back. Also the initial\n      // arm of the watchdog timer, so the timeout is measured from \"we\n      // just sent this\" rather than some earlier idle point.\n      armWatchdogTimer()\n      onActivity?.()\n      const promise = connection\n        .prompt({\n          sessionId,\n          prompt: input.messages as never,\n        } as never)\n        .then((response) => {\n          clearWatchdogTimer()\n          onActivity?.()\n          if (watchdogFired) {\n            console.warn(\n              `[acp] session ${sessionId}: connection.prompt() resolved after the ` +\n                `turn-idle watchdog already synthesized a turn-end — ignoring late response.`,\n            )\n            return\n          }\n          // Map the ACP StopReason enum\n          // (end_turn | max_tokens | max_turn_requests | refusal | cancelled)\n          // to a turn-end reason. The two budget caps (max_tokens,\n          // max_turn_requests) are legitimate completions that DID produce\n          // output — route them to the non-failing \"max_turns\" bucket, never\n          // \"error\". \"refusal\" is an adapter's honest \"I could not complete\n          // this turn\" (e.g. claude-sdk returns it after a 401 auth failure,\n          // emitting a `[claude-sdk error]` chunk — so the turn is NOT empty\n          // and the empty-turn guard can't catch it); it — and any\n          // unknown/missing stopReason — must map to \"error\", not the\n          // false-green \"completed\" that let an un-authenticated reviewer\n          // report success without posting a review.\n          const stopReason = (response as { stopReason?: string }).stopReason\n          // Our own orphan cancel: the prompt's work was done in the cycle.\n          if (orphanCancelled && stopReason === \"cancelled\") {\n            enqueue(state, { kind: \"turn-end\", sessionId, reason: \"completed\" })\n            return\n          }\n          enqueue(state, {\n            kind: \"turn-end\",\n            sessionId,\n            reason:\n              (stopReason === \"cancelled\" && \"cancelled\") ||\n              (stopReason === \"max_tokens\" && \"max_turns\") ||\n              (stopReason === \"max_turn_requests\" && \"max_turns\") ||\n              (stopReason === \"end_turn\" && \"completed\") ||\n              \"error\",\n          })\n        })\n        .catch((err: unknown) => {\n          clearWatchdogTimer()\n          if (watchdogFired) {\n            console.warn(\n              `[acp] session ${sessionId}: connection.prompt() rejected after the ` +\n                `turn-idle watchdog already synthesized a turn-end — ignoring late error:`,\n              err instanceof Error ? err.message : err,\n            )\n            return\n          }\n          // A server-side throw during the turn arrives as a JSON-RPC\n          // -32603 whose message is just \"Internal error\" — surface the\n          // `error.data.details` cause (the vendor's API error, a missing\n          // credential, …) in the message instead.\n          const cause = enrichInternalAcpError(err)\n          const message =\n            cause instanceof Error ? cause.message : String(cause)\n          enqueue(state, {\n            kind: \"error\",\n            sessionId,\n            error: { message },\n          })\n        })\n        .finally(() => {\n          state.active = false\n          state.done = true\n          state.resetWatchdogTimer = undefined\n          state.observeTurnUpdate = undefined\n          clearWatchdogTimer()\n          clearOrphanTimer()\n          flush(state)\n        })\n\n      if (input.signal) {\n        input.signal.addEventListener(\n          \"abort\",\n          () => {\n            void connection.cancel({ sessionId } as never)\n          },\n          { once: true },\n        )\n      }\n\n      void promise\n      return iter\n    },\n    async cancel() {\n      if (!state.active) return\n      await connection.cancel({ sessionId } as never)\n      onActivity?.()\n    },\n    async steer(content) {\n      if (!steeringSupported) return \"unsupported\"\n      // Host-turn gate: steer only into a turn WE started. With no prompt()\n      // in flight there's nothing to inject into from the host's point of\n      // view (an agent-autonomous cycle doesn't count), so hand the content\n      // back for a normal prompt without touching the wire.\n      if (!state.active) return \"promptRequired\"\n      const prompt = toContentBlocks(content)\n      if (!prompt.length) return \"unsupported\"\n      try {\n        const res = (await connection.extMethod(ACP_STEER_METHOD, {\n          sessionId,\n          prompt,\n          _meta: { steering: { idleBehavior: \"promptRequired\" } },\n        })) as { outcome?: unknown }\n        onActivity?.()\n        switch (res?.outcome) {\n          case \"injected\":\n            return \"steered\"\n          case \"promptRequired\":\n            return \"promptRequired\"\n          case \"startedNewTurn\":\n            // The agent ignored the opt-in and started a detached turn — the\n            // content WAS delivered, so report it (a caller must not re-send).\n            console.warn(\n              `[acp] session ${sessionId}: steering ignored idleBehavior:\"promptRequired\" ` +\n                `and started a new turn`,\n            )\n            return \"steered\"\n          default:\n            console.warn(\n              `[acp] session ${sessionId}: unexpected steering outcome ${JSON.stringify(res?.outcome)}`,\n            )\n            return \"unsupported\"\n        }\n      } catch (err) {\n        console.warn(\n          `[acp] session ${sessionId}: ${ACP_STEER_METHOD} rejected — ` +\n            (err instanceof Error ? err.message : String(err)),\n        )\n        return \"unsupported\"\n      }\n    },\n    async setConfigOption(configId, value) {\n      try {\n        await connection.setSessionConfigOption({\n          configId,\n          value,\n          sessionId,\n        } as never)\n        onActivity?.()\n        return { applied: true }\n      } catch (err) {\n        // Non-fatal by design — same reasoning as newSession's own\n        // model/effort/mode application above: the agent's accepted\n        // vocabulary for a config option is dynamic (varies by wrapper\n        // version + account entitlements), so a rejection here is\n        // expected and must never propagate as a thrown error. The\n        // caller decides what to do with `{applied:false, reason}`\n        // (e.g. surface a non-modal warning), the session itself is\n        // completely unaffected.\n        const reason = configOptionErrorDetail(err)\n        console.warn(\n          `[acp] session ${sessionId}: set_config_option ${configId}=\"${value}\" ` +\n            `rejected by server — ${reason}`,\n        )\n        return { applied: false, reason }\n      }\n    },\n    async setSessionMode(modeId) {\n      try {\n        await connection.setSessionMode({ sessionId, modeId })\n        onActivity?.()\n        return { applied: true }\n      } catch (err) {\n        // Non-fatal by design — same reasoning as `setConfigOption` above:\n        // a mode id the wrapper doesn't (or no longer) recognize must never\n        // propagate as a thrown error. The caller decides what to do with\n        // `{applied:false, reason}` (e.g. route the pick through a restart\n        // override instead), the session itself is completely unaffected.\n        const reason = configOptionErrorDetail(err)\n        console.warn(\n          `[acp] session ${sessionId}: set_mode \"${modeId}\" rejected by server — ${reason}`,\n        )\n        return { applied: false, reason }\n      }\n    },\n    onOutOfTurnEvent(listener) {\n      state.outOfTurnListeners.add(listener)\n      return () => {\n        state.outOfTurnListeners.delete(listener)\n      }\n    },\n    async close() {\n      // Cancel any permission requests this session parked before dropping it,\n      // so the agent's held RPCs settle rather than hang.\n      cancelPermissionsForSession(sessionId)\n      sessions.delete(sessionId)\n    },\n  }\n}\n\nfunction makeIterator(state: SessionState): AsyncIterable<StreamEvent> {\n  return {\n    [Symbol.asyncIterator]() {\n      return {\n        async next() {\n          if (state.events.length > 0) {\n            const value = state.events.shift() as StreamEvent\n            return { value, done: false }\n          }\n          if (state.done) return { value: undefined, done: true }\n          const value = await new Promise<StreamEvent | undefined>(\n            (resolve) => {\n              state.resolveNext = resolve\n            },\n          )\n          if (value === undefined) return { value: undefined, done: true }\n          return { value, done: false }\n        },\n      }\n    },\n  }\n}\n\n/**\n * Route an agent-originated event: into the in-flight turn's iterator, or —\n * when no `prompt()` is in flight — to the session's out-of-turn listeners\n * (see `AcpClientSession.onOutOfTurnEvent`). Never buffered while idle: the\n * next `prompt()` clears the buffer, so buffering only ever lost them.\n */\nfunction deliver(state: SessionState, event: StreamEvent) {\n  if (state.active) {\n    enqueue(state, event)\n    return\n  }\n  for (const listener of state.outOfTurnListeners) {\n    try {\n      listener(event)\n    } catch (err) {\n      console.warn(\n        `[acp] out-of-turn listener threw:`,\n        err instanceof Error ? err.message : err,\n      )\n    }\n  }\n}\n\nfunction enqueue(state: SessionState, event: StreamEvent) {\n  if (state.resolveNext) {\n    const r = state.resolveNext\n    state.resolveNext = null\n    r(event)\n    return\n  }\n  state.events.push(event)\n}\n\nfunction flush(state: SessionState) {\n  if (state.resolveNext) {\n    const r = state.resolveNext\n    state.resolveNext = null\n    r(undefined)\n  }\n}\n\ninterface PermissionHoldContext {\n  permissionHold: boolean\n  pendingPermissions: Map<string, HeldPermission>\n  nextRequestId: () => string\n}\n\n/**\n * Shape of an ACP `session/request_permission` params object — only the\n * fields we read. Narrowed defensively (all optional) since it arrives as\n * `unknown` from the SDK handler boundary.\n */\ninterface RequestPermissionParams {\n  sessionId?: string\n  toolCall?: {\n    toolCallId?: string\n    title?: string\n    kind?: string\n    /** ACP `ToolCallUpdate.rawInput` — the tool's actual arguments (e.g. a\n     *  Bash command string). Carried through as-is; see the `agent-prompt`\n     *  event's `rawInput` field. */\n    rawInput?: unknown\n    /** ACP `ToolCallUpdate._meta` — vendor-extension bag (e.g. mastra-agent's\n     *  `mastra-agent/suspendPayload`). Carried through as-is; see the\n     *  `agent-prompt` event's `_meta` field. */\n    _meta?: unknown\n  }\n  options?: Array<{ optionId?: string; name?: string; kind?: string }>\n}\n\n/**\n * Permission-hold path: surface the request as an `agent-prompt` StreamEvent\n * on the owning session's stream and park the RPC in `pendingPermissions`,\n * returning a promise that resolves only when the host calls\n * `respondPermission` (or the session/client tears down). The `agent-prompt`\n * event carries the minted request id as `toolCallId` so the host has the\n * exact key to respond with.\n */\nfunction holdPermissionRequest(\n  rawParams: unknown,\n  sessions: Map<string, SessionState>,\n  ctx: PermissionHoldContext,\n): Promise<RequestPermissionResponse> {\n  const params = (rawParams ?? {}) as RequestPermissionParams\n  const sessionId = params.sessionId ?? \"\"\n  const requestId = ctx.nextRequestId()\n  const options = Array.isArray(params.options)\n    ? params.options\n        .filter((o): o is { optionId: string; name?: string; kind?: string } =>\n          typeof o?.optionId === \"string\",\n        )\n        .map(o => ({\n          optionId: o.optionId,\n          ...(typeof o.name === \"string\" ? { name: o.name } : {}),\n          ...(typeof o.kind === \"string\" ? { kind: o.kind } : {}),\n        }))\n    : []\n  const toolName = params.toolCall?.title ?? params.toolCall?.kind\n  const text = toolName\n    ? `Allow \"${toolName}\"?`\n    : \"The agent is requesting permission to run a tool.\"\n  const rawInput = params.toolCall?.rawInput\n  const meta = params.toolCall?._meta\n\n  const state = sessions.get(sessionId)\n  if (state) {\n    // `deliver`, not `enqueue`: an autonomous cycle (no prompt in flight)\n    // can ask permission too, and a request parked where nobody reads it\n    // would hang that cycle forever.\n    deliver(state, {\n      kind: \"agent-prompt\",\n      sessionId,\n      toolCallId: requestId,\n      options,\n      text,\n      ...(toolName ? { toolName } : {}),\n      ...(rawInput !== undefined ? { rawInput } : {}),\n      ...(meta !== undefined ? { _meta: meta } : {}),\n    })\n  } else {\n    // No session slot for this id — the agent-prompt event can't be surfaced,\n    // so the host won't see the request in its stream. We still park the RPC\n    // below (so the agent doesn't hang), but log it: a missing state here means\n    // the request arrived for an unknown/torn-down session and would otherwise\n    // vanish silently.\n    console.warn(\n      `[acp] permission-hold: no session state for sessionId=\"${sessionId}\" ` +\n        `(request ${requestId}) — parking the RPC but not surfacing an agent-prompt event.`,\n    )\n  }\n\n  return new Promise<RequestPermissionResponse>(resolve => {\n    ctx.pendingPermissions.set(requestId, { sessionId, resolve })\n  })\n}\n\n/**\n * Internal extension method that carries an AIR `async_task_*` session update\n * past the SDK — see {@link withAirTaskUpdatesRerouted}.\n */\nconst AIR_TASK_UPDATE_METHOD = \"_agentproto/air_task_update\"\n\n/**\n * The ACP SDK validates every `session/update` against the core schema and\n * rejects (logs + drops, `-32602 Invalid params`) any `sessionUpdate` kind it\n * doesn't know — which includes the AIR extension's `async_task_spawned` /\n * `async_task_progress` / `async_task_state_update`. Rewrite exactly those\n * frames, in place in the inbound message stream, into an extension\n * notification the SDK routes to `extNotification` unvalidated. Staying in\n * the stream (rather than handling them on the side) keeps them in wire\n * order with every other notification and the prompt response.\n */\nfunction withAirTaskUpdatesRerouted(stream: Stream): Stream {\n  type Message = Stream[\"readable\"] extends ReadableStream<infer M> ? M : never\n  // A stand-in transport without a real readable (unit tests mock the SDK\n  // stream as `{}`) has nothing to reroute.\n  if (typeof stream.readable?.pipeThrough !== \"function\") return stream\n  return {\n    writable: stream.writable,\n    readable: stream.readable.pipeThrough(\n      new TransformStream<Message, Message>({\n        transform(message, controller) {\n          const frame = message as { method?: unknown; params?: unknown; id?: unknown }\n          const update = (frame.params as { update?: { sessionUpdate?: unknown } } | undefined)\n            ?.update\n          if (\n            frame.method === \"session/update\" &&\n            frame.id === undefined &&\n            typeof update?.sessionUpdate === \"string\" &&\n            update.sessionUpdate.startsWith(\"async_task_\")\n          ) {\n            controller.enqueue({ ...frame, method: AIR_TASK_UPDATE_METHOD } as Message)\n            return\n          }\n          controller.enqueue(message)\n        },\n      }),\n    ),\n  }\n}\n\nfunction buildClientHandlers(\n  partial: Partial<AcpClientHandlers>,\n  sessions: Map<string, SessionState>,\n  onActivity: (() => void) | undefined,\n  hold: PermissionHoldContext,\n): AcpClientHandlers {\n  /** Shared body of `sessionUpdate` and the rerouted AIR task updates. */\n  const routeSessionUpdate = (params: unknown): void => {\n    // Every notification is a liveness signal, even ones that don't\n    // translate into a StreamEvent below (e.g. an in-progress\n    // tool_call_update) — this is the gap that leaves lastOutputAt\n    // stale during a long internal tool-call chain.\n    onActivity?.()\n\n    const sid = (params as { sessionId?: string }).sessionId\n    if (!sid) return\n    const state = sessions.get(sid)\n    if (!state) return\n\n    // Reset this session's in-flight turn watchdog (if any) — an\n    // incoming notification is exactly the \"not silent\" signal the\n    // watchdog exists to detect the absence of.\n    state.resetWatchdogTimer?.()\n\n    const update = (params as { update?: Record<string, unknown> }).update\n    if (!update) return\n    const event = translateSessionUpdate(sid, update)\n    state.observeTurnUpdate?.(event)\n    if (event) deliver(state, event)\n  }\n  return {\n    // Spread the caller-supplied handlers FIRST so the named methods defined\n    // below always win. This matters for `requestPermission`: the arm always\n    // passes a `requestPermission` handler, and if that spread came last it\n    // would clobber the permission-hold guard below — silently bypassing hold\n    // mode. With the spread first, our guard stays in control and still falls\n    // through to `partial.requestPermission` when hold mode is OFF.\n    ...(partial as object),\n    async sessionUpdate(params) {\n      routeSessionUpdate(params)\n      if (partial.sessionUpdate) await partial.sessionUpdate(params)\n    },\n    async extNotification(method, params) {\n      if (method === AIR_TASK_UPDATE_METHOD) {\n        routeSessionUpdate(params)\n        return\n      }\n      if (partial.extNotification) await partial.extNotification(method, params)\n    },\n    async requestPermission(params) {\n      // Every incoming request is a liveness signal.\n      onActivity?.()\n      // Permission-hold mode intercepts BEFORE any auto-answer handler: the\n      // request is surfaced + parked instead of resolved in-arm.\n      if (hold.permissionHold) {\n        return holdPermissionRequest(params, sessions, hold) as never\n      }\n      if (partial.requestPermission) return partial.requestPermission(params)\n      throw new Error(\"AcpClient.requestPermission: no handler configured\")\n    },\n    async readTextFile(params) {\n      if (partial.readTextFile) return partial.readTextFile(params)\n      throw new Error(\"AcpClient.readTextFile: capability not advertised\")\n    },\n    async writeTextFile(params) {\n      if (partial.writeTextFile) return partial.writeTextFile(params)\n      throw new Error(\"AcpClient.writeTextFile: capability not advertised\")\n    },\n  } as AcpClientHandlers\n}\n\n/**\n * Nothing worth calling a tool's input: absent, `{}`, or `[]`. All three are\n * what an agent sends when it hasn't decided the input yet — the claude-code\n * bridge announces a read with `rawInput: {}` and `content: []` before it\n * knows the path.\n */\nfunction isEmptyish(value: unknown): boolean {\n  if (value == null) return true\n  if (Array.isArray(value)) return value.length === 0\n  if (typeof value === \"object\") return Object.keys(value as object).length === 0\n  return false\n}\n\n/**\n * Derive a tool call's `arguments` from an ACP tool_call / tool_call_update\n * payload, or undefined when the payload says nothing about the input.\n *\n * Preference order: `rawInput` (the real thing) → the file paths in\n * `locations` (some agents describe a read only that way) → `content`. An\n * EMPTY `rawInput` counts as \"nothing\", not as \"the input is {}\" — otherwise\n * the placeholder the agent sends before it knows the input would outrank the\n * locations it did send, and would later look indistinguishable from a real\n * no-argument call.\n */\nfunction toolCallArguments(update: Record<string, unknown>): unknown | undefined {\n  const rawInput = update.rawInput\n  if (!isEmptyish(rawInput)) return rawInput\n\n  const locations = update.locations as\n    | Array<{ path: string; line?: number | null }>\n    | undefined\n  // Some tool calls (e.g. a bare \"read\" with no structured input) carry only\n  // `locations` — fold the file paths into `arguments` so they survive\n  // downstream instead of being dropped. Reached whenever rawInput said\n  // nothing, including the `{}` placeholder: a real path beats a placeholder.\n  if (locations && locations.length > 0) {\n    const first = locations[0]!\n    return locations.length === 1\n      ? { path: first.path, ...(first.line != null ? { line: first.line } : {}) }\n      : { paths: locations.map(location => location.path) }\n  }\n\n  if (!isEmptyish(update.content)) return update.content\n  // Distinguish \"the agent sent an empty input\" from \"the agent said nothing\n  // about the input\". The announcement keeps rendering the former as-is; an\n  // enrichment carrying the latter isn't worth emitting at all.\n  return rawInput != null ? rawInput : undefined\n}\n\n/**\n * Build the tool-call ENRICHMENT for a non-terminal `tool_call_update` — the\n * frame where the claude-code bridge delivers the input and the real title\n * for a call it already announced as a bare \"Read File\" with `rawInput: {}`.\n *\n * Returns null when the update adds nothing (e.g. a bare `{_meta, toolCallId}`\n * keep-alive), so a no-op frame stays a no-op event.\n */\nfunction toolCallEnrichment(\n  sessionId: string,\n  update: Record<string, unknown>,\n): StreamEvent | null {\n  const toolCallId = update.toolCallId as string | undefined\n  if (!toolCallId) return null\n  const args = toolCallArguments(update)\n  const title = typeof update.title === \"string\" ? update.title : undefined\n  if (args === undefined && title === undefined) return null\n  return {\n    kind: \"tool-call\",\n    sessionId,\n    toolCallId,\n    // \"\" when the update carried no title — consumers merge only non-empty\n    // names, so an untitled enrichment can't erase the announced one.\n    toolName: title ?? \"\",\n    arguments: args,\n    isUpdate: true,\n  }\n}\n\nfunction translateSessionUpdate(\n  sessionId: string,\n  update: Record<string, unknown>,\n): StreamEvent | null {\n  switch (update.sessionUpdate) {\n    case \"agent_message_chunk\":\n      return {\n        kind: \"text-delta\",\n        sessionId,\n        text: extractText(update.content),\n      }\n    case \"agent_thought_chunk\":\n      return {\n        kind: \"thought\",\n        sessionId,\n        text: extractText(update.content),\n      }\n    case \"tool_call\": {\n      const toolCallId = (update.toolCallId as string) ?? \"\"\n      // `title` is the descriptive label an agent gives a tool call\n      // (\"Reading src/foo.ts\") — prefer it over the coarse `kind`\n      // bucket (read/edit/search/execute/…) so rendered lines are\n      // informative instead of generic.\n      const toolName =\n        (update.title as string) ?? (update.kind as string) ?? \"tool\"\n      return {\n        kind: \"tool-call\",\n        sessionId,\n        toolCallId,\n        toolName,\n        arguments: toolCallArguments(update) ?? {},\n      }\n    }\n    case \"tool_call_update\": {\n      const status = update.status as string | undefined\n      if (status === \"completed\" || status === \"failed\") {\n        return {\n          kind: \"tool-result\",\n          sessionId,\n          toolCallId: (update.toolCallId as string) ?? \"\",\n          result: update.rawOutput ?? update.content ?? null,\n          isError: status === \"failed\",\n        }\n      }\n      // A non-terminal update is where several agents actually DELIVER the\n      // call's input. Captured off the wire from the claude-code bridge:\n      //\n      //   tool_call        title=\"Read File\"  rawInput={}   locations=[]\n      //   tool_call_update title=\"Read /tmp/probe.txt\"\n      //                    rawInput={\"file_path\":\"/tmp/probe.txt\"}\n      //                    locations=[{path:\"/tmp/probe.txt\",line:1}]\n      //   tool_call_update status=completed   rawOutput=…\n      //\n      // The middle frame has no `status`, so returning null here discarded the\n      // arguments AND the real title of ~95% of that adapter's tool calls —\n      // which is why they rendered as \"Read File\" with an empty input while\n      // adapters that inline their input on the initial call looked fine.\n      return toolCallEnrichment(sessionId, update)\n    }\n    case \"plan\": {\n      const entries = (update.entries as Array<Record<string, unknown>>) ?? []\n      const title = typeof update.title === \"string\" ? update.title : undefined\n      return {\n        kind: \"plan\",\n        sessionId,\n        ...(title ? { title } : {}),\n        entries: entries.map((entry) => ({\n          content: (entry.content as string) ?? \"\",\n          priority: (entry.priority as \"high\" | \"medium\" | \"low\") ?? \"medium\",\n          status:\n            (entry.status as \"pending\" | \"in_progress\" | \"completed\") ??\n            \"pending\",\n        })),\n      }\n    }\n    case \"usage_update\": {\n      const cost = update.cost as { amount: number; currency: string } | null | undefined\n      // Accept both camelCase and snake_case token fields — agents differ on\n      // the convention and this update kind is non-standard ACP.\n      const numeric = (...keys: string[]): number | undefined => {\n        for (const key of keys) {\n          const v = update[key]\n          if (typeof v === \"number\") return v\n        }\n        return undefined\n      }\n      const tokensIn = numeric(\"tokensIn\", \"input_tokens\", \"inputTokens\")\n      const tokensOut = numeric(\"tokensOut\", \"output_tokens\", \"outputTokens\")\n      // ACP's usage_update has no model field; claude-agent-acp carries the\n      // model the usage belongs to in `_meta[\"_claude/model\"]`. That wrapper\n      // also documents its cost-less frames' `size` as a best-effort seed\n      // (a text heuristic over the model id, 200k unless the id says \"1m\")\n      // that only its cost-bearing `result` frame makes authoritative — so\n      // flag those as inferred for the daemon to weigh against the catalog.\n      const meta = update._meta as Record<string, unknown> | undefined\n      const model = typeof meta?.[\"_claude/model\"] === \"string\" ? meta[\"_claude/model\"] : undefined\n      const sizeInferred = model !== undefined && !cost\n      const originMeta = meta?.[\"_claude/origin\"]\n      const origin =\n        originMeta && typeof originMeta === \"object\" &&\n        typeof (originMeta as { kind?: unknown }).kind === \"string\"\n          ? (originMeta as { kind: string }).kind\n          : undefined\n      return {\n        kind: \"usage_update\",\n        sessionId,\n        size: (update.size as number) ?? 0,\n        used: (update.used as number) ?? 0,\n        ...(cost ? { cost } : {}),\n        ...(model ? { model } : {}),\n        ...(sizeInferred ? { sizeInferred } : {}),\n        ...(tokensIn !== undefined ? { tokensIn } : {}),\n        ...(tokensOut !== undefined ? { tokensOut } : {}),\n        ...(origin ? { origin } : {}),\n      }\n    }\n    case \"available_commands_update\": {\n      const commands = (update.availableCommands as Array<Record<string, unknown>>) ?? []\n      return {\n        kind: \"available-commands\",\n        sessionId,\n        commands: commands.map((cmd) => ({\n          name: (cmd.name as string) ?? \"\",\n          ...(typeof cmd.description === \"string\" ? { description: cmd.description } : {}),\n          ...(cmd.input !== undefined\n            ? { input: cmd.input as { hint?: string } | null }\n            : {}),\n          ...(cmd._meta !== undefined\n            ? {\n                _meta: cmd._meta as {\n                  scope?: string\n                  path?: string\n                  bareName?: string\n                  qualifiedName?: string\n                },\n              }\n            : {}),\n        })),\n      }\n    }\n    case \"async_task_spawned\":\n    case \"async_task_progress\":\n    case \"async_task_state_update\":\n      return translateAsyncTaskUpdate(sessionId, update)\n    case \"user_message_chunk\":\n      return null\n    default:\n      return null\n  }\n}\n\nconst BACKGROUND_TASK_STATUSES = new Set([\n  \"running\",\n  \"paused\",\n  \"completed\",\n  \"failed\",\n  \"stopped\",\n])\n\n/**\n * AIR `asyncTasks` lifecycle → `background-task` StreamEvent. Wire shapes\n * (claude-agent-acp `async-tasks.js`):\n *   async_task_spawned      {asyncTaskId, name, taskType, description, outputFilePath?, toolCallId?}\n *   async_task_progress     {asyncTaskId, description?, summary?, outputFilePath?, ...}\n *   async_task_state_update {asyncTaskId, state, summary?, outputFilePath?, toolCallId?}\n * A `state_update` to running/paused is a mid-life update, not a settle.\n */\nfunction translateAsyncTaskUpdate(\n  sessionId: string,\n  update: Record<string, unknown>,\n): StreamEvent | null {\n  const str = (key: string): string | undefined => {\n    const value = update[key]\n    return typeof value === \"string\" && value.trim().length > 0 ? value.trim() : undefined\n  }\n  const taskId = str(\"asyncTaskId\")\n  if (!taskId) return null\n  const state = str(\"state\")\n  const status =\n    state && BACKGROUND_TASK_STATUSES.has(state)\n      ? (state as BackgroundTaskInfo[\"status\"])\n      : undefined\n  const phase =\n    update.sessionUpdate === \"async_task_spawned\"\n      ? \"started\"\n      : status === \"completed\" || status === \"failed\" || status === \"stopped\"\n        ? \"settled\"\n        : \"updated\"\n  const description = str(\"description\") ?? str(\"name\")\n  const task: BackgroundTaskInfo = {\n    taskId,\n    ...(str(\"taskType\") ? { taskKind: str(\"taskType\") } : {}),\n    ...(description ? { description } : {}),\n    ...(str(\"outputFilePath\") ? { outputFile: str(\"outputFilePath\") } : {}),\n    ...(phase === \"started\" ? { status: \"running\" as const } : status ? { status } : {}),\n    ...(str(\"summary\") ? { summary: str(\"summary\") } : {}),\n    ...(str(\"toolCallId\") ? { toolCallId: str(\"toolCallId\") } : {}),\n  }\n  return { kind: \"background-task\", sessionId, phase, task }\n}\n\n/**\n * The ACP SDK maps a server-side thrown error to a JSON-RPC `-32603` whose\n * `message` is JUST \"Internal error\" — `RequestError.internalError` never\n * embeds the cause in the message; the useful text travels in\n * `error.data.details` (e.g. a managed cloud adapter naming the credential\n * that is missing, or the vendor's API error). Surface that detail in the\n * message AND carry `code`/`data`/`name` through, so a host that reads only\n * `error.message` shows the real cause instead of a bare \"Internal error\",\n * and a host that inspects `error.code` still sees -32603. Returns the\n * original error untouched when it isn't such an opaque re-wrapping.\n */\nexport function enrichInternalAcpError<T>(err: T): T | Error {\n  if (\n    typeof err !== \"object\" ||\n    err === null ||\n    !(\"message\" in err) ||\n    (err as { message?: unknown }).message !== \"Internal error\"\n  ) {\n    return err\n  }\n  const data = (err as unknown as { data?: unknown }).data\n  const details =\n    typeof data === \"object\" && data !== null ? (data as { details?: unknown }).details : undefined\n  if (typeof details !== \"string\" || details.trim().length === 0) return err\n  const wrapped = err as unknown as { name?: unknown; code?: unknown; stack?: unknown }\n  const enriched = new Error(`Internal error: ${details}`)\n  Object.assign(enriched, {\n    ...(typeof wrapped.name === \"string\" ? { name: wrapped.name } : {}),\n    ...(typeof wrapped.code === \"number\" ? { code: wrapped.code } : {}),\n    data,\n  })\n  if (typeof wrapped.stack === \"string\") enriched.stack = wrapped.stack\n  return enriched\n}\n\n/**\n * Best human-readable reason from a failed `session/set_config_option`.\n *\n * The ACP SDK surfaces a server-side rejection as a JSON-RPC `RequestError`\n * whose generic `message` is just \"Internal error\" (code -32603) — the useful\n * text lives in `error.data.details` (e.g. claude-agent-acp's\n * \"Invalid value for config option model: claude-sonnet-4-6\"). Prefer that\n * detail, falling back to the error's own message, then a stringified form.\n * Narrows `unknown` with `in`/`typeof` guards — no casts.\n */\nfunction configOptionErrorDetail(err: unknown): string {\n  if (typeof err === \"object\" && err !== null) {\n    if (\"data\" in err && typeof err.data === \"object\" && err.data !== null) {\n      const data = err.data\n      if (\n        \"details\" in data &&\n        typeof data.details === \"string\" &&\n        data.details.length > 0\n      ) {\n        return data.details\n      }\n    }\n    if (\n      \"message\" in err &&\n      typeof err.message === \"string\" &&\n      err.message.length > 0\n    ) {\n      return err.message\n    }\n  }\n  return String(err)\n}\n\n/**\n * Flatten a config option's selectable values. ACP allows a select option to\n * carry either a flat `SessionConfigSelectOption[]` or grouped\n * `SessionConfigSelectGroup[]` (each group holding its own options); callers\n * only care about the leaf values either way.\n */\nfunction selectOptionValues(\n  options: SessionConfigSelectOptions,\n): SessionConfigSelectOption[] {\n  return (\n    options as Array<SessionConfigSelectOption | SessionConfigSelectGroup>\n  ).flatMap(entry => (\"options\" in entry ? entry.options : [entry]))\n}\n\n/**\n * The session's advertised modes, normalized to the SDK's `SessionModeState`\n * shape regardless of which ACP channel carried them.\n *\n * Most ACP servers publish their mode registry as the `modes` field of the\n * `session/new` / `session/load` response. OpenCode (1.19+) does not: it leaves\n * `modes` undefined and advertises the SAME registry as a `category:\"mode\"`\n * entry in `configOptions` (`{id:\"mode\", options:[build, plan]}`), switched\n * over the wire by `session/set_mode` or\n * `session/set_config_option(configId:\"mode\")`. Without folding that entry in,\n * `availableModes` is empty for every opencode session, so NO canonical posture\n * (`plan`, `bypass`, …) ever resolves to a native mode — they all degrade to a\n * prompt-injection preamble, and a live `set_posture` reports\n * `requires-restart` instead of switching the harness's real `plan` mode.\n */\nfunction sessionModes(\n  native: SessionModeState | null | undefined,\n  configOptions: SessionConfigOption[],\n): { modes: SessionMode[]; currentModeId: string | undefined } {\n  if (native?.availableModes?.length) {\n    return { modes: native.availableModes, currentModeId: native.currentModeId }\n  }\n  const modeOption = configOptions.find(\n    option => option.category === \"mode\" && option.type === \"select\",\n  )\n  if (modeOption && modeOption.type === \"select\") {\n    return {\n      modes: selectOptionValues(modeOption.options).map(option => ({\n        id: option.value,\n        name: option.name,\n        ...(option.description ? { description: option.description } : {}),\n      })),\n      currentModeId: modeOption.currentValue,\n    }\n  }\n  return {\n    modes: native?.availableModes ?? [],\n    currentModeId: native?.currentModeId,\n  }\n}\n\nfunction extractText(content: unknown): string {\n  if (!content) return \"\"\n  if (typeof content === \"string\") return content\n  if (typeof content === \"object\" && content !== null) {\n    const c = content as { type?: string; text?: string }\n    if (c.type === \"text\" && typeof c.text === \"string\") return c.text\n  }\n  return \"\"\n}\n"]}