@ai-sdk/harness-claude-code 1.0.24 → 1.0.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +7 -0
- package/dist/bridge/index.mjs +6 -4
- package/dist/bridge/index.mjs.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
package/dist/bridge/index.mjs
CHANGED
|
@@ -340,10 +340,12 @@ async function runBridge(options) {
|
|
|
340
340
|
return;
|
|
341
341
|
case "interrupt":
|
|
342
342
|
try {
|
|
343
|
-
if (
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
343
|
+
if (pendingToolResults.size === 0 && pendingToolApprovals.size === 0) {
|
|
344
|
+
if (currentInterruptHandler) {
|
|
345
|
+
await currentInterruptHandler();
|
|
346
|
+
} else {
|
|
347
|
+
turnAbort?.abort();
|
|
348
|
+
}
|
|
347
349
|
}
|
|
348
350
|
sendControl({ type: "bridge-interrupted", ok: true });
|
|
349
351
|
} catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../harness/src/bridge/index.ts","../../src/bridge/compaction-latch.ts","../../src/bridge/index.ts","../../src/bridge/claude-skills-option.ts"],"sourcesContent":["// Shared in-sandbox bridge runtime. Adapter `bridge.mjs` bundles re-bundle\n// this module (tsup inlines it; `ws` stays external and resolves from the\n// sandbox-installed node_modules). It owns everything generic to the bridge\n// transport — the WebSocket server, token auth, single-flight connection\n// replacement, the in-memory event log + monotonic `seq`, resume replay, and\n// the lifecycle/meta files. The adapter supplies only `onStart` (drive its\n// CLI/SDK and translate to wire events) and `onDetach` (its resume payload).\n\nimport { appendFile, mkdir, writeFile } from 'node:fs/promises';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { env as procEnv, pid, stdout } from 'node:process';\nimport { WebSocketServer, type WebSocket } from 'ws';\n\nexport type BridgeState = 'init' | 'waiting' | 'running' | 'draining' | 'done';\n\n/** Outbound turn event the adapter emits. `seq` is added by the runtime. */\nexport type BridgeEvent = Record<string, unknown> & { type: string };\n\nexport type BridgeDebugLevel = 'error' | 'warn' | 'info' | 'debug' | 'trace';\n\n/**\n * Per-session diagnostics config. The host resolves it from settings +\n * env and sends it on `start.debug`; the bridge gates console capture and\n * structured `debug-event`s on it. When disabled, nothing is captured or\n * emitted and no `seq` is consumed.\n */\nexport interface BridgeDebugConfig {\n enabled?: boolean;\n level?: BridgeDebugLevel;\n subsystems?: string[];\n}\n\nconst DEBUG_LEVEL_WEIGHT: Record<BridgeDebugLevel, number> = {\n error: 0,\n warn: 1,\n info: 2,\n debug: 3,\n trace: 4,\n};\n\n/** Exact-or-dotted-prefix subsystem match (`'bridge'` matches `'bridge.turn'`). */\nfunction subsystemMatches(\n filters: string[] | undefined,\n subsystem: string,\n): boolean {\n if (!filters || filters.length === 0) return true;\n return filters.some(\n filter => subsystem === filter || subsystem.startsWith(`${filter}.`),\n );\n}\n\nfunction formatBridgeError(err: unknown): {\n name?: string;\n message: string;\n stack?: string;\n} {\n if (err instanceof Error) {\n return { name: err.name, message: err.message, stack: err.stack };\n }\n if (typeof err === 'string') {\n return { message: err };\n }\n if (err !== null && typeof err === 'object') {\n try {\n return { message: JSON.stringify(err) };\n } catch {}\n }\n return { message: String(err) };\n}\n\nfunction parseEnvList(value: string | undefined): string[] | undefined {\n if (!value) return undefined;\n const items = value\n .split(',')\n .map(item => item.trim())\n .filter(Boolean);\n return items.length > 0 ? items : undefined;\n}\n\nconst ENV_TRUTHY = new Set(['1', 'true', 'yes', 'on']);\n\n/**\n * Per-turn surface handed to {@link RunBridgeOptions.onStart}. The adapter\n * drives its runtime against these primitives; the runtime owns the transport.\n */\nexport interface BridgeTurn {\n /**\n * Emit a turn event to the host. Stamps a monotonic `seq`, appends to the\n * in-memory replay log, and sends to the live socket (best-effort — if the\n * host is mid-reconnect the event waits in the log and is replayed on\n * resume).\n */\n emit(event: BridgeEvent): void;\n\n /**\n * Register interest in a host-executed tool result and resolve when the\n * matching `tool-result` arrives. The adapter emits the `tool-call` event\n * itself (via {@link emit}) using the same `toolCallId`.\n */\n requestToolResult(\n toolCallId: string,\n ): Promise<{ output: unknown; isError?: boolean }>;\n\n /**\n * Register interest in a host approval decision and resolve when the matching\n * `tool-approval-response` arrives. The adapter emits the\n * `tool-approval-request` event itself using the same `approvalId`.\n */\n requestToolApproval(\n approvalId: string,\n ): Promise<{ approved: boolean; reason?: string }>;\n\n /**\n * Live queue of mid-turn user messages. The runtime pushes inbound\n * `user-message` text here; the adapter drains it as its runtime accepts\n * interactive input.\n */\n readonly pendingUserMessages: string[];\n\n /** Aborts when the host sends `abort`. */\n readonly abortSignal: AbortSignal;\n\n /**\n * Register the runtime-specific interrupt hook for this active turn. The\n * shared bridge invokes it when the host sends `interrupt`, then acknowledges\n * only after the hook settles.\n */\n onInterrupt(handler: () => void | Promise<void>): void;\n\n /** True for the first turn since this bridge process started. */\n readonly firstTurn: boolean;\n\n /**\n * Emit a structured diagnostic. Gated by the session's debug level +\n * subsystem filter; a no-op when diagnostics are disabled. Adapters use this\n * for runtime-level instrumentation; raw `console.*` output is captured and\n * forwarded automatically.\n */\n bridgeLog(input: {\n level?: BridgeDebugLevel;\n subsystem: string;\n message: string;\n attrs?: Record<string, unknown>;\n error?: unknown;\n }): void;\n\n /**\n * Emit a non-fatal bridge warning to stderr using the runtime's harness\n * prefix. This is diagnostic-only: it does not emit a stream event, does not\n * consume a `seq`, and does not fail the turn.\n */\n emitWarning(input: { message: string }): void;\n\n emitError(input: { error: unknown; message?: string }): void;\n}\n\nexport interface RunBridgeOptions<TStart extends { type: 'start' }> {\n /** Identifier written into `bridge-meta.json` (`'claude-code'` / `'codex'`). */\n bridgeType: string;\n /** Directory for `bridge-meta.json` / `start-config.json`. Created if absent. */\n bridgeStateDir: string;\n /** Drive one prompt turn. Rejections surface to the host as an `error` event. */\n onStart(start: TStart, turn: BridgeTurn): Promise<void>;\n /** Produce the adapter-defined resume payload for a `detach`. Defaults to `{}`. */\n onDetach?(): unknown | Promise<unknown>;\n /** WS port. Defaults to `BRIDGE_WS_PORT` env (0 = OS-assigned). */\n port?: number;\n /** Auth token. Defaults to `BRIDGE_CHANNEL_TOKEN` env. */\n token?: string;\n /** Called with the bound port once the server is listening. */\n onListening?(port: number): void;\n /**\n * Tear the process down after a `shutdown` / `detach`. Defaults to closing\n * the server and calling `process.exit(0)`. Overridable for tests.\n */\n onExit?(): void;\n}\n\ntype InboundControl =\n | {\n type: 'tool-result';\n toolCallId: string;\n output: unknown;\n isError?: boolean;\n }\n | {\n type: 'tool-approval-response';\n approvalId: string;\n approved: boolean;\n reason?: string;\n }\n | { type: 'user-message'; text: string }\n | { type: 'abort' }\n | { type: 'interrupt' }\n | { type: 'shutdown' }\n | { type: 'detach' }\n | { type: 'resume'; lastSeenEventId: number };\n\nconst WS_OPEN = 1;\n\n/**\n * Boot the bridge: bind the WebSocket server, announce `bridge-ready`, and\n * service host connections for the lifetime of the process. Resolves once the\n * server is listening; the process then stays alive on the server until a\n * `shutdown` / `detach` exits it.\n */\nexport interface BridgeHandle {\n /** The port the WebSocket server bound to. */\n readonly port: number;\n /** Close the WebSocket server. Does not call `process.exit`. */\n close(): Promise<void>;\n}\n\nexport async function runBridge<TStart extends { type: 'start' }>(\n options: RunBridgeOptions<TStart>,\n): Promise<BridgeHandle> {\n const { bridgeType, bridgeStateDir, onStart, onDetach } = options;\n const expectedToken = options.token ?? procEnv.BRIDGE_CHANNEL_TOKEN ?? '';\n const bridgeWsPort =\n options.port ?? parseInt(procEnv.BRIDGE_WS_PORT ?? '0', 10);\n\n const bridgeMetaPath = `${bridgeStateDir}/bridge-meta.json`;\n const startConfigPath = `${bridgeStateDir}/start-config.json`;\n const rerunStartConfigPath = `${bridgeStateDir}/rerun-start-config.json`;\n const eventLogPath = `${bridgeStateDir}/event-log.ndjson`;\n\n try {\n await mkdir(bridgeStateDir, { recursive: true });\n } catch {\n // Best-effort; the bridge still runs without its state files.\n }\n\n // ─── mutable runtime state ──────────────────────────────────────────\n let currentBoundPort = 0;\n let currentTurnState: BridgeState = 'init';\n let activeSocket: WebSocket | undefined;\n let isFirstTurn = true;\n let turnAbort: AbortController | undefined;\n let currentUserMessages: string[] | undefined;\n let currentInterruptHandler: (() => void | Promise<void>) | undefined;\n\n // Diagnostics. Resolved per turn from `start.debug` with a sandbox-side\n // env fallback; gates console capture + structured `debug-event`s.\n let debugConfig: BridgeDebugConfig | undefined;\n let consoleCaptureInstalled = false;\n const envDebugEnabled = ENV_TRUTHY.has(\n (procEnv.HARNESS_DEBUG ?? '').toLowerCase(),\n );\n\n // Replay log. `seq` is monotonic across the whole process — never reset —\n // because the host's `SandboxChannel` cursor (`lastSeenEventId`) lives across\n // turns. The log *contents* are cleared at the start of each turn to bound\n // memory; the just-finished turn stays replayable until the next `start`.\n let seqCounter = 0;\n let eventLog: Array<{ seq: number; line: string }> = [];\n\n /*\n * Disk mirror of the in-memory replay log. The in-memory log is lost when the\n * bridge process dies; the on-disk `event-log.ndjson` survives in the sandbox\n * filesystem so a respawned bridge (started with `BRIDGE_REPLAY_FROM_DISK=1`)\n * can reload the just-interrupted turn and serve a host's resume cursor —\n * `replay` recovery. Writes are batched on `setImmediate` (single-flight via\n * `flushPromise`) to keep `emit` off the disk hot path.\n */\n let diskBuffer = '';\n let flushPromise: Promise<void> | null = null;\n\n const flushEventsToDisk = async (): Promise<void> => {\n while (diskBuffer.length > 0) {\n const buf = diskBuffer;\n diskBuffer = '';\n await appendFile(eventLogPath, buf).catch(() => {\n // Best-effort crash-recovery mirror; the in-memory log is the source of\n // truth for the live connection.\n });\n }\n };\n\n const scheduleEventFlush = (): void => {\n if (flushPromise) return;\n flushPromise = new Promise<void>(resolve => {\n setImmediate(() => {\n void flushEventsToDisk().finally(resolve);\n });\n }).finally(() => {\n flushPromise = null;\n if (diskBuffer.length > 0) {\n scheduleEventFlush();\n }\n });\n };\n\n const flushPendingEventsToDisk = async (): Promise<void> => {\n if (diskBuffer.length > 0 && !flushPromise) {\n scheduleEventFlush();\n }\n // Await each in-flight flush, re-reading `flushPromise` after every await\n // since a fresh flush may have been scheduled for buffer that arrived while\n // we waited.\n let inFlight = flushPromise;\n while (inFlight) {\n await inFlight;\n inFlight = flushPromise;\n }\n };\n\n /*\n * When respawned for `replay`, reload the previous turn's log from disk before\n * accepting any connection so the very first `resume{lastSeenEventId}` can be\n * served the tail (including the terminal `finish`). The seq counter is\n * restored to the last persisted seq so it stays aligned with the host's\n * long-lived cursor. The file is NOT truncated in this mode — only a fresh\n * `start` (next turn) clears it.\n */\n const replayFromDisk = procEnv.BRIDGE_REPLAY_FROM_DISK === '1';\n if (replayFromDisk && existsSync(eventLogPath)) {\n try {\n const lines = readFileSync(eventLogPath, 'utf8')\n .split('\\n')\n .map(line => line.trim())\n .filter(Boolean);\n eventLog = lines.map(line => ({\n seq: (JSON.parse(line) as { seq: number }).seq,\n line,\n }));\n seqCounter = eventLog.at(-1)?.seq ?? 0;\n } catch {\n // Corrupt/partial log: fall back to an empty log; the host then degrades\n // to `rerun` instead of replaying a malformed tail.\n eventLog = [];\n seqCounter = 0;\n }\n }\n\n const pendingToolResults = new Map<\n string,\n (output: { output: unknown; isError?: boolean }) => void\n >();\n const pendingToolApprovals = new Map<\n string,\n (response: { approved: boolean; reason?: string }) => void\n >();\n\n // ─── persistence (best-effort meta + start config) ──────────────────\n const writeBridgeMeta = async (state: BridgeState): Promise<void> => {\n try {\n await writeFile(\n bridgeMetaPath,\n JSON.stringify({\n type: bridgeType,\n port: currentBoundPort,\n state,\n pid,\n }),\n );\n } catch {\n // Best-effort resilience metadata; not load-bearing for the active turn.\n }\n };\n\n const writeStartConfig = async (start: unknown): Promise<void> => {\n try {\n const serialized = JSON.stringify(start);\n await writeFile(startConfigPath, serialized);\n // Frozen copy: written once, restored over start-config.json by future\n // rerun-mode recovery to re-run the original turn from scratch.\n if (!existsSync(rerunStartConfigPath)) {\n await writeFile(rerunStartConfigPath, serialized);\n }\n } catch {\n // Best-effort.\n }\n };\n\n // ─── wire send + replay ─────────────────────────────────────────────\n const sendControl = (msg: Record<string, unknown>): void => {\n if (activeSocket?.readyState === WS_OPEN) {\n try {\n activeSocket.send(JSON.stringify(msg));\n } catch {\n // best-effort\n }\n }\n };\n\n const emit = (event: BridgeEvent): void => {\n const seq = ++seqCounter;\n const line = JSON.stringify({ ...event, seq });\n eventLog.push({ seq, line });\n diskBuffer += `${line}\\n`;\n scheduleEventFlush();\n if (activeSocket?.readyState === WS_OPEN) {\n try {\n activeSocket.send(line);\n } catch {\n // Send is best-effort: a dropped socket leaves the event in the log,\n // replayed once the host reconnects and sends `resume`.\n }\n }\n };\n\n const replay = (ws: WebSocket, afterSeq: number): void => {\n for (const entry of eventLog) {\n if (entry.seq > afterSeq && ws.readyState === WS_OPEN) {\n ws.send(entry.line);\n }\n }\n };\n\n // ─── diagnostics ──────────────────────────────────────────────\n const shouldEmitDebugEvent = (\n level: BridgeDebugLevel,\n subsystem: string,\n ): boolean => {\n if (!debugConfig?.enabled) return false;\n const threshold = debugConfig.level ?? 'debug';\n if (DEBUG_LEVEL_WEIGHT[level] > DEBUG_LEVEL_WEIGHT[threshold]) return false;\n return subsystemMatches(debugConfig.subsystems, subsystem);\n };\n\n /*\n * Forward sandbox console output. We line-buffer the original writers (kept so\n * output still reaches the real fds) and emit one `sandbox-log` per complete\n * line. `emit` never writes to stdout/stderr, so there is no recursion.\n * Installed lazily the first time a turn enables diagnostics; once installed,\n * capture is gated per-write on `debugConfig.enabled` so a later turn can\n * disable it. Console capture is independent of the subsystem/level filter.\n */\n const rawStdoutWrite = process.stdout.write.bind(process.stdout);\n const rawStderrWrite = process.stderr.write.bind(process.stderr);\n\n const writeErrorToStderr = (input: {\n message: string;\n error: unknown;\n }): void => {\n try {\n const formatted = formatBridgeError(input.error);\n rawStderrWrite(\n `[harness:${bridgeType}:error] ${input.message}: ${formatted.message}\\n`,\n );\n if (formatted.stack) {\n rawStderrWrite(`${formatted.stack}\\n`);\n }\n } catch {}\n };\n\n const emitWarning = (input: { message: string }): void => {\n try {\n for (const line of input.message.split('\\n')) {\n if (line.trim().length > 0) {\n rawStderrWrite(`[harness:${bridgeType}:warn] ${line}\\n`);\n }\n }\n } catch {}\n };\n\n const emitError = (input: { error: unknown; message?: string }): void => {\n writeErrorToStderr({\n message: input.message ?? 'bridge error',\n error: input.error,\n });\n emit({ type: 'error', error: serialiseError(input.error) });\n };\n\n const installConsoleCapture = (): void => {\n if (consoleCaptureInstalled) return;\n consoleCaptureInstalled = true;\n const buffers: { stdout: string; stderr: string } = {\n stdout: '',\n stderr: '',\n };\n const patch =\n (stream: 'stdout' | 'stderr', raw: typeof process.stdout.write) =>\n (chunk: unknown, encoding?: unknown, cb?: unknown): boolean => {\n if (debugConfig?.enabled) {\n try {\n const enc = typeof encoding === 'string' ? encoding : 'utf8';\n const text =\n typeof chunk === 'string'\n ? chunk\n : Buffer.from(chunk as Uint8Array).toString(\n enc as BufferEncoding,\n );\n const combined = buffers[stream] + text.replace(/\\r\\n/g, '\\n');\n const parts = combined.split('\\n');\n buffers[stream] = parts.pop() ?? '';\n for (const line of parts) {\n const trimmed = line.replace(/\\s+$/, '');\n if (trimmed) {\n emit({\n type: 'sandbox-log',\n source: bridgeType,\n stream,\n line: trimmed,\n });\n }\n }\n } catch {\n // Never let capture break real output.\n }\n }\n return (raw as (c: unknown, e?: unknown, cb?: unknown) => boolean)(\n chunk,\n encoding,\n cb,\n );\n };\n process.stdout.write = patch(\n 'stdout',\n rawStdoutWrite,\n ) as typeof process.stdout.write;\n process.stderr.write = patch(\n 'stderr',\n rawStderrWrite,\n ) as typeof process.stderr.write;\n };\n\n // ─── inbound routing ────────────────────────────────────────────────\n const handleInbound = async (\n msg: TStart | InboundControl,\n ws: WebSocket,\n ): Promise<void> => {\n switch (msg.type) {\n case 'start': {\n const firstTurn = isFirstTurn;\n isFirstTurn = false;\n eventLog = []; // clear previous turn; keep seqCounter monotonic\n // Mirror the in-memory clear to disk: the log tracks only the current\n // turn. Discard any unflushed tail from the prior turn first.\n diskBuffer = '';\n void writeFile(eventLogPath, '').catch(() => {});\n turnAbort = new AbortController();\n currentTurnState = 'running';\n currentInterruptHandler = undefined;\n void writeStartConfig(msg);\n void writeBridgeMeta('running');\n const startDebug = (msg as { debug?: BridgeDebugConfig }).debug;\n debugConfig = {\n enabled: startDebug?.enabled ?? envDebugEnabled,\n level:\n startDebug?.level ??\n (procEnv.HARNESS_DEBUG_LEVEL as BridgeDebugLevel | undefined),\n subsystems:\n startDebug?.subsystems ??\n parseEnvList(procEnv.HARNESS_DEBUG_SUBSYSTEMS),\n };\n if (debugConfig.enabled) {\n installConsoleCapture();\n }\n const turn: BridgeTurn = {\n emit,\n requestToolResult: toolCallId =>\n new Promise(resolve => {\n pendingToolResults.set(toolCallId, resolve);\n }),\n requestToolApproval: approvalId =>\n new Promise(resolve => {\n pendingToolApprovals.set(approvalId, resolve);\n }),\n pendingUserMessages: [],\n abortSignal: turnAbort.signal,\n onInterrupt: handler => {\n currentInterruptHandler = handler;\n },\n firstTurn,\n bridgeLog: input => {\n const level = input.level ?? 'debug';\n if (!shouldEmitDebugEvent(level, input.subsystem)) return;\n emit({\n type: 'debug-event',\n level,\n subsystem: input.subsystem,\n message: input.message,\n ...(input.attrs ? { attrs: input.attrs } : {}),\n ...(input.error !== undefined\n ? { error: formatBridgeError(input.error) }\n : {}),\n });\n },\n emitWarning,\n emitError,\n };\n currentUserMessages = turn.pendingUserMessages;\n try {\n await onStart(msg as TStart, turn);\n } catch (err) {\n emitError({ error: err, message: 'bridge turn failed' });\n } finally {\n currentInterruptHandler = undefined;\n currentTurnState = 'waiting';\n void writeBridgeMeta('waiting');\n }\n return;\n }\n case 'tool-result': {\n const resolver = pendingToolResults.get(msg.toolCallId);\n if (resolver) {\n pendingToolResults.delete(msg.toolCallId);\n resolver({ output: msg.output, isError: msg.isError });\n }\n return;\n }\n case 'tool-approval-response': {\n const resolver = pendingToolApprovals.get(msg.approvalId);\n if (resolver) {\n pendingToolApprovals.delete(msg.approvalId);\n resolver({ approved: msg.approved, reason: msg.reason });\n }\n return;\n }\n case 'user-message':\n currentUserMessages?.push(msg.text);\n return;\n case 'abort':\n turnAbort?.abort();\n return;\n case 'interrupt':\n try {\n if (currentInterruptHandler) {\n await currentInterruptHandler();\n } else {\n turnAbort?.abort();\n }\n sendControl({ type: 'bridge-interrupted', ok: true });\n } catch (err) {\n sendControl({\n type: 'bridge-interrupted',\n ok: false,\n error: serialiseError(err),\n });\n }\n return;\n case 'resume':\n replay(ws, msg.lastSeenEventId);\n return;\n case 'shutdown':\n currentTurnState = 'done';\n void writeBridgeMeta('done');\n drainThenExit(ws, 1000, 'shutdown');\n return;\n case 'detach': {\n currentTurnState = 'done';\n void writeBridgeMeta('done');\n const data = (await onDetach?.()) ?? {};\n sendControl({ type: 'bridge-detach', data });\n drainThenExit(ws, 1000, 'detach');\n return;\n }\n }\n };\n\n // ─── server ─────────────────────────────────────────────────────────\n void writeBridgeMeta('init');\n\n const wss = new WebSocketServer({ port: bridgeWsPort, host: '0.0.0.0' });\n\n const exit = (): void => {\n if (options.onExit) {\n options.onExit();\n return;\n }\n wss.close(() => process.exit(0));\n setTimeout(() => process.exit(0), 1000).unref();\n };\n\n const drainThenExit = (ws: WebSocket, code: number, reason: string): void => {\n const start = Date.now();\n const tick = (): void => {\n const drained = ws.bufferedAmount === 0 || ws.readyState !== WS_OPEN;\n if (drained || Date.now() - start >= 5_000) {\n // Flush the on-disk log so a clean shutdown/detach leaves a complete\n // event-log.ndjson for any later replay recovery.\n void flushPendingEventsToDisk().finally(() => {\n try {\n ws.close(code, reason);\n } finally {\n exit();\n }\n });\n return;\n }\n setTimeout(tick, 10).unref();\n };\n tick();\n };\n\n wss.on('listening', () => {\n const addr = wss.address();\n currentBoundPort = typeof addr === 'object' && addr ? addr.port : 0;\n currentTurnState = 'waiting';\n void writeBridgeMeta('waiting');\n stdout.write(\n JSON.stringify({\n type: 'bridge-ready',\n port: currentBoundPort,\n }) + '\\n',\n );\n options.onListening?.(currentBoundPort);\n });\n\n wss.on('connection', (ws: WebSocket, req: { url?: string }) => {\n const url = new URL(req.url ?? '/', 'http://localhost');\n if (url.searchParams.get('agent_bridge_token') !== expectedToken) {\n ws.close(1008, 'unauthorized');\n return;\n }\n\n // Single-flight: a fresh authorized connection *replaces* the active one\n // (the host reconnecting after a drop). The previous socket's close is a\n // no-op below because it is no longer `activeSocket`.\n activeSocket = ws;\n\n // Announce liveness the instant we accept. Some sandbox runtimes complete\n // the host-side WS handshake before the connection is forwarded here; the\n // host waits for this frame before sending `start`/`resume`.\n sendControl({\n type: 'bridge-hello',\n state: currentTurnState,\n lastSeq: seqCounter,\n });\n\n ws.on('message', (raw: ArrayBufferLike | string) => {\n let parsed: TStart | InboundControl;\n try {\n const text =\n typeof raw === 'string' ? raw : Buffer.from(raw).toString('utf8');\n parsed = JSON.parse(text) as TStart | InboundControl;\n } catch (err) {\n sendControl({\n type: 'error',\n error: `protocol parse error: ${(err as Error).message}`,\n });\n return;\n }\n void handleInbound(parsed, ws);\n });\n\n ws.on('close', () => {\n // Only the *current* socket's close matters. A stale socket (already\n // replaced by a reconnect) closing is a no-op. Crucially we do NOT abort\n // the in-flight turn — it keeps running and its events accumulate in the\n // log for replay when the host reconnects.\n if (activeSocket === ws) {\n activeSocket = undefined;\n }\n });\n\n ws.on('error', () => {\n // 'close' follows; nothing to do beyond keeping the process alive.\n });\n });\n\n // Surface bridge-internal crashes to the host instead of dying silently.\n process.on('uncaughtException', err => {\n emitError({ error: err, message: 'uncaught exception' });\n });\n process.on('unhandledRejection', err => {\n emitError({ error: err, message: 'unhandled rejection' });\n });\n\n await new Promise<void>((resolve, reject) => {\n if (wss.address() != null) {\n resolve();\n return;\n }\n\n wss.once('listening', resolve);\n wss.once('error', reject);\n });\n\n return {\n port: currentBoundPort,\n close: () =>\n new Promise<void>(resolve => {\n wss.close(() => resolve());\n }),\n };\n}\n\nfunction serialiseError(err: unknown): unknown {\n if (err instanceof Error) {\n return { name: err.name, message: err.message, stack: err.stack };\n }\n return err;\n}\n","/*\n * Claude reports a compaction in two pieces whose arrival order is not\n * guaranteed: the `compact_boundary` system message (trigger + token counts)\n * and the `PostCompact` hook (the summary text). The harness `compaction`\n * event needs fields from both, so this latch holds each half and emits a\n * single merged event once both have arrived, then resets for the next\n * compaction in the same turn.\n */\n\nexport type CompactionBoundary = {\n trigger: 'manual' | 'auto';\n tokensBefore?: number;\n tokensAfter?: number;\n};\n\nexport type CompactionEvent = {\n type: 'compaction';\n trigger: 'manual' | 'auto';\n summary: string;\n tokensBefore?: number;\n tokensAfter?: number;\n};\n\nexport type CompactionLatch = {\n onBoundary(boundary: CompactionBoundary): void;\n onSummary(summary: string): void;\n};\n\nexport function createCompactionLatch(\n emit: (event: CompactionEvent) => void,\n): CompactionLatch {\n let boundary: CompactionBoundary | undefined;\n let summary: string | undefined;\n\n const tryEmit = (): void => {\n if (!boundary || summary === undefined) return;\n emit({\n type: 'compaction',\n trigger: boundary.trigger,\n summary,\n ...(boundary.tokensBefore !== undefined\n ? { tokensBefore: boundary.tokensBefore }\n : {}),\n ...(boundary.tokensAfter !== undefined\n ? { tokensAfter: boundary.tokensAfter }\n : {}),\n });\n boundary = undefined;\n summary = undefined;\n };\n\n return {\n onBoundary(next) {\n boundary = next;\n tryEmit();\n },\n onSummary(next) {\n summary = next;\n tryEmit();\n },\n };\n}\n","// Long-running bridge that runs inside a sandbox alongside the `claude` CLI.\n// The generic transport — WebSocket server, token auth, single-flight\n// reconnect, the in-memory event log + `seq`, resume replay, and the\n// lifecycle/meta files — lives in the shared `@ai-sdk/harness/bridge` runtime.\n// This file supplies only the Claude-specific turn driver.\n\nimport {\n runBridge,\n type BridgeEvent,\n type BridgeTurn,\n} from '@ai-sdk/harness/bridge';\nimport { createCompactionLatch } from './compaction-latch';\nimport type { StartMessage } from '../claude-code-bridge-protocol';\nimport { randomUUID } from 'node:crypto';\nimport { argv, stdout } from 'node:process';\n\n/*\n * CONSTRAINT — the third-party imports below are NEVER bundled into the\n * compiled `bridge/index.mjs`. They are declared `external` in\n * tsup.config.ts and resolved at runtime from the node_modules that this\n * bridge installs *inside the sandbox* from `src/bridge/package.json` (and\n * its pinned `pnpm-lock.yaml`). That bridge package.json — NOT this host\n * package — is the single source of truth for these packages and their\n * versions; the published `@ai-sdk/harness-claude-code` package does not\n * provide them at runtime.\n *\n * When adding or changing a third-party import here you MUST keep all three\n * in sync, or the bridge will either get the dependency bundled in or fail\n * to resolve it in the sandbox:\n * 1. the import statement below,\n * 2. the `external` array in tsup.config.ts, and\n * 3. the dependency entry in `src/bridge/package.json`.\n */\nimport * as claudeAgentSdk from '@anthropic-ai/claude-agent-sdk';\nimport * as mcpServerModule from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod/v4';\nimport { toClaudeSkillsOption } from './claude-skills-option';\n\n/*\n * Native Claude Code tool name → cross-harness common name. Tools outside this\n * map (e.g. `WebFetch`, `NotebookEdit`) have no common equivalent; their\n * native name is forwarded as-is on `tool-call` events.\n */\ntype CommonBuiltinToolName =\n | 'read'\n | 'write'\n | 'edit'\n | 'bash'\n | 'glob'\n | 'grep'\n | 'webSearch';\n\nconst NATIVE_TO_COMMON: Readonly<Record<string, CommonBuiltinToolName>> = {\n Read: 'read',\n Write: 'write',\n Edit: 'edit',\n Bash: 'bash',\n Glob: 'glob',\n Grep: 'grep',\n WebSearch: 'webSearch',\n};\n\nconst PUBLIC_TO_NATIVE: Readonly<Record<string, string>> = {\n read: 'Read',\n write: 'Write',\n edit: 'Edit',\n bash: 'Bash',\n glob: 'Glob',\n grep: 'Grep',\n webSearch: 'WebSearch',\n WebFetch: 'WebFetch',\n NotebookEdit: 'NotebookEdit',\n TodoWrite: 'TodoWrite',\n Agent: 'Agent',\n TaskCreate: 'TaskCreate',\n TaskGet: 'TaskGet',\n TaskUpdate: 'TaskUpdate',\n TaskList: 'TaskList',\n TaskStop: 'TaskStop',\n TaskOutput: 'TaskOutput',\n Monitor: 'Monitor',\n ListMcpResources: 'ListMcpResources',\n ReadMcpResource: 'ReadMcpResource',\n ExitPlanMode: 'ExitPlanMode',\n EnterWorktree: 'EnterWorktree',\n ExitWorktree: 'ExitWorktree',\n AskUserQuestion: 'AskUserQuestion',\n Skill: 'Skill',\n};\n\nconst PUBLIC_TOOL_NAMES = Object.keys(PUBLIC_TO_NATIVE);\nconst UNRECOVERABLE_API_RETRY_STATUSES = new Set([401, 403, 404]);\n\nconst NATIVE_TOOL_KINDS: Readonly<\n Record<string, 'readonly' | 'edit' | 'bash'>\n> = {\n Read: 'readonly',\n Glob: 'readonly',\n Grep: 'readonly',\n WebSearch: 'readonly',\n WebFetch: 'readonly',\n TaskGet: 'readonly',\n TaskList: 'readonly',\n TaskOutput: 'readonly',\n ListMcpResources: 'readonly',\n ReadMcpResource: 'readonly',\n Write: 'edit',\n Edit: 'edit',\n NotebookEdit: 'edit',\n TodoWrite: 'edit',\n TaskCreate: 'edit',\n TaskUpdate: 'edit',\n TaskStop: 'edit',\n EnterWorktree: 'edit',\n ExitWorktree: 'edit',\n ExitPlanMode: 'edit',\n Skill: 'edit',\n AskUserQuestion: 'readonly',\n Bash: 'bash',\n Monitor: 'bash',\n};\n\nfunction toCommonName(nativeName: string): CommonBuiltinToolName | string {\n return NATIVE_TO_COMMON[nativeName] ?? nativeName;\n}\n\nfunction toNativeName(toolName: string): string {\n return PUBLIC_TO_NATIVE[toolName] ?? toolName;\n}\n\nfunction resolveNativeTools(start: StartMessage): string[] | undefined {\n const toolFiltering = start.builtinToolFiltering;\n if (toolFiltering == null) return undefined;\n const activeToolNames =\n toolFiltering.mode === 'allow'\n ? toolFiltering.toolNames\n : PUBLIC_TOOL_NAMES.filter(\n name => !toolFiltering.toolNames.includes(name),\n );\n return activeToolNames.map(name => toNativeName(name));\n}\n\nfunction resolveInactiveNativeTools(start: StartMessage): string[] {\n const toolFiltering = start.builtinToolFiltering;\n if (toolFiltering == null) return [];\n const inactiveToolNames =\n toolFiltering.mode === 'allow'\n ? PUBLIC_TOOL_NAMES.filter(\n name => !toolFiltering.toolNames.includes(name),\n )\n : toolFiltering.toolNames;\n return inactiveToolNames.map(name => toNativeName(name));\n}\n\nconst args = parseArgs(argv.slice(2));\nconst workdir = args.workdir;\nconst bridgeStateDir = args.bridgeStateDir;\nif (!workdir) {\n emitFatal('Missing --workdir argument.');\n}\nif (!bridgeStateDir) {\n emitFatal('Missing --bridge-state-dir argument.');\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst claudeSdk = claudeAgentSdk as any;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst mcpModule = mcpServerModule as any;\n\nawait runBridge<StartMessage>({\n bridgeType: 'claude-code',\n bridgeStateDir,\n onStart: runTurn,\n // Claude Code's session state lives in the workdir on the sandbox filesystem\n // (captured by the sandbox snapshot on stop); the resume payload is empty.\n onDetach: () => ({}),\n});\n\ntype Emit = (msg: Record<string, unknown>) => void;\n\nfunction createPermissionOptions(input: {\n start: StartMessage;\n inactiveNativeTools: readonly string[];\n turn: BridgeTurn;\n emit: Emit;\n finishApprovalStep: (approvalId: string) => void;\n nativeToolCallNames: Map<string, string>;\n approvalRequestedToolUseIds: Set<string>;\n}): Record<string, unknown> {\n const permissionMode = input.start.permissionMode ?? 'allow-all';\n const inactiveNativeTools = new Set(input.inactiveNativeTools);\n const permissionSettings = createPermissionSettings({\n permissionMode,\n inactiveNativeTools,\n });\n if (permissionMode === 'allow-all' && inactiveNativeTools.size === 0) {\n return {\n permissionMode: 'bypassPermissions',\n allowDangerouslySkipPermissions: true,\n };\n }\n\n return {\n permissionMode:\n permissionMode === 'allow-edits' ? 'acceptEdits' : 'default',\n allowDangerouslySkipPermissions: false,\n ...(permissionSettings ? { settings: permissionSettings } : {}),\n canUseTool: async (\n toolName: string,\n toolInput: Record<string, unknown>,\n options: { toolUseID: string },\n ) => {\n if (toolName.startsWith('mcp__harness-tools__')) {\n return { behavior: 'allow', updatedInput: toolInput };\n }\n if (\n !inactiveNativeTools.has(toolName) &&\n !nativeToolRequiresApproval({\n nativeName: toolName,\n permissionMode,\n })\n ) {\n return { behavior: 'allow', updatedInput: toolInput };\n }\n\n const approvalId = options.toolUseID;\n input.approvalRequestedToolUseIds.add(approvalId);\n input.nativeToolCallNames.set(approvalId, toolName);\n input.emit({\n type: 'tool-call',\n toolCallId: approvalId,\n toolName: toCommonName(toolName),\n nativeName: toolName,\n input: JSON.stringify(toolInput ?? {}),\n providerExecuted: true,\n });\n input.emit({\n type: 'tool-approval-request',\n approvalId,\n toolCallId: approvalId,\n });\n input.finishApprovalStep(approvalId);\n\n const decision = await input.turn.requestToolApproval(approvalId);\n return decision.approved\n ? { behavior: 'allow', updatedInput: toolInput, toolUseID: approvalId }\n : {\n behavior: 'deny',\n message: decision.reason ?? 'Denied',\n toolUseID: approvalId,\n };\n },\n };\n}\n\nfunction createPermissionSettings(input: {\n permissionMode: 'allow-reads' | 'allow-edits' | 'allow-all';\n inactiveNativeTools: ReadonlySet<string>;\n}): Record<string, unknown> | undefined {\n const askRules = new Set<string>();\n for (const [nativeName, kind] of Object.entries(NATIVE_TOOL_KINDS)) {\n if (\n input.inactiveNativeTools.has(nativeName) ||\n (input.permissionMode === 'allow-reads'\n ? kind === 'edit' || kind === 'bash'\n : input.permissionMode === 'allow-edits'\n ? kind === 'bash'\n : false)\n ) {\n askRules.add(`${nativeName}(*)`);\n }\n }\n\n if (askRules.size === 0) return undefined;\n\n return {\n permissions: { ask: [...askRules] },\n sandbox: { autoAllowBashIfSandboxed: false },\n };\n}\n\nfunction nativeToolRequiresApproval(input: {\n nativeName: string;\n permissionMode: 'allow-reads' | 'allow-edits' | 'allow-all';\n}): boolean {\n if (input.permissionMode === 'allow-all') return false;\n const kind = NATIVE_TOOL_KINDS[input.nativeName] ?? 'edit';\n if (input.permissionMode === 'allow-edits') return kind === 'bash';\n return kind === 'edit' || kind === 'bash';\n}\n\nasync function runTurn(start: StartMessage, turn: BridgeTurn): Promise<void> {\n const emit: Emit = msg => turn.emit(msg as BridgeEvent);\n\n // Local controller for the Claude query. Aborted either by the host (via the\n // shared runtime's `turn.abortSignal`) or by us on a terminal error.\n const abortCtl = new AbortController();\n if (turn.abortSignal.aborted) {\n abortCtl.abort();\n } else {\n turn.abortSignal.addEventListener('abort', () => abortCtl.abort(), {\n once: true,\n });\n }\n\n /*\n * Map of native tool-use id → tool name. Claude assistant messages emit\n * `tool_use` blocks with both `id` and `name`; the matching `tool_result`\n * block on a later user message carries only `tool_use_id`, so without this\n * map the tool-result event would have to emit `toolName: 'unknown'`.\n */\n const nativeToolCallNames = new Map<string, string>();\n const approvalRequestedToolUseIds = new Set<string>();\n const partialBlocks = new Map<\n number,\n { id: string; kind: 'text' | 'thinking' }\n >();\n let stepUsage: Record<string, unknown> | undefined;\n let pendingStepToolUseIds = new Set<string>();\n let pendingStepUsage: Record<string, unknown> | undefined;\n let stepOpen = false;\n\n const emitFinishStep = (usage: Record<string, unknown> | undefined): void => {\n emit({\n type: 'finish-step',\n finishReason: { unified: 'stop', raw: 'stop' },\n usage: usage ?? defaultUsage(),\n });\n stepUsage = usage ?? stepUsage;\n pendingStepUsage = undefined;\n pendingStepToolUseIds = new Set();\n stepOpen = false;\n };\n\n const closeStepIfReady = (): void => {\n if (!stepOpen || pendingStepToolUseIds.size > 0 || partialBlocks.size > 0) {\n return;\n }\n emitFinishStep(pendingStepUsage);\n };\n\n /*\n * Tool-use ids that originated from the MCP server hosting user-supplied\n * tools. The MCP handler emits its own `tool-call`/`tool-result` pair with\n * the user-facing tool name and a synthetic id, so the duplicate\n * `tool_result` block Claude reports for the underlying native id must be\n * suppressed.\n */\n const mcpToolUseIds = new Set<string>();\n\n const mcpServers: Record<string, unknown> = {};\n if (start.tools && start.tools.length > 0) {\n const server = new mcpModule.McpServer({\n name: 'harness-tools',\n version: '1.0.0',\n });\n for (const tool of start.tools) {\n const shape = jsonSchemaToZodShape(tool.inputSchema, z);\n server.tool(\n tool.name,\n tool.description ?? '',\n shape,\n async (input: Record<string, unknown>) => {\n const toolCallId = randomUUID();\n emit({\n type: 'tool-call',\n toolCallId,\n toolName: tool.name,\n input: JSON.stringify(input),\n providerExecuted: false,\n });\n const { output, isError } = await turn.requestToolResult(toolCallId);\n emit({\n type: 'tool-result',\n toolCallId,\n toolName: tool.name,\n result: output ?? null,\n isError: !!isError,\n });\n return {\n content: [{ type: 'text', text: JSON.stringify(output ?? null) }],\n isError,\n };\n },\n );\n }\n mcpServers['harness-tools'] = {\n type: 'sdk',\n name: 'harness-tools',\n instance: server,\n };\n }\n\n // Compaction observation: merge Claude's `compact_boundary` message and\n // `PostCompact` hook (which arrive in either order) into one `compaction`\n // event. See `createCompactionLatch`.\n const compaction = createCompactionLatch(event => emit(event));\n\n // `stream-start` is emitted lazily on the first SDK message (below) so it can\n // carry the model the CLI resolved to, reported on the `system`/`init` message.\n\n const queryInput = createQueryInput({\n initialUserMessage: start.prompt,\n pendingUserMessages: turn.pendingUserMessages,\n abortSignal: abortCtl.signal,\n });\n const skillsOption = toClaudeSkillsOption(start.skills);\n const nativeTools = resolveNativeTools(start);\n const inactiveNativeTools = resolveInactiveNativeTools(start);\n const permissionOptions = createPermissionOptions({\n start,\n inactiveNativeTools,\n turn,\n emit,\n finishApprovalStep: approvalId => {\n stepOpen = true;\n pendingStepToolUseIds.delete(approvalId);\n closeStepIfReady();\n },\n nativeToolCallNames,\n approvalRequestedToolUseIds,\n });\n\n const q = claudeSdk.query({\n prompt: queryInput.input,\n options: {\n ...(start.model ? { model: start.model } : {}),\n ...(start.maxTurns !== undefined ? { maxTurns: start.maxTurns } : {}),\n ...(skillsOption ? { skills: skillsOption } : {}),\n ...(nativeTools !== undefined ? { tools: nativeTools } : {}),\n ...(inactiveNativeTools.length > 0\n ? { disallowedTools: inactiveNativeTools }\n : {}),\n thinking: start.thinking,\n includePartialMessages: true,\n // The `PostCompact` hook carries the compaction summary, which the\n // `compact_boundary` system message does not. Latch it for the unified\n // `compaction` event; return an empty output so compaction proceeds.\n hooks: {\n PostCompact: [\n {\n hooks: [\n async (input: { compact_summary?: unknown }) => {\n if (typeof input?.compact_summary === 'string') {\n compaction.onSummary(input.compact_summary);\n }\n return {};\n },\n ],\n },\n ],\n },\n // Continuation rule: the host can force-continue (resume after a\n // cross-process detach) by setting `start.continue: true`; otherwise\n // we continue every subsequent turn after the first one in this\n // bridge process.\n ...(start.continue === true || !turn.firstTurn ? { continue: true } : {}),\n ...permissionOptions,\n mcpServers,\n cwd: workdir,\n abortSignal: abortCtl.signal,\n },\n });\n turn.onInterrupt(() => q.interrupt());\n\n let turnUsage: Record<string, unknown> | undefined;\n let totalCostUsd: number | undefined;\n let observedTerminalError: string | undefined;\n let emittedTerminalError = false;\n let emittedTerminalFinish = false;\n let streamStarted = false;\n\n const emitTerminalError = (message: string | undefined): void => {\n const normalized = message?.trim();\n if (!normalized || emittedTerminalError || emittedTerminalFinish) return;\n observedTerminalError = normalized;\n emittedTerminalError = true;\n turn.emitError({\n error: normalized,\n message: 'claude-code terminal error',\n });\n queryInput.close();\n abortCtl.abort();\n };\n\n try {\n for await (const msg of q as AsyncIterable<ClaudeMessage>) {\n if (abortCtl.signal.aborted) break;\n\n const type = msg.type;\n\n // Emit `stream-start` once, on the first message, carrying the model the\n // CLI resolved to (the `system`/`init` message reports it — this is the\n // default model when none was configured).\n if (!streamStarted) {\n const initModel =\n type === 'system' &&\n msg.subtype === 'init' &&\n typeof (msg as { model?: unknown }).model === 'string'\n ? (msg as { model: string }).model\n : undefined;\n emit({\n type: 'stream-start',\n ...(initModel ? { modelId: initModel } : {}),\n });\n streamStarted = true;\n }\n\n if (type === 'system' && msg.subtype === 'api_retry') {\n if (\n typeof msg.error_status === 'number' &&\n UNRECOVERABLE_API_RETRY_STATUSES.has(msg.error_status)\n ) {\n emitTerminalError(\n `HTTP ${msg.error_status}: ${\n msg.error ?? 'provider request failed'\n }`,\n );\n continue;\n }\n\n turn.emitWarning({ message: formatApiRetryWarning(msg) });\n continue;\n }\n\n if (typeof msg.error === 'string' && msg.error.trim()) {\n observedTerminalError = msg.error.trim();\n }\n\n if (\n type === 'auth_status' &&\n typeof msg.error === 'string' &&\n msg.error.trim()\n ) {\n emitTerminalError(msg.error);\n continue;\n }\n\n if (\n type === 'system' &&\n msg.subtype === 'task_updated' &&\n msg.patch?.status === 'failed' &&\n typeof msg.patch.error === 'string'\n ) {\n emitTerminalError(msg.patch.error);\n continue;\n }\n\n if (type === 'system' && msg.subtype === 'compact_boundary') {\n const meta = msg.compact_metadata;\n if (meta) {\n compaction.onBoundary({\n trigger: meta.trigger,\n ...(typeof meta.pre_tokens === 'number'\n ? { tokensBefore: meta.pre_tokens }\n : {}),\n ...(typeof meta.post_tokens === 'number'\n ? { tokensAfter: meta.post_tokens }\n : {}),\n });\n }\n continue;\n }\n\n if (type === 'stream_event') {\n handleStreamEvent(msg.event, partialBlocks, emit);\n continue;\n }\n\n if (type === 'assistant' && msg.message?.content) {\n const usage = mapUsage(msg.message.usage);\n const toolUseIds: string[] = [];\n let opensStep = false;\n for (const block of msg.message.content) {\n if (\n block.type === 'tool_use' &&\n typeof block.id === 'string' &&\n typeof block.name === 'string'\n ) {\n toolUseIds.push(block.id);\n const mcpPrefix = 'mcp__harness-tools__';\n if (block.name.startsWith(mcpPrefix)) {\n pendingStepToolUseIds.add(block.id);\n mcpToolUseIds.add(block.id);\n opensStep = true;\n continue;\n }\n nativeToolCallNames.set(block.id, block.name);\n if (approvalRequestedToolUseIds.has(block.id)) {\n continue;\n }\n pendingStepToolUseIds.add(block.id);\n opensStep = true;\n emit({\n type: 'tool-call',\n toolCallId: block.id,\n toolName: toCommonName(block.name),\n nativeName: block.name,\n input: JSON.stringify(block.input ?? {}),\n providerExecuted: true,\n });\n }\n }\n if (opensStep || toolUseIds.length === 0) {\n stepOpen = true;\n if (usage) pendingStepUsage = usage;\n }\n continue;\n }\n\n if (type === 'user' && msg.message?.content) {\n for (const block of msg.message.content) {\n if (\n block.type === 'tool_result' &&\n typeof block.tool_use_id === 'string'\n ) {\n if (mcpToolUseIds.has(block.tool_use_id)) {\n mcpToolUseIds.delete(block.tool_use_id);\n pendingStepToolUseIds.delete(block.tool_use_id);\n continue;\n }\n approvalRequestedToolUseIds.delete(block.tool_use_id);\n const nativeName =\n nativeToolCallNames.get(block.tool_use_id) ?? 'unknown';\n nativeToolCallNames.delete(block.tool_use_id);\n const toolName = toCommonName(nativeName);\n const isError = !!block.is_error;\n const content = stringifyContent(block.content);\n /*\n * Claude Code's Bash tool does not report the command's real\n * numeric exit code — the SDK exposes only stdout/stderr text and\n * an is_error flag. Consumers (and the example UI) render bash\n * failures from an `exitCode` field on a structured result, the\n * shape Codex's shell tool provides natively. To match it, derive\n * a binary code from is_error: 1 on failure, 0 on success. This is\n * a stand-in for failed/succeeded, not the process's true exit\n * status.\n */\n const result =\n toolName === 'bash'\n ? { exitCode: isError ? 1 : 0, stdout: content }\n : content;\n emit({\n type: 'tool-result',\n toolCallId: block.tool_use_id,\n toolName,\n result,\n isError,\n });\n pendingStepToolUseIds.delete(block.tool_use_id);\n }\n }\n closeStepIfReady();\n continue;\n }\n\n if (type === 'result') {\n if (msg.subtype === 'success') {\n const emptyResult = !msg.result?.trim?.();\n if (emptyResult && observedTerminalError) {\n emitTerminalError(observedTerminalError);\n continue;\n }\n const usage = msg.usage ?? msg.message?.usage;\n const harnessUsage = mapUsage(usage);\n if (harnessUsage) turnUsage = harnessUsage;\n if (typeof msg.total_cost_usd === 'number') {\n totalCostUsd = (totalCostUsd ?? 0) + msg.total_cost_usd;\n }\n if (stepOpen) emitFinishStep(harnessUsage ?? pendingStepUsage);\n queryInput.close();\n break;\n } else {\n emitTerminalError(\n (Array.isArray(msg.errors) ? msg.errors.join('\\n') : undefined) ||\n observedTerminalError ||\n msg.result ||\n 'Unknown error',\n );\n }\n continue;\n }\n }\n } catch (err) {\n if (!(abortCtl.signal.aborted && emittedTerminalError)) {\n turn.emitError({ error: err, message: 'claude-code turn failed' });\n }\n return;\n } finally {\n queryInput.close();\n }\n\n if (emittedTerminalError) return;\n emittedTerminalFinish = true;\n void emittedTerminalFinish;\n emit({\n type: 'finish',\n finishReason: { unified: 'stop', raw: 'stop' },\n totalUsage: turnUsage ?? stepUsage ?? defaultUsage(),\n ...(totalCostUsd !== undefined\n ? { harnessMetadata: { 'claude-code': { costUsd: totalCostUsd } } }\n : {}),\n });\n}\n\ntype ClaudeMessage = {\n type?: string;\n subtype?: string;\n error?: string;\n error_status?: number | null;\n attempt?: number;\n max_retries?: number;\n retry_delay_ms?: number;\n patch?: { status?: string; error?: string };\n compact_metadata?: {\n trigger: 'manual' | 'auto';\n pre_tokens?: number;\n post_tokens?: number;\n };\n event?: {\n type?: string;\n index?: number;\n content_block?: { type?: string };\n delta?: { type?: string; text?: string; thinking?: string };\n };\n message?: {\n content?: ReadonlyArray<MessageBlock>;\n usage?: Record<string, unknown>;\n };\n result?: string;\n errors?: ReadonlyArray<string>;\n usage?: Record<string, unknown>;\n total_cost_usd?: number;\n};\n\nfunction formatApiRetryWarning(msg: ClaudeMessage): string {\n const details: string[] = [];\n if (typeof msg.attempt === 'number') {\n const maxRetries =\n typeof msg.max_retries === 'number' ? `/${msg.max_retries}` : '';\n details.push(`attempt ${msg.attempt}${maxRetries}`);\n }\n if (typeof msg.error_status === 'number') {\n details.push(`HTTP ${msg.error_status}`);\n }\n if (typeof msg.retry_delay_ms === 'number') {\n details.push(`retrying in ${msg.retry_delay_ms}ms`);\n }\n if (msg.error) details.push(msg.error);\n return details.length > 0\n ? `Claude Code API retry: ${details.join('; ')}`\n : 'Claude Code API retry';\n}\n\nfunction handleStreamEvent(\n event: ClaudeMessage['event'] | undefined,\n partialBlocks: Map<number, { id: string; kind: 'text' | 'thinking' }>,\n send: Emit,\n): void {\n if (!event || typeof event.index !== 'number') return;\n const index = event.index;\n\n if (event.type === 'content_block_start') {\n const blockType = event.content_block?.type;\n if (blockType === 'text') {\n const id = randomUUID();\n partialBlocks.set(index, { id, kind: 'text' });\n send({ type: 'text-start', id });\n } else if (blockType === 'thinking') {\n const id = randomUUID();\n partialBlocks.set(index, { id, kind: 'thinking' });\n send({ type: 'reasoning-start', id });\n }\n return;\n }\n\n if (event.type === 'content_block_delta') {\n const block = partialBlocks.get(index);\n if (!block) return;\n if (\n block.kind === 'text' &&\n event.delta?.type === 'text_delta' &&\n typeof event.delta.text === 'string'\n ) {\n send({ type: 'text-delta', id: block.id, delta: event.delta.text });\n } else if (\n block.kind === 'thinking' &&\n event.delta?.type === 'thinking_delta' &&\n typeof event.delta.thinking === 'string'\n ) {\n send({\n type: 'reasoning-delta',\n id: block.id,\n delta: event.delta.thinking,\n });\n }\n return;\n }\n\n if (event.type === 'content_block_stop') {\n const block = partialBlocks.get(index);\n if (!block) return;\n partialBlocks.delete(index);\n if (block.kind === 'text') {\n send({ type: 'text-end', id: block.id });\n } else {\n send({ type: 'reasoning-end', id: block.id });\n }\n }\n}\n\nfunction createQueryInput({\n initialUserMessage,\n pendingUserMessages,\n abortSignal,\n}: {\n initialUserMessage: string;\n pendingUserMessages: string[];\n abortSignal: AbortSignal;\n}): {\n input: AsyncIterable<unknown>;\n close(): void;\n} {\n let closed = false;\n const close = (): void => {\n closed = true;\n };\n if (abortSignal.aborted) {\n close();\n } else {\n abortSignal.addEventListener('abort', close, { once: true });\n }\n\n const toUserMessage = (text: string): unknown => ({\n type: 'user',\n message: {\n role: 'user',\n content: [{ type: 'text', text }],\n },\n });\n\n return {\n close,\n input: {\n [Symbol.asyncIterator]() {\n let sentInitial = false;\n return {\n async next() {\n // eslint-disable-next-line no-unmodified-loop-condition\n while (!closed && !abortSignal.aborted) {\n if (!sentInitial) {\n sentInitial = true;\n return {\n value: toUserMessage(initialUserMessage),\n done: false,\n };\n }\n if (pendingUserMessages.length > 0) {\n return {\n value: toUserMessage(pendingUserMessages.shift()!),\n done: false,\n };\n }\n await new Promise(resolve => setTimeout(resolve, 50));\n }\n return { value: undefined, done: true } as IteratorResult<unknown>;\n },\n };\n },\n },\n };\n}\n\ntype MessageBlock = {\n type: string;\n text?: string;\n thinking?: string;\n id?: string;\n name?: string;\n input?: unknown;\n tool_use_id?: string;\n content?: unknown;\n is_error?: boolean;\n};\n\nfunction stringifyContent(content: unknown): string {\n if (typeof content === 'string') return content;\n if (Array.isArray(content)) {\n return content\n .map(entry =>\n entry && typeof entry === 'object' && 'text' in entry\n ? String((entry as { text?: unknown }).text ?? '')\n : JSON.stringify(entry),\n )\n .join('');\n }\n return JSON.stringify(content);\n}\n\nfunction mapUsage(usage: unknown): Record<string, unknown> | undefined {\n if (!usage || typeof usage !== 'object') return undefined;\n const u = usage as {\n input_tokens?: number;\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n output_tokens?: number;\n };\n return {\n inputTokens: {\n total:\n (u.input_tokens ?? 0) +\n (u.cache_creation_input_tokens ?? 0) +\n (u.cache_read_input_tokens ?? 0),\n noCache: u.input_tokens ?? 0,\n cacheRead: u.cache_read_input_tokens ?? 0,\n cacheWrite: u.cache_creation_input_tokens ?? 0,\n },\n outputTokens: {\n total: u.output_tokens ?? 0,\n text: u.output_tokens ?? 0,\n },\n };\n}\n\nfunction defaultUsage(): Record<string, unknown> {\n return {\n inputTokens: { total: 0, noCache: 0, cacheRead: 0, cacheWrite: 0 },\n outputTokens: { total: 0, text: 0 },\n };\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction jsonSchemaToZodShape(\n schema: unknown,\n z: any,\n): Record<string, unknown> {\n if (!schema || typeof schema !== 'object') return {};\n const s = schema as {\n properties?: Record<string, { type?: string; description?: string }>;\n required?: string[];\n };\n const shape: Record<string, unknown> = {};\n const required = new Set(s.required ?? []);\n for (const [key, val] of Object.entries(s.properties ?? {})) {\n let z_: unknown;\n switch (val.type) {\n case 'string':\n z_ = z.string();\n break;\n case 'number':\n case 'integer':\n z_ = z.number();\n break;\n case 'boolean':\n z_ = z.boolean();\n break;\n case 'array':\n z_ = z.array(z.any());\n break;\n default:\n z_ = z.any();\n }\n if (val.description)\n z_ = (z_ as { describe: (s: string) => unknown }).describe(\n val.description,\n );\n shape[key] = required.has(key)\n ? z_\n : (z_ as { optional: () => unknown }).optional();\n }\n return shape;\n}\n\nfunction parseArgs(args: string[]): {\n workdir?: string;\n bridgeStateDir?: string;\n} {\n const out: { workdir?: string; bridgeStateDir?: string } = {};\n for (let i = 0; i < args.length; i++) {\n if (args[i] === '--workdir' && i + 1 < args.length) {\n out.workdir = args[++i];\n } else if (args[i] === '--bridge-state-dir' && i + 1 < args.length) {\n out.bridgeStateDir = args[++i];\n }\n }\n return out;\n}\n\nfunction emitFatal(message: string): never {\n stdout.write(JSON.stringify({ type: 'bridge-fatal', message }) + '\\n');\n process.exit(1);\n}\n","export function toClaudeSkillsOption(\n skills: ReadonlyArray<string> | undefined,\n): 'all' | undefined {\n /*\n * The Claude Agent SDK treats `skills: string[]` as an allowlist, which hides\n * built-in/default skills. When the harness writes project skills, ask Claude\n * to enable every discovered skill so bundled defaults and project skills are\n * both visible.\n */\n return skills && skills.length > 0 ? 'all' : undefined;\n}\n"],"mappings":"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","names":["bridgeStateDir","stdout","z","args","stdout"]}
|
|
1
|
+
{"version":3,"sources":["../../../harness/src/bridge/index.ts","../../src/bridge/compaction-latch.ts","../../src/bridge/index.ts","../../src/bridge/claude-skills-option.ts"],"sourcesContent":["// Shared in-sandbox bridge runtime. Adapter `bridge.mjs` bundles re-bundle\n// this module (tsup inlines it; `ws` stays external and resolves from the\n// sandbox-installed node_modules). It owns everything generic to the bridge\n// transport — the WebSocket server, token auth, single-flight connection\n// replacement, the in-memory event log + monotonic `seq`, resume replay, and\n// the lifecycle/meta files. The adapter supplies only `onStart` (drive its\n// CLI/SDK and translate to wire events) and `onDetach` (its resume payload).\n\nimport { appendFile, mkdir, writeFile } from 'node:fs/promises';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { env as procEnv, pid, stdout } from 'node:process';\nimport { WebSocketServer, type WebSocket } from 'ws';\n\nexport type BridgeState = 'init' | 'waiting' | 'running' | 'draining' | 'done';\n\n/** Outbound turn event the adapter emits. `seq` is added by the runtime. */\nexport type BridgeEvent = Record<string, unknown> & { type: string };\n\nexport type BridgeDebugLevel = 'error' | 'warn' | 'info' | 'debug' | 'trace';\n\n/**\n * Per-session diagnostics config. The host resolves it from settings +\n * env and sends it on `start.debug`; the bridge gates console capture and\n * structured `debug-event`s on it. When disabled, nothing is captured or\n * emitted and no `seq` is consumed.\n */\nexport interface BridgeDebugConfig {\n enabled?: boolean;\n level?: BridgeDebugLevel;\n subsystems?: string[];\n}\n\nconst DEBUG_LEVEL_WEIGHT: Record<BridgeDebugLevel, number> = {\n error: 0,\n warn: 1,\n info: 2,\n debug: 3,\n trace: 4,\n};\n\n/** Exact-or-dotted-prefix subsystem match (`'bridge'` matches `'bridge.turn'`). */\nfunction subsystemMatches(\n filters: string[] | undefined,\n subsystem: string,\n): boolean {\n if (!filters || filters.length === 0) return true;\n return filters.some(\n filter => subsystem === filter || subsystem.startsWith(`${filter}.`),\n );\n}\n\nfunction formatBridgeError(err: unknown): {\n name?: string;\n message: string;\n stack?: string;\n} {\n if (err instanceof Error) {\n return { name: err.name, message: err.message, stack: err.stack };\n }\n if (typeof err === 'string') {\n return { message: err };\n }\n if (err !== null && typeof err === 'object') {\n try {\n return { message: JSON.stringify(err) };\n } catch {}\n }\n return { message: String(err) };\n}\n\nfunction parseEnvList(value: string | undefined): string[] | undefined {\n if (!value) return undefined;\n const items = value\n .split(',')\n .map(item => item.trim())\n .filter(Boolean);\n return items.length > 0 ? items : undefined;\n}\n\nconst ENV_TRUTHY = new Set(['1', 'true', 'yes', 'on']);\n\n/**\n * Per-turn surface handed to {@link RunBridgeOptions.onStart}. The adapter\n * drives its runtime against these primitives; the runtime owns the transport.\n */\nexport interface BridgeTurn {\n /**\n * Emit a turn event to the host. Stamps a monotonic `seq`, appends to the\n * in-memory replay log, and sends to the live socket (best-effort — if the\n * host is mid-reconnect the event waits in the log and is replayed on\n * resume).\n */\n emit(event: BridgeEvent): void;\n\n /**\n * Register interest in a host-executed tool result and resolve when the\n * matching `tool-result` arrives. The adapter emits the `tool-call` event\n * itself (via {@link emit}) using the same `toolCallId`.\n */\n requestToolResult(\n toolCallId: string,\n ): Promise<{ output: unknown; isError?: boolean }>;\n\n /**\n * Register interest in a host approval decision and resolve when the matching\n * `tool-approval-response` arrives. The adapter emits the\n * `tool-approval-request` event itself using the same `approvalId`.\n */\n requestToolApproval(\n approvalId: string,\n ): Promise<{ approved: boolean; reason?: string }>;\n\n /**\n * Live queue of mid-turn user messages. The runtime pushes inbound\n * `user-message` text here; the adapter drains it as its runtime accepts\n * interactive input.\n */\n readonly pendingUserMessages: string[];\n\n /** Aborts when the host sends `abort`. */\n readonly abortSignal: AbortSignal;\n\n /**\n * Register the runtime-specific interrupt hook for this active turn. The\n * shared bridge invokes it when the host sends `interrupt`, then acknowledges\n * only after the hook settles.\n */\n onInterrupt(handler: () => void | Promise<void>): void;\n\n /** True for the first turn since this bridge process started. */\n readonly firstTurn: boolean;\n\n /**\n * Emit a structured diagnostic. Gated by the session's debug level +\n * subsystem filter; a no-op when diagnostics are disabled. Adapters use this\n * for runtime-level instrumentation; raw `console.*` output is captured and\n * forwarded automatically.\n */\n bridgeLog(input: {\n level?: BridgeDebugLevel;\n subsystem: string;\n message: string;\n attrs?: Record<string, unknown>;\n error?: unknown;\n }): void;\n\n /**\n * Emit a non-fatal bridge warning to stderr using the runtime's harness\n * prefix. This is diagnostic-only: it does not emit a stream event, does not\n * consume a `seq`, and does not fail the turn.\n */\n emitWarning(input: { message: string }): void;\n\n emitError(input: { error: unknown; message?: string }): void;\n}\n\nexport interface RunBridgeOptions<TStart extends { type: 'start' }> {\n /** Identifier written into `bridge-meta.json` (`'claude-code'` / `'codex'`). */\n bridgeType: string;\n /** Directory for `bridge-meta.json` / `start-config.json`. Created if absent. */\n bridgeStateDir: string;\n /** Drive one prompt turn. Rejections surface to the host as an `error` event. */\n onStart(start: TStart, turn: BridgeTurn): Promise<void>;\n /** Produce the adapter-defined resume payload for a `detach`. Defaults to `{}`. */\n onDetach?(): unknown | Promise<unknown>;\n /** WS port. Defaults to `BRIDGE_WS_PORT` env (0 = OS-assigned). */\n port?: number;\n /** Auth token. Defaults to `BRIDGE_CHANNEL_TOKEN` env. */\n token?: string;\n /** Called with the bound port once the server is listening. */\n onListening?(port: number): void;\n /**\n * Tear the process down after a `shutdown` / `detach`. Defaults to closing\n * the server and calling `process.exit(0)`. Overridable for tests.\n */\n onExit?(): void;\n}\n\ntype InboundControl =\n | {\n type: 'tool-result';\n toolCallId: string;\n output: unknown;\n isError?: boolean;\n }\n | {\n type: 'tool-approval-response';\n approvalId: string;\n approved: boolean;\n reason?: string;\n }\n | { type: 'user-message'; text: string }\n | { type: 'abort' }\n | { type: 'interrupt' }\n | { type: 'shutdown' }\n | { type: 'detach' }\n | { type: 'resume'; lastSeenEventId: number };\n\nconst WS_OPEN = 1;\n\n/**\n * Boot the bridge: bind the WebSocket server, announce `bridge-ready`, and\n * service host connections for the lifetime of the process. Resolves once the\n * server is listening; the process then stays alive on the server until a\n * `shutdown` / `detach` exits it.\n */\nexport interface BridgeHandle {\n /** The port the WebSocket server bound to. */\n readonly port: number;\n /** Close the WebSocket server. Does not call `process.exit`. */\n close(): Promise<void>;\n}\n\nexport async function runBridge<TStart extends { type: 'start' }>(\n options: RunBridgeOptions<TStart>,\n): Promise<BridgeHandle> {\n const { bridgeType, bridgeStateDir, onStart, onDetach } = options;\n const expectedToken = options.token ?? procEnv.BRIDGE_CHANNEL_TOKEN ?? '';\n const bridgeWsPort =\n options.port ?? parseInt(procEnv.BRIDGE_WS_PORT ?? '0', 10);\n\n const bridgeMetaPath = `${bridgeStateDir}/bridge-meta.json`;\n const startConfigPath = `${bridgeStateDir}/start-config.json`;\n const rerunStartConfigPath = `${bridgeStateDir}/rerun-start-config.json`;\n const eventLogPath = `${bridgeStateDir}/event-log.ndjson`;\n\n try {\n await mkdir(bridgeStateDir, { recursive: true });\n } catch {\n // Best-effort; the bridge still runs without its state files.\n }\n\n // ─── mutable runtime state ──────────────────────────────────────────\n let currentBoundPort = 0;\n let currentTurnState: BridgeState = 'init';\n let activeSocket: WebSocket | undefined;\n let isFirstTurn = true;\n let turnAbort: AbortController | undefined;\n let currentUserMessages: string[] | undefined;\n let currentInterruptHandler: (() => void | Promise<void>) | undefined;\n\n // Diagnostics. Resolved per turn from `start.debug` with a sandbox-side\n // env fallback; gates console capture + structured `debug-event`s.\n let debugConfig: BridgeDebugConfig | undefined;\n let consoleCaptureInstalled = false;\n const envDebugEnabled = ENV_TRUTHY.has(\n (procEnv.HARNESS_DEBUG ?? '').toLowerCase(),\n );\n\n // Replay log. `seq` is monotonic across the whole process — never reset —\n // because the host's `SandboxChannel` cursor (`lastSeenEventId`) lives across\n // turns. The log *contents* are cleared at the start of each turn to bound\n // memory; the just-finished turn stays replayable until the next `start`.\n let seqCounter = 0;\n let eventLog: Array<{ seq: number; line: string }> = [];\n\n /*\n * Disk mirror of the in-memory replay log. The in-memory log is lost when the\n * bridge process dies; the on-disk `event-log.ndjson` survives in the sandbox\n * filesystem so a respawned bridge (started with `BRIDGE_REPLAY_FROM_DISK=1`)\n * can reload the just-interrupted turn and serve a host's resume cursor —\n * `replay` recovery. Writes are batched on `setImmediate` (single-flight via\n * `flushPromise`) to keep `emit` off the disk hot path.\n */\n let diskBuffer = '';\n let flushPromise: Promise<void> | null = null;\n\n const flushEventsToDisk = async (): Promise<void> => {\n while (diskBuffer.length > 0) {\n const buf = diskBuffer;\n diskBuffer = '';\n await appendFile(eventLogPath, buf).catch(() => {\n // Best-effort crash-recovery mirror; the in-memory log is the source of\n // truth for the live connection.\n });\n }\n };\n\n const scheduleEventFlush = (): void => {\n if (flushPromise) return;\n flushPromise = new Promise<void>(resolve => {\n setImmediate(() => {\n void flushEventsToDisk().finally(resolve);\n });\n }).finally(() => {\n flushPromise = null;\n if (diskBuffer.length > 0) {\n scheduleEventFlush();\n }\n });\n };\n\n const flushPendingEventsToDisk = async (): Promise<void> => {\n if (diskBuffer.length > 0 && !flushPromise) {\n scheduleEventFlush();\n }\n // Await each in-flight flush, re-reading `flushPromise` after every await\n // since a fresh flush may have been scheduled for buffer that arrived while\n // we waited.\n let inFlight = flushPromise;\n while (inFlight) {\n await inFlight;\n inFlight = flushPromise;\n }\n };\n\n /*\n * When respawned for `replay`, reload the previous turn's log from disk before\n * accepting any connection so the very first `resume{lastSeenEventId}` can be\n * served the tail (including the terminal `finish`). The seq counter is\n * restored to the last persisted seq so it stays aligned with the host's\n * long-lived cursor. The file is NOT truncated in this mode — only a fresh\n * `start` (next turn) clears it.\n */\n const replayFromDisk = procEnv.BRIDGE_REPLAY_FROM_DISK === '1';\n if (replayFromDisk && existsSync(eventLogPath)) {\n try {\n const lines = readFileSync(eventLogPath, 'utf8')\n .split('\\n')\n .map(line => line.trim())\n .filter(Boolean);\n eventLog = lines.map(line => ({\n seq: (JSON.parse(line) as { seq: number }).seq,\n line,\n }));\n seqCounter = eventLog.at(-1)?.seq ?? 0;\n } catch {\n // Corrupt/partial log: fall back to an empty log; the host then degrades\n // to `rerun` instead of replaying a malformed tail.\n eventLog = [];\n seqCounter = 0;\n }\n }\n\n const pendingToolResults = new Map<\n string,\n (output: { output: unknown; isError?: boolean }) => void\n >();\n const pendingToolApprovals = new Map<\n string,\n (response: { approved: boolean; reason?: string }) => void\n >();\n\n // ─── persistence (best-effort meta + start config) ──────────────────\n const writeBridgeMeta = async (state: BridgeState): Promise<void> => {\n try {\n await writeFile(\n bridgeMetaPath,\n JSON.stringify({\n type: bridgeType,\n port: currentBoundPort,\n state,\n pid,\n }),\n );\n } catch {\n // Best-effort resilience metadata; not load-bearing for the active turn.\n }\n };\n\n const writeStartConfig = async (start: unknown): Promise<void> => {\n try {\n const serialized = JSON.stringify(start);\n await writeFile(startConfigPath, serialized);\n // Frozen copy: written once, restored over start-config.json by future\n // rerun-mode recovery to re-run the original turn from scratch.\n if (!existsSync(rerunStartConfigPath)) {\n await writeFile(rerunStartConfigPath, serialized);\n }\n } catch {\n // Best-effort.\n }\n };\n\n // ─── wire send + replay ─────────────────────────────────────────────\n const sendControl = (msg: Record<string, unknown>): void => {\n if (activeSocket?.readyState === WS_OPEN) {\n try {\n activeSocket.send(JSON.stringify(msg));\n } catch {\n // best-effort\n }\n }\n };\n\n const emit = (event: BridgeEvent): void => {\n const seq = ++seqCounter;\n const line = JSON.stringify({ ...event, seq });\n eventLog.push({ seq, line });\n diskBuffer += `${line}\\n`;\n scheduleEventFlush();\n if (activeSocket?.readyState === WS_OPEN) {\n try {\n activeSocket.send(line);\n } catch {\n // Send is best-effort: a dropped socket leaves the event in the log,\n // replayed once the host reconnects and sends `resume`.\n }\n }\n };\n\n const replay = (ws: WebSocket, afterSeq: number): void => {\n for (const entry of eventLog) {\n if (entry.seq > afterSeq && ws.readyState === WS_OPEN) {\n ws.send(entry.line);\n }\n }\n };\n\n // ─── diagnostics ──────────────────────────────────────────────\n const shouldEmitDebugEvent = (\n level: BridgeDebugLevel,\n subsystem: string,\n ): boolean => {\n if (!debugConfig?.enabled) return false;\n const threshold = debugConfig.level ?? 'debug';\n if (DEBUG_LEVEL_WEIGHT[level] > DEBUG_LEVEL_WEIGHT[threshold]) return false;\n return subsystemMatches(debugConfig.subsystems, subsystem);\n };\n\n /*\n * Forward sandbox console output. We line-buffer the original writers (kept so\n * output still reaches the real fds) and emit one `sandbox-log` per complete\n * line. `emit` never writes to stdout/stderr, so there is no recursion.\n * Installed lazily the first time a turn enables diagnostics; once installed,\n * capture is gated per-write on `debugConfig.enabled` so a later turn can\n * disable it. Console capture is independent of the subsystem/level filter.\n */\n const rawStdoutWrite = process.stdout.write.bind(process.stdout);\n const rawStderrWrite = process.stderr.write.bind(process.stderr);\n\n const writeErrorToStderr = (input: {\n message: string;\n error: unknown;\n }): void => {\n try {\n const formatted = formatBridgeError(input.error);\n rawStderrWrite(\n `[harness:${bridgeType}:error] ${input.message}: ${formatted.message}\\n`,\n );\n if (formatted.stack) {\n rawStderrWrite(`${formatted.stack}\\n`);\n }\n } catch {}\n };\n\n const emitWarning = (input: { message: string }): void => {\n try {\n for (const line of input.message.split('\\n')) {\n if (line.trim().length > 0) {\n rawStderrWrite(`[harness:${bridgeType}:warn] ${line}\\n`);\n }\n }\n } catch {}\n };\n\n const emitError = (input: { error: unknown; message?: string }): void => {\n writeErrorToStderr({\n message: input.message ?? 'bridge error',\n error: input.error,\n });\n emit({ type: 'error', error: serialiseError(input.error) });\n };\n\n const installConsoleCapture = (): void => {\n if (consoleCaptureInstalled) return;\n consoleCaptureInstalled = true;\n const buffers: { stdout: string; stderr: string } = {\n stdout: '',\n stderr: '',\n };\n const patch =\n (stream: 'stdout' | 'stderr', raw: typeof process.stdout.write) =>\n (chunk: unknown, encoding?: unknown, cb?: unknown): boolean => {\n if (debugConfig?.enabled) {\n try {\n const enc = typeof encoding === 'string' ? encoding : 'utf8';\n const text =\n typeof chunk === 'string'\n ? chunk\n : Buffer.from(chunk as Uint8Array).toString(\n enc as BufferEncoding,\n );\n const combined = buffers[stream] + text.replace(/\\r\\n/g, '\\n');\n const parts = combined.split('\\n');\n buffers[stream] = parts.pop() ?? '';\n for (const line of parts) {\n const trimmed = line.replace(/\\s+$/, '');\n if (trimmed) {\n emit({\n type: 'sandbox-log',\n source: bridgeType,\n stream,\n line: trimmed,\n });\n }\n }\n } catch {\n // Never let capture break real output.\n }\n }\n return (raw as (c: unknown, e?: unknown, cb?: unknown) => boolean)(\n chunk,\n encoding,\n cb,\n );\n };\n process.stdout.write = patch(\n 'stdout',\n rawStdoutWrite,\n ) as typeof process.stdout.write;\n process.stderr.write = patch(\n 'stderr',\n rawStderrWrite,\n ) as typeof process.stderr.write;\n };\n\n // ─── inbound routing ────────────────────────────────────────────────\n const handleInbound = async (\n msg: TStart | InboundControl,\n ws: WebSocket,\n ): Promise<void> => {\n switch (msg.type) {\n case 'start': {\n const firstTurn = isFirstTurn;\n isFirstTurn = false;\n eventLog = []; // clear previous turn; keep seqCounter monotonic\n // Mirror the in-memory clear to disk: the log tracks only the current\n // turn. Discard any unflushed tail from the prior turn first.\n diskBuffer = '';\n void writeFile(eventLogPath, '').catch(() => {});\n turnAbort = new AbortController();\n currentTurnState = 'running';\n currentInterruptHandler = undefined;\n void writeStartConfig(msg);\n void writeBridgeMeta('running');\n const startDebug = (msg as { debug?: BridgeDebugConfig }).debug;\n debugConfig = {\n enabled: startDebug?.enabled ?? envDebugEnabled,\n level:\n startDebug?.level ??\n (procEnv.HARNESS_DEBUG_LEVEL as BridgeDebugLevel | undefined),\n subsystems:\n startDebug?.subsystems ??\n parseEnvList(procEnv.HARNESS_DEBUG_SUBSYSTEMS),\n };\n if (debugConfig.enabled) {\n installConsoleCapture();\n }\n const turn: BridgeTurn = {\n emit,\n requestToolResult: toolCallId =>\n new Promise(resolve => {\n pendingToolResults.set(toolCallId, resolve);\n }),\n requestToolApproval: approvalId =>\n new Promise(resolve => {\n pendingToolApprovals.set(approvalId, resolve);\n }),\n pendingUserMessages: [],\n abortSignal: turnAbort.signal,\n onInterrupt: handler => {\n currentInterruptHandler = handler;\n },\n firstTurn,\n bridgeLog: input => {\n const level = input.level ?? 'debug';\n if (!shouldEmitDebugEvent(level, input.subsystem)) return;\n emit({\n type: 'debug-event',\n level,\n subsystem: input.subsystem,\n message: input.message,\n ...(input.attrs ? { attrs: input.attrs } : {}),\n ...(input.error !== undefined\n ? { error: formatBridgeError(input.error) }\n : {}),\n });\n },\n emitWarning,\n emitError,\n };\n currentUserMessages = turn.pendingUserMessages;\n try {\n await onStart(msg as TStart, turn);\n } catch (err) {\n emitError({ error: err, message: 'bridge turn failed' });\n } finally {\n currentInterruptHandler = undefined;\n currentTurnState = 'waiting';\n void writeBridgeMeta('waiting');\n }\n return;\n }\n case 'tool-result': {\n const resolver = pendingToolResults.get(msg.toolCallId);\n if (resolver) {\n pendingToolResults.delete(msg.toolCallId);\n resolver({ output: msg.output, isError: msg.isError });\n }\n return;\n }\n case 'tool-approval-response': {\n const resolver = pendingToolApprovals.get(msg.approvalId);\n if (resolver) {\n pendingToolApprovals.delete(msg.approvalId);\n resolver({ approved: msg.approved, reason: msg.reason });\n }\n return;\n }\n case 'user-message':\n currentUserMessages?.push(msg.text);\n return;\n case 'abort':\n turnAbort?.abort();\n return;\n case 'interrupt':\n try {\n /*\n * A bridge waiting for a host tool result or approval is already\n * paused at a resumable boundary. Interrupting the native runtime at\n * that point terminates the operation that owns the pending request,\n * so a later host process cannot satisfy it. Active turns without\n * pending host input are interrupted before suspension as usual.\n */\n if (\n pendingToolResults.size === 0 &&\n pendingToolApprovals.size === 0\n ) {\n if (currentInterruptHandler) {\n await currentInterruptHandler();\n } else {\n turnAbort?.abort();\n }\n }\n sendControl({ type: 'bridge-interrupted', ok: true });\n } catch (err) {\n sendControl({\n type: 'bridge-interrupted',\n ok: false,\n error: serialiseError(err),\n });\n }\n return;\n case 'resume':\n replay(ws, msg.lastSeenEventId);\n return;\n case 'shutdown':\n currentTurnState = 'done';\n void writeBridgeMeta('done');\n drainThenExit(ws, 1000, 'shutdown');\n return;\n case 'detach': {\n currentTurnState = 'done';\n void writeBridgeMeta('done');\n const data = (await onDetach?.()) ?? {};\n sendControl({ type: 'bridge-detach', data });\n drainThenExit(ws, 1000, 'detach');\n return;\n }\n }\n };\n\n // ─── server ─────────────────────────────────────────────────────────\n void writeBridgeMeta('init');\n\n const wss = new WebSocketServer({ port: bridgeWsPort, host: '0.0.0.0' });\n\n const exit = (): void => {\n if (options.onExit) {\n options.onExit();\n return;\n }\n wss.close(() => process.exit(0));\n setTimeout(() => process.exit(0), 1000).unref();\n };\n\n const drainThenExit = (ws: WebSocket, code: number, reason: string): void => {\n const start = Date.now();\n const tick = (): void => {\n const drained = ws.bufferedAmount === 0 || ws.readyState !== WS_OPEN;\n if (drained || Date.now() - start >= 5_000) {\n // Flush the on-disk log so a clean shutdown/detach leaves a complete\n // event-log.ndjson for any later replay recovery.\n void flushPendingEventsToDisk().finally(() => {\n try {\n ws.close(code, reason);\n } finally {\n exit();\n }\n });\n return;\n }\n setTimeout(tick, 10).unref();\n };\n tick();\n };\n\n wss.on('listening', () => {\n const addr = wss.address();\n currentBoundPort = typeof addr === 'object' && addr ? addr.port : 0;\n currentTurnState = 'waiting';\n void writeBridgeMeta('waiting');\n stdout.write(\n JSON.stringify({\n type: 'bridge-ready',\n port: currentBoundPort,\n }) + '\\n',\n );\n options.onListening?.(currentBoundPort);\n });\n\n wss.on('connection', (ws: WebSocket, req: { url?: string }) => {\n const url = new URL(req.url ?? '/', 'http://localhost');\n if (url.searchParams.get('agent_bridge_token') !== expectedToken) {\n ws.close(1008, 'unauthorized');\n return;\n }\n\n // Single-flight: a fresh authorized connection *replaces* the active one\n // (the host reconnecting after a drop). The previous socket's close is a\n // no-op below because it is no longer `activeSocket`.\n activeSocket = ws;\n\n // Announce liveness the instant we accept. Some sandbox runtimes complete\n // the host-side WS handshake before the connection is forwarded here; the\n // host waits for this frame before sending `start`/`resume`.\n sendControl({\n type: 'bridge-hello',\n state: currentTurnState,\n lastSeq: seqCounter,\n });\n\n ws.on('message', (raw: ArrayBufferLike | string) => {\n let parsed: TStart | InboundControl;\n try {\n const text =\n typeof raw === 'string' ? raw : Buffer.from(raw).toString('utf8');\n parsed = JSON.parse(text) as TStart | InboundControl;\n } catch (err) {\n sendControl({\n type: 'error',\n error: `protocol parse error: ${(err as Error).message}`,\n });\n return;\n }\n void handleInbound(parsed, ws);\n });\n\n ws.on('close', () => {\n // Only the *current* socket's close matters. A stale socket (already\n // replaced by a reconnect) closing is a no-op. Crucially we do NOT abort\n // the in-flight turn — it keeps running and its events accumulate in the\n // log for replay when the host reconnects.\n if (activeSocket === ws) {\n activeSocket = undefined;\n }\n });\n\n ws.on('error', () => {\n // 'close' follows; nothing to do beyond keeping the process alive.\n });\n });\n\n // Surface bridge-internal crashes to the host instead of dying silently.\n process.on('uncaughtException', err => {\n emitError({ error: err, message: 'uncaught exception' });\n });\n process.on('unhandledRejection', err => {\n emitError({ error: err, message: 'unhandled rejection' });\n });\n\n await new Promise<void>((resolve, reject) => {\n if (wss.address() != null) {\n resolve();\n return;\n }\n\n wss.once('listening', resolve);\n wss.once('error', reject);\n });\n\n return {\n port: currentBoundPort,\n close: () =>\n new Promise<void>(resolve => {\n wss.close(() => resolve());\n }),\n };\n}\n\nfunction serialiseError(err: unknown): unknown {\n if (err instanceof Error) {\n return { name: err.name, message: err.message, stack: err.stack };\n }\n return err;\n}\n","/*\n * Claude reports a compaction in two pieces whose arrival order is not\n * guaranteed: the `compact_boundary` system message (trigger + token counts)\n * and the `PostCompact` hook (the summary text). The harness `compaction`\n * event needs fields from both, so this latch holds each half and emits a\n * single merged event once both have arrived, then resets for the next\n * compaction in the same turn.\n */\n\nexport type CompactionBoundary = {\n trigger: 'manual' | 'auto';\n tokensBefore?: number;\n tokensAfter?: number;\n};\n\nexport type CompactionEvent = {\n type: 'compaction';\n trigger: 'manual' | 'auto';\n summary: string;\n tokensBefore?: number;\n tokensAfter?: number;\n};\n\nexport type CompactionLatch = {\n onBoundary(boundary: CompactionBoundary): void;\n onSummary(summary: string): void;\n};\n\nexport function createCompactionLatch(\n emit: (event: CompactionEvent) => void,\n): CompactionLatch {\n let boundary: CompactionBoundary | undefined;\n let summary: string | undefined;\n\n const tryEmit = (): void => {\n if (!boundary || summary === undefined) return;\n emit({\n type: 'compaction',\n trigger: boundary.trigger,\n summary,\n ...(boundary.tokensBefore !== undefined\n ? { tokensBefore: boundary.tokensBefore }\n : {}),\n ...(boundary.tokensAfter !== undefined\n ? { tokensAfter: boundary.tokensAfter }\n : {}),\n });\n boundary = undefined;\n summary = undefined;\n };\n\n return {\n onBoundary(next) {\n boundary = next;\n tryEmit();\n },\n onSummary(next) {\n summary = next;\n tryEmit();\n },\n };\n}\n","// Long-running bridge that runs inside a sandbox alongside the `claude` CLI.\n// The generic transport — WebSocket server, token auth, single-flight\n// reconnect, the in-memory event log + `seq`, resume replay, and the\n// lifecycle/meta files — lives in the shared `@ai-sdk/harness/bridge` runtime.\n// This file supplies only the Claude-specific turn driver.\n\nimport {\n runBridge,\n type BridgeEvent,\n type BridgeTurn,\n} from '@ai-sdk/harness/bridge';\nimport { createCompactionLatch } from './compaction-latch';\nimport type { StartMessage } from '../claude-code-bridge-protocol';\nimport { randomUUID } from 'node:crypto';\nimport { argv, stdout } from 'node:process';\n\n/*\n * CONSTRAINT — the third-party imports below are NEVER bundled into the\n * compiled `bridge/index.mjs`. They are declared `external` in\n * tsup.config.ts and resolved at runtime from the node_modules that this\n * bridge installs *inside the sandbox* from `src/bridge/package.json` (and\n * its pinned `pnpm-lock.yaml`). That bridge package.json — NOT this host\n * package — is the single source of truth for these packages and their\n * versions; the published `@ai-sdk/harness-claude-code` package does not\n * provide them at runtime.\n *\n * When adding or changing a third-party import here you MUST keep all three\n * in sync, or the bridge will either get the dependency bundled in or fail\n * to resolve it in the sandbox:\n * 1. the import statement below,\n * 2. the `external` array in tsup.config.ts, and\n * 3. the dependency entry in `src/bridge/package.json`.\n */\nimport * as claudeAgentSdk from '@anthropic-ai/claude-agent-sdk';\nimport * as mcpServerModule from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { z } from 'zod/v4';\nimport { toClaudeSkillsOption } from './claude-skills-option';\n\n/*\n * Native Claude Code tool name → cross-harness common name. Tools outside this\n * map (e.g. `WebFetch`, `NotebookEdit`) have no common equivalent; their\n * native name is forwarded as-is on `tool-call` events.\n */\ntype CommonBuiltinToolName =\n | 'read'\n | 'write'\n | 'edit'\n | 'bash'\n | 'glob'\n | 'grep'\n | 'webSearch';\n\nconst NATIVE_TO_COMMON: Readonly<Record<string, CommonBuiltinToolName>> = {\n Read: 'read',\n Write: 'write',\n Edit: 'edit',\n Bash: 'bash',\n Glob: 'glob',\n Grep: 'grep',\n WebSearch: 'webSearch',\n};\n\nconst PUBLIC_TO_NATIVE: Readonly<Record<string, string>> = {\n read: 'Read',\n write: 'Write',\n edit: 'Edit',\n bash: 'Bash',\n glob: 'Glob',\n grep: 'Grep',\n webSearch: 'WebSearch',\n WebFetch: 'WebFetch',\n NotebookEdit: 'NotebookEdit',\n TodoWrite: 'TodoWrite',\n Agent: 'Agent',\n TaskCreate: 'TaskCreate',\n TaskGet: 'TaskGet',\n TaskUpdate: 'TaskUpdate',\n TaskList: 'TaskList',\n TaskStop: 'TaskStop',\n TaskOutput: 'TaskOutput',\n Monitor: 'Monitor',\n ListMcpResources: 'ListMcpResources',\n ReadMcpResource: 'ReadMcpResource',\n ExitPlanMode: 'ExitPlanMode',\n EnterWorktree: 'EnterWorktree',\n ExitWorktree: 'ExitWorktree',\n AskUserQuestion: 'AskUserQuestion',\n Skill: 'Skill',\n};\n\nconst PUBLIC_TOOL_NAMES = Object.keys(PUBLIC_TO_NATIVE);\nconst UNRECOVERABLE_API_RETRY_STATUSES = new Set([401, 403, 404]);\n\nconst NATIVE_TOOL_KINDS: Readonly<\n Record<string, 'readonly' | 'edit' | 'bash'>\n> = {\n Read: 'readonly',\n Glob: 'readonly',\n Grep: 'readonly',\n WebSearch: 'readonly',\n WebFetch: 'readonly',\n TaskGet: 'readonly',\n TaskList: 'readonly',\n TaskOutput: 'readonly',\n ListMcpResources: 'readonly',\n ReadMcpResource: 'readonly',\n Write: 'edit',\n Edit: 'edit',\n NotebookEdit: 'edit',\n TodoWrite: 'edit',\n TaskCreate: 'edit',\n TaskUpdate: 'edit',\n TaskStop: 'edit',\n EnterWorktree: 'edit',\n ExitWorktree: 'edit',\n ExitPlanMode: 'edit',\n Skill: 'edit',\n AskUserQuestion: 'readonly',\n Bash: 'bash',\n Monitor: 'bash',\n};\n\nfunction toCommonName(nativeName: string): CommonBuiltinToolName | string {\n return NATIVE_TO_COMMON[nativeName] ?? nativeName;\n}\n\nfunction toNativeName(toolName: string): string {\n return PUBLIC_TO_NATIVE[toolName] ?? toolName;\n}\n\nfunction resolveNativeTools(start: StartMessage): string[] | undefined {\n const toolFiltering = start.builtinToolFiltering;\n if (toolFiltering == null) return undefined;\n const activeToolNames =\n toolFiltering.mode === 'allow'\n ? toolFiltering.toolNames\n : PUBLIC_TOOL_NAMES.filter(\n name => !toolFiltering.toolNames.includes(name),\n );\n return activeToolNames.map(name => toNativeName(name));\n}\n\nfunction resolveInactiveNativeTools(start: StartMessage): string[] {\n const toolFiltering = start.builtinToolFiltering;\n if (toolFiltering == null) return [];\n const inactiveToolNames =\n toolFiltering.mode === 'allow'\n ? PUBLIC_TOOL_NAMES.filter(\n name => !toolFiltering.toolNames.includes(name),\n )\n : toolFiltering.toolNames;\n return inactiveToolNames.map(name => toNativeName(name));\n}\n\nconst args = parseArgs(argv.slice(2));\nconst workdir = args.workdir;\nconst bridgeStateDir = args.bridgeStateDir;\nif (!workdir) {\n emitFatal('Missing --workdir argument.');\n}\nif (!bridgeStateDir) {\n emitFatal('Missing --bridge-state-dir argument.');\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst claudeSdk = claudeAgentSdk as any;\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nconst mcpModule = mcpServerModule as any;\n\nawait runBridge<StartMessage>({\n bridgeType: 'claude-code',\n bridgeStateDir,\n onStart: runTurn,\n // Claude Code's session state lives in the workdir on the sandbox filesystem\n // (captured by the sandbox snapshot on stop); the resume payload is empty.\n onDetach: () => ({}),\n});\n\ntype Emit = (msg: Record<string, unknown>) => void;\n\nfunction createPermissionOptions(input: {\n start: StartMessage;\n inactiveNativeTools: readonly string[];\n turn: BridgeTurn;\n emit: Emit;\n finishApprovalStep: (approvalId: string) => void;\n nativeToolCallNames: Map<string, string>;\n approvalRequestedToolUseIds: Set<string>;\n}): Record<string, unknown> {\n const permissionMode = input.start.permissionMode ?? 'allow-all';\n const inactiveNativeTools = new Set(input.inactiveNativeTools);\n const permissionSettings = createPermissionSettings({\n permissionMode,\n inactiveNativeTools,\n });\n if (permissionMode === 'allow-all' && inactiveNativeTools.size === 0) {\n return {\n permissionMode: 'bypassPermissions',\n allowDangerouslySkipPermissions: true,\n };\n }\n\n return {\n permissionMode:\n permissionMode === 'allow-edits' ? 'acceptEdits' : 'default',\n allowDangerouslySkipPermissions: false,\n ...(permissionSettings ? { settings: permissionSettings } : {}),\n canUseTool: async (\n toolName: string,\n toolInput: Record<string, unknown>,\n options: { toolUseID: string },\n ) => {\n if (toolName.startsWith('mcp__harness-tools__')) {\n return { behavior: 'allow', updatedInput: toolInput };\n }\n if (\n !inactiveNativeTools.has(toolName) &&\n !nativeToolRequiresApproval({\n nativeName: toolName,\n permissionMode,\n })\n ) {\n return { behavior: 'allow', updatedInput: toolInput };\n }\n\n const approvalId = options.toolUseID;\n input.approvalRequestedToolUseIds.add(approvalId);\n input.nativeToolCallNames.set(approvalId, toolName);\n input.emit({\n type: 'tool-call',\n toolCallId: approvalId,\n toolName: toCommonName(toolName),\n nativeName: toolName,\n input: JSON.stringify(toolInput ?? {}),\n providerExecuted: true,\n });\n input.emit({\n type: 'tool-approval-request',\n approvalId,\n toolCallId: approvalId,\n });\n input.finishApprovalStep(approvalId);\n\n const decision = await input.turn.requestToolApproval(approvalId);\n return decision.approved\n ? { behavior: 'allow', updatedInput: toolInput, toolUseID: approvalId }\n : {\n behavior: 'deny',\n message: decision.reason ?? 'Denied',\n toolUseID: approvalId,\n };\n },\n };\n}\n\nfunction createPermissionSettings(input: {\n permissionMode: 'allow-reads' | 'allow-edits' | 'allow-all';\n inactiveNativeTools: ReadonlySet<string>;\n}): Record<string, unknown> | undefined {\n const askRules = new Set<string>();\n for (const [nativeName, kind] of Object.entries(NATIVE_TOOL_KINDS)) {\n if (\n input.inactiveNativeTools.has(nativeName) ||\n (input.permissionMode === 'allow-reads'\n ? kind === 'edit' || kind === 'bash'\n : input.permissionMode === 'allow-edits'\n ? kind === 'bash'\n : false)\n ) {\n askRules.add(`${nativeName}(*)`);\n }\n }\n\n if (askRules.size === 0) return undefined;\n\n return {\n permissions: { ask: [...askRules] },\n sandbox: { autoAllowBashIfSandboxed: false },\n };\n}\n\nfunction nativeToolRequiresApproval(input: {\n nativeName: string;\n permissionMode: 'allow-reads' | 'allow-edits' | 'allow-all';\n}): boolean {\n if (input.permissionMode === 'allow-all') return false;\n const kind = NATIVE_TOOL_KINDS[input.nativeName] ?? 'edit';\n if (input.permissionMode === 'allow-edits') return kind === 'bash';\n return kind === 'edit' || kind === 'bash';\n}\n\nasync function runTurn(start: StartMessage, turn: BridgeTurn): Promise<void> {\n const emit: Emit = msg => turn.emit(msg as BridgeEvent);\n\n // Local controller for the Claude query. Aborted either by the host (via the\n // shared runtime's `turn.abortSignal`) or by us on a terminal error.\n const abortCtl = new AbortController();\n if (turn.abortSignal.aborted) {\n abortCtl.abort();\n } else {\n turn.abortSignal.addEventListener('abort', () => abortCtl.abort(), {\n once: true,\n });\n }\n\n /*\n * Map of native tool-use id → tool name. Claude assistant messages emit\n * `tool_use` blocks with both `id` and `name`; the matching `tool_result`\n * block on a later user message carries only `tool_use_id`, so without this\n * map the tool-result event would have to emit `toolName: 'unknown'`.\n */\n const nativeToolCallNames = new Map<string, string>();\n const approvalRequestedToolUseIds = new Set<string>();\n const partialBlocks = new Map<\n number,\n { id: string; kind: 'text' | 'thinking' }\n >();\n let stepUsage: Record<string, unknown> | undefined;\n let pendingStepToolUseIds = new Set<string>();\n let pendingStepUsage: Record<string, unknown> | undefined;\n let stepOpen = false;\n\n const emitFinishStep = (usage: Record<string, unknown> | undefined): void => {\n emit({\n type: 'finish-step',\n finishReason: { unified: 'stop', raw: 'stop' },\n usage: usage ?? defaultUsage(),\n });\n stepUsage = usage ?? stepUsage;\n pendingStepUsage = undefined;\n pendingStepToolUseIds = new Set();\n stepOpen = false;\n };\n\n const closeStepIfReady = (): void => {\n if (!stepOpen || pendingStepToolUseIds.size > 0 || partialBlocks.size > 0) {\n return;\n }\n emitFinishStep(pendingStepUsage);\n };\n\n /*\n * Tool-use ids that originated from the MCP server hosting user-supplied\n * tools. The MCP handler emits its own `tool-call`/`tool-result` pair with\n * the user-facing tool name and a synthetic id, so the duplicate\n * `tool_result` block Claude reports for the underlying native id must be\n * suppressed.\n */\n const mcpToolUseIds = new Set<string>();\n\n const mcpServers: Record<string, unknown> = {};\n if (start.tools && start.tools.length > 0) {\n const server = new mcpModule.McpServer({\n name: 'harness-tools',\n version: '1.0.0',\n });\n for (const tool of start.tools) {\n const shape = jsonSchemaToZodShape(tool.inputSchema, z);\n server.tool(\n tool.name,\n tool.description ?? '',\n shape,\n async (input: Record<string, unknown>) => {\n const toolCallId = randomUUID();\n emit({\n type: 'tool-call',\n toolCallId,\n toolName: tool.name,\n input: JSON.stringify(input),\n providerExecuted: false,\n });\n const { output, isError } = await turn.requestToolResult(toolCallId);\n emit({\n type: 'tool-result',\n toolCallId,\n toolName: tool.name,\n result: output ?? null,\n isError: !!isError,\n });\n return {\n content: [{ type: 'text', text: JSON.stringify(output ?? null) }],\n isError,\n };\n },\n );\n }\n mcpServers['harness-tools'] = {\n type: 'sdk',\n name: 'harness-tools',\n instance: server,\n };\n }\n\n // Compaction observation: merge Claude's `compact_boundary` message and\n // `PostCompact` hook (which arrive in either order) into one `compaction`\n // event. See `createCompactionLatch`.\n const compaction = createCompactionLatch(event => emit(event));\n\n // `stream-start` is emitted lazily on the first SDK message (below) so it can\n // carry the model the CLI resolved to, reported on the `system`/`init` message.\n\n const queryInput = createQueryInput({\n initialUserMessage: start.prompt,\n pendingUserMessages: turn.pendingUserMessages,\n abortSignal: abortCtl.signal,\n });\n const skillsOption = toClaudeSkillsOption(start.skills);\n const nativeTools = resolveNativeTools(start);\n const inactiveNativeTools = resolveInactiveNativeTools(start);\n const permissionOptions = createPermissionOptions({\n start,\n inactiveNativeTools,\n turn,\n emit,\n finishApprovalStep: approvalId => {\n stepOpen = true;\n pendingStepToolUseIds.delete(approvalId);\n closeStepIfReady();\n },\n nativeToolCallNames,\n approvalRequestedToolUseIds,\n });\n\n const q = claudeSdk.query({\n prompt: queryInput.input,\n options: {\n ...(start.model ? { model: start.model } : {}),\n ...(start.maxTurns !== undefined ? { maxTurns: start.maxTurns } : {}),\n ...(skillsOption ? { skills: skillsOption } : {}),\n ...(nativeTools !== undefined ? { tools: nativeTools } : {}),\n ...(inactiveNativeTools.length > 0\n ? { disallowedTools: inactiveNativeTools }\n : {}),\n thinking: start.thinking,\n includePartialMessages: true,\n // The `PostCompact` hook carries the compaction summary, which the\n // `compact_boundary` system message does not. Latch it for the unified\n // `compaction` event; return an empty output so compaction proceeds.\n hooks: {\n PostCompact: [\n {\n hooks: [\n async (input: { compact_summary?: unknown }) => {\n if (typeof input?.compact_summary === 'string') {\n compaction.onSummary(input.compact_summary);\n }\n return {};\n },\n ],\n },\n ],\n },\n // Continuation rule: the host can force-continue (resume after a\n // cross-process detach) by setting `start.continue: true`; otherwise\n // we continue every subsequent turn after the first one in this\n // bridge process.\n ...(start.continue === true || !turn.firstTurn ? { continue: true } : {}),\n ...permissionOptions,\n mcpServers,\n cwd: workdir,\n abortSignal: abortCtl.signal,\n },\n });\n turn.onInterrupt(() => q.interrupt());\n\n let turnUsage: Record<string, unknown> | undefined;\n let totalCostUsd: number | undefined;\n let observedTerminalError: string | undefined;\n let emittedTerminalError = false;\n let emittedTerminalFinish = false;\n let streamStarted = false;\n\n const emitTerminalError = (message: string | undefined): void => {\n const normalized = message?.trim();\n if (!normalized || emittedTerminalError || emittedTerminalFinish) return;\n observedTerminalError = normalized;\n emittedTerminalError = true;\n turn.emitError({\n error: normalized,\n message: 'claude-code terminal error',\n });\n queryInput.close();\n abortCtl.abort();\n };\n\n try {\n for await (const msg of q as AsyncIterable<ClaudeMessage>) {\n if (abortCtl.signal.aborted) break;\n\n const type = msg.type;\n\n // Emit `stream-start` once, on the first message, carrying the model the\n // CLI resolved to (the `system`/`init` message reports it — this is the\n // default model when none was configured).\n if (!streamStarted) {\n const initModel =\n type === 'system' &&\n msg.subtype === 'init' &&\n typeof (msg as { model?: unknown }).model === 'string'\n ? (msg as { model: string }).model\n : undefined;\n emit({\n type: 'stream-start',\n ...(initModel ? { modelId: initModel } : {}),\n });\n streamStarted = true;\n }\n\n if (type === 'system' && msg.subtype === 'api_retry') {\n if (\n typeof msg.error_status === 'number' &&\n UNRECOVERABLE_API_RETRY_STATUSES.has(msg.error_status)\n ) {\n emitTerminalError(\n `HTTP ${msg.error_status}: ${\n msg.error ?? 'provider request failed'\n }`,\n );\n continue;\n }\n\n turn.emitWarning({ message: formatApiRetryWarning(msg) });\n continue;\n }\n\n if (typeof msg.error === 'string' && msg.error.trim()) {\n observedTerminalError = msg.error.trim();\n }\n\n if (\n type === 'auth_status' &&\n typeof msg.error === 'string' &&\n msg.error.trim()\n ) {\n emitTerminalError(msg.error);\n continue;\n }\n\n if (\n type === 'system' &&\n msg.subtype === 'task_updated' &&\n msg.patch?.status === 'failed' &&\n typeof msg.patch.error === 'string'\n ) {\n emitTerminalError(msg.patch.error);\n continue;\n }\n\n if (type === 'system' && msg.subtype === 'compact_boundary') {\n const meta = msg.compact_metadata;\n if (meta) {\n compaction.onBoundary({\n trigger: meta.trigger,\n ...(typeof meta.pre_tokens === 'number'\n ? { tokensBefore: meta.pre_tokens }\n : {}),\n ...(typeof meta.post_tokens === 'number'\n ? { tokensAfter: meta.post_tokens }\n : {}),\n });\n }\n continue;\n }\n\n if (type === 'stream_event') {\n handleStreamEvent(msg.event, partialBlocks, emit);\n continue;\n }\n\n if (type === 'assistant' && msg.message?.content) {\n const usage = mapUsage(msg.message.usage);\n const toolUseIds: string[] = [];\n let opensStep = false;\n for (const block of msg.message.content) {\n if (\n block.type === 'tool_use' &&\n typeof block.id === 'string' &&\n typeof block.name === 'string'\n ) {\n toolUseIds.push(block.id);\n const mcpPrefix = 'mcp__harness-tools__';\n if (block.name.startsWith(mcpPrefix)) {\n pendingStepToolUseIds.add(block.id);\n mcpToolUseIds.add(block.id);\n opensStep = true;\n continue;\n }\n nativeToolCallNames.set(block.id, block.name);\n if (approvalRequestedToolUseIds.has(block.id)) {\n continue;\n }\n pendingStepToolUseIds.add(block.id);\n opensStep = true;\n emit({\n type: 'tool-call',\n toolCallId: block.id,\n toolName: toCommonName(block.name),\n nativeName: block.name,\n input: JSON.stringify(block.input ?? {}),\n providerExecuted: true,\n });\n }\n }\n if (opensStep || toolUseIds.length === 0) {\n stepOpen = true;\n if (usage) pendingStepUsage = usage;\n }\n continue;\n }\n\n if (type === 'user' && msg.message?.content) {\n for (const block of msg.message.content) {\n if (\n block.type === 'tool_result' &&\n typeof block.tool_use_id === 'string'\n ) {\n if (mcpToolUseIds.has(block.tool_use_id)) {\n mcpToolUseIds.delete(block.tool_use_id);\n pendingStepToolUseIds.delete(block.tool_use_id);\n continue;\n }\n approvalRequestedToolUseIds.delete(block.tool_use_id);\n const nativeName =\n nativeToolCallNames.get(block.tool_use_id) ?? 'unknown';\n nativeToolCallNames.delete(block.tool_use_id);\n const toolName = toCommonName(nativeName);\n const isError = !!block.is_error;\n const content = stringifyContent(block.content);\n /*\n * Claude Code's Bash tool does not report the command's real\n * numeric exit code — the SDK exposes only stdout/stderr text and\n * an is_error flag. Consumers (and the example UI) render bash\n * failures from an `exitCode` field on a structured result, the\n * shape Codex's shell tool provides natively. To match it, derive\n * a binary code from is_error: 1 on failure, 0 on success. This is\n * a stand-in for failed/succeeded, not the process's true exit\n * status.\n */\n const result =\n toolName === 'bash'\n ? { exitCode: isError ? 1 : 0, stdout: content }\n : content;\n emit({\n type: 'tool-result',\n toolCallId: block.tool_use_id,\n toolName,\n result,\n isError,\n });\n pendingStepToolUseIds.delete(block.tool_use_id);\n }\n }\n closeStepIfReady();\n continue;\n }\n\n if (type === 'result') {\n if (msg.subtype === 'success') {\n const emptyResult = !msg.result?.trim?.();\n if (emptyResult && observedTerminalError) {\n emitTerminalError(observedTerminalError);\n continue;\n }\n const usage = msg.usage ?? msg.message?.usage;\n const harnessUsage = mapUsage(usage);\n if (harnessUsage) turnUsage = harnessUsage;\n if (typeof msg.total_cost_usd === 'number') {\n totalCostUsd = (totalCostUsd ?? 0) + msg.total_cost_usd;\n }\n if (stepOpen) emitFinishStep(harnessUsage ?? pendingStepUsage);\n queryInput.close();\n break;\n } else {\n emitTerminalError(\n (Array.isArray(msg.errors) ? msg.errors.join('\\n') : undefined) ||\n observedTerminalError ||\n msg.result ||\n 'Unknown error',\n );\n }\n continue;\n }\n }\n } catch (err) {\n if (!(abortCtl.signal.aborted && emittedTerminalError)) {\n turn.emitError({ error: err, message: 'claude-code turn failed' });\n }\n return;\n } finally {\n queryInput.close();\n }\n\n if (emittedTerminalError) return;\n emittedTerminalFinish = true;\n void emittedTerminalFinish;\n emit({\n type: 'finish',\n finishReason: { unified: 'stop', raw: 'stop' },\n totalUsage: turnUsage ?? stepUsage ?? defaultUsage(),\n ...(totalCostUsd !== undefined\n ? { harnessMetadata: { 'claude-code': { costUsd: totalCostUsd } } }\n : {}),\n });\n}\n\ntype ClaudeMessage = {\n type?: string;\n subtype?: string;\n error?: string;\n error_status?: number | null;\n attempt?: number;\n max_retries?: number;\n retry_delay_ms?: number;\n patch?: { status?: string; error?: string };\n compact_metadata?: {\n trigger: 'manual' | 'auto';\n pre_tokens?: number;\n post_tokens?: number;\n };\n event?: {\n type?: string;\n index?: number;\n content_block?: { type?: string };\n delta?: { type?: string; text?: string; thinking?: string };\n };\n message?: {\n content?: ReadonlyArray<MessageBlock>;\n usage?: Record<string, unknown>;\n };\n result?: string;\n errors?: ReadonlyArray<string>;\n usage?: Record<string, unknown>;\n total_cost_usd?: number;\n};\n\nfunction formatApiRetryWarning(msg: ClaudeMessage): string {\n const details: string[] = [];\n if (typeof msg.attempt === 'number') {\n const maxRetries =\n typeof msg.max_retries === 'number' ? `/${msg.max_retries}` : '';\n details.push(`attempt ${msg.attempt}${maxRetries}`);\n }\n if (typeof msg.error_status === 'number') {\n details.push(`HTTP ${msg.error_status}`);\n }\n if (typeof msg.retry_delay_ms === 'number') {\n details.push(`retrying in ${msg.retry_delay_ms}ms`);\n }\n if (msg.error) details.push(msg.error);\n return details.length > 0\n ? `Claude Code API retry: ${details.join('; ')}`\n : 'Claude Code API retry';\n}\n\nfunction handleStreamEvent(\n event: ClaudeMessage['event'] | undefined,\n partialBlocks: Map<number, { id: string; kind: 'text' | 'thinking' }>,\n send: Emit,\n): void {\n if (!event || typeof event.index !== 'number') return;\n const index = event.index;\n\n if (event.type === 'content_block_start') {\n const blockType = event.content_block?.type;\n if (blockType === 'text') {\n const id = randomUUID();\n partialBlocks.set(index, { id, kind: 'text' });\n send({ type: 'text-start', id });\n } else if (blockType === 'thinking') {\n const id = randomUUID();\n partialBlocks.set(index, { id, kind: 'thinking' });\n send({ type: 'reasoning-start', id });\n }\n return;\n }\n\n if (event.type === 'content_block_delta') {\n const block = partialBlocks.get(index);\n if (!block) return;\n if (\n block.kind === 'text' &&\n event.delta?.type === 'text_delta' &&\n typeof event.delta.text === 'string'\n ) {\n send({ type: 'text-delta', id: block.id, delta: event.delta.text });\n } else if (\n block.kind === 'thinking' &&\n event.delta?.type === 'thinking_delta' &&\n typeof event.delta.thinking === 'string'\n ) {\n send({\n type: 'reasoning-delta',\n id: block.id,\n delta: event.delta.thinking,\n });\n }\n return;\n }\n\n if (event.type === 'content_block_stop') {\n const block = partialBlocks.get(index);\n if (!block) return;\n partialBlocks.delete(index);\n if (block.kind === 'text') {\n send({ type: 'text-end', id: block.id });\n } else {\n send({ type: 'reasoning-end', id: block.id });\n }\n }\n}\n\nfunction createQueryInput({\n initialUserMessage,\n pendingUserMessages,\n abortSignal,\n}: {\n initialUserMessage: string;\n pendingUserMessages: string[];\n abortSignal: AbortSignal;\n}): {\n input: AsyncIterable<unknown>;\n close(): void;\n} {\n let closed = false;\n const close = (): void => {\n closed = true;\n };\n if (abortSignal.aborted) {\n close();\n } else {\n abortSignal.addEventListener('abort', close, { once: true });\n }\n\n const toUserMessage = (text: string): unknown => ({\n type: 'user',\n message: {\n role: 'user',\n content: [{ type: 'text', text }],\n },\n });\n\n return {\n close,\n input: {\n [Symbol.asyncIterator]() {\n let sentInitial = false;\n return {\n async next() {\n // eslint-disable-next-line no-unmodified-loop-condition\n while (!closed && !abortSignal.aborted) {\n if (!sentInitial) {\n sentInitial = true;\n return {\n value: toUserMessage(initialUserMessage),\n done: false,\n };\n }\n if (pendingUserMessages.length > 0) {\n return {\n value: toUserMessage(pendingUserMessages.shift()!),\n done: false,\n };\n }\n await new Promise(resolve => setTimeout(resolve, 50));\n }\n return { value: undefined, done: true } as IteratorResult<unknown>;\n },\n };\n },\n },\n };\n}\n\ntype MessageBlock = {\n type: string;\n text?: string;\n thinking?: string;\n id?: string;\n name?: string;\n input?: unknown;\n tool_use_id?: string;\n content?: unknown;\n is_error?: boolean;\n};\n\nfunction stringifyContent(content: unknown): string {\n if (typeof content === 'string') return content;\n if (Array.isArray(content)) {\n return content\n .map(entry =>\n entry && typeof entry === 'object' && 'text' in entry\n ? String((entry as { text?: unknown }).text ?? '')\n : JSON.stringify(entry),\n )\n .join('');\n }\n return JSON.stringify(content);\n}\n\nfunction mapUsage(usage: unknown): Record<string, unknown> | undefined {\n if (!usage || typeof usage !== 'object') return undefined;\n const u = usage as {\n input_tokens?: number;\n cache_creation_input_tokens?: number;\n cache_read_input_tokens?: number;\n output_tokens?: number;\n };\n return {\n inputTokens: {\n total:\n (u.input_tokens ?? 0) +\n (u.cache_creation_input_tokens ?? 0) +\n (u.cache_read_input_tokens ?? 0),\n noCache: u.input_tokens ?? 0,\n cacheRead: u.cache_read_input_tokens ?? 0,\n cacheWrite: u.cache_creation_input_tokens ?? 0,\n },\n outputTokens: {\n total: u.output_tokens ?? 0,\n text: u.output_tokens ?? 0,\n },\n };\n}\n\nfunction defaultUsage(): Record<string, unknown> {\n return {\n inputTokens: { total: 0, noCache: 0, cacheRead: 0, cacheWrite: 0 },\n outputTokens: { total: 0, text: 0 },\n };\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction jsonSchemaToZodShape(\n schema: unknown,\n z: any,\n): Record<string, unknown> {\n if (!schema || typeof schema !== 'object') return {};\n const s = schema as {\n properties?: Record<string, { type?: string; description?: string }>;\n required?: string[];\n };\n const shape: Record<string, unknown> = {};\n const required = new Set(s.required ?? []);\n for (const [key, val] of Object.entries(s.properties ?? {})) {\n let z_: unknown;\n switch (val.type) {\n case 'string':\n z_ = z.string();\n break;\n case 'number':\n case 'integer':\n z_ = z.number();\n break;\n case 'boolean':\n z_ = z.boolean();\n break;\n case 'array':\n z_ = z.array(z.any());\n break;\n default:\n z_ = z.any();\n }\n if (val.description)\n z_ = (z_ as { describe: (s: string) => unknown }).describe(\n val.description,\n );\n shape[key] = required.has(key)\n ? z_\n : (z_ as { optional: () => unknown }).optional();\n }\n return shape;\n}\n\nfunction parseArgs(args: string[]): {\n workdir?: string;\n bridgeStateDir?: string;\n} {\n const out: { workdir?: string; bridgeStateDir?: string } = {};\n for (let i = 0; i < args.length; i++) {\n if (args[i] === '--workdir' && i + 1 < args.length) {\n out.workdir = args[++i];\n } else if (args[i] === '--bridge-state-dir' && i + 1 < args.length) {\n out.bridgeStateDir = args[++i];\n }\n }\n return out;\n}\n\nfunction emitFatal(message: string): never {\n stdout.write(JSON.stringify({ type: 'bridge-fatal', message }) + '\\n');\n process.exit(1);\n}\n","export function toClaudeSkillsOption(\n skills: ReadonlyArray<string> | undefined,\n): 'all' | undefined {\n /*\n * The Claude Agent SDK treats `skills: string[]` as an allowlist, which hides\n * built-in/default skills. When the harness writes project skills, ask Claude\n * to enable every discovered skill so bundled defaults and project skills are\n * both visible.\n */\n return skills && skills.length > 0 ? 'all' : undefined;\n}\n"],"mappings":"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","names":["bridgeStateDir","stdout","z","args","stdout"]}
|
package/dist/index.js
CHANGED
|
@@ -147,7 +147,7 @@ var inboundMessageSchema = z.discriminatedUnion("type", [
|
|
|
147
147
|
]);
|
|
148
148
|
|
|
149
149
|
// src/version.ts
|
|
150
|
-
var VERSION = true ? "1.0.
|
|
150
|
+
var VERSION = true ? "1.0.25" : "0.0.0-test";
|
|
151
151
|
|
|
152
152
|
// src/claude-code-harness.ts
|
|
153
153
|
var CLAUDE_CODE_CLIENT_APP = `ai-sdk/harness-claude-code/${VERSION}`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/harness-claude-code",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.25",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"ws": "^8.21.0",
|
|
30
|
-
"@ai-sdk/harness": "1.0.
|
|
30
|
+
"@ai-sdk/harness": "1.0.25",
|
|
31
31
|
"@ai-sdk/provider-utils": "5.0.7"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|