@ai-sdk/harness-claude-code 1.0.115 → 1.0.117
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 +18 -0
- package/dist/bridge/index.mjs +41 -3
- package/dist/bridge/index.mjs.map +1 -1
- package/dist/index.js +1 -1
- package/package.json +3 -3
- package/src/bridge/create-emit-stream-event.ts +56 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @ai-sdk/harness-claude-code
|
|
2
2
|
|
|
3
|
+
## 1.0.117
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 5145174: fix(harness-claude-code): use message delta usage for per-step metering
|
|
8
|
+
- Updated dependencies [91c2128]
|
|
9
|
+
- Updated dependencies [2cd80b3]
|
|
10
|
+
- Updated dependencies [2fa5e0e]
|
|
11
|
+
- @ai-sdk/provider-utils@5.0.42
|
|
12
|
+
- @ai-sdk/harness@1.0.113
|
|
13
|
+
|
|
14
|
+
## 1.0.116
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- @ai-sdk/harness@1.0.112
|
|
19
|
+
- @ai-sdk/provider-utils@5.0.41
|
|
20
|
+
|
|
3
21
|
## 1.0.115
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/dist/bridge/index.mjs
CHANGED
|
@@ -701,6 +701,8 @@ function createClaudeStreamEventState() {
|
|
|
701
701
|
partialBlocks: /* @__PURE__ */ new Map(),
|
|
702
702
|
stepUsage: void 0,
|
|
703
703
|
pendingStepToolUseIds: /* @__PURE__ */ new Set(),
|
|
704
|
+
pendingStepAssistantUsage: void 0,
|
|
705
|
+
pendingStepDeltaUsage: void 0,
|
|
704
706
|
pendingStepUsage: void 0,
|
|
705
707
|
stepOpen: false,
|
|
706
708
|
mcpToolUseIds: /* @__PURE__ */ new Set(),
|
|
@@ -778,7 +780,7 @@ function createEmitStreamEvent({
|
|
|
778
780
|
return;
|
|
779
781
|
}
|
|
780
782
|
if (type === "assistant" && msg.message?.content) {
|
|
781
|
-
const usage =
|
|
783
|
+
const usage = toUsageRecord(msg.message.usage);
|
|
782
784
|
const toolUseIds = [];
|
|
783
785
|
let opensStep = false;
|
|
784
786
|
for (const block of msg.message.content) {
|
|
@@ -820,7 +822,10 @@ function createEmitStreamEvent({
|
|
|
820
822
|
}
|
|
821
823
|
if (opensStep || toolUseIds.length === 0) {
|
|
822
824
|
state.stepOpen = true;
|
|
823
|
-
if (usage)
|
|
825
|
+
if (usage) {
|
|
826
|
+
state.pendingStepAssistantUsage = usage;
|
|
827
|
+
updatePendingStepUsage(state);
|
|
828
|
+
}
|
|
824
829
|
}
|
|
825
830
|
return;
|
|
826
831
|
}
|
|
@@ -886,6 +891,8 @@ function emitFinishStep({
|
|
|
886
891
|
usage: usage ?? defaultUsage()
|
|
887
892
|
});
|
|
888
893
|
state.stepUsage = usage ?? state.stepUsage;
|
|
894
|
+
state.pendingStepAssistantUsage = void 0;
|
|
895
|
+
state.pendingStepDeltaUsage = void 0;
|
|
889
896
|
state.pendingStepUsage = void 0;
|
|
890
897
|
state.pendingStepToolUseIds = /* @__PURE__ */ new Set();
|
|
891
898
|
state.stepOpen = false;
|
|
@@ -920,7 +927,19 @@ function handleStreamEvent({
|
|
|
920
927
|
send,
|
|
921
928
|
toCommonName: toCommonName2
|
|
922
929
|
}) {
|
|
923
|
-
if (!event
|
|
930
|
+
if (!event) return;
|
|
931
|
+
if (event.type === "message_delta") {
|
|
932
|
+
const usage = toUsageRecord(event.usage);
|
|
933
|
+
if (usage) {
|
|
934
|
+
state.pendingStepDeltaUsage = mergeNonNullUsage(
|
|
935
|
+
state.pendingStepDeltaUsage,
|
|
936
|
+
usage
|
|
937
|
+
);
|
|
938
|
+
updatePendingStepUsage(state);
|
|
939
|
+
}
|
|
940
|
+
return;
|
|
941
|
+
}
|
|
942
|
+
if (typeof event.index !== "number") return;
|
|
924
943
|
const index = event.index;
|
|
925
944
|
const partialBlocks = state.partialBlocks;
|
|
926
945
|
if (event.type === "content_block_start") {
|
|
@@ -988,6 +1007,25 @@ function handleStreamEvent({
|
|
|
988
1007
|
}
|
|
989
1008
|
}
|
|
990
1009
|
}
|
|
1010
|
+
function toUsageRecord(usage) {
|
|
1011
|
+
return usage != null && typeof usage === "object" ? usage : void 0;
|
|
1012
|
+
}
|
|
1013
|
+
function mergeNonNullUsage(current, update) {
|
|
1014
|
+
const merged = { ...current };
|
|
1015
|
+
for (const [key, value] of Object.entries(update)) {
|
|
1016
|
+
if (value != null) {
|
|
1017
|
+
merged[key] = value;
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
return merged;
|
|
1021
|
+
}
|
|
1022
|
+
function updatePendingStepUsage(state) {
|
|
1023
|
+
const assistantUsage = state.pendingStepAssistantUsage;
|
|
1024
|
+
const deltaUsage = state.pendingStepDeltaUsage;
|
|
1025
|
+
state.pendingStepUsage = mapUsage(
|
|
1026
|
+
assistantUsage || deltaUsage ? { ...assistantUsage, ...deltaUsage } : void 0
|
|
1027
|
+
);
|
|
1028
|
+
}
|
|
991
1029
|
function isTextEntry(entry) {
|
|
992
1030
|
return entry != null && typeof entry === "object" && "text" in entry;
|
|
993
1031
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../harness/src/bridge/index.ts","../../../harness/src/bridge/harness-bridge-capability-unsupported-error.ts","../../src/bridge/compaction-latch.ts","../../src/bridge/index.ts","../../src/bridge/claude-code-system-prompt.ts","../../src/bridge/claude-skills-option.ts","../../src/bridge/create-emit-stream-event.ts","../../src/bridge/json-schema-to-zod.ts","../../src/bridge/tool-filtering.ts","../../src/bridge/question-tool.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, the in-memory event log +\n// monotonic `seq`, resume replay, and the lifecycle/meta files. Any number of\n// hosts may be connected; exactly one of them owns the event stream, and\n// `start`/`resume` transfer that ownership. The adapter supplies only `onStart`\n// (drive its CLI/SDK and translate to wire events) and lifecycle cleanup hooks.\n\nimport { appendFile, mkdir, writeFile } from 'node:fs/promises';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { randomUUID } from 'node:crypto';\nimport { env as procEnv, pid, stdout } from 'node:process';\nimport type { ToolResultPart } from '@ai-sdk/provider-utils';\nimport { WebSocketServer, type WebSocket } from 'ws';\n\nexport { HarnessBridgeCapabilityUnsupportedError } from './harness-bridge-capability-unsupported-error';\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\nexport interface Experimental_BridgeUserMessage {\n readonly messageId: string;\n readonly text: string;\n accept(): void;\n reject(error: unknown): void;\n}\n\nexport interface Experimental_BridgeUserMessageQueue extends AsyncIterable<Experimental_BridgeUserMessage> {\n readonly pendingCount: number;\n close(error?: unknown): void;\n}\n\ntype InternalBridgeUserMessageQueue = Experimental_BridgeUserMessageQueue & {\n enqueue(input: { messageId: string; text: string }): void;\n};\n\ntype BridgeUserMessageResponse = {\n type: 'user-message-response';\n messageId: string;\n accepted: boolean;\n error?: { message: string };\n};\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 createBridgeUserMessageQueue(options: {\n respond(response: BridgeUserMessageResponse): void;\n}): InternalBridgeUserMessageQueue {\n const messages: Experimental_BridgeUserMessage[] = [];\n const waiters: Array<\n (result: IteratorResult<Experimental_BridgeUserMessage>) => void\n > = [];\n const entries = new Map<\n string,\n {\n response?: BridgeUserMessageResponse;\n reject(error: unknown): void;\n }\n >();\n let closed = false;\n let pendingCount = 0;\n\n const enqueue = (input: { messageId: string; text: string }): void => {\n const existing = entries.get(input.messageId);\n if (existing != null) {\n if (existing.response != null) {\n options.respond(existing.response);\n }\n return;\n }\n\n let settled = false;\n const settle = (response: BridgeUserMessageResponse): void => {\n if (settled) return;\n settled = true;\n pendingCount--;\n const entry = entries.get(input.messageId);\n if (entry != null) entry.response = response;\n options.respond(response);\n };\n const message: Experimental_BridgeUserMessage = {\n messageId: input.messageId,\n text: input.text,\n accept: () => {\n settle({\n type: 'user-message-response',\n messageId: input.messageId,\n accepted: true,\n });\n },\n reject: error => {\n settle({\n type: 'user-message-response',\n messageId: input.messageId,\n accepted: false,\n error: { message: formatBridgeError(error).message },\n });\n },\n };\n entries.set(input.messageId, {\n reject: message.reject,\n });\n pendingCount++;\n\n if (closed) {\n message.reject(\n new Error('The bridge turn is no longer accepting user messages.'),\n );\n return;\n }\n\n const waiter = waiters.shift();\n if (waiter != null) {\n waiter({ done: false, value: message });\n } else {\n messages.push(message);\n }\n };\n\n const close = (error?: unknown): void => {\n if (closed) return;\n closed = true;\n const reason =\n error ??\n new Error('The bridge turn ended before accepting the user message.');\n for (const entry of entries.values()) {\n if (entry.response == null) entry.reject(reason);\n }\n messages.length = 0;\n while (waiters.length > 0) {\n waiters.shift()!({ done: true, value: undefined });\n }\n };\n\n return {\n get pendingCount() {\n return pendingCount;\n },\n enqueue,\n close,\n [Symbol.asyncIterator]() {\n return {\n next: () => {\n const message = messages.shift();\n if (message != null) {\n return Promise.resolve({ done: false as const, value: message });\n }\n if (closed) {\n return Promise.resolve({\n done: true as const,\n value: undefined,\n });\n }\n return new Promise<IteratorResult<Experimental_BridgeUserMessage>>(\n resolve => {\n waiters.push(resolve);\n },\n );\n },\n };\n },\n };\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 input:\n | string\n | {\n toolCallId: string;\n matches?: (result: {\n output: unknown;\n isError?: boolean;\n toolResult?: ToolResultPart;\n }) => boolean;\n },\n ): Promise<{\n output: unknown;\n isError?: boolean;\n toolResult?: ToolResultPart;\n }>;\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 readonly experimental_userMessages: Experimental_BridgeUserMessageQueue;\n\n /** Aborts when the host sends `abort`. */\n readonly abortSignal: AbortSignal;\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 /**\n * Drive one prompt turn. Rejections surface to the host as an `error`\n * event.\n *\n * Contract: once `turn.abortSignal` fires, wind down promptly — turns are\n * serialized, and a replacement `start` waits up to\n * {@link turnTeardownGraceMs} for this promise to settle before it\n * proceeds anyway.\n */\n onStart(start: TStart, turn: BridgeTurn): Promise<void>;\n /**\n * How long a replacement `start` waits for the previous turn's teardown\n * after aborting it, in milliseconds. Turns are serialized so an aborted\n * turn cannot emit into its replacement's event log or overlap its runtime\n * process — but only within this bound: an adapter that does not settle\n * `onStart` after its abort signal fires forfeits the protection for that\n * boundary, and the new turn proceeds anyway rather than blocking forever.\n * The default of ten seconds exceeds the Claude bridge's five-second\n * hard-abort fallback.\n */\n turnTeardownGraceMs?: number;\n /**\n * Produce the adapter-defined runtime resume data for `stop`. Defaults to\n * `{}`.\n */\n onStop?(): unknown | Promise<unknown>;\n /**\n * Perform adapter-defined destruction before the bridge exits.\n */\n onDestroy?(): void | Promise<void>;\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 `stop` / `destroy`. 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 toolResult?: ToolResultPart;\n }\n | {\n type: 'tool-approval-response';\n approvalId: string;\n approved: boolean;\n reason?: string;\n }\n | { type: 'user-message'; messageId?: string; text: string }\n | { type: 'abort' }\n | { type: 'stop' }\n | { type: 'destroy' }\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 * `stop` / `destroy` 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, onStop, onDestroy } = options;\n const teardownGraceMs = options.turnTeardownGraceMs ?? 10_000;\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 /*\n * The one connection turn events stream to. A socket claims it by asking for\n * work — `start` (a turn) or `resume` (a catch-up) — never by connecting:\n * every event goes here alone, so claiming on connect would silence a turn\n * already streaming to someone else. Any number of sockets may be connected;\n * the others still exchange control frames, they just get no events.\n */\n let activeSocket: WebSocket | undefined;\n let isFirstTurn = true;\n let turnAbort: AbortController | undefined;\n let currentUserMessages: InternalBridgeUserMessageQueue | undefined;\n /**\n * Settles when the in-flight turn has fully wound down — `onStart`\n * returned or threw AND its completion state was recorded. `undefined`\n * between turns. A new `start` fences on this so turns never overlap.\n */\n let activeTurn: 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 in-flight 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 {\n resolve: (output: {\n output: unknown;\n isError?: boolean;\n toolResult?: ToolResultPart;\n }) => void;\n matches?: (output: {\n output: unknown;\n isError?: boolean;\n toolResult?: ToolResultPart;\n }) => boolean;\n }\n >();\n const bufferedToolResults: Array<{\n toolCallId: string;\n result: {\n output: unknown;\n isError?: boolean;\n toolResult?: ToolResultPart;\n };\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 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 /*\n * A new turn replaces the active one — but only after the active one\n * has fully wound down. Inbound frames are dispatched concurrently,\n * and the host settles a caller abort immediately, so a retry's\n * `start` can arrive while the aborted turn is still tearing down\n * (e.g. a graceful interrupt). Without this fence the old turn would\n * keep emitting into the new turn's cleared event log, two runtime\n * processes would run side by side, and the old turn's completion\n * would mark the bridge `waiting` underneath the new turn. Abort the\n * old turn to hasten its teardown; adapters are expected to bound\n * that teardown themselves (e.g. a hard-abort fallback), but the\n * runtime does not rely on it: the wait is capped by the teardown\n * grace period, after which the new turn proceeds anyway — the\n * pre-fence overlapping behavior — rather than hanging behind a\n * teardown that never settles.\n */\n for (;;) {\n const pendingTurn = activeTurn;\n if (pendingTurn == null) break;\n turnAbort?.abort();\n currentUserMessages?.close(\n new Error('A new bridge turn replaced the active turn.'),\n );\n let graceTimer: ReturnType<typeof setTimeout> | undefined;\n const settled = await Promise.race([\n pendingTurn.then(() => true as const),\n new Promise<false>(resolve => {\n graceTimer = setTimeout(() => resolve(false), teardownGraceMs);\n graceTimer.unref?.();\n }),\n ]);\n clearTimeout(graceTimer);\n if (!settled) break;\n }\n let turnFinished!: () => void;\n const thisTurn = new Promise<void>(resolve => (turnFinished = resolve));\n activeTurn = thisTurn;\n activeSocket = ws; // asking for a turn claims the event stream\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 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 userMessages = createBridgeUserMessageQueue({ respond: emit });\n const turn: BridgeTurn = {\n emit,\n requestToolResult: requestInput => {\n const request =\n typeof requestInput === 'string'\n ? { toolCallId: requestInput }\n : requestInput;\n const bufferedIndex = bufferedToolResults.findIndex(\n buffered =>\n buffered.toolCallId === request.toolCallId ||\n request.matches?.(buffered.result) === true,\n );\n if (bufferedIndex >= 0) {\n return Promise.resolve(\n bufferedToolResults.splice(bufferedIndex, 1)[0].result,\n );\n }\n return new Promise(resolve => {\n pendingToolResults.set(request.toolCallId, {\n resolve,\n matches: request.matches,\n });\n });\n },\n requestToolApproval: approvalId =>\n new Promise(resolve => {\n pendingToolApprovals.set(approvalId, resolve);\n }),\n experimental_userMessages: userMessages,\n abortSignal: turnAbort.signal,\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 = userMessages;\n try {\n await onStart(msg as TStart, turn);\n } catch (err) {\n emitError({ error: err, message: 'bridge turn failed' });\n } finally {\n userMessages.close();\n if (currentUserMessages === userMessages) {\n currentUserMessages = undefined;\n }\n // Only the still-active turn records completion: after a fence\n // timeout a replacement turn is already running, and this stale\n // completion must not mark the bridge waiting underneath it.\n if (activeTurn === thisTurn) {\n activeTurn = undefined;\n currentTurnState = 'waiting';\n void writeBridgeMeta('waiting');\n }\n turnFinished();\n }\n return;\n }\n case 'tool-result': {\n const result = {\n output: msg.output,\n isError: msg.isError,\n toolResult: msg.toolResult,\n };\n const exactPending = pendingToolResults.get(msg.toolCallId);\n const matchingPending =\n exactPending == null\n ? Array.from(pendingToolResults.entries()).find(\n ([, pending]) => pending.matches?.(result) === true,\n )\n : undefined;\n const pending = exactPending ?? matchingPending?.[1];\n const pendingId =\n exactPending != null ? msg.toolCallId : matchingPending?.[0];\n if (pending != null && pendingId != null) {\n pendingToolResults.delete(pendingId);\n pending.resolve(result);\n } else {\n bufferedToolResults.push({\n toolCallId: msg.toolCallId,\n result,\n });\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 const messageId = msg.messageId ?? randomUUID();\n if (currentUserMessages == null) {\n sendControl(ws, {\n type: 'user-message-response',\n messageId,\n accepted: false,\n error: { message: 'The bridge has no active turn to steer.' },\n });\n return;\n }\n if (ws !== activeSocket) {\n sendControl(ws, {\n type: 'user-message-response',\n messageId,\n accepted: false,\n error: {\n message: 'The connection does not own the active bridge turn.',\n },\n });\n return;\n }\n currentUserMessages.enqueue({\n messageId,\n text: msg.text,\n });\n return;\n }\n case 'abort':\n turnAbort?.abort();\n return;\n case 'resume':\n activeSocket = ws; // asking for a catch-up claims it too\n // Synchronous, so no event can slip out live ahead of the replayed tail.\n replay(ws, msg.lastSeenEventId);\n return;\n case 'destroy':\n currentTurnState = 'done';\n void writeBridgeMeta('done');\n await onDestroy?.();\n drainThenExit(ws, 1000, 'destroy');\n return;\n case 'stop': {\n currentTurnState = 'done';\n void writeBridgeMeta('done');\n const data = (await onStop?.()) ?? {};\n sendControl(ws, { type: 'bridge-stop', data });\n drainThenExit(ws, 1000, 'stop');\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 stop/destroy 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 // 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(ws, {\n type: 'bridge-hello',\n state: currentTurnState,\n lastSeq: seqCounter,\n capabilities: { experimental_userMessageResponses: true },\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(ws, {\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 stream owner's close matters; a socket that never claimed it,\n // or that a later `start`/`resume` displaced, closes as a no-op.\n // Crucially we do NOT abort the in-flight turn: it keeps running and its\n // events accumulate in the log for replay on reconnect.\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\n/*\n * Control frames answer the socket that sent the frame they reply to, so the\n * target is always explicit. Event streaming is the separate, stateful path\n * (`emit` → `activeSocket`); this one carries no state at all.\n */\nfunction sendControl(\n socket: WebSocket | undefined,\n message: Record<string, unknown>,\n): void {\n if (socket?.readyState === WS_OPEN) {\n try {\n socket.send(JSON.stringify(message));\n } catch {\n // best-effort\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","const name = 'AI_HarnessBridgeCapabilityUnsupportedError';\n\n/**\n * Signals an unsupported capability discovered inside a sandbox bridge.\n * `isInstance` also recognizes the serialized error shape received by the\n * host, where it can be translated to `HarnessCapabilityUnsupportedError`.\n */\nexport class HarnessBridgeCapabilityUnsupportedError extends Error {\n readonly harnessId?: string;\n readonly cause?: unknown;\n\n constructor({\n message,\n harnessId,\n cause,\n }: {\n message: string;\n harnessId?: string;\n cause?: unknown;\n }) {\n super(message);\n Object.defineProperty(this, 'name', { value: name });\n this.harnessId = harnessId;\n this.cause = cause;\n }\n\n static isInstance(\n error: unknown,\n ): error is HarnessBridgeCapabilityUnsupportedError {\n return (\n error != null &&\n typeof error === 'object' &&\n 'name' in error &&\n error.name === name &&\n 'message' in error &&\n typeof error.message === 'string'\n );\n }\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 type Experimental_BridgeUserMessage,\n type Experimental_BridgeUserMessageQueue,\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, env as procEnv, 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 type {\n HookCallback,\n HookJSONOutput,\n} from '@anthropic-ai/claude-agent-sdk';\nimport * as mcpServerModule from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { createClaudeCodeSystemPrompt } from './claude-code-system-prompt';\nimport { toClaudeSkillsOption } from './claude-skills-option';\nimport {\n createClaudeStreamEventState,\n createEmitStreamEvent,\n defaultUsage,\n emitFinishStep,\n finishApprovalStep,\n isExternalMcpTool,\n mapUsage,\n type ClaudeMessage,\n} from './create-emit-stream-event';\nimport { jsonSchemaToZodShape } from './json-schema-to-zod';\nimport {\n resolveInactiveNativeTools,\n resolveNativeTools,\n} from './tool-filtering';\nimport {\n claudeCodeQuestionKey,\n toClaudeCodeQuestionResult,\n toHarnessQuestionsInput,\n} from './question-tool';\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 | 'askUserQuestions';\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 AskUserQuestion: 'askUserQuestions',\n};\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: 'readonly',\n AskUserQuestion: 'readonly',\n ToolSearch: 'readonly',\n Bash: 'bash',\n Monitor: 'bash',\n};\n\nfunction toCommonName(nativeName: string): CommonBuiltinToolName | string {\n return NATIVE_TO_COMMON[nativeName] ?? nativeName;\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\n/**\n * The Claude session id most recently reported by the SDK, captured from the\n * message stream. Every turn in this bridge process may fork a new id (the\n * SDK's `continue`/`resume` create a new session linked to the previous one),\n * so the latest observation is the one a later resume must name.\n */\nlet lastClaudeSessionId: string | undefined;\n\nawait runBridge<StartMessage>({\n bridgeType: 'claude-code',\n bridgeStateDir,\n onStart: runTurn,\n // Claude Code's conversation state lives in the runtime's own store, keyed\n // by working directory. The resume payload names the exact conversation so a\n // later resume does not have to fall back to \"most recent in this workdir\".\n onStop: () =>\n lastClaudeSessionId == null ? {} : { claudeSessionId: lastClaudeSessionId },\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\n return {\n permissionMode:\n permissionMode === 'allow-all'\n ? 'bypassPermissions'\n : permissionMode === 'allow-edits'\n ? 'acceptEdits'\n : 'default',\n allowDangerouslySkipPermissions: permissionMode === 'allow-all',\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 ...(isExternalMcpTool(toolName) ? { dynamic: 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 createQuestionPreToolUseHook(input: {\n turn: BridgeTurn;\n emit: Emit;\n nativeToolCallNames: Map<string, string>;\n}): HookCallback {\n return async (hookInput, toolUseID): Promise<HookJSONOutput> => {\n if (\n hookInput.hook_event_name !== 'PreToolUse' ||\n hookInput.tool_name !== 'AskUserQuestion'\n ) {\n return {};\n }\n\n const nativeInput = hookInput.tool_input as Parameters<\n typeof toHarnessQuestionsInput\n >[0];\n const canonicalInput = toHarnessQuestionsInput(nativeInput);\n const toolCallId = toolUseID ?? hookInput.tool_use_id;\n input.nativeToolCallNames.set(toolCallId, hookInput.tool_name);\n input.emit({\n type: 'tool-call',\n toolCallId,\n toolName: 'askUserQuestions',\n nativeName: hookInput.tool_name,\n input: JSON.stringify(canonicalInput),\n providerExecuted: false,\n providerMetadata: {\n 'claude-code': {\n nativeRequest: nativeInput,\n },\n },\n });\n\n const questionKey = claudeCodeQuestionKey(nativeInput);\n const result = await input.turn.requestToolResult({\n toolCallId,\n matches: candidate => {\n const nativeRequest = candidate.toolResult?.providerOptions?.[\n 'claude-code'\n ]?.nativeRequest as\n | Parameters<typeof claudeCodeQuestionKey>[0]\n | undefined;\n return (\n nativeRequest != null &&\n claudeCodeQuestionKey(nativeRequest) === questionKey\n );\n },\n });\n const nativeResult = toClaudeCodeQuestionResult({\n nativeInput,\n output: result.output as Parameters<\n typeof toClaudeCodeQuestionResult\n >[0]['output'],\n });\n\n return {\n hookSpecificOutput: {\n hookEventName: 'PreToolUse',\n ...(nativeResult.behavior === 'allow'\n ? {\n permissionDecision: 'allow',\n updatedInput: {\n ...nativeResult.updatedInput,\n } as Record<string, unknown>,\n }\n : {\n permissionDecision: 'deny',\n permissionDecisionReason: nativeResult.message,\n }),\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 // A host abort prefers the SDK's graceful `interrupt()` — Esc semantics: the\n // in-flight turn is persisted to the session transcript and settles with an\n // interrupted result, so a later resume (including the user's own\n // `claude --resume`) still sees the work done before the interrupt. The hard\n // abort kills the CLI process and loses that turn's records, so it is only\n // the fallback — armed unconditionally, because aborting an already-settled\n // query is a no-op — and the immediate path when the abort arrives before\n // the query exists.\n let gracefulAbort: (() => void) | undefined;\n let hardAbortTimer: ReturnType<typeof setTimeout> | undefined;\n const onHostAbort = (): void => {\n if (gracefulAbort) {\n gracefulAbort();\n } else {\n abortCtl.abort();\n }\n };\n if (turn.abortSignal.aborted) {\n abortCtl.abort();\n } else {\n turn.abortSignal.addEventListener('abort', onHostAbort, { once: true });\n }\n\n const streamEventState = createClaudeStreamEventState();\n\n const mcpServers: Record<string, unknown> = { ...(start.mcpServers ?? {}) };\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);\n server.tool(\n tool.name,\n tool.description ?? '',\n shape,\n async (\n ...handlerArgs: [\n Record<string, unknown>,\n { requestId: string | number; _meta?: Record<string, unknown> },\n ]\n ) => {\n const [input, extra] = handlerArgs;\n const metadataToolCallId = extra._meta?.['claudecode/toolUseId'];\n const toolCallId =\n typeof metadataToolCallId === 'string'\n ? metadataToolCallId\n : 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 userMessages: turn.experimental_userMessages,\n abortSignal: abortCtl.signal,\n });\n const skillsOption = toClaudeSkillsOption(start.skills);\n const nativeTools = resolveNativeTools(start.builtinToolFiltering);\n const inactiveNativeTools = resolveInactiveNativeTools(\n start.builtinToolFiltering,\n );\n const permissionOptions = createPermissionOptions({\n start,\n inactiveNativeTools,\n turn,\n emit,\n finishApprovalStep: approvalId => {\n finishApprovalStep({ state: streamEventState, emit, approvalId });\n },\n nativeToolCallNames: streamEventState.nativeToolCallNames,\n approvalRequestedToolUseIds: streamEventState.approvalRequestedToolUseIds,\n });\n const questionPreToolUseHook = createQuestionPreToolUseHook({\n turn,\n emit,\n nativeToolCallNames: streamEventState.nativeToolCallNames,\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 ...(start.env !== undefined ? { env: { ...procEnv, ...start.env } } : {}),\n ...(skillsOption ? { skills: skillsOption } : {}),\n ...(nativeTools !== undefined ? { tools: nativeTools } : {}),\n ...(inactiveNativeTools.length > 0\n ? { disallowedTools: inactiveNativeTools }\n : {}),\n systemPrompt: createClaudeCodeSystemPrompt(start.instructions),\n thinking: start.thinking,\n ...(start.effort !== undefined ? { effort: start.effort } : {}),\n ...(start.responseFormat?.type === 'json' &&\n start.responseFormat.schema != null\n ? {\n outputFormat: {\n type: 'json_schema' as const,\n schema: start.responseFormat.schema,\n },\n }\n : {}),\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 PreToolUse: [\n {\n matcher: 'AskUserQuestion',\n hooks: [questionPreToolUseHook],\n },\n ],\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, most specific first.\n //\n // `resumeSessionId` names the exact conversation and is what a\n // cross-process resume should use: `continue` means \"most recent thread\n // in this workdir\", which silently picks the wrong one once anything\n // else has run there. The bridge also retains the id observed during its\n // previous query, so every later query stays pinned to that conversation\n // even when the host detached and reattached between turns. `resume` and\n // `continue` are mutually exclusive in the SDK.\n //\n // Otherwise the host can force-continue by setting `start.continue`,\n // and turns after the first fall back to the legacy cwd-based behavior\n // when no exact id was observed.\n ...((start.resumeSessionId ?? lastClaudeSessionId)\n ? { resume: start.resumeSessionId ?? lastClaudeSessionId }\n : start.continue === true || !turn.firstTurn\n ? { continue: true }\n : {}),\n ...permissionOptions,\n mcpServers,\n cwd: workdir,\n abortSignal: abortCtl.signal,\n },\n });\n\n gracefulAbort = () => {\n // Backstop for the whole teardown, not just the interrupt call: if the\n // stream has not settled five seconds after a graceful interrupt was\n // requested, fall back to the hard abort. Aborting an already-settled\n // query is a no-op, and `unref` keeps the timer from pinning the bridge\n // process open on its own.\n hardAbortTimer = setTimeout(() => abortCtl.abort(), 5000);\n hardAbortTimer.unref?.();\n void Promise.resolve()\n .then(() => q.interrupt())\n .catch(() => abortCtl.abort());\n };\n let turnUsage: Record<string, unknown> | undefined;\n let totalCostUsd: number | undefined;\n let emittedTerminalError = false;\n let emittedTerminalFinish = false;\n\n const emitTerminalError = (message: string | undefined): void => {\n const normalized = message?.trim();\n if (!normalized || emittedTerminalError || emittedTerminalFinish) return;\n streamEventState.observedTerminalError = normalized;\n emittedTerminalError = true;\n // A turn the host itself stopped ends with an error-shaped result by\n // construction (an interrupted query reports a diagnostic, not success);\n // reporting the host's own stop as a terminal error makes every clean\n // interrupt look like a malfunction. The host has already settled the\n // turn on its side.\n if (!turn.abortSignal.aborted) {\n turn.emitError({\n error: normalized,\n message: 'claude-code terminal error',\n });\n }\n queryInput.close();\n abortCtl.abort();\n };\n\n const emitStreamEvent = createEmitStreamEvent({\n state: streamEventState,\n emit,\n emitWarning: turn.emitWarning,\n emitTerminalError,\n onCompactionBoundary: boundary => compaction.onBoundary(boundary),\n toCommonName,\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 if (type === 'command_lifecycle') {\n queryInput.handleLifecycle(msg);\n }\n\n // Every SDK message carries the session id of the conversation it\n // belongs to. Track the latest so the stop payload and the terminal\n // finish metadata name the exact conversation.\n const sessionId = (msg as { session_id?: unknown }).session_id;\n if (typeof sessionId === 'string' && sessionId.length > 0) {\n lastClaudeSessionId = sessionId;\n }\n\n emitStreamEvent(msg);\n\n if (type === 'result') {\n if (msg.subtype === 'success') {\n // `success` does not mean the turn succeeded: the CLI flags a rejected\n // request with `is_error` and puts the message in `result`, which the\n // empty-result rescue below cannot catch.\n if (msg.is_error) {\n emitTerminalError(\n msg.result?.trim() ||\n streamEventState.observedTerminalError ||\n (typeof msg.api_error_status === 'number'\n ? `Claude Code reported an API error (HTTP ${msg.api_error_status})`\n : 'Claude Code reported a failed result'),\n );\n continue;\n }\n const emptyResult = !msg.result?.trim?.();\n if (emptyResult && streamEventState.observedTerminalError) {\n emitTerminalError(streamEventState.observedTerminalError);\n continue;\n }\n const usage = msg.usage ?? msg.message?.usage;\n const harnessUsage = mapUsage(usage);\n if (harnessUsage) turnUsage = addUsage(turnUsage, harnessUsage);\n if (typeof msg.total_cost_usd === 'number') {\n totalCostUsd = (totalCostUsd ?? 0) + msg.total_cost_usd;\n }\n if (\n start.responseFormat?.type === 'json' &&\n msg.structured_output !== undefined\n ) {\n const id = randomUUID();\n emit({ type: 'text-start', id });\n emit({\n type: 'text-delta',\n id,\n delta: JSON.stringify(msg.structured_output),\n });\n emit({ type: 'text-end', id });\n streamEventState.stepOpen = true;\n }\n if (streamEventState.stepOpen) {\n emitFinishStep({\n state: streamEventState,\n emit,\n usage: streamEventState.pendingStepUsage ?? harnessUsage,\n });\n }\n queryInput.observeResult();\n if (!queryInput.hasActiveUserMessages()) {\n queryInput.close();\n break;\n }\n } else {\n emitTerminalError(\n (Array.isArray(msg.errors) ? msg.errors.join('\\n') : undefined) ||\n streamEventState.observedTerminalError ||\n msg.result ||\n 'Unknown error',\n );\n }\n continue;\n }\n\n if (queryInput.hasObservedResult && !queryInput.hasActiveUserMessages()) {\n queryInput.close();\n break;\n }\n }\n } catch (err) {\n // Same reasoning as `emitTerminalError`: a throw after the host's own\n // abort (e.g. the hard-abort fallback killing the CLI mid-iteration, or\n // a rejected `interrupt()`) is the stop the host asked for, not a\n // malfunction. The host has already settled the turn on its side.\n if (\n !turn.abortSignal.aborted &&\n !(abortCtl.signal.aborted && emittedTerminalError)\n ) {\n turn.emitError({ error: err, message: 'claude-code turn failed' });\n }\n return;\n } finally {\n // The turn is over; disarm the host-abort path first. An abort of this\n // turn's signal arriving after this point (e.g. an `abort` message racing\n // the next `start`) must not interrupt the disposed query or arm the\n // hard-abort fallback timer for it.\n gracefulAbort = undefined;\n if (hardAbortTimer != null) clearTimeout(hardAbortTimer);\n turn.abortSignal.removeEventListener('abort', onHostAbort);\n queryInput.close();\n // Dispose the query explicitly: with streaming input the SDK keeps its\n // CLI subprocess alive for more user messages, and a turn that ended\n // through an interrupt or error path can otherwise leak that process —\n // observed as orphaned `claude` processes holding the very conversation\n // the next turn continues.\n try {\n await (q as { return?: (value?: unknown) => Promise<unknown> }).return?.(\n undefined,\n );\n } catch {\n // Best effort; the abort controller tears the process down otherwise.\n }\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 ?? streamEventState.stepUsage ?? defaultUsage(),\n ...(totalCostUsd !== undefined || lastClaudeSessionId !== undefined\n ? {\n harnessMetadata: {\n 'claude-code': {\n ...(totalCostUsd !== undefined ? { costUsd: totalCostUsd } : {}),\n // The conversation this turn belongs to, resumable outside the\n // SDK with `claude --resume <sessionId>` and captured by the\n // adapter for exact cross-process resume.\n ...(lastClaudeSessionId !== undefined\n ? { sessionId: lastClaudeSessionId }\n : {}),\n },\n },\n }\n : {}),\n });\n}\n\nfunction createQueryInput({\n initialUserMessage,\n userMessages,\n abortSignal,\n}: {\n initialUserMessage: string;\n userMessages: Experimental_BridgeUserMessageQueue;\n abortSignal: AbortSignal;\n}): {\n input: AsyncIterable<unknown>;\n close(error?: unknown): void;\n handleLifecycle(message: ClaudeMessage): void;\n hasActiveUserMessages(): boolean;\n observeResult(): void;\n readonly hasObservedResult: boolean;\n} {\n let closed = false;\n let observedResult = false;\n const submittedMessages = new Map<string, Experimental_BridgeUserMessage>();\n const close = (error?: unknown): void => {\n if (closed) return;\n closed = true;\n userMessages.close(error);\n };\n if (abortSignal.aborted) {\n close(abortSignal.reason);\n } else {\n abortSignal.addEventListener('abort', () => close(abortSignal.reason), {\n once: true,\n });\n }\n\n const toUserMessage = (options: {\n text: string;\n messageId: string;\n priority?: 'next';\n }): unknown => ({\n type: 'user',\n message: {\n role: 'user',\n content: [{ type: 'text', text: options.text }],\n },\n parent_tool_use_id: null,\n uuid: options.messageId,\n ...(options.priority == null ? {} : { priority: options.priority }),\n });\n\n const messageIterator = userMessages[Symbol.asyncIterator]();\n\n return {\n close,\n handleLifecycle: message => {\n const lifecycle = message as ClaudeMessage & {\n command_uuid?: string;\n state?: 'queued' | 'started' | 'completed' | 'cancelled' | 'discarded';\n };\n if (lifecycle.command_uuid == null || lifecycle.state == null) return;\n const submitted = submittedMessages.get(lifecycle.command_uuid);\n if (submitted == null) return;\n if (lifecycle.state === 'queued' || lifecycle.state === 'started') {\n submitted.accept();\n return;\n }\n if (lifecycle.state === 'cancelled' || lifecycle.state === 'discarded') {\n submitted.reject(\n new Error(`Claude Code ${lifecycle.state} the user message.`),\n );\n }\n submittedMessages.delete(lifecycle.command_uuid);\n },\n hasActiveUserMessages: () =>\n submittedMessages.size > 0 || userMessages.pendingCount > 0,\n observeResult: () => {\n observedResult = true;\n },\n get hasObservedResult() {\n return observedResult;\n },\n input: {\n [Symbol.asyncIterator]() {\n let sentInitial = false;\n return {\n async next() {\n if (closed || abortSignal.aborted) {\n return {\n value: undefined,\n done: true,\n } as IteratorResult<unknown>;\n }\n if (!sentInitial) {\n sentInitial = true;\n return {\n value: toUserMessage({\n text: initialUserMessage,\n messageId: randomUUID(),\n }),\n done: false,\n };\n }\n const nextMessage = await messageIterator.next();\n if (nextMessage.done) {\n return {\n value: undefined,\n done: true,\n } as IteratorResult<unknown>;\n }\n submittedMessages.set(\n nextMessage.value.messageId,\n nextMessage.value,\n );\n return {\n value: toUserMessage({\n text: nextMessage.value.text,\n messageId: nextMessage.value.messageId,\n priority: 'next',\n }),\n done: false,\n };\n },\n };\n },\n },\n };\n}\n\nfunction addUsage(\n total: Record<string, unknown> | undefined,\n usage: Record<string, unknown>,\n): Record<string, unknown> {\n if (total == null) return usage;\n const result: Record<string, unknown> = { ...total };\n for (const [key, value] of Object.entries(usage)) {\n const previous = result[key];\n if (typeof value === 'number' && typeof previous === 'number') {\n result[key] = previous + value;\n } else if (\n value != null &&\n previous != null &&\n typeof value === 'object' &&\n typeof previous === 'object' &&\n !Array.isArray(value) &&\n !Array.isArray(previous)\n ) {\n result[key] = addUsage(\n previous as Record<string, unknown>,\n value as Record<string, unknown>,\n );\n } else {\n result[key] = value;\n }\n }\n return result;\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 createClaudeCodeSystemPrompt(instructions?: string): {\n type: 'preset';\n preset: 'claude_code';\n append?: string;\n} {\n return {\n type: 'preset',\n preset: 'claude_code',\n ...(instructions ? { append: instructions } : {}),\n };\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","import { randomUUID } from 'node:crypto';\n\ntype Emit = (message: Record<string, unknown>) => void;\n\nexport type ClaudeMessage = {\n type?: string;\n subtype?: string;\n parent_tool_use_id?: string | null;\n model?: 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?: {\n type?: string;\n id?: string;\n name?: string;\n };\n delta?: {\n type?: string;\n text?: string;\n thinking?: string;\n partial_json?: string;\n };\n };\n message?: {\n content?: ReadonlyArray<MessageBlock>;\n usage?: Record<string, unknown>;\n };\n result?: string;\n /** Result-message error flags; distinct from `error_status` (`api_retry`). */\n is_error?: boolean;\n api_error_status?: number | null;\n errors?: ReadonlyArray<string>;\n usage?: Record<string, unknown>;\n total_cost_usd?: number;\n structured_output?: unknown;\n tool_use_result?: unknown;\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\nexport type ClaudeStreamEventState = {\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 nativeToolCallNames: Map<string, string>;\n approvalRequestedToolUseIds: Set<string>;\n partialBlocks: Map<number, PartialBlock>;\n stepUsage: Record<string, unknown> | undefined;\n pendingStepToolUseIds: Set<string>;\n pendingStepUsage: Record<string, unknown> | undefined;\n stepOpen: boolean;\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, so the duplicate `tool_result` block Claude\n * reports for the underlying native id must be suppressed.\n */\n mcpToolUseIds: Set<string>;\n externalMcpToolUseIds: Set<string>;\n structuredOutputToolUseIds: Set<string>;\n observedTerminalError: string | undefined;\n};\n\ntype PartialBlock =\n | { id: string; kind: 'text' | 'thinking' }\n | { id: string; kind: 'tool-input' };\n\nexport function createClaudeStreamEventState(): ClaudeStreamEventState {\n return {\n nativeToolCallNames: new Map(),\n approvalRequestedToolUseIds: new Set(),\n partialBlocks: new Map(),\n stepUsage: undefined,\n pendingStepToolUseIds: new Set(),\n pendingStepUsage: undefined,\n stepOpen: false,\n mcpToolUseIds: new Set(),\n externalMcpToolUseIds: new Set(),\n structuredOutputToolUseIds: new Set(),\n observedTerminalError: undefined,\n };\n}\n\nconst UNRECOVERABLE_API_RETRY_STATUSES = new Set([401, 403, 404]);\nconst HOST_TOOL_PREFIX = 'mcp__harness-tools__';\n\nexport function isExternalMcpTool(nativeName: string): boolean {\n return (\n nativeName.startsWith('mcp__') && !nativeName.startsWith(HOST_TOOL_PREFIX)\n );\n}\n\nexport function createEmitStreamEvent({\n state,\n emit,\n emitWarning,\n emitTerminalError,\n onCompactionBoundary,\n toCommonName,\n}: {\n state: ClaudeStreamEventState;\n emit: Emit;\n emitWarning: (warning: { message: string }) => void;\n emitTerminalError: (message: string | undefined) => void;\n onCompactionBoundary: (boundary: {\n trigger: 'manual' | 'auto';\n tokensBefore?: number;\n tokensAfter?: number;\n }) => void;\n toCommonName: (nativeName: string) => string;\n}): (event: ClaudeMessage) => void {\n let streamStarted = false;\n\n return msg => {\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}: ${msg.error ?? 'provider request failed'}`,\n );\n return;\n }\n\n emitWarning({ message: formatApiRetryWarning(msg) });\n return;\n }\n\n if (typeof msg.error === 'string' && msg.error.trim()) {\n state.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 return;\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 return;\n }\n\n if (type === 'system' && msg.subtype === 'compact_boundary') {\n const meta = msg.compact_metadata;\n if (meta) {\n onCompactionBoundary({\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 return;\n }\n\n // Messages emitted by a Task-tool subagent carry the parent tool-use id.\n // They belong to the subagent stream and must not affect the parent step,\n // including partial stream events that arrive before assistant messages.\n if (msg.parent_tool_use_id != null) {\n return;\n }\n\n if (type === 'stream_event') {\n handleStreamEvent({\n event: msg.event,\n state,\n send: emit,\n toCommonName,\n });\n return;\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 if (block.name === 'StructuredOutput') {\n state.structuredOutputToolUseIds.add(block.id);\n continue;\n }\n if (block.name.startsWith(HOST_TOOL_PREFIX)) {\n state.pendingStepToolUseIds.add(block.id);\n state.mcpToolUseIds.add(block.id);\n opensStep = true;\n continue;\n }\n state.nativeToolCallNames.set(block.id, block.name);\n if (block.name === 'AskUserQuestion') {\n state.pendingStepToolUseIds.add(block.id);\n opensStep = true;\n continue;\n }\n const dynamic = isExternalMcpTool(block.name);\n if (dynamic) state.externalMcpToolUseIds.add(block.id);\n if (state.approvalRequestedToolUseIds.has(block.id)) {\n continue;\n }\n state.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 ...(dynamic ? { dynamic: true } : {}),\n });\n }\n }\n if (opensStep || toolUseIds.length === 0) {\n state.stepOpen = true;\n if (usage) state.pendingStepUsage = usage;\n }\n return;\n }\n\n if (type === 'user' && msg.message?.content) {\n const toolResultBlocks = msg.message.content.filter(\n block => block.type === 'tool_result',\n );\n const toolUseResult =\n toolResultBlocks.length === 1 ? msg.tool_use_result : undefined;\n\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 (state.structuredOutputToolUseIds.delete(block.tool_use_id)) {\n continue;\n }\n if (state.mcpToolUseIds.has(block.tool_use_id)) {\n state.mcpToolUseIds.delete(block.tool_use_id);\n state.pendingStepToolUseIds.delete(block.tool_use_id);\n continue;\n }\n state.approvalRequestedToolUseIds.delete(block.tool_use_id);\n const nativeName =\n state.nativeToolCallNames.get(block.tool_use_id) ?? 'unknown';\n state.nativeToolCallNames.delete(block.tool_use_id);\n const toolName = toCommonName(nativeName);\n const dynamic = state.externalMcpToolUseIds.delete(block.tool_use_id);\n const isError = !!block.is_error;\n const result =\n toolUseResult !== undefined\n ? toolUseResult\n : resolveToolResult({\n toolName,\n dynamic,\n isError,\n rawContent: block.content,\n });\n emit({\n type: 'tool-result',\n toolCallId: block.tool_use_id,\n toolName,\n result,\n isError,\n ...(dynamic ? { dynamic: true } : {}),\n });\n state.pendingStepToolUseIds.delete(block.tool_use_id);\n }\n }\n closeStepIfReady({ state, emit });\n }\n };\n}\n\nexport function finishApprovalStep({\n state,\n emit,\n approvalId,\n}: {\n state: ClaudeStreamEventState;\n emit: Emit;\n approvalId: string;\n}): void {\n state.stepOpen = true;\n state.pendingStepToolUseIds.delete(approvalId);\n closeStepIfReady({ state, emit });\n}\n\nexport function emitFinishStep({\n state,\n emit,\n usage,\n}: {\n state: ClaudeStreamEventState;\n emit: Emit;\n usage: Record<string, unknown> | undefined;\n}): void {\n emit({\n type: 'finish-step',\n finishReason: { unified: 'stop', raw: 'stop' },\n usage: usage ?? defaultUsage(),\n });\n state.stepUsage = usage ?? state.stepUsage;\n state.pendingStepUsage = undefined;\n state.pendingStepToolUseIds = new Set();\n state.stepOpen = false;\n}\n\nfunction closeStepIfReady({\n state,\n emit,\n}: {\n state: ClaudeStreamEventState;\n emit: Emit;\n}): void {\n if (\n !state.stepOpen ||\n state.pendingStepToolUseIds.size > 0 ||\n state.partialBlocks.size > 0\n ) {\n return;\n }\n emitFinishStep({ state, emit, usage: state.pendingStepUsage });\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,\n state,\n send,\n toCommonName,\n}: {\n event: ClaudeMessage['event'] | undefined;\n state: ClaudeStreamEventState;\n send: Emit;\n toCommonName: (nativeName: string) => string;\n}): void {\n if (!event || typeof event.index !== 'number') return;\n const index = event.index;\n const partialBlocks = state.partialBlocks;\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 } else if (\n blockType === 'tool_use' &&\n typeof event.content_block?.id === 'string' &&\n typeof event.content_block.name === 'string'\n ) {\n const id = event.content_block.id;\n const nativeName = event.content_block.name;\n if (nativeName === 'StructuredOutput') {\n return;\n }\n if (nativeName === 'AskUserQuestion') {\n return;\n }\n const hostToolName = nativeName.startsWith(HOST_TOOL_PREFIX)\n ? nativeName.slice(HOST_TOOL_PREFIX.length)\n : undefined;\n const dynamic = isExternalMcpTool(nativeName);\n partialBlocks.set(index, { id, kind: 'tool-input' });\n send({\n type: 'tool-input-start',\n id,\n toolName: hostToolName ?? toCommonName(nativeName),\n providerExecuted: hostToolName === undefined,\n ...(dynamic ? { dynamic: true } : {}),\n });\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 } else if (\n block.kind === 'tool-input' &&\n event.delta?.type === 'input_json_delta' &&\n typeof event.delta.partial_json === 'string'\n ) {\n send({\n type: 'tool-input-delta',\n id: block.id,\n delta: event.delta.partial_json,\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 if (block.kind === 'thinking') {\n send({ type: 'reasoning-end', id: block.id });\n } else {\n send({ type: 'tool-input-end', id: block.id });\n }\n }\n}\n\nfunction isTextEntry(entry: unknown): entry is { text?: unknown } {\n return entry != null && typeof entry === 'object' && 'text' in entry;\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 isTextEntry(entry) ? String(entry.text ?? '') : JSON.stringify(entry),\n )\n .join('');\n }\n return JSON.stringify(content);\n}\n\nfunction hasNonTextContent(content: unknown): boolean {\n return Array.isArray(content) && content.some(entry => !isTextEntry(entry));\n}\n\nfunction resolveToolResult({\n toolName,\n dynamic,\n isError,\n rawContent,\n}: {\n toolName: string;\n dynamic: boolean;\n isError: boolean;\n rawContent: unknown;\n}): unknown {\n /*\n * Claude Code's Bash tool does not report the command's real numeric exit\n * code — the SDK exposes only stdout/stderr text and an is_error flag.\n * Consumers (and the example UI) render bash failures from an `exitCode`\n * field on a structured result, the shape Codex's shell tool provides\n * natively. When Claude omits `tool_use_result`, derive a binary code from\n * is_error: 1 on failure, 0 on success. This fallback is a stand-in for\n * failed/succeeded, not the process's true exit status.\n */\n if (toolName === 'bash') {\n return { exitCode: isError ? 1 : 0, stdout: stringifyContent(rawContent) };\n }\n // Must precede the MCP branch: flattening a non-text block to base64 text\n // is not recoverable by parsing it back.\n if (hasNonTextContent(rawContent)) return rawContent;\n const content = stringifyContent(rawContent);\n return dynamic ? parseMcpToolResult(content) : content;\n}\n\nfunction parseMcpToolResult(content: string): unknown {\n try {\n const parsed = JSON.parse(content);\n // `JSON.parse` also succeeds on scalars; keep those as the string sent.\n return parsed !== null && typeof parsed === 'object' ? parsed : content;\n } catch {\n return content;\n }\n}\n\nexport function 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\nexport function 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","import { z } from 'zod/v4';\n\ntype JsonLiteral = string | number | boolean | null;\n\nexport type JsonSchemaObject = {\n type?: string | string[];\n description?: string;\n properties?: Record<string, JsonSchemaObject>;\n required?: string[];\n items?: JsonSchemaObject | JsonSchemaObject[];\n enum?: unknown[];\n const?: unknown;\n oneOf?: JsonSchemaObject[];\n anyOf?: JsonSchemaObject[];\n nullable?: boolean;\n};\n\ntype ZodShape = Record<string, z.ZodTypeAny>;\n\nexport function jsonSchemaToZodShape(input: unknown): ZodShape {\n const schema = isJsonSchemaObject(input) ? input : {};\n return toZodShape(schema);\n}\n\nfunction toZodShape(schema: JsonSchemaObject | undefined): ZodShape {\n if (!schema?.properties) return {};\n const required = new Set(schema.required ?? []);\n const shape: ZodShape = {};\n for (const [key, propSchema] of Object.entries(schema.properties)) {\n const propType = toZodType(propSchema);\n let propertyType = required.has(key) ? propType : propType.optional();\n if (propSchema.description) {\n propertyType = propertyType.describe(propSchema.description);\n }\n shape[key] = propertyType;\n }\n return shape;\n}\n\nfunction toZodType(schema: JsonSchemaObject | undefined): z.ZodTypeAny {\n if (!schema) return z.any();\n\n let zType =\n zodForConst(schema) ??\n zodForEnum(schema) ??\n zodForUnion(schema) ??\n zodForType(schema);\n\n if (isNullable(schema)) zType = zType.nullable();\n if (schema.description) zType = zType.describe(schema.description);\n return zType;\n}\n\nfunction zodForType(schema: JsonSchemaObject): z.ZodTypeAny {\n const types = getNonNullTypes(schema);\n if (types.length > 1) return z.any();\n if (Array.isArray(schema.type) && types.length === 0) return z.null();\n const type = types[0] ?? (schema.properties ? 'object' : undefined);\n\n switch (type) {\n case 'string':\n return z.string();\n case 'number':\n return z.number();\n case 'integer':\n return z.number().int();\n case 'boolean':\n return z.boolean();\n case 'array':\n return z.array(\n Array.isArray(schema.items) ? z.any() : toZodType(schema.items),\n );\n case 'object':\n return z.object(toZodShape(schema));\n case 'null':\n return z.null();\n default:\n return z.any();\n }\n}\n\nfunction zodForConst(schema: JsonSchemaObject): z.ZodTypeAny | undefined {\n if (!('const' in schema)) return undefined;\n return isJsonLiteral(schema.const) ? z.literal(schema.const) : z.any();\n}\n\nfunction zodForEnum(schema: JsonSchemaObject): z.ZodTypeAny | undefined {\n if (!Array.isArray(schema.enum)) return undefined;\n if (!schema.enum.every(isJsonLiteral)) return z.any();\n return zodForLiterals(schema.enum);\n}\n\nfunction zodForUnion(schema: JsonSchemaObject): z.ZodTypeAny | undefined {\n const unionSchemas = schema.anyOf ?? schema.oneOf;\n if (!unionSchemas || unionSchemas.length < 2) return undefined;\n\n const options = unionSchemas.map(item => toZodType(item)) as unknown as [\n z.ZodTypeAny,\n z.ZodTypeAny,\n ...z.ZodTypeAny[],\n ];\n return z.union(options);\n}\n\nfunction zodForLiterals(values: JsonLiteral[]): z.ZodTypeAny {\n if (values.length === 0) return z.any();\n if (values.length === 1) return z.literal(values[0]);\n\n const literals = values.map(value => z.literal(value)) as unknown as [\n z.ZodTypeAny,\n z.ZodTypeAny,\n ...z.ZodTypeAny[],\n ];\n return z.union(literals);\n}\n\nfunction getNonNullTypes(schema: JsonSchemaObject): string[] {\n return Array.isArray(schema.type)\n ? schema.type.filter(type => type !== 'null')\n : ([schema.type].filter(Boolean) as string[]);\n}\n\nfunction isNullable(schema: JsonSchemaObject): boolean {\n return (\n schema.nullable === true ||\n (Array.isArray(schema.type) && schema.type.includes('null'))\n );\n}\n\nfunction isJsonSchemaObject(input: unknown): input is JsonSchemaObject {\n return input != null && typeof input === 'object' && !Array.isArray(input);\n}\n\nfunction isJsonLiteral(value: unknown): value is JsonLiteral {\n return (\n value === null ||\n typeof value === 'string' ||\n typeof value === 'boolean' ||\n (typeof value === 'number' && Number.isFinite(value))\n );\n}\n","import type { StartMessage } from '../claude-code-bridge-protocol';\n\ntype BuiltinToolFiltering = StartMessage['builtinToolFiltering'];\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 askUserQuestions: 'AskUserQuestion',\n Skill: 'Skill',\n ToolSearch: 'ToolSearch',\n};\n\nconst PUBLIC_TOOL_NAMES = Object.keys(PUBLIC_TO_NATIVE);\n\nfunction toNativeName(toolName: string): string {\n return PUBLIC_TO_NATIVE[toolName] ?? toolName;\n}\n\nexport function resolveNativeTools(\n toolFiltering: BuiltinToolFiltering,\n): string[] | undefined {\n if (toolFiltering == null || toolFiltering.mode === 'deny') return undefined;\n return toolFiltering.toolNames.map(name => toNativeName(name));\n}\n\nexport function resolveInactiveNativeTools(\n toolFiltering: BuiltinToolFiltering,\n): string[] {\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","import type {\n HarnessV1QuestionsToolInput,\n HarnessV1QuestionsToolOutput,\n} from '@ai-sdk/harness';\nimport type { AskUserQuestionInput } from '@anthropic-ai/claude-agent-sdk/sdk-tools.js';\n\ntype ClaudeCodeQuestion = AskUserQuestionInput['questions'][number];\n\nexport function claudeCodeQuestionKey(\n nativeInput: AskUserQuestionInput,\n): string {\n return JSON.stringify(nativeInput.questions);\n}\n\nexport function toHarnessQuestionsInput(\n nativeInput: AskUserQuestionInput,\n): HarnessV1QuestionsToolInput {\n return {\n allowPartialAnswers: true,\n questions: nativeInput.questions.map((question, questionIndex) => ({\n id: `question-${questionIndex + 1}`,\n question: question.question,\n header: question.header,\n options: question.options.map((option, optionIndex) => ({\n id: `option-${optionIndex + 1}`,\n label: option.label,\n description: option.description,\n ...(option.preview !== undefined ? { preview: option.preview } : {}),\n })),\n allowMultiple: question.multiSelect,\n allowFreeForm: true,\n })),\n };\n}\n\nexport function toClaudeCodeQuestionResult(input: {\n nativeInput: AskUserQuestionInput;\n output: HarnessV1QuestionsToolOutput;\n}):\n | {\n behavior: 'allow';\n updatedInput: AskUserQuestionInput & { answers: Record<string, string> };\n }\n | { behavior: 'deny'; message: string } {\n const output = input.output;\n if (output.action === 'declined' || output.action === 'cancelled') {\n return {\n behavior: 'deny',\n message: `The user ${output.action} the questions.`,\n };\n }\n\n const canonicalInput = toHarnessQuestionsInput(input.nativeInput);\n const answers = Object.fromEntries(\n canonicalInput.questions.flatMap((question, questionIndex) => {\n const answer = output.answers[question.id];\n if (answer == null) return [];\n const nativeQuestion = input.nativeInput.questions[questionIndex];\n return [\n [\n nativeQuestion.question,\n toClaudeCodeAnswer({\n nativeQuestion,\n optionIds: answer.optionIds,\n freeform: answer.freeform,\n }),\n ],\n ];\n }),\n );\n\n return {\n behavior: 'allow',\n updatedInput: { ...input.nativeInput, answers },\n };\n}\n\nfunction toClaudeCodeAnswer(input: {\n nativeQuestion: ClaudeCodeQuestion;\n optionIds: string[];\n freeform: string | undefined;\n}): string {\n if (input.freeform !== undefined) return input.freeform;\n const labels = input.optionIds.flatMap(optionId => {\n const index = positionalIdIndex({ id: optionId, prefix: 'option-' });\n const option =\n index == null ? undefined : input.nativeQuestion.options[index];\n return option == null ? [] : [option.label];\n });\n return input.nativeQuestion.multiSelect\n ? labels.join(', ')\n : (labels[0] ?? '');\n}\n\nfunction positionalIdIndex(input: {\n id: string;\n prefix: string;\n}): number | undefined {\n if (!input.id.startsWith(input.prefix)) return undefined;\n const oneBasedIndex = Number(input.id.slice(input.prefix.length));\n return Number.isInteger(oneBasedIndex) && oneBasedIndex > 0\n ? oneBasedIndex - 1\n : undefined;\n}\n"],"mappings":"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","names":["bridgeStateDir","pending","randomUUID","procEnv","stdout","randomUUID","toCommonName","randomUUID","procEnv","args","stdout"]}
|
|
1
|
+
{"version":3,"sources":["../../../harness/src/bridge/index.ts","../../../harness/src/bridge/harness-bridge-capability-unsupported-error.ts","../../src/bridge/compaction-latch.ts","../../src/bridge/index.ts","../../src/bridge/claude-code-system-prompt.ts","../../src/bridge/claude-skills-option.ts","../../src/bridge/create-emit-stream-event.ts","../../src/bridge/json-schema-to-zod.ts","../../src/bridge/tool-filtering.ts","../../src/bridge/question-tool.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, the in-memory event log +\n// monotonic `seq`, resume replay, and the lifecycle/meta files. Any number of\n// hosts may be connected; exactly one of them owns the event stream, and\n// `start`/`resume` transfer that ownership. The adapter supplies only `onStart`\n// (drive its CLI/SDK and translate to wire events) and lifecycle cleanup hooks.\n\nimport { appendFile, mkdir, writeFile } from 'node:fs/promises';\nimport { existsSync, readFileSync } from 'node:fs';\nimport { randomUUID } from 'node:crypto';\nimport { env as procEnv, pid, stdout } from 'node:process';\nimport type { ToolResultPart } from '@ai-sdk/provider-utils';\nimport { WebSocketServer, type WebSocket } from 'ws';\n\nexport { HarnessBridgeCapabilityUnsupportedError } from './harness-bridge-capability-unsupported-error';\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\nexport interface Experimental_BridgeUserMessage {\n readonly messageId: string;\n readonly text: string;\n accept(): void;\n reject(error: unknown): void;\n}\n\nexport interface Experimental_BridgeUserMessageQueue extends AsyncIterable<Experimental_BridgeUserMessage> {\n readonly pendingCount: number;\n close(error?: unknown): void;\n}\n\ntype InternalBridgeUserMessageQueue = Experimental_BridgeUserMessageQueue & {\n enqueue(input: { messageId: string; text: string }): void;\n};\n\ntype BridgeUserMessageResponse = {\n type: 'user-message-response';\n messageId: string;\n accepted: boolean;\n error?: { message: string };\n};\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 createBridgeUserMessageQueue(options: {\n respond(response: BridgeUserMessageResponse): void;\n}): InternalBridgeUserMessageQueue {\n const messages: Experimental_BridgeUserMessage[] = [];\n const waiters: Array<\n (result: IteratorResult<Experimental_BridgeUserMessage>) => void\n > = [];\n const entries = new Map<\n string,\n {\n response?: BridgeUserMessageResponse;\n reject(error: unknown): void;\n }\n >();\n let closed = false;\n let pendingCount = 0;\n\n const enqueue = (input: { messageId: string; text: string }): void => {\n const existing = entries.get(input.messageId);\n if (existing != null) {\n if (existing.response != null) {\n options.respond(existing.response);\n }\n return;\n }\n\n let settled = false;\n const settle = (response: BridgeUserMessageResponse): void => {\n if (settled) return;\n settled = true;\n pendingCount--;\n const entry = entries.get(input.messageId);\n if (entry != null) entry.response = response;\n options.respond(response);\n };\n const message: Experimental_BridgeUserMessage = {\n messageId: input.messageId,\n text: input.text,\n accept: () => {\n settle({\n type: 'user-message-response',\n messageId: input.messageId,\n accepted: true,\n });\n },\n reject: error => {\n settle({\n type: 'user-message-response',\n messageId: input.messageId,\n accepted: false,\n error: { message: formatBridgeError(error).message },\n });\n },\n };\n entries.set(input.messageId, {\n reject: message.reject,\n });\n pendingCount++;\n\n if (closed) {\n message.reject(\n new Error('The bridge turn is no longer accepting user messages.'),\n );\n return;\n }\n\n const waiter = waiters.shift();\n if (waiter != null) {\n waiter({ done: false, value: message });\n } else {\n messages.push(message);\n }\n };\n\n const close = (error?: unknown): void => {\n if (closed) return;\n closed = true;\n const reason =\n error ??\n new Error('The bridge turn ended before accepting the user message.');\n for (const entry of entries.values()) {\n if (entry.response == null) entry.reject(reason);\n }\n messages.length = 0;\n while (waiters.length > 0) {\n waiters.shift()!({ done: true, value: undefined });\n }\n };\n\n return {\n get pendingCount() {\n return pendingCount;\n },\n enqueue,\n close,\n [Symbol.asyncIterator]() {\n return {\n next: () => {\n const message = messages.shift();\n if (message != null) {\n return Promise.resolve({ done: false as const, value: message });\n }\n if (closed) {\n return Promise.resolve({\n done: true as const,\n value: undefined,\n });\n }\n return new Promise<IteratorResult<Experimental_BridgeUserMessage>>(\n resolve => {\n waiters.push(resolve);\n },\n );\n },\n };\n },\n };\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 input:\n | string\n | {\n toolCallId: string;\n matches?: (result: {\n output: unknown;\n isError?: boolean;\n toolResult?: ToolResultPart;\n }) => boolean;\n },\n ): Promise<{\n output: unknown;\n isError?: boolean;\n toolResult?: ToolResultPart;\n }>;\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 readonly experimental_userMessages: Experimental_BridgeUserMessageQueue;\n\n /** Aborts when the host sends `abort`. */\n readonly abortSignal: AbortSignal;\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 /**\n * Drive one prompt turn. Rejections surface to the host as an `error`\n * event.\n *\n * Contract: once `turn.abortSignal` fires, wind down promptly — turns are\n * serialized, and a replacement `start` waits up to\n * {@link turnTeardownGraceMs} for this promise to settle before it\n * proceeds anyway.\n */\n onStart(start: TStart, turn: BridgeTurn): Promise<void>;\n /**\n * How long a replacement `start` waits for the previous turn's teardown\n * after aborting it, in milliseconds. Turns are serialized so an aborted\n * turn cannot emit into its replacement's event log or overlap its runtime\n * process — but only within this bound: an adapter that does not settle\n * `onStart` after its abort signal fires forfeits the protection for that\n * boundary, and the new turn proceeds anyway rather than blocking forever.\n * The default of ten seconds exceeds the Claude bridge's five-second\n * hard-abort fallback.\n */\n turnTeardownGraceMs?: number;\n /**\n * Produce the adapter-defined runtime resume data for `stop`. Defaults to\n * `{}`.\n */\n onStop?(): unknown | Promise<unknown>;\n /**\n * Perform adapter-defined destruction before the bridge exits.\n */\n onDestroy?(): void | Promise<void>;\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 `stop` / `destroy`. 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 toolResult?: ToolResultPart;\n }\n | {\n type: 'tool-approval-response';\n approvalId: string;\n approved: boolean;\n reason?: string;\n }\n | { type: 'user-message'; messageId?: string; text: string }\n | { type: 'abort' }\n | { type: 'stop' }\n | { type: 'destroy' }\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 * `stop` / `destroy` 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, onStop, onDestroy } = options;\n const teardownGraceMs = options.turnTeardownGraceMs ?? 10_000;\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 /*\n * The one connection turn events stream to. A socket claims it by asking for\n * work — `start` (a turn) or `resume` (a catch-up) — never by connecting:\n * every event goes here alone, so claiming on connect would silence a turn\n * already streaming to someone else. Any number of sockets may be connected;\n * the others still exchange control frames, they just get no events.\n */\n let activeSocket: WebSocket | undefined;\n let isFirstTurn = true;\n let turnAbort: AbortController | undefined;\n let currentUserMessages: InternalBridgeUserMessageQueue | undefined;\n /**\n * Settles when the in-flight turn has fully wound down — `onStart`\n * returned or threw AND its completion state was recorded. `undefined`\n * between turns. A new `start` fences on this so turns never overlap.\n */\n let activeTurn: 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 in-flight 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 {\n resolve: (output: {\n output: unknown;\n isError?: boolean;\n toolResult?: ToolResultPart;\n }) => void;\n matches?: (output: {\n output: unknown;\n isError?: boolean;\n toolResult?: ToolResultPart;\n }) => boolean;\n }\n >();\n const bufferedToolResults: Array<{\n toolCallId: string;\n result: {\n output: unknown;\n isError?: boolean;\n toolResult?: ToolResultPart;\n };\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 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 /*\n * A new turn replaces the active one — but only after the active one\n * has fully wound down. Inbound frames are dispatched concurrently,\n * and the host settles a caller abort immediately, so a retry's\n * `start` can arrive while the aborted turn is still tearing down\n * (e.g. a graceful interrupt). Without this fence the old turn would\n * keep emitting into the new turn's cleared event log, two runtime\n * processes would run side by side, and the old turn's completion\n * would mark the bridge `waiting` underneath the new turn. Abort the\n * old turn to hasten its teardown; adapters are expected to bound\n * that teardown themselves (e.g. a hard-abort fallback), but the\n * runtime does not rely on it: the wait is capped by the teardown\n * grace period, after which the new turn proceeds anyway — the\n * pre-fence overlapping behavior — rather than hanging behind a\n * teardown that never settles.\n */\n for (;;) {\n const pendingTurn = activeTurn;\n if (pendingTurn == null) break;\n turnAbort?.abort();\n currentUserMessages?.close(\n new Error('A new bridge turn replaced the active turn.'),\n );\n let graceTimer: ReturnType<typeof setTimeout> | undefined;\n const settled = await Promise.race([\n pendingTurn.then(() => true as const),\n new Promise<false>(resolve => {\n graceTimer = setTimeout(() => resolve(false), teardownGraceMs);\n graceTimer.unref?.();\n }),\n ]);\n clearTimeout(graceTimer);\n if (!settled) break;\n }\n let turnFinished!: () => void;\n const thisTurn = new Promise<void>(resolve => (turnFinished = resolve));\n activeTurn = thisTurn;\n activeSocket = ws; // asking for a turn claims the event stream\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 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 userMessages = createBridgeUserMessageQueue({ respond: emit });\n const turn: BridgeTurn = {\n emit,\n requestToolResult: requestInput => {\n const request =\n typeof requestInput === 'string'\n ? { toolCallId: requestInput }\n : requestInput;\n const bufferedIndex = bufferedToolResults.findIndex(\n buffered =>\n buffered.toolCallId === request.toolCallId ||\n request.matches?.(buffered.result) === true,\n );\n if (bufferedIndex >= 0) {\n return Promise.resolve(\n bufferedToolResults.splice(bufferedIndex, 1)[0].result,\n );\n }\n return new Promise(resolve => {\n pendingToolResults.set(request.toolCallId, {\n resolve,\n matches: request.matches,\n });\n });\n },\n requestToolApproval: approvalId =>\n new Promise(resolve => {\n pendingToolApprovals.set(approvalId, resolve);\n }),\n experimental_userMessages: userMessages,\n abortSignal: turnAbort.signal,\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 = userMessages;\n try {\n await onStart(msg as TStart, turn);\n } catch (err) {\n emitError({ error: err, message: 'bridge turn failed' });\n } finally {\n userMessages.close();\n if (currentUserMessages === userMessages) {\n currentUserMessages = undefined;\n }\n // Only the still-active turn records completion: after a fence\n // timeout a replacement turn is already running, and this stale\n // completion must not mark the bridge waiting underneath it.\n if (activeTurn === thisTurn) {\n activeTurn = undefined;\n currentTurnState = 'waiting';\n void writeBridgeMeta('waiting');\n }\n turnFinished();\n }\n return;\n }\n case 'tool-result': {\n const result = {\n output: msg.output,\n isError: msg.isError,\n toolResult: msg.toolResult,\n };\n const exactPending = pendingToolResults.get(msg.toolCallId);\n const matchingPending =\n exactPending == null\n ? Array.from(pendingToolResults.entries()).find(\n ([, pending]) => pending.matches?.(result) === true,\n )\n : undefined;\n const pending = exactPending ?? matchingPending?.[1];\n const pendingId =\n exactPending != null ? msg.toolCallId : matchingPending?.[0];\n if (pending != null && pendingId != null) {\n pendingToolResults.delete(pendingId);\n pending.resolve(result);\n } else {\n bufferedToolResults.push({\n toolCallId: msg.toolCallId,\n result,\n });\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 const messageId = msg.messageId ?? randomUUID();\n if (currentUserMessages == null) {\n sendControl(ws, {\n type: 'user-message-response',\n messageId,\n accepted: false,\n error: { message: 'The bridge has no active turn to steer.' },\n });\n return;\n }\n if (ws !== activeSocket) {\n sendControl(ws, {\n type: 'user-message-response',\n messageId,\n accepted: false,\n error: {\n message: 'The connection does not own the active bridge turn.',\n },\n });\n return;\n }\n currentUserMessages.enqueue({\n messageId,\n text: msg.text,\n });\n return;\n }\n case 'abort':\n turnAbort?.abort();\n return;\n case 'resume':\n activeSocket = ws; // asking for a catch-up claims it too\n // Synchronous, so no event can slip out live ahead of the replayed tail.\n replay(ws, msg.lastSeenEventId);\n return;\n case 'destroy':\n currentTurnState = 'done';\n void writeBridgeMeta('done');\n await onDestroy?.();\n drainThenExit(ws, 1000, 'destroy');\n return;\n case 'stop': {\n currentTurnState = 'done';\n void writeBridgeMeta('done');\n const data = (await onStop?.()) ?? {};\n sendControl(ws, { type: 'bridge-stop', data });\n drainThenExit(ws, 1000, 'stop');\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 stop/destroy 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 // 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(ws, {\n type: 'bridge-hello',\n state: currentTurnState,\n lastSeq: seqCounter,\n capabilities: { experimental_userMessageResponses: true },\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(ws, {\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 stream owner's close matters; a socket that never claimed it,\n // or that a later `start`/`resume` displaced, closes as a no-op.\n // Crucially we do NOT abort the in-flight turn: it keeps running and its\n // events accumulate in the log for replay on reconnect.\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\n/*\n * Control frames answer the socket that sent the frame they reply to, so the\n * target is always explicit. Event streaming is the separate, stateful path\n * (`emit` → `activeSocket`); this one carries no state at all.\n */\nfunction sendControl(\n socket: WebSocket | undefined,\n message: Record<string, unknown>,\n): void {\n if (socket?.readyState === WS_OPEN) {\n try {\n socket.send(JSON.stringify(message));\n } catch {\n // best-effort\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","const name = 'AI_HarnessBridgeCapabilityUnsupportedError';\n\n/**\n * Signals an unsupported capability discovered inside a sandbox bridge.\n * `isInstance` also recognizes the serialized error shape received by the\n * host, where it can be translated to `HarnessCapabilityUnsupportedError`.\n */\nexport class HarnessBridgeCapabilityUnsupportedError extends Error {\n readonly harnessId?: string;\n readonly cause?: unknown;\n\n constructor({\n message,\n harnessId,\n cause,\n }: {\n message: string;\n harnessId?: string;\n cause?: unknown;\n }) {\n super(message);\n Object.defineProperty(this, 'name', { value: name });\n this.harnessId = harnessId;\n this.cause = cause;\n }\n\n static isInstance(\n error: unknown,\n ): error is HarnessBridgeCapabilityUnsupportedError {\n return (\n error != null &&\n typeof error === 'object' &&\n 'name' in error &&\n error.name === name &&\n 'message' in error &&\n typeof error.message === 'string'\n );\n }\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 type Experimental_BridgeUserMessage,\n type Experimental_BridgeUserMessageQueue,\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, env as procEnv, 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 type {\n HookCallback,\n HookJSONOutput,\n} from '@anthropic-ai/claude-agent-sdk';\nimport * as mcpServerModule from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { createClaudeCodeSystemPrompt } from './claude-code-system-prompt';\nimport { toClaudeSkillsOption } from './claude-skills-option';\nimport {\n createClaudeStreamEventState,\n createEmitStreamEvent,\n defaultUsage,\n emitFinishStep,\n finishApprovalStep,\n isExternalMcpTool,\n mapUsage,\n type ClaudeMessage,\n} from './create-emit-stream-event';\nimport { jsonSchemaToZodShape } from './json-schema-to-zod';\nimport {\n resolveInactiveNativeTools,\n resolveNativeTools,\n} from './tool-filtering';\nimport {\n claudeCodeQuestionKey,\n toClaudeCodeQuestionResult,\n toHarnessQuestionsInput,\n} from './question-tool';\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 | 'askUserQuestions';\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 AskUserQuestion: 'askUserQuestions',\n};\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: 'readonly',\n AskUserQuestion: 'readonly',\n ToolSearch: 'readonly',\n Bash: 'bash',\n Monitor: 'bash',\n};\n\nfunction toCommonName(nativeName: string): CommonBuiltinToolName | string {\n return NATIVE_TO_COMMON[nativeName] ?? nativeName;\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\n/**\n * The Claude session id most recently reported by the SDK, captured from the\n * message stream. Every turn in this bridge process may fork a new id (the\n * SDK's `continue`/`resume` create a new session linked to the previous one),\n * so the latest observation is the one a later resume must name.\n */\nlet lastClaudeSessionId: string | undefined;\n\nawait runBridge<StartMessage>({\n bridgeType: 'claude-code',\n bridgeStateDir,\n onStart: runTurn,\n // Claude Code's conversation state lives in the runtime's own store, keyed\n // by working directory. The resume payload names the exact conversation so a\n // later resume does not have to fall back to \"most recent in this workdir\".\n onStop: () =>\n lastClaudeSessionId == null ? {} : { claudeSessionId: lastClaudeSessionId },\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\n return {\n permissionMode:\n permissionMode === 'allow-all'\n ? 'bypassPermissions'\n : permissionMode === 'allow-edits'\n ? 'acceptEdits'\n : 'default',\n allowDangerouslySkipPermissions: permissionMode === 'allow-all',\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 ...(isExternalMcpTool(toolName) ? { dynamic: 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 createQuestionPreToolUseHook(input: {\n turn: BridgeTurn;\n emit: Emit;\n nativeToolCallNames: Map<string, string>;\n}): HookCallback {\n return async (hookInput, toolUseID): Promise<HookJSONOutput> => {\n if (\n hookInput.hook_event_name !== 'PreToolUse' ||\n hookInput.tool_name !== 'AskUserQuestion'\n ) {\n return {};\n }\n\n const nativeInput = hookInput.tool_input as Parameters<\n typeof toHarnessQuestionsInput\n >[0];\n const canonicalInput = toHarnessQuestionsInput(nativeInput);\n const toolCallId = toolUseID ?? hookInput.tool_use_id;\n input.nativeToolCallNames.set(toolCallId, hookInput.tool_name);\n input.emit({\n type: 'tool-call',\n toolCallId,\n toolName: 'askUserQuestions',\n nativeName: hookInput.tool_name,\n input: JSON.stringify(canonicalInput),\n providerExecuted: false,\n providerMetadata: {\n 'claude-code': {\n nativeRequest: nativeInput,\n },\n },\n });\n\n const questionKey = claudeCodeQuestionKey(nativeInput);\n const result = await input.turn.requestToolResult({\n toolCallId,\n matches: candidate => {\n const nativeRequest = candidate.toolResult?.providerOptions?.[\n 'claude-code'\n ]?.nativeRequest as\n | Parameters<typeof claudeCodeQuestionKey>[0]\n | undefined;\n return (\n nativeRequest != null &&\n claudeCodeQuestionKey(nativeRequest) === questionKey\n );\n },\n });\n const nativeResult = toClaudeCodeQuestionResult({\n nativeInput,\n output: result.output as Parameters<\n typeof toClaudeCodeQuestionResult\n >[0]['output'],\n });\n\n return {\n hookSpecificOutput: {\n hookEventName: 'PreToolUse',\n ...(nativeResult.behavior === 'allow'\n ? {\n permissionDecision: 'allow',\n updatedInput: {\n ...nativeResult.updatedInput,\n } as Record<string, unknown>,\n }\n : {\n permissionDecision: 'deny',\n permissionDecisionReason: nativeResult.message,\n }),\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 // A host abort prefers the SDK's graceful `interrupt()` — Esc semantics: the\n // in-flight turn is persisted to the session transcript and settles with an\n // interrupted result, so a later resume (including the user's own\n // `claude --resume`) still sees the work done before the interrupt. The hard\n // abort kills the CLI process and loses that turn's records, so it is only\n // the fallback — armed unconditionally, because aborting an already-settled\n // query is a no-op — and the immediate path when the abort arrives before\n // the query exists.\n let gracefulAbort: (() => void) | undefined;\n let hardAbortTimer: ReturnType<typeof setTimeout> | undefined;\n const onHostAbort = (): void => {\n if (gracefulAbort) {\n gracefulAbort();\n } else {\n abortCtl.abort();\n }\n };\n if (turn.abortSignal.aborted) {\n abortCtl.abort();\n } else {\n turn.abortSignal.addEventListener('abort', onHostAbort, { once: true });\n }\n\n const streamEventState = createClaudeStreamEventState();\n\n const mcpServers: Record<string, unknown> = { ...(start.mcpServers ?? {}) };\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);\n server.tool(\n tool.name,\n tool.description ?? '',\n shape,\n async (\n ...handlerArgs: [\n Record<string, unknown>,\n { requestId: string | number; _meta?: Record<string, unknown> },\n ]\n ) => {\n const [input, extra] = handlerArgs;\n const metadataToolCallId = extra._meta?.['claudecode/toolUseId'];\n const toolCallId =\n typeof metadataToolCallId === 'string'\n ? metadataToolCallId\n : 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 userMessages: turn.experimental_userMessages,\n abortSignal: abortCtl.signal,\n });\n const skillsOption = toClaudeSkillsOption(start.skills);\n const nativeTools = resolveNativeTools(start.builtinToolFiltering);\n const inactiveNativeTools = resolveInactiveNativeTools(\n start.builtinToolFiltering,\n );\n const permissionOptions = createPermissionOptions({\n start,\n inactiveNativeTools,\n turn,\n emit,\n finishApprovalStep: approvalId => {\n finishApprovalStep({ state: streamEventState, emit, approvalId });\n },\n nativeToolCallNames: streamEventState.nativeToolCallNames,\n approvalRequestedToolUseIds: streamEventState.approvalRequestedToolUseIds,\n });\n const questionPreToolUseHook = createQuestionPreToolUseHook({\n turn,\n emit,\n nativeToolCallNames: streamEventState.nativeToolCallNames,\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 ...(start.env !== undefined ? { env: { ...procEnv, ...start.env } } : {}),\n ...(skillsOption ? { skills: skillsOption } : {}),\n ...(nativeTools !== undefined ? { tools: nativeTools } : {}),\n ...(inactiveNativeTools.length > 0\n ? { disallowedTools: inactiveNativeTools }\n : {}),\n systemPrompt: createClaudeCodeSystemPrompt(start.instructions),\n thinking: start.thinking,\n ...(start.effort !== undefined ? { effort: start.effort } : {}),\n ...(start.responseFormat?.type === 'json' &&\n start.responseFormat.schema != null\n ? {\n outputFormat: {\n type: 'json_schema' as const,\n schema: start.responseFormat.schema,\n },\n }\n : {}),\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 PreToolUse: [\n {\n matcher: 'AskUserQuestion',\n hooks: [questionPreToolUseHook],\n },\n ],\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, most specific first.\n //\n // `resumeSessionId` names the exact conversation and is what a\n // cross-process resume should use: `continue` means \"most recent thread\n // in this workdir\", which silently picks the wrong one once anything\n // else has run there. The bridge also retains the id observed during its\n // previous query, so every later query stays pinned to that conversation\n // even when the host detached and reattached between turns. `resume` and\n // `continue` are mutually exclusive in the SDK.\n //\n // Otherwise the host can force-continue by setting `start.continue`,\n // and turns after the first fall back to the legacy cwd-based behavior\n // when no exact id was observed.\n ...((start.resumeSessionId ?? lastClaudeSessionId)\n ? { resume: start.resumeSessionId ?? lastClaudeSessionId }\n : start.continue === true || !turn.firstTurn\n ? { continue: true }\n : {}),\n ...permissionOptions,\n mcpServers,\n cwd: workdir,\n abortSignal: abortCtl.signal,\n },\n });\n\n gracefulAbort = () => {\n // Backstop for the whole teardown, not just the interrupt call: if the\n // stream has not settled five seconds after a graceful interrupt was\n // requested, fall back to the hard abort. Aborting an already-settled\n // query is a no-op, and `unref` keeps the timer from pinning the bridge\n // process open on its own.\n hardAbortTimer = setTimeout(() => abortCtl.abort(), 5000);\n hardAbortTimer.unref?.();\n void Promise.resolve()\n .then(() => q.interrupt())\n .catch(() => abortCtl.abort());\n };\n let turnUsage: Record<string, unknown> | undefined;\n let totalCostUsd: number | undefined;\n let emittedTerminalError = false;\n let emittedTerminalFinish = false;\n\n const emitTerminalError = (message: string | undefined): void => {\n const normalized = message?.trim();\n if (!normalized || emittedTerminalError || emittedTerminalFinish) return;\n streamEventState.observedTerminalError = normalized;\n emittedTerminalError = true;\n // A turn the host itself stopped ends with an error-shaped result by\n // construction (an interrupted query reports a diagnostic, not success);\n // reporting the host's own stop as a terminal error makes every clean\n // interrupt look like a malfunction. The host has already settled the\n // turn on its side.\n if (!turn.abortSignal.aborted) {\n turn.emitError({\n error: normalized,\n message: 'claude-code terminal error',\n });\n }\n queryInput.close();\n abortCtl.abort();\n };\n\n const emitStreamEvent = createEmitStreamEvent({\n state: streamEventState,\n emit,\n emitWarning: turn.emitWarning,\n emitTerminalError,\n onCompactionBoundary: boundary => compaction.onBoundary(boundary),\n toCommonName,\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 if (type === 'command_lifecycle') {\n queryInput.handleLifecycle(msg);\n }\n\n // Every SDK message carries the session id of the conversation it\n // belongs to. Track the latest so the stop payload and the terminal\n // finish metadata name the exact conversation.\n const sessionId = (msg as { session_id?: unknown }).session_id;\n if (typeof sessionId === 'string' && sessionId.length > 0) {\n lastClaudeSessionId = sessionId;\n }\n\n emitStreamEvent(msg);\n\n if (type === 'result') {\n if (msg.subtype === 'success') {\n // `success` does not mean the turn succeeded: the CLI flags a rejected\n // request with `is_error` and puts the message in `result`, which the\n // empty-result rescue below cannot catch.\n if (msg.is_error) {\n emitTerminalError(\n msg.result?.trim() ||\n streamEventState.observedTerminalError ||\n (typeof msg.api_error_status === 'number'\n ? `Claude Code reported an API error (HTTP ${msg.api_error_status})`\n : 'Claude Code reported a failed result'),\n );\n continue;\n }\n const emptyResult = !msg.result?.trim?.();\n if (emptyResult && streamEventState.observedTerminalError) {\n emitTerminalError(streamEventState.observedTerminalError);\n continue;\n }\n const usage = msg.usage ?? msg.message?.usage;\n const harnessUsage = mapUsage(usage);\n if (harnessUsage) turnUsage = addUsage(turnUsage, harnessUsage);\n if (typeof msg.total_cost_usd === 'number') {\n totalCostUsd = (totalCostUsd ?? 0) + msg.total_cost_usd;\n }\n if (\n start.responseFormat?.type === 'json' &&\n msg.structured_output !== undefined\n ) {\n const id = randomUUID();\n emit({ type: 'text-start', id });\n emit({\n type: 'text-delta',\n id,\n delta: JSON.stringify(msg.structured_output),\n });\n emit({ type: 'text-end', id });\n streamEventState.stepOpen = true;\n }\n if (streamEventState.stepOpen) {\n emitFinishStep({\n state: streamEventState,\n emit,\n usage: streamEventState.pendingStepUsage ?? harnessUsage,\n });\n }\n queryInput.observeResult();\n if (!queryInput.hasActiveUserMessages()) {\n queryInput.close();\n break;\n }\n } else {\n emitTerminalError(\n (Array.isArray(msg.errors) ? msg.errors.join('\\n') : undefined) ||\n streamEventState.observedTerminalError ||\n msg.result ||\n 'Unknown error',\n );\n }\n continue;\n }\n\n if (queryInput.hasObservedResult && !queryInput.hasActiveUserMessages()) {\n queryInput.close();\n break;\n }\n }\n } catch (err) {\n // Same reasoning as `emitTerminalError`: a throw after the host's own\n // abort (e.g. the hard-abort fallback killing the CLI mid-iteration, or\n // a rejected `interrupt()`) is the stop the host asked for, not a\n // malfunction. The host has already settled the turn on its side.\n if (\n !turn.abortSignal.aborted &&\n !(abortCtl.signal.aborted && emittedTerminalError)\n ) {\n turn.emitError({ error: err, message: 'claude-code turn failed' });\n }\n return;\n } finally {\n // The turn is over; disarm the host-abort path first. An abort of this\n // turn's signal arriving after this point (e.g. an `abort` message racing\n // the next `start`) must not interrupt the disposed query or arm the\n // hard-abort fallback timer for it.\n gracefulAbort = undefined;\n if (hardAbortTimer != null) clearTimeout(hardAbortTimer);\n turn.abortSignal.removeEventListener('abort', onHostAbort);\n queryInput.close();\n // Dispose the query explicitly: with streaming input the SDK keeps its\n // CLI subprocess alive for more user messages, and a turn that ended\n // through an interrupt or error path can otherwise leak that process —\n // observed as orphaned `claude` processes holding the very conversation\n // the next turn continues.\n try {\n await (q as { return?: (value?: unknown) => Promise<unknown> }).return?.(\n undefined,\n );\n } catch {\n // Best effort; the abort controller tears the process down otherwise.\n }\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 ?? streamEventState.stepUsage ?? defaultUsage(),\n ...(totalCostUsd !== undefined || lastClaudeSessionId !== undefined\n ? {\n harnessMetadata: {\n 'claude-code': {\n ...(totalCostUsd !== undefined ? { costUsd: totalCostUsd } : {}),\n // The conversation this turn belongs to, resumable outside the\n // SDK with `claude --resume <sessionId>` and captured by the\n // adapter for exact cross-process resume.\n ...(lastClaudeSessionId !== undefined\n ? { sessionId: lastClaudeSessionId }\n : {}),\n },\n },\n }\n : {}),\n });\n}\n\nfunction createQueryInput({\n initialUserMessage,\n userMessages,\n abortSignal,\n}: {\n initialUserMessage: string;\n userMessages: Experimental_BridgeUserMessageQueue;\n abortSignal: AbortSignal;\n}): {\n input: AsyncIterable<unknown>;\n close(error?: unknown): void;\n handleLifecycle(message: ClaudeMessage): void;\n hasActiveUserMessages(): boolean;\n observeResult(): void;\n readonly hasObservedResult: boolean;\n} {\n let closed = false;\n let observedResult = false;\n const submittedMessages = new Map<string, Experimental_BridgeUserMessage>();\n const close = (error?: unknown): void => {\n if (closed) return;\n closed = true;\n userMessages.close(error);\n };\n if (abortSignal.aborted) {\n close(abortSignal.reason);\n } else {\n abortSignal.addEventListener('abort', () => close(abortSignal.reason), {\n once: true,\n });\n }\n\n const toUserMessage = (options: {\n text: string;\n messageId: string;\n priority?: 'next';\n }): unknown => ({\n type: 'user',\n message: {\n role: 'user',\n content: [{ type: 'text', text: options.text }],\n },\n parent_tool_use_id: null,\n uuid: options.messageId,\n ...(options.priority == null ? {} : { priority: options.priority }),\n });\n\n const messageIterator = userMessages[Symbol.asyncIterator]();\n\n return {\n close,\n handleLifecycle: message => {\n const lifecycle = message as ClaudeMessage & {\n command_uuid?: string;\n state?: 'queued' | 'started' | 'completed' | 'cancelled' | 'discarded';\n };\n if (lifecycle.command_uuid == null || lifecycle.state == null) return;\n const submitted = submittedMessages.get(lifecycle.command_uuid);\n if (submitted == null) return;\n if (lifecycle.state === 'queued' || lifecycle.state === 'started') {\n submitted.accept();\n return;\n }\n if (lifecycle.state === 'cancelled' || lifecycle.state === 'discarded') {\n submitted.reject(\n new Error(`Claude Code ${lifecycle.state} the user message.`),\n );\n }\n submittedMessages.delete(lifecycle.command_uuid);\n },\n hasActiveUserMessages: () =>\n submittedMessages.size > 0 || userMessages.pendingCount > 0,\n observeResult: () => {\n observedResult = true;\n },\n get hasObservedResult() {\n return observedResult;\n },\n input: {\n [Symbol.asyncIterator]() {\n let sentInitial = false;\n return {\n async next() {\n if (closed || abortSignal.aborted) {\n return {\n value: undefined,\n done: true,\n } as IteratorResult<unknown>;\n }\n if (!sentInitial) {\n sentInitial = true;\n return {\n value: toUserMessage({\n text: initialUserMessage,\n messageId: randomUUID(),\n }),\n done: false,\n };\n }\n const nextMessage = await messageIterator.next();\n if (nextMessage.done) {\n return {\n value: undefined,\n done: true,\n } as IteratorResult<unknown>;\n }\n submittedMessages.set(\n nextMessage.value.messageId,\n nextMessage.value,\n );\n return {\n value: toUserMessage({\n text: nextMessage.value.text,\n messageId: nextMessage.value.messageId,\n priority: 'next',\n }),\n done: false,\n };\n },\n };\n },\n },\n };\n}\n\nfunction addUsage(\n total: Record<string, unknown> | undefined,\n usage: Record<string, unknown>,\n): Record<string, unknown> {\n if (total == null) return usage;\n const result: Record<string, unknown> = { ...total };\n for (const [key, value] of Object.entries(usage)) {\n const previous = result[key];\n if (typeof value === 'number' && typeof previous === 'number') {\n result[key] = previous + value;\n } else if (\n value != null &&\n previous != null &&\n typeof value === 'object' &&\n typeof previous === 'object' &&\n !Array.isArray(value) &&\n !Array.isArray(previous)\n ) {\n result[key] = addUsage(\n previous as Record<string, unknown>,\n value as Record<string, unknown>,\n );\n } else {\n result[key] = value;\n }\n }\n return result;\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 createClaudeCodeSystemPrompt(instructions?: string): {\n type: 'preset';\n preset: 'claude_code';\n append?: string;\n} {\n return {\n type: 'preset',\n preset: 'claude_code',\n ...(instructions ? { append: instructions } : {}),\n };\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","import { randomUUID } from 'node:crypto';\n\ntype Emit = (message: Record<string, unknown>) => void;\n\nexport type ClaudeMessage = {\n type?: string;\n subtype?: string;\n parent_tool_use_id?: string | null;\n model?: 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 usage?: Record<string, unknown>;\n content_block?: {\n type?: string;\n id?: string;\n name?: string;\n };\n delta?: {\n type?: string;\n text?: string;\n thinking?: string;\n partial_json?: string;\n };\n };\n message?: {\n content?: ReadonlyArray<MessageBlock>;\n usage?: Record<string, unknown>;\n };\n result?: string;\n /** Result-message error flags; distinct from `error_status` (`api_retry`). */\n is_error?: boolean;\n api_error_status?: number | null;\n errors?: ReadonlyArray<string>;\n usage?: Record<string, unknown>;\n total_cost_usd?: number;\n structured_output?: unknown;\n tool_use_result?: unknown;\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\nexport type ClaudeStreamEventState = {\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 nativeToolCallNames: Map<string, string>;\n approvalRequestedToolUseIds: Set<string>;\n partialBlocks: Map<number, PartialBlock>;\n stepUsage: Record<string, unknown> | undefined;\n pendingStepToolUseIds: Set<string>;\n pendingStepAssistantUsage: Record<string, unknown> | undefined;\n pendingStepDeltaUsage: Record<string, unknown> | undefined;\n pendingStepUsage: Record<string, unknown> | undefined;\n stepOpen: boolean;\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, so the duplicate `tool_result` block Claude\n * reports for the underlying native id must be suppressed.\n */\n mcpToolUseIds: Set<string>;\n externalMcpToolUseIds: Set<string>;\n structuredOutputToolUseIds: Set<string>;\n observedTerminalError: string | undefined;\n};\n\ntype PartialBlock =\n | { id: string; kind: 'text' | 'thinking' }\n | { id: string; kind: 'tool-input' };\n\nexport function createClaudeStreamEventState(): ClaudeStreamEventState {\n return {\n nativeToolCallNames: new Map(),\n approvalRequestedToolUseIds: new Set(),\n partialBlocks: new Map(),\n stepUsage: undefined,\n pendingStepToolUseIds: new Set(),\n pendingStepAssistantUsage: undefined,\n pendingStepDeltaUsage: undefined,\n pendingStepUsage: undefined,\n stepOpen: false,\n mcpToolUseIds: new Set(),\n externalMcpToolUseIds: new Set(),\n structuredOutputToolUseIds: new Set(),\n observedTerminalError: undefined,\n };\n}\n\nconst UNRECOVERABLE_API_RETRY_STATUSES = new Set([401, 403, 404]);\nconst HOST_TOOL_PREFIX = 'mcp__harness-tools__';\n\nexport function isExternalMcpTool(nativeName: string): boolean {\n return (\n nativeName.startsWith('mcp__') && !nativeName.startsWith(HOST_TOOL_PREFIX)\n );\n}\n\nexport function createEmitStreamEvent({\n state,\n emit,\n emitWarning,\n emitTerminalError,\n onCompactionBoundary,\n toCommonName,\n}: {\n state: ClaudeStreamEventState;\n emit: Emit;\n emitWarning: (warning: { message: string }) => void;\n emitTerminalError: (message: string | undefined) => void;\n onCompactionBoundary: (boundary: {\n trigger: 'manual' | 'auto';\n tokensBefore?: number;\n tokensAfter?: number;\n }) => void;\n toCommonName: (nativeName: string) => string;\n}): (event: ClaudeMessage) => void {\n let streamStarted = false;\n\n return msg => {\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}: ${msg.error ?? 'provider request failed'}`,\n );\n return;\n }\n\n emitWarning({ message: formatApiRetryWarning(msg) });\n return;\n }\n\n if (typeof msg.error === 'string' && msg.error.trim()) {\n state.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 return;\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 return;\n }\n\n if (type === 'system' && msg.subtype === 'compact_boundary') {\n const meta = msg.compact_metadata;\n if (meta) {\n onCompactionBoundary({\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 return;\n }\n\n // Messages emitted by a Task-tool subagent carry the parent tool-use id.\n // They belong to the subagent stream and must not affect the parent step,\n // including partial stream events that arrive before assistant messages.\n if (msg.parent_tool_use_id != null) {\n return;\n }\n\n if (type === 'stream_event') {\n handleStreamEvent({\n event: msg.event,\n state,\n send: emit,\n toCommonName,\n });\n return;\n }\n\n if (type === 'assistant' && msg.message?.content) {\n const usage = toUsageRecord(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 if (block.name === 'StructuredOutput') {\n state.structuredOutputToolUseIds.add(block.id);\n continue;\n }\n if (block.name.startsWith(HOST_TOOL_PREFIX)) {\n state.pendingStepToolUseIds.add(block.id);\n state.mcpToolUseIds.add(block.id);\n opensStep = true;\n continue;\n }\n state.nativeToolCallNames.set(block.id, block.name);\n if (block.name === 'AskUserQuestion') {\n state.pendingStepToolUseIds.add(block.id);\n opensStep = true;\n continue;\n }\n const dynamic = isExternalMcpTool(block.name);\n if (dynamic) state.externalMcpToolUseIds.add(block.id);\n if (state.approvalRequestedToolUseIds.has(block.id)) {\n continue;\n }\n state.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 ...(dynamic ? { dynamic: true } : {}),\n });\n }\n }\n if (opensStep || toolUseIds.length === 0) {\n state.stepOpen = true;\n if (usage) {\n state.pendingStepAssistantUsage = usage;\n updatePendingStepUsage(state);\n }\n }\n return;\n }\n\n if (type === 'user' && msg.message?.content) {\n const toolResultBlocks = msg.message.content.filter(\n block => block.type === 'tool_result',\n );\n const toolUseResult =\n toolResultBlocks.length === 1 ? msg.tool_use_result : undefined;\n\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 (state.structuredOutputToolUseIds.delete(block.tool_use_id)) {\n continue;\n }\n if (state.mcpToolUseIds.has(block.tool_use_id)) {\n state.mcpToolUseIds.delete(block.tool_use_id);\n state.pendingStepToolUseIds.delete(block.tool_use_id);\n continue;\n }\n state.approvalRequestedToolUseIds.delete(block.tool_use_id);\n const nativeName =\n state.nativeToolCallNames.get(block.tool_use_id) ?? 'unknown';\n state.nativeToolCallNames.delete(block.tool_use_id);\n const toolName = toCommonName(nativeName);\n const dynamic = state.externalMcpToolUseIds.delete(block.tool_use_id);\n const isError = !!block.is_error;\n const result =\n toolUseResult !== undefined\n ? toolUseResult\n : resolveToolResult({\n toolName,\n dynamic,\n isError,\n rawContent: block.content,\n });\n emit({\n type: 'tool-result',\n toolCallId: block.tool_use_id,\n toolName,\n result,\n isError,\n ...(dynamic ? { dynamic: true } : {}),\n });\n state.pendingStepToolUseIds.delete(block.tool_use_id);\n }\n }\n closeStepIfReady({ state, emit });\n }\n };\n}\n\nexport function finishApprovalStep({\n state,\n emit,\n approvalId,\n}: {\n state: ClaudeStreamEventState;\n emit: Emit;\n approvalId: string;\n}): void {\n state.stepOpen = true;\n state.pendingStepToolUseIds.delete(approvalId);\n closeStepIfReady({ state, emit });\n}\n\nexport function emitFinishStep({\n state,\n emit,\n usage,\n}: {\n state: ClaudeStreamEventState;\n emit: Emit;\n usage: Record<string, unknown> | undefined;\n}): void {\n emit({\n type: 'finish-step',\n finishReason: { unified: 'stop', raw: 'stop' },\n usage: usage ?? defaultUsage(),\n });\n state.stepUsage = usage ?? state.stepUsage;\n state.pendingStepAssistantUsage = undefined;\n state.pendingStepDeltaUsage = undefined;\n state.pendingStepUsage = undefined;\n state.pendingStepToolUseIds = new Set();\n state.stepOpen = false;\n}\n\nfunction closeStepIfReady({\n state,\n emit,\n}: {\n state: ClaudeStreamEventState;\n emit: Emit;\n}): void {\n if (\n !state.stepOpen ||\n state.pendingStepToolUseIds.size > 0 ||\n state.partialBlocks.size > 0\n ) {\n return;\n }\n emitFinishStep({ state, emit, usage: state.pendingStepUsage });\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,\n state,\n send,\n toCommonName,\n}: {\n event: ClaudeMessage['event'] | undefined;\n state: ClaudeStreamEventState;\n send: Emit;\n toCommonName: (nativeName: string) => string;\n}): void {\n if (!event) return;\n\n if (event.type === 'message_delta') {\n const usage = toUsageRecord(event.usage);\n if (usage) {\n state.pendingStepDeltaUsage = mergeNonNullUsage(\n state.pendingStepDeltaUsage,\n usage,\n );\n updatePendingStepUsage(state);\n }\n return;\n }\n\n if (typeof event.index !== 'number') return;\n const index = event.index;\n const partialBlocks = state.partialBlocks;\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 } else if (\n blockType === 'tool_use' &&\n typeof event.content_block?.id === 'string' &&\n typeof event.content_block.name === 'string'\n ) {\n const id = event.content_block.id;\n const nativeName = event.content_block.name;\n if (nativeName === 'StructuredOutput') {\n return;\n }\n if (nativeName === 'AskUserQuestion') {\n return;\n }\n const hostToolName = nativeName.startsWith(HOST_TOOL_PREFIX)\n ? nativeName.slice(HOST_TOOL_PREFIX.length)\n : undefined;\n const dynamic = isExternalMcpTool(nativeName);\n partialBlocks.set(index, { id, kind: 'tool-input' });\n send({\n type: 'tool-input-start',\n id,\n toolName: hostToolName ?? toCommonName(nativeName),\n providerExecuted: hostToolName === undefined,\n ...(dynamic ? { dynamic: true } : {}),\n });\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 } else if (\n block.kind === 'tool-input' &&\n event.delta?.type === 'input_json_delta' &&\n typeof event.delta.partial_json === 'string'\n ) {\n send({\n type: 'tool-input-delta',\n id: block.id,\n delta: event.delta.partial_json,\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 if (block.kind === 'thinking') {\n send({ type: 'reasoning-end', id: block.id });\n } else {\n send({ type: 'tool-input-end', id: block.id });\n }\n }\n}\n\nfunction toUsageRecord(usage: unknown): Record<string, unknown> | undefined {\n return usage != null && typeof usage === 'object'\n ? (usage as Record<string, unknown>)\n : undefined;\n}\n\nfunction mergeNonNullUsage(\n current: Record<string, unknown> | undefined,\n update: Record<string, unknown>,\n): Record<string, unknown> {\n const merged = { ...current };\n for (const [key, value] of Object.entries(update)) {\n if (value != null) {\n merged[key] = value;\n }\n }\n return merged;\n}\n\nfunction updatePendingStepUsage(state: ClaudeStreamEventState): void {\n const assistantUsage = state.pendingStepAssistantUsage;\n const deltaUsage = state.pendingStepDeltaUsage;\n state.pendingStepUsage = mapUsage(\n assistantUsage || deltaUsage\n ? { ...assistantUsage, ...deltaUsage }\n : undefined,\n );\n}\n\nfunction isTextEntry(entry: unknown): entry is { text?: unknown } {\n return entry != null && typeof entry === 'object' && 'text' in entry;\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 isTextEntry(entry) ? String(entry.text ?? '') : JSON.stringify(entry),\n )\n .join('');\n }\n return JSON.stringify(content);\n}\n\nfunction hasNonTextContent(content: unknown): boolean {\n return Array.isArray(content) && content.some(entry => !isTextEntry(entry));\n}\n\nfunction resolveToolResult({\n toolName,\n dynamic,\n isError,\n rawContent,\n}: {\n toolName: string;\n dynamic: boolean;\n isError: boolean;\n rawContent: unknown;\n}): unknown {\n /*\n * Claude Code's Bash tool does not report the command's real numeric exit\n * code — the SDK exposes only stdout/stderr text and an is_error flag.\n * Consumers (and the example UI) render bash failures from an `exitCode`\n * field on a structured result, the shape Codex's shell tool provides\n * natively. When Claude omits `tool_use_result`, derive a binary code from\n * is_error: 1 on failure, 0 on success. This fallback is a stand-in for\n * failed/succeeded, not the process's true exit status.\n */\n if (toolName === 'bash') {\n return { exitCode: isError ? 1 : 0, stdout: stringifyContent(rawContent) };\n }\n // Must precede the MCP branch: flattening a non-text block to base64 text\n // is not recoverable by parsing it back.\n if (hasNonTextContent(rawContent)) return rawContent;\n const content = stringifyContent(rawContent);\n return dynamic ? parseMcpToolResult(content) : content;\n}\n\nfunction parseMcpToolResult(content: string): unknown {\n try {\n const parsed = JSON.parse(content);\n // `JSON.parse` also succeeds on scalars; keep those as the string sent.\n return parsed !== null && typeof parsed === 'object' ? parsed : content;\n } catch {\n return content;\n }\n}\n\nexport function 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\nexport function 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","import { z } from 'zod/v4';\n\ntype JsonLiteral = string | number | boolean | null;\n\nexport type JsonSchemaObject = {\n type?: string | string[];\n description?: string;\n properties?: Record<string, JsonSchemaObject>;\n required?: string[];\n items?: JsonSchemaObject | JsonSchemaObject[];\n enum?: unknown[];\n const?: unknown;\n oneOf?: JsonSchemaObject[];\n anyOf?: JsonSchemaObject[];\n nullable?: boolean;\n};\n\ntype ZodShape = Record<string, z.ZodTypeAny>;\n\nexport function jsonSchemaToZodShape(input: unknown): ZodShape {\n const schema = isJsonSchemaObject(input) ? input : {};\n return toZodShape(schema);\n}\n\nfunction toZodShape(schema: JsonSchemaObject | undefined): ZodShape {\n if (!schema?.properties) return {};\n const required = new Set(schema.required ?? []);\n const shape: ZodShape = {};\n for (const [key, propSchema] of Object.entries(schema.properties)) {\n const propType = toZodType(propSchema);\n let propertyType = required.has(key) ? propType : propType.optional();\n if (propSchema.description) {\n propertyType = propertyType.describe(propSchema.description);\n }\n shape[key] = propertyType;\n }\n return shape;\n}\n\nfunction toZodType(schema: JsonSchemaObject | undefined): z.ZodTypeAny {\n if (!schema) return z.any();\n\n let zType =\n zodForConst(schema) ??\n zodForEnum(schema) ??\n zodForUnion(schema) ??\n zodForType(schema);\n\n if (isNullable(schema)) zType = zType.nullable();\n if (schema.description) zType = zType.describe(schema.description);\n return zType;\n}\n\nfunction zodForType(schema: JsonSchemaObject): z.ZodTypeAny {\n const types = getNonNullTypes(schema);\n if (types.length > 1) return z.any();\n if (Array.isArray(schema.type) && types.length === 0) return z.null();\n const type = types[0] ?? (schema.properties ? 'object' : undefined);\n\n switch (type) {\n case 'string':\n return z.string();\n case 'number':\n return z.number();\n case 'integer':\n return z.number().int();\n case 'boolean':\n return z.boolean();\n case 'array':\n return z.array(\n Array.isArray(schema.items) ? z.any() : toZodType(schema.items),\n );\n case 'object':\n return z.object(toZodShape(schema));\n case 'null':\n return z.null();\n default:\n return z.any();\n }\n}\n\nfunction zodForConst(schema: JsonSchemaObject): z.ZodTypeAny | undefined {\n if (!('const' in schema)) return undefined;\n return isJsonLiteral(schema.const) ? z.literal(schema.const) : z.any();\n}\n\nfunction zodForEnum(schema: JsonSchemaObject): z.ZodTypeAny | undefined {\n if (!Array.isArray(schema.enum)) return undefined;\n if (!schema.enum.every(isJsonLiteral)) return z.any();\n return zodForLiterals(schema.enum);\n}\n\nfunction zodForUnion(schema: JsonSchemaObject): z.ZodTypeAny | undefined {\n const unionSchemas = schema.anyOf ?? schema.oneOf;\n if (!unionSchemas || unionSchemas.length < 2) return undefined;\n\n const options = unionSchemas.map(item => toZodType(item)) as unknown as [\n z.ZodTypeAny,\n z.ZodTypeAny,\n ...z.ZodTypeAny[],\n ];\n return z.union(options);\n}\n\nfunction zodForLiterals(values: JsonLiteral[]): z.ZodTypeAny {\n if (values.length === 0) return z.any();\n if (values.length === 1) return z.literal(values[0]);\n\n const literals = values.map(value => z.literal(value)) as unknown as [\n z.ZodTypeAny,\n z.ZodTypeAny,\n ...z.ZodTypeAny[],\n ];\n return z.union(literals);\n}\n\nfunction getNonNullTypes(schema: JsonSchemaObject): string[] {\n return Array.isArray(schema.type)\n ? schema.type.filter(type => type !== 'null')\n : ([schema.type].filter(Boolean) as string[]);\n}\n\nfunction isNullable(schema: JsonSchemaObject): boolean {\n return (\n schema.nullable === true ||\n (Array.isArray(schema.type) && schema.type.includes('null'))\n );\n}\n\nfunction isJsonSchemaObject(input: unknown): input is JsonSchemaObject {\n return input != null && typeof input === 'object' && !Array.isArray(input);\n}\n\nfunction isJsonLiteral(value: unknown): value is JsonLiteral {\n return (\n value === null ||\n typeof value === 'string' ||\n typeof value === 'boolean' ||\n (typeof value === 'number' && Number.isFinite(value))\n );\n}\n","import type { StartMessage } from '../claude-code-bridge-protocol';\n\ntype BuiltinToolFiltering = StartMessage['builtinToolFiltering'];\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 askUserQuestions: 'AskUserQuestion',\n Skill: 'Skill',\n ToolSearch: 'ToolSearch',\n};\n\nconst PUBLIC_TOOL_NAMES = Object.keys(PUBLIC_TO_NATIVE);\n\nfunction toNativeName(toolName: string): string {\n return PUBLIC_TO_NATIVE[toolName] ?? toolName;\n}\n\nexport function resolveNativeTools(\n toolFiltering: BuiltinToolFiltering,\n): string[] | undefined {\n if (toolFiltering == null || toolFiltering.mode === 'deny') return undefined;\n return toolFiltering.toolNames.map(name => toNativeName(name));\n}\n\nexport function resolveInactiveNativeTools(\n toolFiltering: BuiltinToolFiltering,\n): string[] {\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","import type {\n HarnessV1QuestionsToolInput,\n HarnessV1QuestionsToolOutput,\n} from '@ai-sdk/harness';\nimport type { AskUserQuestionInput } from '@anthropic-ai/claude-agent-sdk/sdk-tools.js';\n\ntype ClaudeCodeQuestion = AskUserQuestionInput['questions'][number];\n\nexport function claudeCodeQuestionKey(\n nativeInput: AskUserQuestionInput,\n): string {\n return JSON.stringify(nativeInput.questions);\n}\n\nexport function toHarnessQuestionsInput(\n nativeInput: AskUserQuestionInput,\n): HarnessV1QuestionsToolInput {\n return {\n allowPartialAnswers: true,\n questions: nativeInput.questions.map((question, questionIndex) => ({\n id: `question-${questionIndex + 1}`,\n question: question.question,\n header: question.header,\n options: question.options.map((option, optionIndex) => ({\n id: `option-${optionIndex + 1}`,\n label: option.label,\n description: option.description,\n ...(option.preview !== undefined ? { preview: option.preview } : {}),\n })),\n allowMultiple: question.multiSelect,\n allowFreeForm: true,\n })),\n };\n}\n\nexport function toClaudeCodeQuestionResult(input: {\n nativeInput: AskUserQuestionInput;\n output: HarnessV1QuestionsToolOutput;\n}):\n | {\n behavior: 'allow';\n updatedInput: AskUserQuestionInput & { answers: Record<string, string> };\n }\n | { behavior: 'deny'; message: string } {\n const output = input.output;\n if (output.action === 'declined' || output.action === 'cancelled') {\n return {\n behavior: 'deny',\n message: `The user ${output.action} the questions.`,\n };\n }\n\n const canonicalInput = toHarnessQuestionsInput(input.nativeInput);\n const answers = Object.fromEntries(\n canonicalInput.questions.flatMap((question, questionIndex) => {\n const answer = output.answers[question.id];\n if (answer == null) return [];\n const nativeQuestion = input.nativeInput.questions[questionIndex];\n return [\n [\n nativeQuestion.question,\n toClaudeCodeAnswer({\n nativeQuestion,\n optionIds: answer.optionIds,\n freeform: answer.freeform,\n }),\n ],\n ];\n }),\n );\n\n return {\n behavior: 'allow',\n updatedInput: { ...input.nativeInput, answers },\n };\n}\n\nfunction toClaudeCodeAnswer(input: {\n nativeQuestion: ClaudeCodeQuestion;\n optionIds: string[];\n freeform: string | undefined;\n}): string {\n if (input.freeform !== undefined) return input.freeform;\n const labels = input.optionIds.flatMap(optionId => {\n const index = positionalIdIndex({ id: optionId, prefix: 'option-' });\n const option =\n index == null ? undefined : input.nativeQuestion.options[index];\n return option == null ? [] : [option.label];\n });\n return input.nativeQuestion.multiSelect\n ? labels.join(', ')\n : (labels[0] ?? '');\n}\n\nfunction positionalIdIndex(input: {\n id: string;\n prefix: string;\n}): number | undefined {\n if (!input.id.startsWith(input.prefix)) return undefined;\n const oneBasedIndex = Number(input.id.slice(input.prefix.length));\n return Number.isInteger(oneBasedIndex) && oneBasedIndex > 0\n ? oneBasedIndex - 1\n : undefined;\n}\n"],"mappings":"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","names":["bridgeStateDir","pending","randomUUID","procEnv","stdout","randomUUID","toCommonName","randomUUID","procEnv","args","stdout"]}
|
package/dist/index.js
CHANGED
|
@@ -442,7 +442,7 @@ var inboundMessageSchema = z.discriminatedUnion("type", [
|
|
|
442
442
|
]);
|
|
443
443
|
|
|
444
444
|
// src/version.ts
|
|
445
|
-
var VERSION = true ? "1.0.
|
|
445
|
+
var VERSION = true ? "1.0.117" : "0.0.0-test";
|
|
446
446
|
|
|
447
447
|
// src/claude-code-harness.ts
|
|
448
448
|
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.117",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
}
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@ai-sdk/harness": "1.0.
|
|
30
|
-
"@ai-sdk/provider-utils": "5.0.
|
|
29
|
+
"@ai-sdk/harness": "1.0.113",
|
|
30
|
+
"@ai-sdk/provider-utils": "5.0.42",
|
|
31
31
|
"ws": "^8.21.0"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
@@ -21,6 +21,7 @@ export type ClaudeMessage = {
|
|
|
21
21
|
event?: {
|
|
22
22
|
type?: string;
|
|
23
23
|
index?: number;
|
|
24
|
+
usage?: Record<string, unknown>;
|
|
24
25
|
content_block?: {
|
|
25
26
|
type?: string;
|
|
26
27
|
id?: string;
|
|
@@ -72,6 +73,8 @@ export type ClaudeStreamEventState = {
|
|
|
72
73
|
partialBlocks: Map<number, PartialBlock>;
|
|
73
74
|
stepUsage: Record<string, unknown> | undefined;
|
|
74
75
|
pendingStepToolUseIds: Set<string>;
|
|
76
|
+
pendingStepAssistantUsage: Record<string, unknown> | undefined;
|
|
77
|
+
pendingStepDeltaUsage: Record<string, unknown> | undefined;
|
|
75
78
|
pendingStepUsage: Record<string, unknown> | undefined;
|
|
76
79
|
stepOpen: boolean;
|
|
77
80
|
/*
|
|
@@ -97,6 +100,8 @@ export function createClaudeStreamEventState(): ClaudeStreamEventState {
|
|
|
97
100
|
partialBlocks: new Map(),
|
|
98
101
|
stepUsage: undefined,
|
|
99
102
|
pendingStepToolUseIds: new Set(),
|
|
103
|
+
pendingStepAssistantUsage: undefined,
|
|
104
|
+
pendingStepDeltaUsage: undefined,
|
|
100
105
|
pendingStepUsage: undefined,
|
|
101
106
|
stepOpen: false,
|
|
102
107
|
mcpToolUseIds: new Set(),
|
|
@@ -228,7 +233,7 @@ export function createEmitStreamEvent({
|
|
|
228
233
|
}
|
|
229
234
|
|
|
230
235
|
if (type === 'assistant' && msg.message?.content) {
|
|
231
|
-
const usage =
|
|
236
|
+
const usage = toUsageRecord(msg.message.usage);
|
|
232
237
|
const toolUseIds: string[] = [];
|
|
233
238
|
let opensStep = false;
|
|
234
239
|
for (const block of msg.message.content) {
|
|
@@ -274,7 +279,10 @@ export function createEmitStreamEvent({
|
|
|
274
279
|
}
|
|
275
280
|
if (opensStep || toolUseIds.length === 0) {
|
|
276
281
|
state.stepOpen = true;
|
|
277
|
-
if (usage)
|
|
282
|
+
if (usage) {
|
|
283
|
+
state.pendingStepAssistantUsage = usage;
|
|
284
|
+
updatePendingStepUsage(state);
|
|
285
|
+
}
|
|
278
286
|
}
|
|
279
287
|
return;
|
|
280
288
|
}
|
|
@@ -360,6 +368,8 @@ export function emitFinishStep({
|
|
|
360
368
|
usage: usage ?? defaultUsage(),
|
|
361
369
|
});
|
|
362
370
|
state.stepUsage = usage ?? state.stepUsage;
|
|
371
|
+
state.pendingStepAssistantUsage = undefined;
|
|
372
|
+
state.pendingStepDeltaUsage = undefined;
|
|
363
373
|
state.pendingStepUsage = undefined;
|
|
364
374
|
state.pendingStepToolUseIds = new Set();
|
|
365
375
|
state.stepOpen = false;
|
|
@@ -412,7 +422,21 @@ function handleStreamEvent({
|
|
|
412
422
|
send: Emit;
|
|
413
423
|
toCommonName: (nativeName: string) => string;
|
|
414
424
|
}): void {
|
|
415
|
-
if (!event
|
|
425
|
+
if (!event) return;
|
|
426
|
+
|
|
427
|
+
if (event.type === 'message_delta') {
|
|
428
|
+
const usage = toUsageRecord(event.usage);
|
|
429
|
+
if (usage) {
|
|
430
|
+
state.pendingStepDeltaUsage = mergeNonNullUsage(
|
|
431
|
+
state.pendingStepDeltaUsage,
|
|
432
|
+
usage,
|
|
433
|
+
);
|
|
434
|
+
updatePendingStepUsage(state);
|
|
435
|
+
}
|
|
436
|
+
return;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
if (typeof event.index !== 'number') return;
|
|
416
440
|
const index = event.index;
|
|
417
441
|
const partialBlocks = state.partialBlocks;
|
|
418
442
|
|
|
@@ -502,6 +526,35 @@ function handleStreamEvent({
|
|
|
502
526
|
}
|
|
503
527
|
}
|
|
504
528
|
|
|
529
|
+
function toUsageRecord(usage: unknown): Record<string, unknown> | undefined {
|
|
530
|
+
return usage != null && typeof usage === 'object'
|
|
531
|
+
? (usage as Record<string, unknown>)
|
|
532
|
+
: undefined;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
function mergeNonNullUsage(
|
|
536
|
+
current: Record<string, unknown> | undefined,
|
|
537
|
+
update: Record<string, unknown>,
|
|
538
|
+
): Record<string, unknown> {
|
|
539
|
+
const merged = { ...current };
|
|
540
|
+
for (const [key, value] of Object.entries(update)) {
|
|
541
|
+
if (value != null) {
|
|
542
|
+
merged[key] = value;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
return merged;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
function updatePendingStepUsage(state: ClaudeStreamEventState): void {
|
|
549
|
+
const assistantUsage = state.pendingStepAssistantUsage;
|
|
550
|
+
const deltaUsage = state.pendingStepDeltaUsage;
|
|
551
|
+
state.pendingStepUsage = mapUsage(
|
|
552
|
+
assistantUsage || deltaUsage
|
|
553
|
+
? { ...assistantUsage, ...deltaUsage }
|
|
554
|
+
: undefined,
|
|
555
|
+
);
|
|
556
|
+
}
|
|
557
|
+
|
|
505
558
|
function isTextEntry(entry: unknown): entry is { text?: unknown } {
|
|
506
559
|
return entry != null && typeof entry === 'object' && 'text' in entry;
|
|
507
560
|
}
|