@skaile/workspaces 0.10.0 → 0.11.0
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 +57 -0
- package/README.md +2 -2
- package/dist/asset-manager/index.js +2 -2
- package/dist/asset-manager/scaffold.js +1 -1
- package/dist/base-assets/connectors/deploy.js +1 -1
- package/dist/base-assets/connectors/devserver.js +1 -1
- package/dist/base-assets/connectors/flow/adapter.js +1 -1
- package/dist/base-assets/connectors/flow/run-flow.js +2 -2
- package/dist/base-assets/connectors/flow.js +1 -1
- package/dist/base-assets/connectors/git.js +1 -1
- package/dist/base-assets/connectors/gmail.js +1 -1
- package/dist/base-assets/connectors/local.js +1 -1
- package/dist/base-assets/connectors/mattermost.js +1 -1
- package/dist/base-assets/connectors/memory.js +1 -1
- package/dist/base-assets/connectors/minio.js +1 -1
- package/dist/base-assets/connectors/postgres.js +1 -1
- package/dist/base-assets/connectors/redis.js +1 -1
- package/dist/base-assets/connectors/s3.js +1 -1
- package/dist/base-assets/connectors/sharepoint.js +1 -1
- package/dist/base-assets/connectors/sqlite.js +1 -1
- package/dist/base-assets/connectors/static-server.js +1 -1
- package/dist/base-assets/connectors/tunnel.js +1 -1
- package/dist/base-assets/connectors/webdav.js +1 -1
- package/dist/base-assets/connectors/xstate-store.js +1 -1
- package/dist/base-assets/connectors/xstate.js +1 -1
- package/dist/base-assets/connectors/yjs.js +1 -1
- package/dist/bridge/drivers/claude-sdk.js +42 -1
- package/dist/bridge/drivers/claude-sdk.js.map +1 -1
- package/dist/bridge/drivers/codex.js +1 -1
- package/dist/bridge/drivers/echo.js +1 -1
- package/dist/bridge/drivers/omp.js +1 -1
- package/dist/bridge/index.js +2 -2
- package/dist/bridge/src/drivers/claude-sdk.d.ts +22 -0
- package/dist/bridge/src/drivers/claude-sdk.d.ts.map +1 -1
- package/dist/{chunk-YWQ3NGCS.js → chunk-BTKNSMLK.js} +2 -2
- package/dist/{chunk-YWQ3NGCS.js.map → chunk-BTKNSMLK.js.map} +1 -1
- package/dist/{chunk-I3S4BAAR.js → chunk-FEBLE7QX.js} +2 -2
- package/dist/{chunk-I3S4BAAR.js.map → chunk-FEBLE7QX.js.map} +1 -1
- package/dist/{chunk-BYZI6FMB.js → chunk-L6PKR6YY.js} +199 -85
- package/dist/chunk-L6PKR6YY.js.map +1 -0
- package/dist/{chunk-XIVOEUAF.js → chunk-OQIBHB4F.js} +2 -2
- package/dist/{chunk-XIVOEUAF.js.map → chunk-OQIBHB4F.js.map} +1 -1
- package/dist/{chunk-EPGHAOEU.js → chunk-UHSC75L7.js} +19 -3
- package/dist/chunk-UHSC75L7.js.map +1 -0
- package/dist/{chunk-OSJH4SPO.js → chunk-VMU2WEN7.js} +3 -3
- package/dist/{chunk-OSJH4SPO.js.map → chunk-VMU2WEN7.js.map} +1 -1
- package/dist/{chunk-S7RACIZI.js → chunk-YOFKTALB.js} +2 -2
- package/dist/{chunk-S7RACIZI.js.map → chunk-YOFKTALB.js.map} +1 -1
- package/dist/{chunk-NPNRWHCU.js → chunk-ZLLUIIZR.js} +3 -3
- package/dist/{chunk-NPNRWHCU.js.map → chunk-ZLLUIIZR.js.map} +1 -1
- package/dist/cli/index.js +9 -9
- package/dist/connectors/index.js +1 -1
- package/dist/connectors/src/connector-manager.d.ts +7 -0
- package/dist/connectors/src/connector-manager.d.ts.map +1 -1
- package/dist/runner/index.js +5 -5
- package/dist/runner/src/ai-credential-refresh.d.ts +74 -0
- package/dist/runner/src/ai-credential-refresh.d.ts.map +1 -0
- package/dist/runner/src/serve-credentials.d.ts +21 -0
- package/dist/runner/src/serve-credentials.d.ts.map +1 -1
- package/dist/runner/src/serve.d.ts +2 -2
- package/dist/runner/src/serve.d.ts.map +1 -1
- package/dist/sdk/asset-manager.js +2 -2
- package/dist/sdk/bridge.js +2 -2
- package/dist/sdk/index.js +5 -5
- package/dist/sdk/runner.js +5 -5
- package/dist/{setup-QIEPIYH2.js → setup-QAOUBECX.js} +4 -4
- package/dist/{setup-QIEPIYH2.js.map → setup-QAOUBECX.js.map} +1 -1
- package/dist/tui/index.js +5 -5
- package/dist/workspace-plugin/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-BYZI6FMB.js.map +0 -1
- package/dist/chunk-EPGHAOEU.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../bridge/src/drivers/scrub-transcript.ts","../../../bridge/src/drivers/claude-sdk.ts"],"names":["z","join","existsSync"],"mappings":"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","file":"claude-sdk.js","sourcesContent":["/**\n * Poisoned-transcript repair for the Claude Agent SDK driver.\n *\n * The Anthropic Messages API can permanently reject a conversation once its\n * persisted history contains a malformed content block. Because the bad block\n * lives in the SDK's on-disk JSONL transcript, every replayed turn fails with\n * the same `400 invalid_request_error` and the session is bricked with no\n * in-band recovery.\n *\n * This module repairs the transcript in place, covering three known poison\n * classes:\n *\n * 1. **Image `media_type` mismatch / omission.** An image block whose declared\n * `media_type` does not match — or is missing for — the actual bytes:\n * `... The image was specified using the image/png media type, but the\n * image appears to be a image/jpeg image`. Produced by the Claude Code\n * `Read` tool's format fallback (anthropics/claude-code#55338, #30124,\n * #33179). Repaired by sniffing the base64 magic bytes and correcting\n * `media_type`.\n * 2. **Oversized image.** An image whose decoded payload exceeds the API's\n * 5 MB per-image limit (anthropics/claude-code#34566). Replaced with a\n * text stub — the byte budget cannot be recovered any other way.\n * 3. **`cache_control` on an empty text block.** A text block carrying a\n * `cache_control` marker with empty/whitespace `text`\n * (anthropics/claude-code#59626). The `cache_control` field is stripped.\n *\n * Genuinely unidentifiable image blocks are also replaced with a text stub.\n *\n * Recovering by content scan (rather than parsing the API's `messages.N`\n * index) is deliberate: the index addresses the assembled API request, not a\n * JSONL line, and reproducing the SDK's message-assembly is fragile. A full\n * scan is index-free and repairs every poisoned block in one pass.\n *\n * @module\n */\n\nimport { existsSync, readdirSync, readFileSync, renameSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\n/**\n * Minimal logger shape accepted by {@link scrubPoisonedTranscript}. Compatible\n * with the bridge `Logger`, but narrowed so the helper stays unit-testable\n * without a real logger instance.\n *\n * @category Transcript repair\n */\nexport interface ScrubLogger {\n info(message: string, data?: Record<string, unknown>): void;\n warn(message: string, data?: Record<string, unknown>): void;\n}\n\n/**\n * Options for {@link scrubPoisonedTranscript}.\n *\n * @category Transcript repair\n */\nexport interface ScrubTranscriptOptions {\n /**\n * Claude Code config directory — the parent of `projects/`. Resolve from\n * `CLAUDE_CONFIG_DIR`, falling back to `~/.claude`.\n */\n configDir: string;\n /** SDK session id whose transcript JSONL should be repaired. */\n sessionId: string;\n /** Optional logger for diagnostics. */\n log?: ScrubLogger;\n}\n\n/**\n * Outcome of a {@link scrubPoisonedTranscript} pass.\n *\n * @category Transcript repair\n */\nexport interface ScrubTranscriptResult {\n /** The located JSONL transcript path, or `null` when not found. */\n filePath: string | null;\n /** Image blocks whose `media_type` was corrected (or filled in) to match the bytes. */\n corrected: number;\n /**\n * Image blocks replaced with a text stub — either unidentifiable bytes or a\n * payload over the API's 5 MB per-image limit.\n */\n stubbed: number;\n /** Empty text blocks from which a rejected `cache_control` marker was stripped. */\n cacheStripped: number;\n /**\n * `true` when the transcript was located, contained at least one poisoned\n * block, and was rewritten. `false` means nothing needed repair (or the\n * file was not found) — the caller should not retry the resume.\n */\n changed: boolean;\n}\n\n/** Text inserted in place of an image block whose format cannot be identified. */\nconst STUB_TEXT = \"[image removed: unprocessable image data]\";\n\n/** Text inserted in place of an image block that exceeds the API size limit. */\nconst STUB_TEXT_OVERSIZED = \"[image removed: image too large]\";\n\n/**\n * The Anthropic Messages API rejects any single image whose decoded payload\n * exceeds 5 MB. An image at or under this is left alone; a larger one is\n * stubbed (its byte budget cannot be recovered).\n */\nconst MAX_IMAGE_BYTES = 5 * 1024 * 1024;\n\n/**\n * Identify an image's media type from the leading bytes of its base64 payload.\n *\n * Recognises the four formats the Anthropic API accepts. Returns `null` when\n * the magic bytes match no known format — the caller treats that as a\n * genuinely corrupt block and stubs it.\n *\n * @param base64 - Base64-encoded image data (only the prefix is inspected).\n * @returns An `image/*` media type, or `null` when unrecognised.\n * @category Transcript repair\n */\nexport function sniffImageMediaType(base64: string): string | null {\n let buf: Buffer;\n try {\n // 32 base64 chars decode to 24 bytes — enough for the WebP check at 12.\n buf = Buffer.from(base64.slice(0, 32), \"base64\");\n } catch {\n return null;\n }\n if (buf.length < 4) {\n return null;\n }\n // JPEG — SOI marker `FF D8`. Third byte varies (and may be corrupt), so a\n // two-byte check is intentional: it still matches malformed JPEGs, which is\n // exactly the poison case the API flags as \"appears to be image/jpeg\".\n if (buf[0] === 0xff && buf[1] === 0xd8) {\n return \"image/jpeg\";\n }\n // PNG — `89 50 4E 47`.\n if (buf[0] === 0x89 && buf[1] === 0x50 && buf[2] === 0x4e && buf[3] === 0x47) {\n return \"image/png\";\n }\n // GIF — `47 49 46 38` (\"GIF8\").\n if (buf[0] === 0x47 && buf[1] === 0x49 && buf[2] === 0x46 && buf[3] === 0x38) {\n return \"image/gif\";\n }\n // WebP — `RIFF` at 0..3 and `WEBP` at 8..11.\n if (\n buf.length >= 12 &&\n buf[0] === 0x52 &&\n buf[1] === 0x49 &&\n buf[2] === 0x46 &&\n buf[3] === 0x46 &&\n buf[8] === 0x57 &&\n buf[9] === 0x45 &&\n buf[10] === 0x42 &&\n buf[11] === 0x50\n ) {\n return \"image/webp\";\n }\n return null;\n}\n\n/** A base64 image source on a content block (shape is SDK-defined). */\ninterface Base64ImageSource {\n type?: string;\n media_type?: string;\n data?: string;\n}\n\n/** Loosely-typed content block from a transcript message. */\ninterface ContentBlockLike {\n type?: string;\n source?: Base64ImageSource;\n content?: unknown;\n [k: string]: unknown;\n}\n\n/** Mutable counters threaded through one scrub pass. */\ninterface ScrubCounters {\n corrected: number;\n stubbed: number;\n cacheStripped: number;\n}\n\n/** Total repairs recorded in a counter set — used to detect per-line changes. */\nfunction totalChanges(c: ScrubCounters): number {\n return c.corrected + c.stubbed + c.cacheStripped;\n}\n\n/**\n * Repair a single content block. Returns the (possibly replaced) block.\n *\n * - A `tool_result` block recurses into its `content` array.\n * - A text block carrying a `cache_control` marker whose `text` is empty or\n * whitespace has the marker stripped (the API rejects `cache_control` on\n * empty text blocks).\n * - An image block whose decoded payload exceeds the API's 5 MB limit is\n * replaced with a text stub.\n * - An image block whose bytes match no known format is replaced with a text\n * stub (an image cannot simply be dropped — a `tool_result` must keep at\n * least one content entry, and a bare `image` block is replaced 1:1).\n * - An image block whose declared `media_type` mismatches (or is missing for)\n * the sniffed type is corrected in place.\n * - Every other block is returned untouched.\n */\nfunction scrubBlock(block: ContentBlockLike, counters: ScrubCounters): ContentBlockLike {\n if (block.type === \"tool_result\" && Array.isArray(block.content)) {\n return {\n ...block,\n content: (block.content as ContentBlockLike[]).map((inner) => scrubBlock(inner, counters)),\n };\n }\n\n // A `cache_control` marker on a text block whose text is empty or whitespace\n // is rejected by the API (\"cache_control cannot be set for empty text\n // blocks\"). Strip the marker — the empty block itself is harmless.\n if (block.type === \"text\" && block.cache_control != null) {\n const text = typeof block.text === \"string\" ? block.text : \"\";\n if (text.trim() === \"\") {\n counters.cacheStripped++;\n const clone = { ...block };\n delete clone.cache_control;\n return clone;\n }\n }\n\n if (\n block.type === \"image\" &&\n block.source?.type === \"base64\" &&\n typeof block.source.data === \"string\"\n ) {\n const data = block.source.data;\n // The API rejects any image whose decoded payload exceeds 5 MB. The byte\n // budget cannot be salvaged, so the whole block becomes a text stub.\n // base64 encodes 3 bytes per 4 chars, so decoded length ≈ len * 3 / 4.\n if (Math.floor((data.length * 3) / 4) > MAX_IMAGE_BYTES) {\n counters.stubbed++;\n return { type: \"text\", text: STUB_TEXT_OVERSIZED };\n }\n const sniffed = sniffImageMediaType(data);\n if (sniffed === null) {\n counters.stubbed++;\n return { type: \"text\", text: STUB_TEXT };\n }\n if (sniffed !== block.source.media_type) {\n counters.corrected++;\n return { ...block, source: { ...block.source, media_type: sniffed } };\n }\n }\n\n return block;\n}\n\n/**\n * Locate the JSONL transcript for `sessionId` under `<configDir>/projects/`.\n *\n * Claude Code encodes the project directory into the `projects/` subfolder\n * name; rather than reproduce that encoding, this scans every subfolder for\n * `<sessionId>.jsonl` (the session id is a UUID — globally unique).\n */\nfunction locateTranscript(configDir: string, sessionId: string): string | null {\n const projectsDir = join(configDir, \"projects\");\n if (!existsSync(projectsDir)) {\n return null;\n }\n let entries: string[];\n try {\n entries = readdirSync(projectsDir);\n } catch {\n return null;\n }\n for (const entry of entries) {\n const candidate = join(projectsDir, entry, `${sessionId}.jsonl`);\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n return null;\n}\n\n/**\n * Scan a Claude Code SDK transcript for image content blocks whose declared\n * `media_type` does not match the actual bytes, repair them, and atomically\n * rewrite the file.\n *\n * Safe to call after a turn has failed: the SDK query is dead at that point,\n * and the next resume re-reads the transcript from disk.\n *\n * @param opts - Config directory, session id, and an optional logger.\n * @returns A {@link ScrubTranscriptResult}. When `changed` is `true` the\n * caller may retry the resume with the same session id.\n * @category Transcript repair\n */\nexport function scrubPoisonedTranscript(opts: ScrubTranscriptOptions): ScrubTranscriptResult {\n const { configDir, sessionId, log } = opts;\n const result: ScrubTranscriptResult = {\n filePath: null,\n corrected: 0,\n stubbed: 0,\n cacheStripped: 0,\n changed: false,\n };\n\n const filePath = locateTranscript(configDir, sessionId);\n if (!filePath) {\n log?.warn(\"scrub-transcript: no transcript found\", { configDir, sessionId });\n return result;\n }\n result.filePath = filePath;\n\n let raw: string;\n try {\n raw = readFileSync(filePath, \"utf8\");\n } catch (err) {\n log?.warn(\"scrub-transcript: failed to read transcript\", {\n filePath,\n error: err instanceof Error ? err.message : String(err),\n });\n return result;\n }\n\n const counters: ScrubCounters = { corrected: 0, stubbed: 0, cacheStripped: 0 };\n // Split without filtering so blank lines / trailing newline survive verbatim.\n const lines = raw.split(\"\\n\");\n let dirty = false;\n\n const repaired = lines.map((line) => {\n if (line.trim() === \"\") {\n return line;\n }\n let entry: { message?: { content?: unknown } };\n try {\n entry = JSON.parse(line);\n } catch {\n return line; // Not JSON — leave untouched.\n }\n const content = entry.message?.content;\n if (!Array.isArray(content)) {\n return line;\n }\n const before = totalChanges(counters);\n const scrubbed = (content as ContentBlockLike[]).map((block) => scrubBlock(block, counters));\n if (totalChanges(counters) === before) {\n return line; // Nothing changed on this line.\n }\n dirty = true;\n return JSON.stringify({ ...entry, message: { ...entry.message, content: scrubbed } });\n });\n\n result.corrected = counters.corrected;\n result.stubbed = counters.stubbed;\n result.cacheStripped = counters.cacheStripped;\n\n if (!dirty) {\n return result;\n }\n\n // Atomic rewrite: write a sibling temp file, then rename over the original.\n const tmpPath = `${filePath}.scrub-tmp`;\n try {\n writeFileSync(tmpPath, repaired.join(\"\\n\"), \"utf8\");\n renameSync(tmpPath, filePath);\n } catch (err) {\n log?.warn(\"scrub-transcript: failed to rewrite transcript\", {\n filePath,\n error: err instanceof Error ? err.message : String(err),\n });\n return result;\n }\n\n result.changed = true;\n log?.info(\"scrub-transcript: repaired poisoned transcript\", {\n filePath,\n corrected: result.corrected,\n stubbed: result.stubbed,\n cacheStripped: result.cacheStripped,\n });\n return result;\n}\n","import { spawnSync } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type {\n SDKAssistantMessage,\n SDKMessage,\n SDKUserMessage,\n Options as SdkOptions,\n Query as SdkQuery,\n query as sdkQueryFn,\n} from \"@anthropic-ai/claude-agent-sdk\";\nimport type { Logger, TokenUsage } from \"@skaile/workspaces/types\";\n// Static namespace import so bun --compile bundles zod into the binary.\n// Dynamic import(\"zod\") via a string variable evades bun's static analysis\n// and fails at runtime inside /$bunfs/. The unwrap (zNS.z ?? zNS.default\n// ?? zNS) handles both bun's native ESM and vitest's CJS-interop resolver,\n// which return the zod namespace at different keys.\nimport * as zNS from \"zod\";\n\nconst zStatic: any = (zNS as any).z ?? (zNS as any).default ?? zNS;\n\nimport { dispatchCapability } from \"../capability-dispatch.js\";\nimport { AuthError, classifyClaudeSdkError } from \"../error-classifier.js\";\nimport { getBridgeLogger } from \"../logger.js\";\nimport { fetchProviderModels, type ModelEntry } from \"../models.js\";\nimport { DRIVER_CATALOG, registerDriver } from \"../registry.js\";\nimport {\n type AgentConfig,\n AgentDriver,\n type AgentEvent,\n type AgentMessage,\n type ContentBlock,\n type DriverInfo,\n type SlashCommandInfo,\n type ToolCall,\n} from \"../types.js\";\nimport { scrubPoisonedTranscript } from \"./scrub-transcript.js\";\n\n/**\n * Best-effort conversion of a JSON Schema object's top-level `properties` into\n * a `Record<string, ZodTypeAny>` accepted by `createSdkMcpServer`'s\n * `inputSchema`. The SDK only needs a shallow shape to advertise to the LLM —\n * deep validation is handled by the registry's Zod schema in `hooks.invoke()`.\n *\n * Returns null on schemas the bridge can't represent (anyOf at the root, etc.);\n * the caller falls back to a permissive `{ args: z.unknown().optional() }`.\n */\nfunction jsonSchemaToZodLoose(\n schema: Record<string, unknown>,\n z: any,\n): Record<string, unknown> | null {\n const props = (schema?.properties ?? null) as Record<string, any> | null;\n if (!props || typeof props !== \"object\") return null;\n const required = new Set(Array.isArray(schema?.required) ? (schema.required as string[]) : []);\n const out: Record<string, unknown> = {};\n for (const [key, def] of Object.entries(props)) {\n let zod: any;\n switch (def?.type) {\n case \"string\":\n zod = z.string();\n break;\n case \"number\":\n case \"integer\":\n zod = z.number();\n break;\n case \"boolean\":\n zod = z.boolean();\n break;\n case \"array\":\n zod = z.array(z.any());\n break;\n case \"object\":\n zod = z.record(z.string(), z.any());\n break;\n default:\n zod = z.any();\n }\n if (def?.description && typeof def.description === \"string\") {\n zod = zod.describe(def.description);\n }\n if (!required.has(key)) zod = zod.optional();\n out[key] = zod;\n }\n return out;\n}\n\n// The Claude Agent SDK bundles ajv which uses CJS require() internally.\n// Polyfill globalThis.require so it works in a pure ESM context.\n// In CJS (e.g. NestJS webpack bundle), require already exists — skip.\nif (typeof globalThis.require === \"undefined\") {\n try {\n // Dynamic eval avoids static parse errors in CJS bundlers\n // biome-ignore lint/security/noGlobalEval: intentional — CJS/ESM interop requires dynamic eval\n const metaUrl = (0, eval)(\"import.meta.url\");\n (globalThis as any).require = createRequire(metaUrl);\n } catch {\n // CJS context — require is already available via the module system\n }\n}\n\n/**\n * Agent driver for the Anthropic Claude Agent SDK.\n *\n * Runs the agent in-process — no subprocess is spawned. Anthropic models only.\n *\n * @remarks\n * **Lazy-loading** — `@anthropic-ai/claude-agent-sdk` is imported dynamically inside\n * `start()` so it remains an optional peer dependency. If the package is not installed\n * an actionable error is thrown. The CJS/ESM `require` polyfill at the top of this file\n * is required because the SDK bundles ajv which uses `require()` internally.\n *\n * **Session continuity** — each `prompt()` tries to feed into a live SDK query via\n * `streamInput()` (persistent multi-turn mode). When no live query exists it starts a\n * new one, applying a three-level resume chain:\n * 1. `resumeSessionId` from config (explicit caller resume)\n * 2. `sessionId` captured from the current driver lifetime\n * 3. `continue: true` (resume most recent session in cwd from disk)\n *\n * **Tool synthesis** — emits `tool_call` and `tool_execution_end` events that the\n * runner's activity tracker needs for file-change detection. These are not native SDK\n * events; they are synthesised from `assistant` and `user` SDK messages.\n *\n * **agentName** — maps to the `agent` SDK query option. The SDK reads\n * `.claude/agents/<agentName>.md` from `cwd` for model, tools, and system prompt.\n * Requires the agent file to have been rendered by `asset-manager` (claudeCodeRenderer)\n * during `skaile install`. Ignored by other drivers.\n *\n * **mcpServers** — `AgentConfig.mcpServers` passes in-process MCP server instances to\n * the SDK's `mcpServers` query option. Used by `workspaces/connectors` to inject\n * resource tools as native `tool_use`. Ignored by other drivers.\n *\n * @docLink packages/bridge/drivers#claude-sdk-driver\n */\nexport class ClaudeSdkDriver extends AgentDriver {\n readonly driverInfo: DriverInfo = {\n id: \"claude-sdk\",\n name: \"Claude Agent SDK\",\n modelAgnostic: false,\n supportsInBandAbort: true,\n };\n\n private readonly log: Logger = getBridgeLogger(\"claude-sdk\");\n private config: AgentConfig;\n private abortController: AbortController | null = null;\n private running = false;\n private sdk: { query: typeof sdkQueryFn } | null = null;\n private toolIdToName = new Map<string, string>();\n private prevText = \"\";\n\n /** Active query — may stay alive between turns if streamInput works. */\n private query: SdkQuery | null = null;\n /** Resolves when the current turn completes. */\n private turnResolve: (() => void) | null = null;\n /** Rejects when the current turn errors. */\n private turnReject: ((err: Error) => void) | null = null;\n /** Guards against duplicate agent_end emissions per turn. */\n private turnCompleted = false;\n /** Tracks whether a session has been started (for continue: true). */\n private hasSession = false;\n /** Session ID from the SDK — used for streamInput messages. */\n private sessionId = \"\";\n /** Cached slash commands discovered from the SDK. */\n private cachedCommands: SlashCommandInfo[] = [];\n /** Token usage from the most recent completed turn. */\n private _lastTokens: TokenUsage | null = null;\n /** Context window size from the most recent result's modelUsage. */\n private _contextWindow: number | null = null;\n /**\n * `true` when the active credential is a Claude Code OAuth subscription\n * (no API key in config) rather than a raw `ANTHROPIC_API_KEY`. Set on\n * every `startQuery` because the credential source can be reconfigured\n * at runtime via `configure`. Threaded into `classifyClaudeSdkError` so\n * upstream auth-shaped failures get a quota-aware hint when warranted.\n */\n private usingOauthCredential = false;\n\n /**\n * @param config - Driver configuration. Claude SDK-relevant fields:\n * - `cwd` — working directory; SDK session files and agent definitions are read from here.\n * - `model` — Anthropic model identifier (e.g. `\"claude-sonnet-4-5\"`). Defaults to `\"sonnet\"`.\n * - `apiKeys.anthropic` / `env.ANTHROPIC_API_KEY` — API key forwarded to the SDK query.\n * - `agentName` — name of a `.claude/agents/<name>.md` agent definition to use as identity.\n * - `mcpServers` — in-process MCP server instances injected as native `tool_use` tools.\n * - `systemPrompt` — appended to the `claude_code` preset system prompt.\n * - `resumeSessionId` — SDK session UUID to resume from a prior driver lifetime.\n * - `maxTurns` — maximum agentic turns per `prompt()` call (default: 15).\n */\n constructor(config: AgentConfig) {\n super();\n this.config = config;\n }\n\n override get runtimeSessionId(): string | undefined {\n return this.sessionId || undefined;\n }\n\n override reconfigure(patch: Partial<Pick<AgentConfig, \"model\" | \"thinking\" | \"effort\">>): void {\n if (patch.model !== undefined) this.config.model = patch.model;\n if (patch.thinking !== undefined) this.config.thinking = patch.thinking;\n if (patch.effort !== undefined) this.config.effort = patch.effort;\n }\n\n override getModel(): string | undefined {\n return this.config.model;\n }\n\n /**\n * Dynamically imports `@anthropic-ai/claude-agent-sdk`.\n *\n * @throws {Error} When the SDK package is not installed. Install it with\n * `bun add @anthropic-ai/claude-agent-sdk`.\n */\n public async start(): Promise<void> {\n try {\n this.sdk = await import(\"@anthropic-ai/claude-agent-sdk\");\n this.log.info(\"Claude Agent SDK loaded\");\n } catch {\n throw new Error(\n \"Claude Agent SDK not installed. Run: bun add @anthropic-ai/claude-agent-sdk\",\n );\n }\n }\n\n /**\n * Sends a user message to the Claude Agent SDK and resolves when the turn completes.\n *\n * If a live SDK query already exists (from a prior turn in this session) the message\n * is fed via `streamInput()` for efficient multi-turn continuity. Otherwise a new query\n * is started applying the resume chain described in the class-level remarks.\n *\n * @param message - Plain-text user prompt.\n * @throws {Error} When the SDK reports a fatal error that cannot be auto-recovered.\n *\n * @remarks\n * A single automatic retry is performed when the SDK throws\n * \"No conversation found with session ID …\" — a recoverable stale-resume error that\n * occurs after a container crash that prevented the SDK from flushing its session file.\n */\n public async prompt(message: string, _retryCount = 0): Promise<void> {\n if (!this.sdk) await this.start();\n\n // When the catch block decides to recurse (stale-resume or auth-error\n // retry), the recursive prompt() sets fresh turnResolve / turnReject on\n // `this` synchronously before its first `await`. If the outer finally\n // ran unconditionally it would clobber those handlers, leaving the\n // recursive turn's promise unresolvable — completeTurn would see\n // `this.turnResolve === null` and the recursive prompt() would hang\n // forever. The flag tells the finally to skip state-reset on the\n // retry path.\n //\n // EVERY retry branch in the catch block MUST set `retrying = true`\n // before returning the recursive call. Adding a third retry branch\n // without setting this flag will re-introduce a hard-to-diagnose\n // hang: the recursive prompt's turnPromise never resolves because\n // its resolver was nulled by this function's finally.\n let retrying = false;\n\n // Clear last-turn usage on entry, except when this is a retry recursion\n // (auth-error / stale-resume) — the retry shares the same logical turn\n // so we keep prior usage available until the SDK reports a fresh value.\n if (_retryCount === 0) this._lastTokens = null;\n\n this.running = true;\n this.prevText = \"\";\n this.turnCompleted = false;\n\n // Install the per-turn resolver before we send any input. Fast turns can\n // complete on the next microtask; if the result lands before turnResolve is\n // assigned, completeTurn() has nothing to resolve and prompt() hangs forever.\n const turnPromise = new Promise<void>((resolve, reject) => {\n this.turnResolve = resolve;\n this.turnReject = reject;\n });\n\n try {\n if (this.query) {\n // Try feeding into the live query via streamInput (persistent mode)\n const userMsg = this.buildUserMessage(message);\n this.query.streamInput(this.singleItemIterable(userMsg));\n } else {\n // No live query — start a new one (continue: true resumes session)\n await this.startQuery(message);\n }\n } catch (err) {\n this.turnResolve = null;\n this.turnReject = null;\n this.running = false;\n throw err;\n }\n\n // Wait for this turn to complete\n try {\n await turnPromise;\n } catch (err) {\n // The Claude Agent SDK throws \"No conversation found with session ID\n // <uuid>\" when we try to resume a session whose JSONL persistence was\n // lost — most commonly after a container crash that killed the query\n // mid-stream, so the driver captured the session id but the SDK never\n // flushed the session file to disk. The resume is permanently broken;\n // retry the prompt once with a fresh session so the user can continue\n // (and emit a non-fatal warning so the UI can surface that Claude's\n // short-term memory was dropped).\n const errMsg = err instanceof Error ? err.message : String(err);\n const isStaleResume =\n _retryCount === 0 && /No conversation found with session ID/i.test(errMsg);\n if (isStaleResume) {\n const staleId = this.config.resumeSessionId || this.sessionId || \"unknown\";\n this.log.warn(\"stale Claude Code session, retrying with a fresh session\", { staleId });\n // Structured event for the platform's resume outcome listener.\n // Emitted before the non-fatal error so the gateway records the\n // outcome regardless of what surfaces the error string.\n this.emit(\"agent-event\", {\n type: \"resume_failed\",\n resumeSessionId: staleId,\n reason: \"jsonl_lost\",\n } satisfies AgentEvent);\n this.emit(\"agent-event\", {\n type: \"error\",\n error:\n \"Claude Code session state was lost (likely a prior crash). Restarting with a fresh session — previous conversation context is not available.\",\n fatal: false,\n } satisfies AgentEvent);\n this.sessionId = \"\";\n this.hasSession = false;\n this.query = null;\n // Clear the config override too — leaving it in place would make the\n // retry re-trigger the same failure via startQuery's resume chain.\n this.config.resumeSessionId = undefined;\n this.turnResolve = null;\n this.turnReject = null;\n this.running = false;\n retrying = true;\n return this.prompt(message, _retryCount + 1);\n }\n // ── Poisoned-transcript self-heal ──────────────────────────────────\n // The Anthropic API permanently rejects a conversation once its history\n // contains a malformed content block. Every replayed turn 400s with\n // `invalid_request_error`, bricking the session with no in-band recovery.\n // `scrubPoisonedTranscript` repairs three known poison classes on the\n // on-disk SDK transcript: image `media_type` mismatch/omission, oversized\n // images, and `cache_control` on empty text blocks (Claude Code bugs\n // #55338 / #30124 / #33179 / #34566 / #59626). The resume is retried once.\n // Unlike the stale-resume path above, this preserves the conversation —\n // the same session id is resumed against the now-clean transcript.\n //\n // The detection regex is intentionally broad: if it matches a 400 the\n // scrubber cannot actually repair, `scrub.changed` stays `false`, this\n // branch falls through, and the original error is rethrown. The\n // `_retryCount === 0` guard caps recovery at a single retry regardless.\n const isPoisonedHistory =\n _retryCount === 0 &&\n /invalid_request_error/i.test(errMsg) &&\n /media[_ ]?type|could not process image|image exceeds|cache_control/i.test(errMsg);\n const poisonSessionId = this.config.resumeSessionId || this.sessionId;\n if (isPoisonedHistory && poisonSessionId) {\n const scrub = scrubPoisonedTranscript({\n configDir: this.resolveClaudeConfigDir(),\n sessionId: poisonSessionId,\n log: this.log,\n });\n if (scrub.changed) {\n this.log.warn(\"scrubbed poisoned Claude Code transcript, retrying resume\", {\n sessionId: poisonSessionId,\n corrected: scrub.corrected,\n stubbed: scrub.stubbed,\n cacheStripped: scrub.cacheStripped,\n });\n // Structured event for the platform's resume outcome listener.\n this.emit(\"agent-event\", {\n type: \"resume_failed\",\n resumeSessionId: poisonSessionId,\n reason: \"jsonl_poisoned\",\n } satisfies AgentEvent);\n const plural = (n: number) => (n === 1 ? \"\" : \"s\");\n const repairs: string[] = [];\n if (scrub.corrected > 0)\n repairs.push(`${scrub.corrected} media type${plural(scrub.corrected)} corrected`);\n if (scrub.stubbed > 0)\n repairs.push(`${scrub.stubbed} image${plural(scrub.stubbed)} removed`);\n if (scrub.cacheStripped > 0)\n repairs.push(\n `${scrub.cacheStripped} malformed block${plural(scrub.cacheStripped)} cleaned`,\n );\n this.emit(\"agent-event\", {\n type: \"error\",\n error: `Recovered corrupt data in the conversation history (${repairs.join(\", \")}). Retrying — earlier context is preserved.`,\n fatal: false,\n } satisfies AgentEvent);\n // Drop the dead query; keep sessionId / resumeSessionId so startQuery\n // resumes the now-clean transcript.\n this.query = null;\n this.turnResolve = null;\n this.turnReject = null;\n this.running = false;\n retrying = true;\n return this.prompt(message, _retryCount + 1);\n }\n this.log.warn(\"poisoned-transcript error but scrub found nothing to repair\", {\n sessionId: poisonSessionId,\n filePath: scrub.filePath,\n });\n }\n // ── Auth-error retry: ask the runner to refresh the credential, then\n // replay the in-flight prompt once. Centralising this inside the driver\n // means every `driver.prompt(...)` call site (serve handler, compaction\n // orchestrator, flow orchestrator, future call sites) gets self-healing\n // for free — no per-call-site wrapping. The runner provides the\n // `onAuthError` callback in `AgentConfig`; standalone CLI / forge\n // sessions leave it unset and surface the original `AuthError`.\n //\n // No idempotence gate around `onAuthError`: a single driver instance\n // owns exactly one consumer loop, which means at most one auth error\n // surfaces per turn. Concurrent prompt() calls feed the same query via\n // streamInput rather than running parallel consumer loops, so two\n // simultaneous 401s for the same driver are not physically possible.\n // The runner's previous in-flight Map (Step 9b of the original spec)\n // existed to coalesce the per-call-site wrappers and is unnecessary\n // here.\n //\n // Spec: `_devlog/specs/2026-05-07-unified-credential-mediation.md`\n // § \"Runner-side handling on 401\" (moved bridge-side).\n const isAuthError = err instanceof AuthError && _retryCount === 0;\n if (isAuthError && this.config.onAuthError) {\n this.log.info(\"auth error caught; invoking onAuthError refresh callback\");\n // Protocol v3: the callback returns a typed `CredentialMint`. A\n // success branch (`ok: true`) means the runner has provisioned a\n // fresh credential and the driver should retry. A failure branch\n // (`ok: false`) carries a stable `code` the runner already\n // surfaced upstream; the driver surfaces the original `AuthError`\n // to its caller without retrying.\n let refreshed = false;\n try {\n const mint = await this.config.onAuthError({\n configId: this.config.aiProviderConfigId ?? \"\",\n });\n refreshed = mint.ok;\n if (!mint.ok) {\n this.log.info(\"onAuthError reported refresh failure; surfacing AuthError\", {\n code: mint.code,\n });\n }\n } catch (refreshErr) {\n this.log.warn(\"onAuthError callback threw; surfacing original AuthError\", {\n error: refreshErr instanceof Error ? refreshErr.message : String(refreshErr),\n });\n }\n if (refreshed) {\n this.log.info(\"credentials refreshed; retrying prompt\");\n // Drop the dead SDK query so the next prompt() invocation creates a\n // fresh one (which reads the rewritten credentials file). Keep\n // sessionId / hasSession so the new query resumes the same Claude\n // SDK session.\n this.query = null;\n this.turnResolve = null;\n this.turnReject = null;\n this.running = false;\n retrying = true;\n return this.prompt(message, _retryCount + 1);\n }\n }\n throw err;\n } finally {\n // Skip state reset when we recursed — the inner prompt() owns the\n // turnResolve / turnReject handlers and we must not clobber them.\n // See the `retrying` flag declared at the top of this function.\n if (!retrying) {\n this.turnResolve = null;\n this.turnReject = null;\n this.running = false;\n }\n }\n }\n\n /**\n * Resolve the Claude Code config directory — the parent of `projects/` — from\n * the driver config, the process environment, or the `~/.claude` default.\n */\n private resolveClaudeConfigDir(): string {\n return (\n this.config.env?.CLAUDE_CONFIG_DIR ||\n process.env.CLAUDE_CONFIG_DIR ||\n join(homedir(), \".claude\")\n );\n }\n\n /**\n * Preventively repair the on-disk SDK transcript before a resume.\n *\n * The reactive {@link scrubPoisonedTranscript} pass in `prompt()` only fires\n * *after* a turn has already failed with a `400 invalid_request_error`,\n * costing a wasted round-trip and surfacing a scary (if non-fatal) error to\n * the user. A transcript poisoned in a prior driver lifetime — most commonly\n * an image block whose `media_type` does not match its bytes, produced by the\n * Claude Code `Read` tool on a PDF with embedded JPEGs (anthropics/claude-code\n * #55338) — would otherwise 400 on the very first resumed turn.\n *\n * Running the same magic-byte scrub *before* handing the transcript to the\n * SDK means a known poison class never reaches the API, so recovery is\n * invisible. This is regex-free (unlike the reactive gate) and idempotent: a\n * clean transcript is left byte-for-byte untouched. The reactive path remains\n * the safety net for poison introduced mid-turn within the current lifetime.\n */\n private preventivelyScrubTranscript(): void {\n const sessionId = this.config.resumeSessionId || this.sessionId;\n if (!sessionId) {\n return; // Fresh session — no transcript to repair yet.\n }\n try {\n const scrub = scrubPoisonedTranscript({\n configDir: this.resolveClaudeConfigDir(),\n sessionId,\n log: this.log,\n });\n if (scrub.changed) {\n this.log.warn(\"preventively scrubbed poisoned Claude Code transcript before resume\", {\n sessionId,\n corrected: scrub.corrected,\n stubbed: scrub.stubbed,\n cacheStripped: scrub.cacheStripped,\n });\n }\n } catch (err) {\n // A scrub failure must never block the turn — the reactive path still\n // covers a poisoned block if one survives to the API.\n this.log.warn(\"preventive transcript scrub failed; continuing\", {\n sessionId,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n private async startQuery(message: string): Promise<void> {\n this.abortController = new AbortController();\n\n // Repair any poisoned content block left in the on-disk transcript before\n // the SDK resumes it — converts the reactive post-400 self-heal into a\n // deterministic, user-invisible recovery. See the method doc for rationale.\n this.preventivelyScrubTranscript();\n\n const apiKey =\n this.config.apiKeys?.anthropic ||\n this.config.env?.ANTHROPIC_API_KEY ||\n process.env.ANTHROPIC_API_KEY;\n\n // When no apiKey is configured the SDK falls back to OAuth credentials\n // discovered via `settingSources: [\"user\"]` (i.e. `~/.claude/.credentials.json`).\n // The driver remembers this so the error classifier can branch on the\n // credential type — auth-shaped failures from OAuth subscriptions\n // overwhelmingly correlate with quota/rate-limit, not invalid tokens.\n this.usingOauthCredential = !apiKey;\n\n const claudePath = this.findClaudeBinary();\n\n const options: SdkOptions = {\n cwd: this.config.cwd,\n // Load project + user settings so .claude/skills/ are discovered\n settingSources: [\"user\", \"project\"],\n // Use full Claude Code tool preset so skills, agents, etc. work\n tools: { type: \"preset\", preset: \"claude_code\" },\n permissionMode: \"bypassPermissions\",\n allowDangerouslySkipPermissions: true,\n abortController: this.abortController,\n model: this.config.model || \"sonnet\",\n maxTurns: this.config.maxTurns ?? 15,\n includePartialMessages: true,\n // Thinking mode — maps simple string config to SDK ThinkingConfig objects\n ...(this.config.thinking ? { thinking: this.mapThinkingConfig(this.config.thinking) } : {}),\n // Reasoning effort — passed directly to the SDK\n ...(this.config.effort ? { effort: this.config.effort } : {}),\n hooks: {},\n stderr: (data: string) => this.log.warn(\"claude stderr\", { line: data.trim() }),\n ...(claudePath ? { pathToClaudeCodeExecutable: claudePath } : {}),\n ...(this.config.systemPrompt\n ? {\n systemPrompt: {\n type: \"preset\",\n preset: \"claude_code\",\n append: this.config.systemPrompt,\n },\n }\n : {}),\n // ── Session continuity ────────────────────────────────────────────────\n // Three-level fallback ensures the right session is always resumed:\n // resumeSessionId — caller explicitly wants this session (skaile resume)\n // sessionId — a session was already started this driver lifetime (multi-turn)\n // continue: true — resume the most recent session in cwd (between restarts)\n // (none) — start fresh\n ...(this.config.resumeSessionId\n ? { resume: this.config.resumeSessionId }\n : this.sessionId\n ? { resume: this.sessionId }\n : this.hasSession\n ? { continue: true }\n : {}),\n // ── Connector tool injection ──────────────────────────────────────────\n // In-process MCP servers from ConnectorManager (buildSdkConnectorTools in resources.ts).\n // These expose skaile.yaml connectors as native tool_use calls inside the session.\n // omp does not use this — it falls back to `skaile res <id> <op>` CLI commands\n // documented in the system prompt section (buildConnectorPromptSection).\n //\n // Protocol v2: when `config.capabilities` is provided, the runner's\n // CapabilityRegistry contributes an additional `skaile-capabilities`\n // synthetic MCP server alongside any pre-existing `mcpServers`. Tool\n // calls into that server route back through `hooks.invoke()` so the\n // registry's per-handler logger fires and fire-and-forget / render\n // semantics apply uniformly.\n ...(await this.buildEffectiveMcpServers()),\n // ── Main-agent handoff ────────────────────────────────────────────────\n // agentName (from AgentConfig) is the equivalent of `claude --agent <name>`.\n // The SDK reads .claude/agents/<agentName>.md from the cwd; that file was\n // rendered by asset-manager (claudeCodeRenderer) during `skaile install`.\n // Its YAML frontmatter sets model / tools / maxTurns; its markdown body is the\n // assembled system prompt (SOUL + fragments + RULES + abilities + contracts).\n // Omitting agentName uses Claude Code's default identity (no custom agent file).\n ...(this.config.agentName ? { agent: this.config.agentName } : {}),\n // Tool restrictions from agent.yaml — always include a wildcard allow-entry for each\n // injected MCP server so connector tools aren't silently blocked by an allowlist.\n ...this.buildToolRestrictions(),\n };\n\n this.log.debug(\"query start\", {\n model: this.config.model || \"default\",\n session: this.config.resumeSessionId || this.sessionId || this.config.sessionId || \"new\",\n });\n\n const { query } = this.sdk!;\n const queryArgs: { prompt: string; options: SdkOptions; apiKey?: string } = {\n prompt: message,\n options,\n };\n if (apiKey) queryArgs.apiKey = apiKey;\n\n this.query = query(queryArgs);\n this.consumeMessages();\n }\n\n override getSlashCommands(): SlashCommandInfo[] {\n return this.cachedCommands;\n }\n\n /**\n * Compose the MCP servers passed to the SDK query. Merges the legacy\n * `config.mcpServers` (connectors / workspace plugin / declarative skaile.yaml\n * entries) with a synthetic `skaile-capabilities` server built from the\n * runner-provided {@link BridgeCapabilityHooks} when present.\n *\n * Returns an empty options patch when neither source is configured, so legacy\n * v1 sessions remain unaffected.\n */\n private async buildEffectiveMcpServers(): Promise<Pick<SdkOptions, \"mcpServers\">> {\n const out: Record<string, unknown> = {};\n if (this.config.mcpServers) {\n Object.assign(out, this.config.mcpServers);\n }\n\n const hooks = this.config.capabilities;\n if (hooks) {\n const capServer = await this.buildCapabilityMcpServer();\n if (capServer) {\n out[\"skaile-capabilities\"] = capServer;\n }\n }\n\n return Object.keys(out).length > 0 ? { mcpServers: out as SdkOptions[\"mcpServers\"] } : {};\n }\n\n /**\n * Build the synthetic MCP server that exposes registered capabilities to the\n * Claude Agent SDK. Lazy-imports `createSdkMcpServer` from the SDK and `zod`\n * (an SDK peer) since both are optional peers of this bridge.\n *\n * Returns null when the SDK or zod is unavailable, or when the registry\n * exposes no tools — leaving the legacy `mcpServers` untouched.\n */\n private async buildCapabilityMcpServer(): Promise<unknown | null> {\n const hooks = this.config.capabilities;\n if (!hooks) return null;\n const tools = hooks.composeTools();\n if (tools.length === 0) return null;\n\n let sdk: any;\n try {\n sdk = await import(\"@anthropic-ai/claude-agent-sdk\");\n } catch {\n this.log.warn(\"claude-agent-sdk unavailable; cannot build capability MCP server\");\n return null;\n }\n // Static import below at module scope ensures bun --compile bundles zod\n // into the binary; dynamic import(\"zod\") via a string variable evades\n // bun's static analysis and fails at runtime inside /$bunfs/.\n const z: any = zStatic;\n\n // Build per-tool entries. Schemas arrive from the registry as JSON Schema\n // (Zod -> z.toJSONSchema in `defineCapability`). The Claude SDK accepts\n // either a Zod object or a record of Zod fields; we mirror the existing\n // `buildSdkConnectorTools` path which uses an inputSchema record. The full\n // input contract is enforced server-side by `hooks.invoke()` (Zod parse).\n const sdkTools = tools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n // Pass through the JSON Schema object directly. The SDK forwards it to\n // the LLM as the function parameter spec. Concrete validation runs in\n // `hooks.invoke()`, not the SDK.\n inputSchema: jsonSchemaToZodLoose(tool.parameters, z) ?? { args: z.unknown().optional() },\n handler: async (input: unknown) => {\n const callId = `cap-${Date.now()}-${Math.floor(Math.random() * 1e6)}`;\n try {\n const dispatch = await dispatchCapability(hooks, callId, tool.name, input, (err) =>\n this.log.warn(\"background capability handler failed\", {\n name: tool.name,\n error: String(err),\n }),\n );\n const text =\n typeof dispatch.result === \"string\"\n ? dispatch.result\n : JSON.stringify(dispatch.result ?? {});\n return { content: [{ type: \"text\" as const, text }] };\n } catch (err: any) {\n return {\n content: [{ type: \"text\" as const, text: `Error: ${err?.message ?? String(err)}` }],\n isError: true,\n };\n }\n },\n }));\n\n return sdk.createSdkMcpServer({ name: \"skaile-capabilities\", tools: sdkTools });\n }\n\n /** Fetch and cache slash commands from the SDK query. */\n private async fetchSlashCommands(): Promise<void> {\n if (!this.query) return;\n try {\n const commands = await this.query.supportedCommands();\n this.cachedCommands = commands.map((c) => ({\n name: c.name,\n description: c.description,\n argumentHint: c.argumentHint || undefined,\n }));\n this.emit(\"agent-event\", {\n type: \"commands_available\",\n commands: this.cachedCommands,\n } satisfies AgentEvent);\n this.log.debug(\"discovered slash commands\", { count: this.cachedCommands.length });\n } catch (err) {\n this.log.warn(\"failed to fetch slash commands\", { error: String(err) });\n }\n }\n\n /**\n * Background loop — consumes the query's async generator continuously.\n * The generator stays alive between turns; streamInput() feeds new messages.\n * If it ends unexpectedly, query is nulled so the next prompt() restarts.\n */\n private async consumeMessages(): Promise<void> {\n // Fetch slash commands in the background once the query is live\n this.fetchSlashCommands();\n\n try {\n for await (const msg of this.query!) {\n if (this.abortController?.signal.aborted) break;\n\n // Capture session info from first message\n const sessionId = \"session_id\" in msg ? msg.session_id : undefined;\n if (sessionId) {\n if (!this.hasSession) {\n this.hasSession = true;\n this.log.debug(\"session id assigned\", { sessionId });\n }\n this.sessionId = sessionId;\n }\n\n this.handleSdkMessage(msg);\n\n // result = turn boundary — but only complete the turn when the\n // result was NOT an error. The Claude Agent SDK occasionally emits\n // `{type: \"result\", subtype: \"success\", is_error: true, errors: []}`\n // when an upstream API call (e.g. a 401) made the run fail; the\n // actual error text arrives ~200 ms later as a thrown exception\n // from this iterator. If we resolve the turn here on the\n // is_error result, the consumer-error catch below fires with\n // `turnReject` already null, the bridge's auth-retry path in\n // `prompt()` never runs, and the user sees a fatal 401. By\n // skipping `completeTurn` for is_error results, the turn stays\n // pending until the thrown exception lands in the catch and\n // `failTurn(AuthError)` rejects the promise with the real error.\n //\n // Spec: `_devlog/specs/2026-05-07-unified-credential-mediation.md`.\n if (msg.type === \"result\" && !(msg as { is_error?: boolean }).is_error) {\n this.completeTurn();\n }\n }\n } catch (err: unknown) {\n const error = err instanceof Error ? err : new Error(String(err));\n if (error.name === \"AbortError\" || this.abortController?.signal.aborted) {\n this.log.info(\"aborted\");\n } else {\n const detail = classifyClaudeSdkError({\n errors: [error.message],\n oauthCredential: this.usingOauthCredential,\n });\n this.log.error(\"consumer error\", {\n message: error.message,\n category: detail.category,\n retryable: detail.retryable,\n });\n // Promote auth-shaped failures to a structured AuthError subclass so\n // the runner's 401-mediation handler can `instanceof`-discriminate\n // without parsing strings. Other categories surface as plain Error.\n const surfaced = detail.category === \"auth\" ? new AuthError(detail) : error;\n this.failTurn(surfaced, detail);\n }\n } finally {\n this.log.debug(\"query generator ended\");\n this.completeTurn();\n this.query = null;\n }\n }\n\n /**\n * Signal the current turn as done — idempotent per turn.\n *\n * Same defensive ordering as {@link failTurn}: settle the turn promise\n * before emitting `agent_end` so a misbehaving listener cannot trap the\n * promise in a pending state. See failTurn's docblock for the production\n * incident that motivated this pattern.\n */\n private completeTurn(): void {\n if (this.turnCompleted) return;\n this.turnCompleted = true;\n if (this.turnResolve) {\n this.turnResolve();\n this.turnResolve = null;\n this.turnReject = null;\n }\n try {\n this.emit(\"agent-event\", { type: \"agent_end\" } satisfies AgentEvent);\n } catch (emitErr) {\n this.log.warn(\"agent-event listener threw during completeTurn; suppressing\", {\n error: emitErr instanceof Error ? emitErr.message : String(emitErr),\n });\n }\n }\n\n /**\n * Signal the current turn as failed. When a structured `detail` is\n * supplied, the AgentEvent carries the category + hint so downstream\n * consumers (normalizer → runner → platform → frontend) can surface a\n * useful diagnosis instead of the raw upstream string.\n *\n * Reject ordering: `turnReject()` runs FIRST, then the agent-event is\n * emitted. `EventEmitter#emit` calls listeners synchronously; if any\n * listener throws (transport.send on a closed socket, normalizer bug,\n * compaction tracking error, etc.) the throw would otherwise propagate\n * out of failTurn before `turnReject` can run, leaving `await\n * turnPromise` pending forever and silently hanging `driver.prompt(...)`\n * — which in turn prevents the runner's `onAuthError` callback from\n * firing on stale-token 401s. Settling the promise first guarantees the\n * caller transitions even if the listener chain misbehaves; the emit is\n * wrapped in try/catch so a listener failure cannot leak out.\n *\n * Spec: `_devlog/specs/2026-05-07-unified-credential-mediation.md`\n * § \"Runner-side handling on 401\" (the AI 401 mediation path that\n * exposed this hang).\n */\n private failTurn(err: Error, detail?: import(\"../types.js\").AgentError): void {\n if (this.turnReject) {\n this.turnReject(err);\n this.turnResolve = null;\n this.turnReject = null;\n }\n try {\n this.emit(\"agent-event\", {\n type: \"error\",\n error: err.message,\n ...(detail ? { detail } : {}),\n } satisfies AgentEvent);\n } catch (emitErr) {\n this.log.warn(\"agent-event listener threw during failTurn; suppressing\", {\n error: emitErr instanceof Error ? emitErr.message : String(emitErr),\n });\n }\n }\n\n // ---------------------------------------------------------------------------\n // Message handling\n // ---------------------------------------------------------------------------\n\n private handleSdkMessage(msg: SDKMessage): void {\n // SDKRateLimitEvent — claude.ai subscription rate-limit telemetry. Surfaced\n // as a structured warning log so the debug pane and CLI logs show that the\n // upstream limiter is degrading. We do NOT promote `allowed_warning` to a\n // user-visible error; only `rejected` aligns with a turn-blocking failure\n // and that path emits its own `error` event when the SDK returns the\n // result.\n const maybeRateLimit = msg as unknown as {\n type?: string;\n rate_limit_info?: {\n status?: string;\n rateLimitType?: string;\n utilization?: number;\n resetsAt?: number;\n };\n };\n if (maybeRateLimit.type === \"rate_limit_event\" && maybeRateLimit.rate_limit_info) {\n const info = maybeRateLimit.rate_limit_info;\n this.log.warn(\"upstream rate-limit telemetry\", {\n status: info.status,\n type: info.rateLimitType,\n utilization: info.utilization,\n resetsAt: info.resetsAt,\n });\n // Don't emit an agent-event for warning levels — the user only needs to\n // hear about it on `rejected`, which the result handler already covers.\n return;\n }\n\n if (msg.type === \"assistant\") {\n const agentMsg = this.mapAssistantMessage(msg);\n\n this.emit(\"agent-event\", { type: \"message_start\", message: agentMsg } satisfies AgentEvent);\n\n if (agentMsg.toolCalls) {\n for (const tc of agentMsg.toolCalls) {\n this.emit(\"agent-event\", {\n type: \"tool_call\",\n name: tc.name,\n tool: { name: tc.name },\n input: tc.input,\n });\n }\n }\n\n this.prevText = \"\";\n this.emit(\"agent-event\", { type: \"message_end\", message: agentMsg } satisfies AgentEvent);\n } else if (msg.type === \"stream_event\") {\n const event = msg.event;\n if (\n event?.type === \"content_block_delta\" &&\n event.delta?.type === \"text_delta\" &&\n event.delta.text\n ) {\n const delta = event.delta.text;\n this.prevText += delta;\n const agentMsg: AgentMessage = {\n role: \"assistant\",\n content: [{ type: \"text\", text: this.prevText }],\n };\n this.emit(\"agent-event\", {\n type: \"message_update\",\n message: agentMsg,\n _textDelta: delta,\n } satisfies AgentEvent as any);\n }\n } else if (msg.type === \"user\") {\n const toolResults = this.mapToolResults(msg);\n for (const result of toolResults) {\n this.emit(\"agent-event\", {\n type: \"tool_execution_end\",\n toolName: result.toolName,\n });\n }\n if (toolResults.length > 0) {\n this.emit(\"agent-event\", { type: \"turn_end\", toolResults } satisfies AgentEvent);\n }\n } else if (msg.type === \"result\") {\n // Capture token usage from the result message. Anthropic separates\n // fresh prompt input from cached/cache-creation tokens — surface all\n // four to consumers that want a complete picture.\n const usage = (msg as any).usage as\n | {\n input_tokens?: number;\n output_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n }\n | undefined;\n if (usage) {\n const tokens: TokenUsage = {};\n if (typeof usage.input_tokens === \"number\") tokens.inputTokens = usage.input_tokens;\n if (typeof usage.output_tokens === \"number\") tokens.outputTokens = usage.output_tokens;\n if (typeof usage.cache_read_input_tokens === \"number\")\n tokens.cacheReadTokens = usage.cache_read_input_tokens;\n if (typeof usage.cache_creation_input_tokens === \"number\")\n tokens.cacheCreationTokens = usage.cache_creation_input_tokens;\n this._lastTokens = tokens;\n }\n const modelUsage = (msg as any).modelUsage as\n | Record<string, { contextWindow?: number }>\n | undefined;\n if (modelUsage) {\n const first = Object.values(modelUsage)[0];\n if (first?.contextWindow) this._contextWindow = first.contextWindow;\n }\n\n // Branch on `is_error` BEFORE `subtype === \"success\"`. The Claude Agent\n // SDK occasionally emits result messages where `subtype === \"success\"`\n // AND `is_error === true` AND `errors === []` — observed in production\n // when an upstream `authentication_error` from the Anthropic API made\n // the SDK fail the turn but still tag it as a \"successful run\" because\n // the agent loop itself (the SDK process) terminated without a process\n // crash. The actual 401 surfaces ~200 ms later as a thrown exception\n // in the for-await iterator. Without this guard, `handleSdkMessage`\n // takes the success branch on subtype, `consumeMessages` calls\n // `completeTurn` (resolving the turn promise), and the subsequent\n // throw lands in the consumer-error catch with `turnReject` already\n // null — the bridge's auth-retry catch in `prompt()` never runs and\n // the user sees a fatal 401. Treating any `is_error: true` result as\n // an error (regardless of subtype) routes through `failTurn` so the\n // turn promise rejects with a structured `AuthError` and the runner's\n // `onAuthError` callback can refresh the credential.\n //\n // Spec: `_devlog/specs/2026-05-07-unified-credential-mediation.md`.\n if (msg.subtype === \"success\" && !msg.is_error) {\n if (msg.result) {\n const agentMsg: AgentMessage = {\n role: \"assistant\",\n content: msg.result,\n };\n this.emit(\"agent-event\", { type: \"message_end\", message: agentMsg } satisfies AgentEvent);\n }\n this.emit(\"agent-event\", {\n type: \"result\",\n subtype: msg.subtype,\n summary: msg.result ?? \"Task completed\",\n costUsd: msg.total_cost_usd ?? 0,\n ...(this._lastTokens ? { tokens: this._lastTokens } : {}),\n } as AgentEvent);\n } else {\n // The else branch is now reachable for two cases:\n // 1) `subtype !== 'success'` (the legacy SDKResultError shape)\n // 2) `subtype === 'success' && is_error === true` (production\n // observation 2026-05-09 — an upstream 401 makes the SDK tag\n // the run as a successful exit code while still flagging\n // `is_error: true`; see the success-branch guard above).\n // Case (2) carries no `errors` field on the typed\n // `SDKResultSuccess` variant, so we coerce through the loose\n // result shape to read it uniformly.\n const looseMsg = msg as { errors?: string[]; is_error?: boolean; terminal_reason?: string };\n const errors: string[] = looseMsg.errors?.length ? looseMsg.errors : [];\n if (looseMsg.is_error) {\n // SDKResultError carries `terminal_reason` and `subtype` we use\n // to override the raw text — `blocking_limit` is authoritatively\n // a quota issue even when the surrounding errors[] reads as auth.\n const detail = classifyClaudeSdkError({\n errors,\n terminalReason: (msg as { terminal_reason?: string }).terminal_reason,\n subtype: msg.subtype,\n oauthCredential: this.usingOauthCredential,\n });\n this.log.error(\"turn ended with error\", {\n subtype: msg.subtype,\n terminalReason: (msg as { terminal_reason?: string }).terminal_reason,\n errorsCount: errors.length,\n category: detail.category,\n retryable: detail.retryable,\n });\n const errorText = errors.join(\"; \") || `Agent stopped: ${msg.subtype}`;\n // Auth-shaped result errors (`authentication_error` structured body\n // or 401 in the error text) surface as a thrown `AuthError` so the\n // runner's 401-mediation handler can `instanceof`-discriminate\n // without parsing strings. `failTurn` emits the `error` AgentEvent\n // itself, so we route through it on the auth path to avoid emitting\n // a duplicate `error` event before the turn rejects.\n //\n // When `errors` is empty AND the classifier could not pin a\n // category, the SDK has signalled \"the turn failed but the actual\n // error text is coming via a thrown exception ~200 ms later\"\n // (observed in production for upstream 401s). We must NOT emit a\n // placeholder error event here — the consumer-error catch below\n // will surface the real error with the correct classification, and\n // emitting a stub now would leak `Agent stopped: success` to the\n // frontend before the real 401 arrives. The matching guard in\n // `consumeMessages` skips `completeTurn` for is_error results so\n // the turn stays pending until the thrown exception lands.\n //\n // Spec: `_devlog/specs/2026-05-07-unified-credential-mediation.md`\n // § \"Runner-side handling on 401\".\n if (detail.category === \"auth\") {\n this.failTurn(new AuthError({ ...detail, message: errorText }), detail);\n } else if (errors.length > 0) {\n // Real error info present — surface it normally.\n this.emit(\"agent-event\", {\n type: \"error\",\n error: errorText,\n detail,\n } satisfies AgentEvent);\n }\n // is_error + empty errors → defer to consumer-error catch.\n }\n this.emit(\"agent-event\", {\n type: \"result\",\n subtype: msg.subtype,\n errors,\n } as AgentEvent);\n }\n }\n }\n\n // ---------------------------------------------------------------------------\n // Helpers\n // ---------------------------------------------------------------------------\n\n /** Build an SDKUserMessage for streamInput. */\n private buildUserMessage(text: string): SDKUserMessage {\n return {\n type: \"user\",\n message: {\n role: \"user\",\n content: text,\n },\n parent_tool_use_id: null,\n session_id: this.sessionId,\n };\n }\n\n /** Wrap a single value as an AsyncIterable that yields once. */\n private async *singleItemIterable<T>(item: T): AsyncIterable<T> {\n yield item;\n }\n\n private mapAssistantMessage(msg: SDKAssistantMessage): AgentMessage {\n const contentBlocks: ContentBlock[] = [];\n const toolCalls: ToolCall[] = [];\n const content = msg.message.content;\n\n if (Array.isArray(content)) {\n for (const block of content) {\n if (block.type === \"text\") {\n contentBlocks.push({ type: \"text\", text: block.text });\n } else if (block.type === \"tool_use\") {\n contentBlocks.push({\n type: \"tool_use\",\n id: block.id,\n name: block.name,\n input: block.input,\n });\n toolCalls.push({ id: block.id, name: block.name, input: block.input });\n this.toolIdToName.set(block.id, block.name);\n } else if (block.type === \"thinking\") {\n contentBlocks.push({ type: \"thinking\", text: block.thinking });\n }\n }\n }\n\n return {\n role: \"assistant\",\n content: contentBlocks,\n toolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n };\n }\n\n private mapToolResults(msg: SDKUserMessage): AgentMessage[] {\n const results: AgentMessage[] = [];\n const content = msg.message.content;\n\n if (Array.isArray(content)) {\n for (const block of content) {\n if (block.type === \"tool_result\") {\n results.push({\n role: \"tool\",\n content:\n typeof block.content === \"string\" ? block.content : JSON.stringify(block.content),\n toolName: this.toolIdToName.get(block.tool_use_id) ?? block.tool_use_id,\n isError: block.is_error,\n });\n }\n }\n }\n\n return results;\n }\n\n /**\n * Requests the current SDK query to stop processing via `query.interrupt()` and\n * signals the underlying `AbortController`. The driver remains usable after abort.\n *\n * @remarks Best-effort: if `interrupt()` throws (e.g. query already ended) the\n * error is silently swallowed and the abort signal is still sent.\n */\n public async abort(): Promise<void> {\n if (this.query) {\n try {\n await this.query.interrupt();\n } catch {\n /* best effort */\n }\n }\n if (this.abortController) {\n this.abortController.abort();\n }\n }\n\n /** `true` while the driver is processing a `prompt()` call. */\n get isRunning(): boolean {\n return this.running;\n }\n\n /**\n * Closes the active SDK query and resets all session state.\n *\n * The driver instance must not be reused after `kill()`. Session IDs are cleared,\n * so a new `ClaudeSdkDriver` will start a fresh session.\n */\n public kill(): void {\n if (this.query) {\n try {\n this.query.close();\n } catch {\n /* best effort */\n }\n this.query = null;\n }\n this.abortController?.abort();\n this.running = false;\n this.sessionId = \"\";\n this.hasSession = false;\n }\n\n override async listModels(): Promise<ModelEntry[]> {\n const apiKey =\n this.config.apiKeys?.anthropic ||\n this.config.env?.ANTHROPIC_API_KEY ||\n process.env.ANTHROPIC_API_KEY;\n if (!apiKey) return [];\n const result = await fetchProviderModels(\"anthropic\", apiKey);\n return result.ok ? (result.models as ModelEntry[]) : [];\n }\n\n override getTokenUsage(): TokenUsage | null {\n return this._lastTokens;\n }\n\n override getContextWindow(): number | null {\n return this._contextWindow;\n }\n\n async resetSession(): Promise<void> {\n if (this.query) {\n try {\n this.query.close();\n } catch {\n /* ignore */\n }\n this.query = null;\n }\n this.abortController?.abort();\n this.sessionId = \"\";\n this.hasSession = false;\n this._lastTokens = null;\n this._contextWindow = null;\n }\n\n /**\n * Build allowedTools / disallowedTools options from AgentConfig.tools.\n *\n * When an allowlist is active, automatically prepend a wildcard entry for\n * every configured MCP server (e.g. `mcp__skaile-connectors__*`) so that\n * connector tools are never silently blocked by agent.yaml restrictions.\n */\n private buildToolRestrictions(): Pick<SdkOptions, \"allowedTools\" | \"disallowedTools\"> {\n const mcpWildcards = this.config.mcpServers\n ? Object.keys(this.config.mcpServers).map((name) => `mcp__${name}__*`)\n : [];\n\n const result: Pick<SdkOptions, \"allowedTools\" | \"disallowedTools\"> = {};\n\n // Only set allowedTools if the manifest explicitly declared an allow list.\n // MCP wildcards are appended to ensure connector tools aren't blocked by\n // the allowlist, but they should NOT create an allowlist on their own —\n // that would block all non-MCP tools (Read, Write, Bash, etc.).\n const allowed = this.config.tools?.allowed;\n if (allowed?.length) {\n result.allowedTools = [...allowed, ...mcpWildcards];\n }\n\n if (this.config.tools?.denied?.length) {\n result.disallowedTools = this.config.tools.denied;\n }\n\n return result;\n }\n\n /**\n * Map the simple string thinking config to SDK ThinkingConfig objects.\n * This keeps the platform-layer SDK-agnostic while the bridge handles the mapping.\n */\n private mapThinkingConfig(\n thinking: \"adaptive\" | \"enabled\" | \"disabled\",\n ): { type: \"adaptive\" } | { type: \"enabled\" } | { type: \"disabled\" } {\n switch (thinking) {\n case \"adaptive\":\n return { type: \"adaptive\" };\n case \"enabled\":\n return { type: \"enabled\" };\n case \"disabled\":\n return { type: \"disabled\" };\n }\n }\n\n /**\n * Find the Claude Code CLI executable.\n *\n * Resolution order:\n * 1. CLAUDE_CODE_PATH env var (set in Docker containers where cli.js is\n * extracted from the SDK during build — bun-compiled binaries can't\n * access the SDK's bundled cli.js via $bunfs)\n * 2. `which claude` on PATH (dev machines with claude installed globally)\n * 3. undefined — let the SDK resolve its own bundled cli.js (works when\n * not running inside a bun-compiled binary)\n */\n private findClaudeBinary(): string | undefined {\n const envPath = process.env.CLAUDE_CODE_PATH;\n if (envPath && existsSync(envPath)) return envPath;\n\n const result = spawnSync(\"which\", [\"claude\"], { encoding: \"utf-8\" });\n const p = result.stdout?.trim();\n return p || undefined;\n }\n}\n\nregisterDriver(\"claude-sdk\", (config) => new ClaudeSdkDriver(config), DRIVER_CATALOG[\"claude-sdk\"]);\n"]}
|
|
1
|
+
{"version":3,"sources":["../../../bridge/src/drivers/scrub-transcript.ts","../../../bridge/src/drivers/claude-sdk.ts"],"names":["z","join","existsSync"],"mappings":"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","file":"claude-sdk.js","sourcesContent":["/**\n * Poisoned-transcript repair for the Claude Agent SDK driver.\n *\n * The Anthropic Messages API can permanently reject a conversation once its\n * persisted history contains a malformed content block. Because the bad block\n * lives in the SDK's on-disk JSONL transcript, every replayed turn fails with\n * the same `400 invalid_request_error` and the session is bricked with no\n * in-band recovery.\n *\n * This module repairs the transcript in place, covering three known poison\n * classes:\n *\n * 1. **Image `media_type` mismatch / omission.** An image block whose declared\n * `media_type` does not match — or is missing for — the actual bytes:\n * `... The image was specified using the image/png media type, but the\n * image appears to be a image/jpeg image`. Produced by the Claude Code\n * `Read` tool's format fallback (anthropics/claude-code#55338, #30124,\n * #33179). Repaired by sniffing the base64 magic bytes and correcting\n * `media_type`.\n * 2. **Oversized image.** An image whose decoded payload exceeds the API's\n * 5 MB per-image limit (anthropics/claude-code#34566). Replaced with a\n * text stub — the byte budget cannot be recovered any other way.\n * 3. **`cache_control` on an empty text block.** A text block carrying a\n * `cache_control` marker with empty/whitespace `text`\n * (anthropics/claude-code#59626). The `cache_control` field is stripped.\n *\n * Genuinely unidentifiable image blocks are also replaced with a text stub.\n *\n * Recovering by content scan (rather than parsing the API's `messages.N`\n * index) is deliberate: the index addresses the assembled API request, not a\n * JSONL line, and reproducing the SDK's message-assembly is fragile. A full\n * scan is index-free and repairs every poisoned block in one pass.\n *\n * @module\n */\n\nimport { existsSync, readdirSync, readFileSync, renameSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\n\n/**\n * Minimal logger shape accepted by {@link scrubPoisonedTranscript}. Compatible\n * with the bridge `Logger`, but narrowed so the helper stays unit-testable\n * without a real logger instance.\n *\n * @category Transcript repair\n */\nexport interface ScrubLogger {\n info(message: string, data?: Record<string, unknown>): void;\n warn(message: string, data?: Record<string, unknown>): void;\n}\n\n/**\n * Options for {@link scrubPoisonedTranscript}.\n *\n * @category Transcript repair\n */\nexport interface ScrubTranscriptOptions {\n /**\n * Claude Code config directory — the parent of `projects/`. Resolve from\n * `CLAUDE_CONFIG_DIR`, falling back to `~/.claude`.\n */\n configDir: string;\n /** SDK session id whose transcript JSONL should be repaired. */\n sessionId: string;\n /** Optional logger for diagnostics. */\n log?: ScrubLogger;\n}\n\n/**\n * Outcome of a {@link scrubPoisonedTranscript} pass.\n *\n * @category Transcript repair\n */\nexport interface ScrubTranscriptResult {\n /** The located JSONL transcript path, or `null` when not found. */\n filePath: string | null;\n /** Image blocks whose `media_type` was corrected (or filled in) to match the bytes. */\n corrected: number;\n /**\n * Image blocks replaced with a text stub — either unidentifiable bytes or a\n * payload over the API's 5 MB per-image limit.\n */\n stubbed: number;\n /** Empty text blocks from which a rejected `cache_control` marker was stripped. */\n cacheStripped: number;\n /**\n * `true` when the transcript was located, contained at least one poisoned\n * block, and was rewritten. `false` means nothing needed repair (or the\n * file was not found) — the caller should not retry the resume.\n */\n changed: boolean;\n}\n\n/** Text inserted in place of an image block whose format cannot be identified. */\nconst STUB_TEXT = \"[image removed: unprocessable image data]\";\n\n/** Text inserted in place of an image block that exceeds the API size limit. */\nconst STUB_TEXT_OVERSIZED = \"[image removed: image too large]\";\n\n/**\n * The Anthropic Messages API rejects any single image whose decoded payload\n * exceeds 5 MB. An image at or under this is left alone; a larger one is\n * stubbed (its byte budget cannot be recovered).\n */\nconst MAX_IMAGE_BYTES = 5 * 1024 * 1024;\n\n/**\n * Identify an image's media type from the leading bytes of its base64 payload.\n *\n * Recognises the four formats the Anthropic API accepts. Returns `null` when\n * the magic bytes match no known format — the caller treats that as a\n * genuinely corrupt block and stubs it.\n *\n * @param base64 - Base64-encoded image data (only the prefix is inspected).\n * @returns An `image/*` media type, or `null` when unrecognised.\n * @category Transcript repair\n */\nexport function sniffImageMediaType(base64: string): string | null {\n let buf: Buffer;\n try {\n // 32 base64 chars decode to 24 bytes — enough for the WebP check at 12.\n buf = Buffer.from(base64.slice(0, 32), \"base64\");\n } catch {\n return null;\n }\n if (buf.length < 4) {\n return null;\n }\n // JPEG — SOI marker `FF D8`. Third byte varies (and may be corrupt), so a\n // two-byte check is intentional: it still matches malformed JPEGs, which is\n // exactly the poison case the API flags as \"appears to be image/jpeg\".\n if (buf[0] === 0xff && buf[1] === 0xd8) {\n return \"image/jpeg\";\n }\n // PNG — `89 50 4E 47`.\n if (buf[0] === 0x89 && buf[1] === 0x50 && buf[2] === 0x4e && buf[3] === 0x47) {\n return \"image/png\";\n }\n // GIF — `47 49 46 38` (\"GIF8\").\n if (buf[0] === 0x47 && buf[1] === 0x49 && buf[2] === 0x46 && buf[3] === 0x38) {\n return \"image/gif\";\n }\n // WebP — `RIFF` at 0..3 and `WEBP` at 8..11.\n if (\n buf.length >= 12 &&\n buf[0] === 0x52 &&\n buf[1] === 0x49 &&\n buf[2] === 0x46 &&\n buf[3] === 0x46 &&\n buf[8] === 0x57 &&\n buf[9] === 0x45 &&\n buf[10] === 0x42 &&\n buf[11] === 0x50\n ) {\n return \"image/webp\";\n }\n return null;\n}\n\n/** A base64 image source on a content block (shape is SDK-defined). */\ninterface Base64ImageSource {\n type?: string;\n media_type?: string;\n data?: string;\n}\n\n/** Loosely-typed content block from a transcript message. */\ninterface ContentBlockLike {\n type?: string;\n source?: Base64ImageSource;\n content?: unknown;\n [k: string]: unknown;\n}\n\n/** Mutable counters threaded through one scrub pass. */\ninterface ScrubCounters {\n corrected: number;\n stubbed: number;\n cacheStripped: number;\n}\n\n/** Total repairs recorded in a counter set — used to detect per-line changes. */\nfunction totalChanges(c: ScrubCounters): number {\n return c.corrected + c.stubbed + c.cacheStripped;\n}\n\n/**\n * Repair a single content block. Returns the (possibly replaced) block.\n *\n * - A `tool_result` block recurses into its `content` array.\n * - A text block carrying a `cache_control` marker whose `text` is empty or\n * whitespace has the marker stripped (the API rejects `cache_control` on\n * empty text blocks).\n * - An image block whose decoded payload exceeds the API's 5 MB limit is\n * replaced with a text stub.\n * - An image block whose bytes match no known format is replaced with a text\n * stub (an image cannot simply be dropped — a `tool_result` must keep at\n * least one content entry, and a bare `image` block is replaced 1:1).\n * - An image block whose declared `media_type` mismatches (or is missing for)\n * the sniffed type is corrected in place.\n * - Every other block is returned untouched.\n */\nfunction scrubBlock(block: ContentBlockLike, counters: ScrubCounters): ContentBlockLike {\n if (block.type === \"tool_result\" && Array.isArray(block.content)) {\n return {\n ...block,\n content: (block.content as ContentBlockLike[]).map((inner) => scrubBlock(inner, counters)),\n };\n }\n\n // A `cache_control` marker on a text block whose text is empty or whitespace\n // is rejected by the API (\"cache_control cannot be set for empty text\n // blocks\"). Strip the marker — the empty block itself is harmless.\n if (block.type === \"text\" && block.cache_control != null) {\n const text = typeof block.text === \"string\" ? block.text : \"\";\n if (text.trim() === \"\") {\n counters.cacheStripped++;\n const clone = { ...block };\n delete clone.cache_control;\n return clone;\n }\n }\n\n if (\n block.type === \"image\" &&\n block.source?.type === \"base64\" &&\n typeof block.source.data === \"string\"\n ) {\n const data = block.source.data;\n // The API rejects any image whose decoded payload exceeds 5 MB. The byte\n // budget cannot be salvaged, so the whole block becomes a text stub.\n // base64 encodes 3 bytes per 4 chars, so decoded length ≈ len * 3 / 4.\n if (Math.floor((data.length * 3) / 4) > MAX_IMAGE_BYTES) {\n counters.stubbed++;\n return { type: \"text\", text: STUB_TEXT_OVERSIZED };\n }\n const sniffed = sniffImageMediaType(data);\n if (sniffed === null) {\n counters.stubbed++;\n return { type: \"text\", text: STUB_TEXT };\n }\n if (sniffed !== block.source.media_type) {\n counters.corrected++;\n return { ...block, source: { ...block.source, media_type: sniffed } };\n }\n }\n\n return block;\n}\n\n/**\n * Locate the JSONL transcript for `sessionId` under `<configDir>/projects/`.\n *\n * Claude Code encodes the project directory into the `projects/` subfolder\n * name; rather than reproduce that encoding, this scans every subfolder for\n * `<sessionId>.jsonl` (the session id is a UUID — globally unique).\n */\nfunction locateTranscript(configDir: string, sessionId: string): string | null {\n const projectsDir = join(configDir, \"projects\");\n if (!existsSync(projectsDir)) {\n return null;\n }\n let entries: string[];\n try {\n entries = readdirSync(projectsDir);\n } catch {\n return null;\n }\n for (const entry of entries) {\n const candidate = join(projectsDir, entry, `${sessionId}.jsonl`);\n if (existsSync(candidate)) {\n return candidate;\n }\n }\n return null;\n}\n\n/**\n * Scan a Claude Code SDK transcript for image content blocks whose declared\n * `media_type` does not match the actual bytes, repair them, and atomically\n * rewrite the file.\n *\n * Safe to call after a turn has failed: the SDK query is dead at that point,\n * and the next resume re-reads the transcript from disk.\n *\n * @param opts - Config directory, session id, and an optional logger.\n * @returns A {@link ScrubTranscriptResult}. When `changed` is `true` the\n * caller may retry the resume with the same session id.\n * @category Transcript repair\n */\nexport function scrubPoisonedTranscript(opts: ScrubTranscriptOptions): ScrubTranscriptResult {\n const { configDir, sessionId, log } = opts;\n const result: ScrubTranscriptResult = {\n filePath: null,\n corrected: 0,\n stubbed: 0,\n cacheStripped: 0,\n changed: false,\n };\n\n const filePath = locateTranscript(configDir, sessionId);\n if (!filePath) {\n log?.warn(\"scrub-transcript: no transcript found\", { configDir, sessionId });\n return result;\n }\n result.filePath = filePath;\n\n let raw: string;\n try {\n raw = readFileSync(filePath, \"utf8\");\n } catch (err) {\n log?.warn(\"scrub-transcript: failed to read transcript\", {\n filePath,\n error: err instanceof Error ? err.message : String(err),\n });\n return result;\n }\n\n const counters: ScrubCounters = { corrected: 0, stubbed: 0, cacheStripped: 0 };\n // Split without filtering so blank lines / trailing newline survive verbatim.\n const lines = raw.split(\"\\n\");\n let dirty = false;\n\n const repaired = lines.map((line) => {\n if (line.trim() === \"\") {\n return line;\n }\n let entry: { message?: { content?: unknown } };\n try {\n entry = JSON.parse(line);\n } catch {\n return line; // Not JSON — leave untouched.\n }\n const content = entry.message?.content;\n if (!Array.isArray(content)) {\n return line;\n }\n const before = totalChanges(counters);\n const scrubbed = (content as ContentBlockLike[]).map((block) => scrubBlock(block, counters));\n if (totalChanges(counters) === before) {\n return line; // Nothing changed on this line.\n }\n dirty = true;\n return JSON.stringify({ ...entry, message: { ...entry.message, content: scrubbed } });\n });\n\n result.corrected = counters.corrected;\n result.stubbed = counters.stubbed;\n result.cacheStripped = counters.cacheStripped;\n\n if (!dirty) {\n return result;\n }\n\n // Atomic rewrite: write a sibling temp file, then rename over the original.\n const tmpPath = `${filePath}.scrub-tmp`;\n try {\n writeFileSync(tmpPath, repaired.join(\"\\n\"), \"utf8\");\n renameSync(tmpPath, filePath);\n } catch (err) {\n log?.warn(\"scrub-transcript: failed to rewrite transcript\", {\n filePath,\n error: err instanceof Error ? err.message : String(err),\n });\n return result;\n }\n\n result.changed = true;\n log?.info(\"scrub-transcript: repaired poisoned transcript\", {\n filePath,\n corrected: result.corrected,\n stubbed: result.stubbed,\n cacheStripped: result.cacheStripped,\n });\n return result;\n}\n","import { spawnSync } from \"node:child_process\";\nimport { existsSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport type {\n SDKAssistantMessage,\n SDKMessage,\n SDKUserMessage,\n Options as SdkOptions,\n Query as SdkQuery,\n query as sdkQueryFn,\n} from \"@anthropic-ai/claude-agent-sdk\";\nimport type { Logger, TokenUsage } from \"@skaile/workspaces/types\";\n// Static namespace import so bun --compile bundles zod into the binary.\n// Dynamic import(\"zod\") via a string variable evades bun's static analysis\n// and fails at runtime inside /$bunfs/. The unwrap (zNS.z ?? zNS.default\n// ?? zNS) handles both bun's native ESM and vitest's CJS-interop resolver,\n// which return the zod namespace at different keys.\nimport * as zNS from \"zod\";\n\nconst zStatic: any = (zNS as any).z ?? (zNS as any).default ?? zNS;\n\nimport { dispatchCapability } from \"../capability-dispatch.js\";\nimport { AuthError, classifyClaudeSdkError } from \"../error-classifier.js\";\nimport { getBridgeLogger } from \"../logger.js\";\nimport { fetchProviderModels, type ModelEntry } from \"../models.js\";\nimport { DRIVER_CATALOG, registerDriver } from \"../registry.js\";\nimport {\n type AgentConfig,\n AgentDriver,\n type AgentEvent,\n type AgentMessage,\n type ContentBlock,\n type DriverInfo,\n type SlashCommandInfo,\n type ToolCall,\n} from \"../types.js\";\nimport { scrubPoisonedTranscript } from \"./scrub-transcript.js\";\n\n/**\n * Best-effort conversion of a JSON Schema object's top-level `properties` into\n * a `Record<string, ZodTypeAny>` accepted by `createSdkMcpServer`'s\n * `inputSchema`. The SDK only needs a shallow shape to advertise to the LLM —\n * deep validation is handled by the registry's Zod schema in `hooks.invoke()`.\n *\n * Returns null on schemas the bridge can't represent (anyOf at the root, etc.);\n * the caller falls back to a permissive `{ args: z.unknown().optional() }`.\n */\nfunction jsonSchemaToZodLoose(\n schema: Record<string, unknown>,\n z: any,\n): Record<string, unknown> | null {\n const props = (schema?.properties ?? null) as Record<string, any> | null;\n if (!props || typeof props !== \"object\") return null;\n const required = new Set(Array.isArray(schema?.required) ? (schema.required as string[]) : []);\n const out: Record<string, unknown> = {};\n for (const [key, def] of Object.entries(props)) {\n let zod: any;\n switch (def?.type) {\n case \"string\":\n zod = z.string();\n break;\n case \"number\":\n case \"integer\":\n zod = z.number();\n break;\n case \"boolean\":\n zod = z.boolean();\n break;\n case \"array\":\n zod = z.array(z.any());\n break;\n case \"object\":\n zod = z.record(z.string(), z.any());\n break;\n default:\n zod = z.any();\n }\n if (def?.description && typeof def.description === \"string\") {\n zod = zod.describe(def.description);\n }\n if (!required.has(key)) zod = zod.optional();\n out[key] = zod;\n }\n return out;\n}\n\n// The Claude Agent SDK bundles ajv which uses CJS require() internally.\n// Polyfill globalThis.require so it works in a pure ESM context.\n// In CJS (e.g. NestJS webpack bundle), require already exists — skip.\nif (typeof globalThis.require === \"undefined\") {\n try {\n // Dynamic eval avoids static parse errors in CJS bundlers\n // biome-ignore lint/security/noGlobalEval: intentional — CJS/ESM interop requires dynamic eval\n const metaUrl = (0, eval)(\"import.meta.url\");\n (globalThis as any).require = createRequire(metaUrl);\n } catch {\n // CJS context — require is already available via the module system\n }\n}\n\n/**\n * Agent driver for the Anthropic Claude Agent SDK.\n *\n * Runs the agent in-process — no subprocess is spawned. Anthropic models only.\n *\n * @remarks\n * **Lazy-loading** — `@anthropic-ai/claude-agent-sdk` is imported dynamically inside\n * `start()` so it remains an optional peer dependency. If the package is not installed\n * an actionable error is thrown. The CJS/ESM `require` polyfill at the top of this file\n * is required because the SDK bundles ajv which uses `require()` internally.\n *\n * **Session continuity** — each `prompt()` tries to feed into a live SDK query via\n * `streamInput()` (persistent multi-turn mode). When no live query exists it starts a\n * new one, applying a three-level resume chain:\n * 1. `resumeSessionId` from config (explicit caller resume)\n * 2. `sessionId` captured from the current driver lifetime\n * 3. `continue: true` (resume most recent session in cwd from disk)\n *\n * **Tool synthesis** — emits `tool_call` and `tool_execution_end` events that the\n * runner's activity tracker needs for file-change detection. These are not native SDK\n * events; they are synthesised from `assistant` and `user` SDK messages.\n *\n * **agentName** — maps to the `agent` SDK query option. The SDK reads\n * `.claude/agents/<agentName>.md` from `cwd` for model, tools, and system prompt.\n * Requires the agent file to have been rendered by `asset-manager` (claudeCodeRenderer)\n * during `skaile install`. Ignored by other drivers.\n *\n * **mcpServers** — `AgentConfig.mcpServers` passes in-process MCP server instances to\n * the SDK's `mcpServers` query option. Used by `workspaces/connectors` to inject\n * resource tools as native `tool_use`. Ignored by other drivers.\n *\n * @docLink packages/bridge/drivers#claude-sdk-driver\n */\nexport class ClaudeSdkDriver extends AgentDriver {\n readonly driverInfo: DriverInfo = {\n id: \"claude-sdk\",\n name: \"Claude Agent SDK\",\n modelAgnostic: false,\n supportsInBandAbort: true,\n };\n\n private readonly log: Logger = getBridgeLogger(\"claude-sdk\");\n private config: AgentConfig;\n private abortController: AbortController | null = null;\n private running = false;\n private sdk: { query: typeof sdkQueryFn } | null = null;\n private toolIdToName = new Map<string, string>();\n private prevText = \"\";\n\n /** Active query — may stay alive between turns if streamInput works. */\n private query: SdkQuery | null = null;\n /** Resolves when the current turn completes. */\n private turnResolve: (() => void) | null = null;\n /** Rejects when the current turn errors. */\n private turnReject: ((err: Error) => void) | null = null;\n /** Guards against duplicate agent_end emissions per turn. */\n private turnCompleted = false;\n /**\n * Mirror of the `_retryCount` argument of the in-flight {@link prompt} call.\n * Read by {@link failTurn} to decide whether to defer the `agent-event:\n * error` emission for a self-healable auth error. `0` means \"first\n * attempt\"; `prompt()` increments to `1` before recursing on its\n * `onAuthError` self-heal branch.\n *\n * Set unconditionally at the top of every {@link prompt} invocation; never\n * reset elsewhere — the next call's set is the only legitimate transition.\n */\n private currentRetryCount = 0;\n /** Tracks whether a session has been started (for continue: true). */\n private hasSession = false;\n /** Session ID from the SDK — used for streamInput messages. */\n private sessionId = \"\";\n /** Cached slash commands discovered from the SDK. */\n private cachedCommands: SlashCommandInfo[] = [];\n /** Token usage from the most recent completed turn. */\n private _lastTokens: TokenUsage | null = null;\n /** Context window size from the most recent result's modelUsage. */\n private _contextWindow: number | null = null;\n /**\n * `true` when the active credential is a Claude Code OAuth subscription\n * (no API key in config) rather than a raw `ANTHROPIC_API_KEY`. Set on\n * every `startQuery` because the credential source can be reconfigured\n * at runtime via `configure`. Threaded into `classifyClaudeSdkError` so\n * upstream auth-shaped failures get a quota-aware hint when warranted.\n */\n private usingOauthCredential = false;\n\n /**\n * @param config - Driver configuration. Claude SDK-relevant fields:\n * - `cwd` — working directory; SDK session files and agent definitions are read from here.\n * - `model` — Anthropic model identifier (e.g. `\"claude-sonnet-4-5\"`). Defaults to `\"sonnet\"`.\n * - `apiKeys.anthropic` / `env.ANTHROPIC_API_KEY` — API key forwarded to the SDK query.\n * - `agentName` — name of a `.claude/agents/<name>.md` agent definition to use as identity.\n * - `mcpServers` — in-process MCP server instances injected as native `tool_use` tools.\n * - `systemPrompt` — appended to the `claude_code` preset system prompt.\n * - `resumeSessionId` — SDK session UUID to resume from a prior driver lifetime.\n * - `maxTurns` — maximum agentic turns per `prompt()` call (default: 15).\n */\n constructor(config: AgentConfig) {\n super();\n this.config = config;\n }\n\n override get runtimeSessionId(): string | undefined {\n return this.sessionId || undefined;\n }\n\n override reconfigure(patch: Partial<Pick<AgentConfig, \"model\" | \"thinking\" | \"effort\">>): void {\n if (patch.model !== undefined) this.config.model = patch.model;\n if (patch.thinking !== undefined) this.config.thinking = patch.thinking;\n if (patch.effort !== undefined) this.config.effort = patch.effort;\n }\n\n override getModel(): string | undefined {\n return this.config.model;\n }\n\n /**\n * Dynamically imports `@anthropic-ai/claude-agent-sdk`.\n *\n * @throws {Error} When the SDK package is not installed. Install it with\n * `bun add @anthropic-ai/claude-agent-sdk`.\n */\n public async start(): Promise<void> {\n try {\n this.sdk = await import(\"@anthropic-ai/claude-agent-sdk\");\n this.log.info(\"Claude Agent SDK loaded\");\n } catch {\n throw new Error(\n \"Claude Agent SDK not installed. Run: bun add @anthropic-ai/claude-agent-sdk\",\n );\n }\n }\n\n /**\n * Sends a user message to the Claude Agent SDK and resolves when the turn completes.\n *\n * If a live SDK query already exists (from a prior turn in this session) the message\n * is fed via `streamInput()` for efficient multi-turn continuity. Otherwise a new query\n * is started applying the resume chain described in the class-level remarks.\n *\n * @param message - Plain-text user prompt.\n * @throws {Error} When the SDK reports a fatal error that cannot be auto-recovered.\n *\n * @remarks\n * A single automatic retry is performed when the SDK throws\n * \"No conversation found with session ID …\" — a recoverable stale-resume error that\n * occurs after a container crash that prevented the SDK from flushing its session file.\n */\n public async prompt(message: string, _retryCount = 0): Promise<void> {\n this.currentRetryCount = _retryCount;\n if (!this.sdk) await this.start();\n\n // When the catch block decides to recurse (stale-resume or auth-error\n // retry), the recursive prompt() sets fresh turnResolve / turnReject on\n // `this` synchronously before its first `await`. If the outer finally\n // ran unconditionally it would clobber those handlers, leaving the\n // recursive turn's promise unresolvable — completeTurn would see\n // `this.turnResolve === null` and the recursive prompt() would hang\n // forever. The flag tells the finally to skip state-reset on the\n // retry path.\n //\n // EVERY retry branch in the catch block MUST set `retrying = true`\n // before returning the recursive call. Adding a third retry branch\n // without setting this flag will re-introduce a hard-to-diagnose\n // hang: the recursive prompt's turnPromise never resolves because\n // its resolver was nulled by this function's finally.\n let retrying = false;\n\n // Clear last-turn usage on entry, except when this is a retry recursion\n // (auth-error / stale-resume) — the retry shares the same logical turn\n // so we keep prior usage available until the SDK reports a fresh value.\n if (_retryCount === 0) this._lastTokens = null;\n\n this.running = true;\n this.prevText = \"\";\n this.turnCompleted = false;\n\n // Install the per-turn resolver before we send any input. Fast turns can\n // complete on the next microtask; if the result lands before turnResolve is\n // assigned, completeTurn() has nothing to resolve and prompt() hangs forever.\n const turnPromise = new Promise<void>((resolve, reject) => {\n this.turnResolve = resolve;\n this.turnReject = reject;\n });\n\n try {\n if (this.query) {\n // Try feeding into the live query via streamInput (persistent mode)\n const userMsg = this.buildUserMessage(message);\n this.query.streamInput(this.singleItemIterable(userMsg));\n } else {\n // No live query — start a new one (continue: true resumes session)\n await this.startQuery(message);\n }\n } catch (err) {\n this.turnResolve = null;\n this.turnReject = null;\n this.running = false;\n throw err;\n }\n\n // Wait for this turn to complete\n try {\n await turnPromise;\n } catch (err) {\n // The Claude Agent SDK throws \"No conversation found with session ID\n // <uuid>\" when we try to resume a session whose JSONL persistence was\n // lost — most commonly after a container crash that killed the query\n // mid-stream, so the driver captured the session id but the SDK never\n // flushed the session file to disk. The resume is permanently broken;\n // retry the prompt once with a fresh session so the user can continue\n // (and emit a non-fatal warning so the UI can surface that Claude's\n // short-term memory was dropped).\n const errMsg = err instanceof Error ? err.message : String(err);\n const isStaleResume =\n _retryCount === 0 && /No conversation found with session ID/i.test(errMsg);\n if (isStaleResume) {\n const staleId = this.config.resumeSessionId || this.sessionId || \"unknown\";\n this.log.warn(\"stale Claude Code session, retrying with a fresh session\", { staleId });\n // Structured event for the platform's resume outcome listener.\n // Emitted before the non-fatal error so the gateway records the\n // outcome regardless of what surfaces the error string.\n this.emit(\"agent-event\", {\n type: \"resume_failed\",\n resumeSessionId: staleId,\n reason: \"jsonl_lost\",\n } satisfies AgentEvent);\n this.emit(\"agent-event\", {\n type: \"error\",\n error:\n \"Claude Code session state was lost (likely a prior crash). Restarting with a fresh session — previous conversation context is not available.\",\n fatal: false,\n } satisfies AgentEvent);\n this.sessionId = \"\";\n this.hasSession = false;\n this.query = null;\n // Clear the config override too — leaving it in place would make the\n // retry re-trigger the same failure via startQuery's resume chain.\n this.config.resumeSessionId = undefined;\n this.turnResolve = null;\n this.turnReject = null;\n this.running = false;\n retrying = true;\n return this.prompt(message, _retryCount + 1);\n }\n // ── Poisoned-transcript self-heal ──────────────────────────────────\n // The Anthropic API permanently rejects a conversation once its history\n // contains a malformed content block. Every replayed turn 400s with\n // `invalid_request_error`, bricking the session with no in-band recovery.\n // `scrubPoisonedTranscript` repairs three known poison classes on the\n // on-disk SDK transcript: image `media_type` mismatch/omission, oversized\n // images, and `cache_control` on empty text blocks (Claude Code bugs\n // #55338 / #30124 / #33179 / #34566 / #59626). The resume is retried once.\n // Unlike the stale-resume path above, this preserves the conversation —\n // the same session id is resumed against the now-clean transcript.\n //\n // The detection regex is intentionally broad: if it matches a 400 the\n // scrubber cannot actually repair, `scrub.changed` stays `false`, this\n // branch falls through, and the original error is rethrown. The\n // `_retryCount === 0` guard caps recovery at a single retry regardless.\n const isPoisonedHistory =\n _retryCount === 0 &&\n /invalid_request_error/i.test(errMsg) &&\n /media[_ ]?type|could not process image|image exceeds|cache_control/i.test(errMsg);\n const poisonSessionId = this.config.resumeSessionId || this.sessionId;\n if (isPoisonedHistory && poisonSessionId) {\n const scrub = scrubPoisonedTranscript({\n configDir: this.resolveClaudeConfigDir(),\n sessionId: poisonSessionId,\n log: this.log,\n });\n if (scrub.changed) {\n this.log.warn(\"scrubbed poisoned Claude Code transcript, retrying resume\", {\n sessionId: poisonSessionId,\n corrected: scrub.corrected,\n stubbed: scrub.stubbed,\n cacheStripped: scrub.cacheStripped,\n });\n // Structured event for the platform's resume outcome listener.\n this.emit(\"agent-event\", {\n type: \"resume_failed\",\n resumeSessionId: poisonSessionId,\n reason: \"jsonl_poisoned\",\n } satisfies AgentEvent);\n const plural = (n: number) => (n === 1 ? \"\" : \"s\");\n const repairs: string[] = [];\n if (scrub.corrected > 0)\n repairs.push(`${scrub.corrected} media type${plural(scrub.corrected)} corrected`);\n if (scrub.stubbed > 0)\n repairs.push(`${scrub.stubbed} image${plural(scrub.stubbed)} removed`);\n if (scrub.cacheStripped > 0)\n repairs.push(\n `${scrub.cacheStripped} malformed block${plural(scrub.cacheStripped)} cleaned`,\n );\n this.emit(\"agent-event\", {\n type: \"error\",\n error: `Recovered corrupt data in the conversation history (${repairs.join(\", \")}). Retrying — earlier context is preserved.`,\n fatal: false,\n } satisfies AgentEvent);\n // Drop the dead query; keep sessionId / resumeSessionId so startQuery\n // resumes the now-clean transcript.\n this.query = null;\n this.turnResolve = null;\n this.turnReject = null;\n this.running = false;\n retrying = true;\n return this.prompt(message, _retryCount + 1);\n }\n this.log.warn(\"poisoned-transcript error but scrub found nothing to repair\", {\n sessionId: poisonSessionId,\n filePath: scrub.filePath,\n });\n }\n // ── Auth-error retry: ask the runner to refresh the credential, then\n // replay the in-flight prompt once. Centralising this inside the driver\n // means every `driver.prompt(...)` call site (serve handler, compaction\n // orchestrator, flow orchestrator, future call sites) gets self-healing\n // for free — no per-call-site wrapping. The runner provides the\n // `onAuthError` callback in `AgentConfig`; standalone CLI / forge\n // sessions leave it unset and surface the original `AuthError`.\n //\n // No idempotence gate around `onAuthError`: a single driver instance\n // owns exactly one consumer loop, which means at most one auth error\n // surfaces per turn. Concurrent prompt() calls feed the same query via\n // streamInput rather than running parallel consumer loops, so two\n // simultaneous 401s for the same driver are not physically possible.\n // The runner's previous in-flight Map (Step 9b of the original spec)\n // existed to coalesce the per-call-site wrappers and is unnecessary\n // here.\n //\n // Spec: `_devlog/specs/2026-05-07-unified-credential-mediation.md`\n // § \"Runner-side handling on 401\" (moved bridge-side).\n const isAuthError = err instanceof AuthError && _retryCount === 0;\n if (isAuthError && this.config.onAuthError) {\n this.log.info(\"auth error caught; invoking onAuthError refresh callback\");\n // Protocol v3: the callback returns a typed `CredentialMint`. A\n // success branch (`ok: true`) means the runner has provisioned a\n // fresh credential and the driver should retry. A failure branch\n // (`ok: false`) carries a stable `code` the runner already\n // surfaced upstream; the driver surfaces the original `AuthError`\n // to its caller without retrying.\n let refreshed = false;\n try {\n const mint = await this.config.onAuthError({\n configId: this.config.aiProviderConfigId ?? \"\",\n });\n refreshed = mint.ok;\n if (!mint.ok) {\n this.log.info(\"onAuthError reported refresh failure; surfacing AuthError\", {\n code: mint.code,\n });\n }\n } catch (refreshErr) {\n this.log.warn(\"onAuthError callback threw; surfacing original AuthError\", {\n error: refreshErr instanceof Error ? refreshErr.message : String(refreshErr),\n });\n }\n if (refreshed) {\n this.log.info(\"credentials refreshed; retrying prompt\");\n // Drop the dead SDK query so the next prompt() invocation creates a\n // fresh one (which reads the rewritten credentials file). Keep\n // sessionId / hasSession so the new query resumes the same Claude\n // SDK session.\n this.query = null;\n this.turnResolve = null;\n this.turnReject = null;\n this.running = false;\n retrying = true;\n return this.prompt(message, _retryCount + 1);\n }\n // Self-heal was attempted and failed (callback declined or threw).\n // `failTurn` suppressed the `agent-event: error` emission so the\n // refresh attempt could play out silently; emit it now before the\n // AuthError surfaces to the caller. Pairs with the deferral in\n // `failTurn` — every auth failure produces exactly one downstream\n // error event, either on the retry's `failTurn` (when self-heal\n // succeeded but the retry itself failed) or here.\n try {\n this.emit(\"agent-event\", {\n type: \"error\",\n error: err.message,\n detail: (err as AuthError).detail,\n } satisfies AgentEvent);\n } catch (emitErr) {\n this.log.warn(\n \"agent-event listener threw during deferred auth-error surfacing; suppressing\",\n { error: emitErr instanceof Error ? emitErr.message : String(emitErr) },\n );\n }\n }\n throw err;\n } finally {\n // Skip state reset when we recursed — the inner prompt() owns the\n // turnResolve / turnReject handlers and we must not clobber them.\n // See the `retrying` flag declared at the top of this function.\n if (!retrying) {\n this.turnResolve = null;\n this.turnReject = null;\n this.running = false;\n }\n }\n }\n\n /**\n * Resolve the Claude Code config directory — the parent of `projects/` — from\n * the driver config, the process environment, or the `~/.claude` default.\n */\n private resolveClaudeConfigDir(): string {\n return (\n this.config.env?.CLAUDE_CONFIG_DIR ||\n process.env.CLAUDE_CONFIG_DIR ||\n join(homedir(), \".claude\")\n );\n }\n\n /**\n * Preventively repair the on-disk SDK transcript before a resume.\n *\n * The reactive {@link scrubPoisonedTranscript} pass in `prompt()` only fires\n * *after* a turn has already failed with a `400 invalid_request_error`,\n * costing a wasted round-trip and surfacing a scary (if non-fatal) error to\n * the user. A transcript poisoned in a prior driver lifetime — most commonly\n * an image block whose `media_type` does not match its bytes, produced by the\n * Claude Code `Read` tool on a PDF with embedded JPEGs (anthropics/claude-code\n * #55338) — would otherwise 400 on the very first resumed turn.\n *\n * Running the same magic-byte scrub *before* handing the transcript to the\n * SDK means a known poison class never reaches the API, so recovery is\n * invisible. This is regex-free (unlike the reactive gate) and idempotent: a\n * clean transcript is left byte-for-byte untouched. The reactive path remains\n * the safety net for poison introduced mid-turn within the current lifetime.\n */\n private preventivelyScrubTranscript(): void {\n const sessionId = this.config.resumeSessionId || this.sessionId;\n if (!sessionId) {\n return; // Fresh session — no transcript to repair yet.\n }\n try {\n const scrub = scrubPoisonedTranscript({\n configDir: this.resolveClaudeConfigDir(),\n sessionId,\n log: this.log,\n });\n if (scrub.changed) {\n this.log.warn(\"preventively scrubbed poisoned Claude Code transcript before resume\", {\n sessionId,\n corrected: scrub.corrected,\n stubbed: scrub.stubbed,\n cacheStripped: scrub.cacheStripped,\n });\n }\n } catch (err) {\n // A scrub failure must never block the turn — the reactive path still\n // covers a poisoned block if one survives to the API.\n this.log.warn(\"preventive transcript scrub failed; continuing\", {\n sessionId,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n }\n\n private async startQuery(message: string): Promise<void> {\n this.abortController = new AbortController();\n\n // Repair any poisoned content block left in the on-disk transcript before\n // the SDK resumes it — converts the reactive post-400 self-heal into a\n // deterministic, user-invisible recovery. See the method doc for rationale.\n this.preventivelyScrubTranscript();\n\n const apiKey =\n this.config.apiKeys?.anthropic ||\n this.config.env?.ANTHROPIC_API_KEY ||\n process.env.ANTHROPIC_API_KEY;\n\n // When no apiKey is configured the SDK falls back to OAuth credentials\n // discovered via `settingSources: [\"user\"]` (i.e. `~/.claude/.credentials.json`).\n // The driver remembers this so the error classifier can branch on the\n // credential type — auth-shaped failures from OAuth subscriptions\n // overwhelmingly correlate with quota/rate-limit, not invalid tokens.\n this.usingOauthCredential = !apiKey;\n\n const claudePath = this.findClaudeBinary();\n\n const options: SdkOptions = {\n cwd: this.config.cwd,\n // Load project + user settings so .claude/skills/ are discovered\n settingSources: [\"user\", \"project\"],\n // Use full Claude Code tool preset so skills, agents, etc. work\n tools: { type: \"preset\", preset: \"claude_code\" },\n permissionMode: \"bypassPermissions\",\n allowDangerouslySkipPermissions: true,\n abortController: this.abortController,\n model: this.config.model || \"sonnet\",\n maxTurns: this.config.maxTurns ?? 15,\n includePartialMessages: true,\n // Thinking mode — maps simple string config to SDK ThinkingConfig objects\n ...(this.config.thinking ? { thinking: this.mapThinkingConfig(this.config.thinking) } : {}),\n // Reasoning effort — passed directly to the SDK\n ...(this.config.effort ? { effort: this.config.effort } : {}),\n hooks: {},\n stderr: (data: string) => this.log.warn(\"claude stderr\", { line: data.trim() }),\n ...(claudePath ? { pathToClaudeCodeExecutable: claudePath } : {}),\n ...(this.config.systemPrompt\n ? {\n systemPrompt: {\n type: \"preset\",\n preset: \"claude_code\",\n append: this.config.systemPrompt,\n },\n }\n : {}),\n // ── Session continuity ────────────────────────────────────────────────\n // Three-level fallback ensures the right session is always resumed:\n // resumeSessionId — caller explicitly wants this session (skaile resume)\n // sessionId — a session was already started this driver lifetime (multi-turn)\n // continue: true — resume the most recent session in cwd (between restarts)\n // (none) — start fresh\n ...(this.config.resumeSessionId\n ? { resume: this.config.resumeSessionId }\n : this.sessionId\n ? { resume: this.sessionId }\n : this.hasSession\n ? { continue: true }\n : {}),\n // ── Connector tool injection ──────────────────────────────────────────\n // In-process MCP servers from ConnectorManager (buildSdkConnectorTools in resources.ts).\n // These expose skaile.yaml connectors as native tool_use calls inside the session.\n // omp does not use this — it falls back to `skaile res <id> <op>` CLI commands\n // documented in the system prompt section (buildConnectorPromptSection).\n //\n // Protocol v2: when `config.capabilities` is provided, the runner's\n // CapabilityRegistry contributes an additional `skaile-capabilities`\n // synthetic MCP server alongside any pre-existing `mcpServers`. Tool\n // calls into that server route back through `hooks.invoke()` so the\n // registry's per-handler logger fires and fire-and-forget / render\n // semantics apply uniformly.\n ...(await this.buildEffectiveMcpServers()),\n // ── Main-agent handoff ────────────────────────────────────────────────\n // agentName (from AgentConfig) is the equivalent of `claude --agent <name>`.\n // The SDK reads .claude/agents/<agentName>.md from the cwd; that file was\n // rendered by asset-manager (claudeCodeRenderer) during `skaile install`.\n // Its YAML frontmatter sets model / tools / maxTurns; its markdown body is the\n // assembled system prompt (SOUL + fragments + RULES + abilities + contracts).\n // Omitting agentName uses Claude Code's default identity (no custom agent file).\n ...(this.config.agentName ? { agent: this.config.agentName } : {}),\n // Tool restrictions from agent.yaml — always include a wildcard allow-entry for each\n // injected MCP server so connector tools aren't silently blocked by an allowlist.\n ...this.buildToolRestrictions(),\n };\n\n this.log.debug(\"query start\", {\n model: this.config.model || \"default\",\n session: this.config.resumeSessionId || this.sessionId || this.config.sessionId || \"new\",\n });\n\n const { query } = this.sdk!;\n const queryArgs: { prompt: string; options: SdkOptions; apiKey?: string } = {\n prompt: message,\n options,\n };\n if (apiKey) queryArgs.apiKey = apiKey;\n\n this.query = query(queryArgs);\n this.consumeMessages();\n }\n\n override getSlashCommands(): SlashCommandInfo[] {\n return this.cachedCommands;\n }\n\n /**\n * Compose the MCP servers passed to the SDK query. Merges the legacy\n * `config.mcpServers` (connectors / workspace plugin / declarative skaile.yaml\n * entries) with a synthetic `skaile-capabilities` server built from the\n * runner-provided {@link BridgeCapabilityHooks} when present.\n *\n * Returns an empty options patch when neither source is configured, so legacy\n * v1 sessions remain unaffected.\n */\n private async buildEffectiveMcpServers(): Promise<Pick<SdkOptions, \"mcpServers\">> {\n const out: Record<string, unknown> = {};\n if (this.config.mcpServers) {\n Object.assign(out, this.config.mcpServers);\n }\n\n const hooks = this.config.capabilities;\n if (hooks) {\n const capServer = await this.buildCapabilityMcpServer();\n if (capServer) {\n out[\"skaile-capabilities\"] = capServer;\n }\n }\n\n return Object.keys(out).length > 0 ? { mcpServers: out as SdkOptions[\"mcpServers\"] } : {};\n }\n\n /**\n * Build the synthetic MCP server that exposes registered capabilities to the\n * Claude Agent SDK. Lazy-imports `createSdkMcpServer` from the SDK and `zod`\n * (an SDK peer) since both are optional peers of this bridge.\n *\n * Returns null when the SDK or zod is unavailable, or when the registry\n * exposes no tools — leaving the legacy `mcpServers` untouched.\n */\n private async buildCapabilityMcpServer(): Promise<unknown | null> {\n const hooks = this.config.capabilities;\n if (!hooks) return null;\n const tools = hooks.composeTools();\n if (tools.length === 0) return null;\n\n let sdk: any;\n try {\n sdk = await import(\"@anthropic-ai/claude-agent-sdk\");\n } catch {\n this.log.warn(\"claude-agent-sdk unavailable; cannot build capability MCP server\");\n return null;\n }\n // Static import below at module scope ensures bun --compile bundles zod\n // into the binary; dynamic import(\"zod\") via a string variable evades\n // bun's static analysis and fails at runtime inside /$bunfs/.\n const z: any = zStatic;\n\n // Build per-tool entries. Schemas arrive from the registry as JSON Schema\n // (Zod -> z.toJSONSchema in `defineCapability`). The Claude SDK accepts\n // either a Zod object or a record of Zod fields; we mirror the existing\n // `buildSdkConnectorTools` path which uses an inputSchema record. The full\n // input contract is enforced server-side by `hooks.invoke()` (Zod parse).\n const sdkTools = tools.map((tool) => ({\n name: tool.name,\n description: tool.description,\n // Pass through the JSON Schema object directly. The SDK forwards it to\n // the LLM as the function parameter spec. Concrete validation runs in\n // `hooks.invoke()`, not the SDK.\n inputSchema: jsonSchemaToZodLoose(tool.parameters, z) ?? { args: z.unknown().optional() },\n handler: async (input: unknown) => {\n const callId = `cap-${Date.now()}-${Math.floor(Math.random() * 1e6)}`;\n try {\n const dispatch = await dispatchCapability(hooks, callId, tool.name, input, (err) =>\n this.log.warn(\"background capability handler failed\", {\n name: tool.name,\n error: String(err),\n }),\n );\n const text =\n typeof dispatch.result === \"string\"\n ? dispatch.result\n : JSON.stringify(dispatch.result ?? {});\n return { content: [{ type: \"text\" as const, text }] };\n } catch (err: any) {\n return {\n content: [{ type: \"text\" as const, text: `Error: ${err?.message ?? String(err)}` }],\n isError: true,\n };\n }\n },\n }));\n\n return sdk.createSdkMcpServer({ name: \"skaile-capabilities\", tools: sdkTools });\n }\n\n /** Fetch and cache slash commands from the SDK query. */\n private async fetchSlashCommands(): Promise<void> {\n if (!this.query) return;\n try {\n const commands = await this.query.supportedCommands();\n this.cachedCommands = commands.map((c) => ({\n name: c.name,\n description: c.description,\n argumentHint: c.argumentHint || undefined,\n }));\n this.emit(\"agent-event\", {\n type: \"commands_available\",\n commands: this.cachedCommands,\n } satisfies AgentEvent);\n this.log.debug(\"discovered slash commands\", { count: this.cachedCommands.length });\n } catch (err) {\n this.log.warn(\"failed to fetch slash commands\", { error: String(err) });\n }\n }\n\n /**\n * Background loop — consumes the query's async generator continuously.\n * The generator stays alive between turns; streamInput() feeds new messages.\n * If it ends unexpectedly, query is nulled so the next prompt() restarts.\n */\n private async consumeMessages(): Promise<void> {\n // Fetch slash commands in the background once the query is live\n this.fetchSlashCommands();\n\n try {\n for await (const msg of this.query!) {\n if (this.abortController?.signal.aborted) break;\n\n // Capture session info from first message\n const sessionId = \"session_id\" in msg ? msg.session_id : undefined;\n if (sessionId) {\n if (!this.hasSession) {\n this.hasSession = true;\n this.log.debug(\"session id assigned\", { sessionId });\n }\n this.sessionId = sessionId;\n }\n\n this.handleSdkMessage(msg);\n\n // result = turn boundary — but only complete the turn when the\n // result was NOT an error. The Claude Agent SDK occasionally emits\n // `{type: \"result\", subtype: \"success\", is_error: true, errors: []}`\n // when an upstream API call (e.g. a 401) made the run fail; the\n // actual error text arrives ~200 ms later as a thrown exception\n // from this iterator. If we resolve the turn here on the\n // is_error result, the consumer-error catch below fires with\n // `turnReject` already null, the bridge's auth-retry path in\n // `prompt()` never runs, and the user sees a fatal 401. By\n // skipping `completeTurn` for is_error results, the turn stays\n // pending until the thrown exception lands in the catch and\n // `failTurn(AuthError)` rejects the promise with the real error.\n //\n // Spec: `_devlog/specs/2026-05-07-unified-credential-mediation.md`.\n if (msg.type === \"result\" && !(msg as { is_error?: boolean }).is_error) {\n this.completeTurn();\n }\n }\n } catch (err: unknown) {\n const error = err instanceof Error ? err : new Error(String(err));\n if (error.name === \"AbortError\" || this.abortController?.signal.aborted) {\n this.log.info(\"aborted\");\n } else {\n const detail = classifyClaudeSdkError({\n errors: [error.message],\n oauthCredential: this.usingOauthCredential,\n });\n this.log.error(\"consumer error\", {\n message: error.message,\n category: detail.category,\n retryable: detail.retryable,\n });\n // Promote auth-shaped failures to a structured AuthError subclass so\n // the runner's 401-mediation handler can `instanceof`-discriminate\n // without parsing strings. Other categories surface as plain Error.\n const surfaced = detail.category === \"auth\" ? new AuthError(detail) : error;\n this.failTurn(surfaced, detail);\n }\n } finally {\n this.log.debug(\"query generator ended\");\n this.completeTurn();\n this.query = null;\n }\n }\n\n /**\n * Signal the current turn as done — idempotent per turn.\n *\n * Same defensive ordering as {@link failTurn}: settle the turn promise\n * before emitting `agent_end` so a misbehaving listener cannot trap the\n * promise in a pending state. See failTurn's docblock for the production\n * incident that motivated this pattern.\n */\n private completeTurn(): void {\n if (this.turnCompleted) return;\n this.turnCompleted = true;\n if (this.turnResolve) {\n this.turnResolve();\n this.turnResolve = null;\n this.turnReject = null;\n }\n try {\n this.emit(\"agent-event\", { type: \"agent_end\" } satisfies AgentEvent);\n } catch (emitErr) {\n this.log.warn(\"agent-event listener threw during completeTurn; suppressing\", {\n error: emitErr instanceof Error ? emitErr.message : String(emitErr),\n });\n }\n }\n\n /**\n * Signal the current turn as failed. When a structured `detail` is\n * supplied, the AgentEvent carries the category + hint so downstream\n * consumers (normalizer → runner → platform → frontend) can surface a\n * useful diagnosis instead of the raw upstream string.\n *\n * Reject ordering: `turnReject()` runs FIRST, then the agent-event is\n * emitted. `EventEmitter#emit` calls listeners synchronously; if any\n * listener throws (transport.send on a closed socket, normalizer bug,\n * compaction tracking error, etc.) the throw would otherwise propagate\n * out of failTurn before `turnReject` can run, leaving `await\n * turnPromise` pending forever and silently hanging `driver.prompt(...)`\n * — which in turn prevents the runner's `onAuthError` callback from\n * firing on stale-token 401s. Settling the promise first guarantees the\n * caller transitions even if the listener chain misbehaves; the emit is\n * wrapped in try/catch so a listener failure cannot leak out.\n *\n * Self-heal deferral: when the failure is an {@link AuthError} on the\n * first attempt (`currentRetryCount === 0`) AND the caller wired an\n * `onAuthError` callback, the downstream `agent-event: error` emission\n * is deferred. The rejected turn promise still travels to {@link prompt}'s\n * catch block where the self-heal runs; if the retry succeeds the user\n * never sees a 401, if the retry fails the second `failTurn` call (now\n * with `currentRetryCount === 1`) emits the error normally. This stops\n * the historical \"401 flashes in the UI even though self-heal worked\"\n * misbehaviour where the bridge emitted the error event before the\n * retry decision was known.\n *\n * Spec: `_devlog/specs/2026-05-07-unified-credential-mediation.md`\n * § \"Runner-side handling on 401\" (the AI 401 mediation path that\n * exposed this hang).\n */\n private failTurn(err: Error, detail?: import(\"../types.js\").AgentError): void {\n if (this.turnReject) {\n this.turnReject(err);\n this.turnResolve = null;\n this.turnReject = null;\n }\n // Mark the turn as completed so the defensive `consumeMessages` finally\n // block (which calls `completeTurn()` regardless of how the iterator\n // exited) does not also emit `agent_end` after we already rejected.\n // Without this, the auth-retry path emits an `agent_end` for the failed\n // attempt AND a second one for the successful retry, doubling the\n // session-end signal downstream. A turn ends EITHER via `completeTurn`\n // (success → emit agent_end) OR via `failTurn` (rejected) — never both.\n this.turnCompleted = true;\n const willSelfHeal =\n err instanceof AuthError && this.currentRetryCount === 0 && this.config.onAuthError != null;\n if (willSelfHeal) {\n this.log.info(\"deferring auth-error event; self-heal will attempt refresh\");\n return;\n }\n try {\n this.emit(\"agent-event\", {\n type: \"error\",\n error: err.message,\n ...(detail ? { detail } : {}),\n } satisfies AgentEvent);\n } catch (emitErr) {\n this.log.warn(\"agent-event listener threw during failTurn; suppressing\", {\n error: emitErr instanceof Error ? emitErr.message : String(emitErr),\n });\n }\n }\n\n // ---------------------------------------------------------------------------\n // Message handling\n // ---------------------------------------------------------------------------\n\n private handleSdkMessage(msg: SDKMessage): void {\n // SDKRateLimitEvent — claude.ai subscription rate-limit telemetry. Surfaced\n // as a structured warning log so the debug pane and CLI logs show that the\n // upstream limiter is degrading. We do NOT promote `allowed_warning` to a\n // user-visible error; only `rejected` aligns with a turn-blocking failure\n // and that path emits its own `error` event when the SDK returns the\n // result.\n const maybeRateLimit = msg as unknown as {\n type?: string;\n rate_limit_info?: {\n status?: string;\n rateLimitType?: string;\n utilization?: number;\n resetsAt?: number;\n };\n };\n if (maybeRateLimit.type === \"rate_limit_event\" && maybeRateLimit.rate_limit_info) {\n const info = maybeRateLimit.rate_limit_info;\n this.log.warn(\"upstream rate-limit telemetry\", {\n status: info.status,\n type: info.rateLimitType,\n utilization: info.utilization,\n resetsAt: info.resetsAt,\n });\n // Don't emit an agent-event for warning levels — the user only needs to\n // hear about it on `rejected`, which the result handler already covers.\n return;\n }\n\n if (msg.type === \"assistant\") {\n const agentMsg = this.mapAssistantMessage(msg);\n\n this.emit(\"agent-event\", { type: \"message_start\", message: agentMsg } satisfies AgentEvent);\n\n if (agentMsg.toolCalls) {\n for (const tc of agentMsg.toolCalls) {\n this.emit(\"agent-event\", {\n type: \"tool_call\",\n name: tc.name,\n tool: { name: tc.name },\n input: tc.input,\n });\n }\n }\n\n this.prevText = \"\";\n this.emit(\"agent-event\", { type: \"message_end\", message: agentMsg } satisfies AgentEvent);\n } else if (msg.type === \"stream_event\") {\n const event = msg.event;\n if (\n event?.type === \"content_block_delta\" &&\n event.delta?.type === \"text_delta\" &&\n event.delta.text\n ) {\n const delta = event.delta.text;\n this.prevText += delta;\n const agentMsg: AgentMessage = {\n role: \"assistant\",\n content: [{ type: \"text\", text: this.prevText }],\n };\n this.emit(\"agent-event\", {\n type: \"message_update\",\n message: agentMsg,\n _textDelta: delta,\n } satisfies AgentEvent as any);\n }\n } else if (msg.type === \"user\") {\n const toolResults = this.mapToolResults(msg);\n for (const result of toolResults) {\n this.emit(\"agent-event\", {\n type: \"tool_execution_end\",\n toolName: result.toolName,\n });\n }\n if (toolResults.length > 0) {\n this.emit(\"agent-event\", { type: \"turn_end\", toolResults } satisfies AgentEvent);\n }\n } else if (msg.type === \"result\") {\n // Capture token usage from the result message. Anthropic separates\n // fresh prompt input from cached/cache-creation tokens — surface all\n // four to consumers that want a complete picture.\n const usage = (msg as any).usage as\n | {\n input_tokens?: number;\n output_tokens?: number;\n cache_read_input_tokens?: number;\n cache_creation_input_tokens?: number;\n }\n | undefined;\n if (usage) {\n const tokens: TokenUsage = {};\n if (typeof usage.input_tokens === \"number\") tokens.inputTokens = usage.input_tokens;\n if (typeof usage.output_tokens === \"number\") tokens.outputTokens = usage.output_tokens;\n if (typeof usage.cache_read_input_tokens === \"number\")\n tokens.cacheReadTokens = usage.cache_read_input_tokens;\n if (typeof usage.cache_creation_input_tokens === \"number\")\n tokens.cacheCreationTokens = usage.cache_creation_input_tokens;\n this._lastTokens = tokens;\n }\n const modelUsage = (msg as any).modelUsage as\n | Record<string, { contextWindow?: number }>\n | undefined;\n if (modelUsage) {\n const first = Object.values(modelUsage)[0];\n if (first?.contextWindow) this._contextWindow = first.contextWindow;\n }\n\n // Branch on `is_error` BEFORE `subtype === \"success\"`. The Claude Agent\n // SDK occasionally emits result messages where `subtype === \"success\"`\n // AND `is_error === true` AND `errors === []` — observed in production\n // when an upstream `authentication_error` from the Anthropic API made\n // the SDK fail the turn but still tag it as a \"successful run\" because\n // the agent loop itself (the SDK process) terminated without a process\n // crash. The actual 401 surfaces ~200 ms later as a thrown exception\n // in the for-await iterator. Without this guard, `handleSdkMessage`\n // takes the success branch on subtype, `consumeMessages` calls\n // `completeTurn` (resolving the turn promise), and the subsequent\n // throw lands in the consumer-error catch with `turnReject` already\n // null — the bridge's auth-retry catch in `prompt()` never runs and\n // the user sees a fatal 401. Treating any `is_error: true` result as\n // an error (regardless of subtype) routes through `failTurn` so the\n // turn promise rejects with a structured `AuthError` and the runner's\n // `onAuthError` callback can refresh the credential.\n //\n // Spec: `_devlog/specs/2026-05-07-unified-credential-mediation.md`.\n if (msg.subtype === \"success\" && !msg.is_error) {\n if (msg.result) {\n const agentMsg: AgentMessage = {\n role: \"assistant\",\n content: msg.result,\n };\n this.emit(\"agent-event\", { type: \"message_end\", message: agentMsg } satisfies AgentEvent);\n }\n this.emit(\"agent-event\", {\n type: \"result\",\n subtype: msg.subtype,\n summary: msg.result ?? \"Task completed\",\n costUsd: msg.total_cost_usd ?? 0,\n ...(this._lastTokens ? { tokens: this._lastTokens } : {}),\n } as AgentEvent);\n } else {\n // The else branch is now reachable for two cases:\n // 1) `subtype !== 'success'` (the legacy SDKResultError shape)\n // 2) `subtype === 'success' && is_error === true` (production\n // observation 2026-05-09 — an upstream 401 makes the SDK tag\n // the run as a successful exit code while still flagging\n // `is_error: true`; see the success-branch guard above).\n // Case (2) carries no `errors` field on the typed\n // `SDKResultSuccess` variant, so we coerce through the loose\n // result shape to read it uniformly.\n const looseMsg = msg as { errors?: string[]; is_error?: boolean; terminal_reason?: string };\n const errors: string[] = looseMsg.errors?.length ? looseMsg.errors : [];\n if (looseMsg.is_error) {\n // SDKResultError carries `terminal_reason` and `subtype` we use\n // to override the raw text — `blocking_limit` is authoritatively\n // a quota issue even when the surrounding errors[] reads as auth.\n const detail = classifyClaudeSdkError({\n errors,\n terminalReason: (msg as { terminal_reason?: string }).terminal_reason,\n subtype: msg.subtype,\n oauthCredential: this.usingOauthCredential,\n });\n this.log.error(\"turn ended with error\", {\n subtype: msg.subtype,\n terminalReason: (msg as { terminal_reason?: string }).terminal_reason,\n errorsCount: errors.length,\n category: detail.category,\n retryable: detail.retryable,\n });\n const errorText = errors.join(\"; \") || `Agent stopped: ${msg.subtype}`;\n // Auth-shaped result errors (`authentication_error` structured body\n // or 401 in the error text) surface as a thrown `AuthError` so the\n // runner's 401-mediation handler can `instanceof`-discriminate\n // without parsing strings. `failTurn` emits the `error` AgentEvent\n // itself, so we route through it on the auth path to avoid emitting\n // a duplicate `error` event before the turn rejects.\n //\n // When `errors` is empty AND the classifier could not pin a\n // category, the SDK has signalled \"the turn failed but the actual\n // error text is coming via a thrown exception ~200 ms later\"\n // (observed in production for upstream 401s). We must NOT emit a\n // placeholder error event here — the consumer-error catch below\n // will surface the real error with the correct classification, and\n // emitting a stub now would leak `Agent stopped: success` to the\n // frontend before the real 401 arrives. The matching guard in\n // `consumeMessages` skips `completeTurn` for is_error results so\n // the turn stays pending until the thrown exception lands.\n //\n // Spec: `_devlog/specs/2026-05-07-unified-credential-mediation.md`\n // § \"Runner-side handling on 401\".\n if (detail.category === \"auth\") {\n this.failTurn(new AuthError({ ...detail, message: errorText }), detail);\n } else if (errors.length > 0) {\n // Real error info present — surface it normally.\n this.emit(\"agent-event\", {\n type: \"error\",\n error: errorText,\n detail,\n } satisfies AgentEvent);\n }\n // is_error + empty errors → defer to consumer-error catch.\n }\n this.emit(\"agent-event\", {\n type: \"result\",\n subtype: msg.subtype,\n errors,\n } as AgentEvent);\n }\n }\n }\n\n // ---------------------------------------------------------------------------\n // Helpers\n // ---------------------------------------------------------------------------\n\n /** Build an SDKUserMessage for streamInput. */\n private buildUserMessage(text: string): SDKUserMessage {\n return {\n type: \"user\",\n message: {\n role: \"user\",\n content: text,\n },\n parent_tool_use_id: null,\n session_id: this.sessionId,\n };\n }\n\n /** Wrap a single value as an AsyncIterable that yields once. */\n private async *singleItemIterable<T>(item: T): AsyncIterable<T> {\n yield item;\n }\n\n private mapAssistantMessage(msg: SDKAssistantMessage): AgentMessage {\n const contentBlocks: ContentBlock[] = [];\n const toolCalls: ToolCall[] = [];\n const content = msg.message.content;\n\n if (Array.isArray(content)) {\n for (const block of content) {\n if (block.type === \"text\") {\n contentBlocks.push({ type: \"text\", text: block.text });\n } else if (block.type === \"tool_use\") {\n contentBlocks.push({\n type: \"tool_use\",\n id: block.id,\n name: block.name,\n input: block.input,\n });\n toolCalls.push({ id: block.id, name: block.name, input: block.input });\n this.toolIdToName.set(block.id, block.name);\n } else if (block.type === \"thinking\") {\n contentBlocks.push({ type: \"thinking\", text: block.thinking });\n }\n }\n }\n\n return {\n role: \"assistant\",\n content: contentBlocks,\n toolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n };\n }\n\n private mapToolResults(msg: SDKUserMessage): AgentMessage[] {\n const results: AgentMessage[] = [];\n const content = msg.message.content;\n\n if (Array.isArray(content)) {\n for (const block of content) {\n if (block.type === \"tool_result\") {\n results.push({\n role: \"tool\",\n content:\n typeof block.content === \"string\" ? block.content : JSON.stringify(block.content),\n toolName: this.toolIdToName.get(block.tool_use_id) ?? block.tool_use_id,\n isError: block.is_error,\n });\n }\n }\n }\n\n return results;\n }\n\n /**\n * Requests the current SDK query to stop processing via `query.interrupt()` and\n * signals the underlying `AbortController`. The driver remains usable after abort.\n *\n * @remarks Best-effort: if `interrupt()` throws (e.g. query already ended) the\n * error is silently swallowed and the abort signal is still sent.\n */\n public async abort(): Promise<void> {\n if (this.query) {\n try {\n await this.query.interrupt();\n } catch {\n /* best effort */\n }\n }\n if (this.abortController) {\n this.abortController.abort();\n }\n }\n\n /** `true` while the driver is processing a `prompt()` call. */\n get isRunning(): boolean {\n return this.running;\n }\n\n /**\n * Closes the active SDK query and resets all session state.\n *\n * The driver instance must not be reused after `kill()`. Session IDs are cleared,\n * so a new `ClaudeSdkDriver` will start a fresh session.\n */\n public kill(): void {\n if (this.query) {\n try {\n this.query.close();\n } catch {\n /* best effort */\n }\n this.query = null;\n }\n this.abortController?.abort();\n this.running = false;\n this.sessionId = \"\";\n this.hasSession = false;\n }\n\n override async listModels(): Promise<ModelEntry[]> {\n const apiKey =\n this.config.apiKeys?.anthropic ||\n this.config.env?.ANTHROPIC_API_KEY ||\n process.env.ANTHROPIC_API_KEY;\n if (!apiKey) return [];\n const result = await fetchProviderModels(\"anthropic\", apiKey);\n return result.ok ? (result.models as ModelEntry[]) : [];\n }\n\n override getTokenUsage(): TokenUsage | null {\n return this._lastTokens;\n }\n\n override getContextWindow(): number | null {\n return this._contextWindow;\n }\n\n async resetSession(): Promise<void> {\n if (this.query) {\n try {\n this.query.close();\n } catch {\n /* ignore */\n }\n this.query = null;\n }\n this.abortController?.abort();\n this.sessionId = \"\";\n this.hasSession = false;\n this._lastTokens = null;\n this._contextWindow = null;\n }\n\n /**\n * Build allowedTools / disallowedTools options from AgentConfig.tools.\n *\n * When an allowlist is active, automatically prepend a wildcard entry for\n * every configured MCP server (e.g. `mcp__skaile-connectors__*`) so that\n * connector tools are never silently blocked by agent.yaml restrictions.\n */\n private buildToolRestrictions(): Pick<SdkOptions, \"allowedTools\" | \"disallowedTools\"> {\n const mcpWildcards = this.config.mcpServers\n ? Object.keys(this.config.mcpServers).map((name) => `mcp__${name}__*`)\n : [];\n\n const result: Pick<SdkOptions, \"allowedTools\" | \"disallowedTools\"> = {};\n\n // Only set allowedTools if the manifest explicitly declared an allow list.\n // MCP wildcards are appended to ensure connector tools aren't blocked by\n // the allowlist, but they should NOT create an allowlist on their own —\n // that would block all non-MCP tools (Read, Write, Bash, etc.).\n const allowed = this.config.tools?.allowed;\n if (allowed?.length) {\n result.allowedTools = [...allowed, ...mcpWildcards];\n }\n\n if (this.config.tools?.denied?.length) {\n result.disallowedTools = this.config.tools.denied;\n }\n\n return result;\n }\n\n /**\n * Map the simple string thinking config to SDK ThinkingConfig objects.\n * This keeps the platform-layer SDK-agnostic while the bridge handles the mapping.\n */\n private mapThinkingConfig(\n thinking: \"adaptive\" | \"enabled\" | \"disabled\",\n ): { type: \"adaptive\" } | { type: \"enabled\" } | { type: \"disabled\" } {\n switch (thinking) {\n case \"adaptive\":\n return { type: \"adaptive\" };\n case \"enabled\":\n return { type: \"enabled\" };\n case \"disabled\":\n return { type: \"disabled\" };\n }\n }\n\n /**\n * Find the Claude Code CLI executable.\n *\n * Resolution order:\n * 1. CLAUDE_CODE_PATH env var (set in Docker containers where cli.js is\n * extracted from the SDK during build — bun-compiled binaries can't\n * access the SDK's bundled cli.js via $bunfs)\n * 2. `which claude` on PATH (dev machines with claude installed globally)\n * 3. undefined — let the SDK resolve its own bundled cli.js (works when\n * not running inside a bun-compiled binary)\n */\n private findClaudeBinary(): string | undefined {\n const envPath = process.env.CLAUDE_CODE_PATH;\n if (envPath && existsSync(envPath)) return envPath;\n\n const result = spawnSync(\"which\", [\"claude\"], { encoding: \"utf-8\" });\n const p = result.stdout?.trim();\n return p || undefined;\n }\n}\n\nregisterDriver(\"claude-sdk\", (config) => new ClaudeSdkDriver(config), DRIVER_CATALOG[\"claude-sdk\"]);\n"]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { fetchProviderModels } from '../../chunk-KOVLSBXK.js';
|
|
2
|
-
import { registerDriver, DRIVER_CATALOG, AgentDriver, getBridgeLogger } from '../../chunk-
|
|
2
|
+
import { registerDriver, DRIVER_CATALOG, AgentDriver, getBridgeLogger } from '../../chunk-YOFKTALB.js';
|
|
3
3
|
import '../../chunk-24UIWON4.js';
|
|
4
4
|
import '../../chunk-NSBPE2FW.js';
|
|
5
5
|
import { existsSync, readFileSync, mkdirSync, writeFileSync } from 'fs';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { dispatchCapability } from '../../chunk-RRVQAE5D.js';
|
|
2
|
-
import { registerDriver, DRIVER_CATALOG, AgentDriver, getBridgeLogger } from '../../chunk-
|
|
2
|
+
import { registerDriver, DRIVER_CATALOG, AgentDriver, getBridgeLogger } from '../../chunk-YOFKTALB.js';
|
|
3
3
|
import '../../chunk-24UIWON4.js';
|
|
4
4
|
import '../../chunk-NSBPE2FW.js';
|
|
5
5
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { registerDriver, DRIVER_CATALOG, AgentDriver, getBridgeLogger } from '../../chunk-
|
|
1
|
+
import { registerDriver, DRIVER_CATALOG, AgentDriver, getBridgeLogger } from '../../chunk-YOFKTALB.js';
|
|
2
2
|
import '../../chunk-24UIWON4.js';
|
|
3
3
|
import '../../chunk-NSBPE2FW.js';
|
|
4
4
|
import { spawn, execFile } from 'child_process';
|
package/dist/bridge/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { BridgeRuntime, EventNormalizer, createRuntime, detectFileChange, detectFileChanges, summarizeToolCall, summarizeToolResult, validateApiKey } from '../chunk-
|
|
1
|
+
export { BridgeRuntime, EventNormalizer, createRuntime, detectFileChange, detectFileChanges, summarizeToolCall, summarizeToolResult, validateApiKey } from '../chunk-VMU2WEN7.js';
|
|
2
2
|
export { AuthError, classifyClaudeSdkError } from '../chunk-EWP5HZBV.js';
|
|
3
3
|
export { STATIC_MODELS, fetchProviderModels, getModels, getStaticModels } from '../chunk-KOVLSBXK.js';
|
|
4
4
|
export { dispatchCapability, filterRenderCapabilities, renderFallback } from '../chunk-RRVQAE5D.js';
|
|
5
|
-
export { AgentDriver, DRIVER_CATALOG, createDriver, getBridgeLogger, listDrivers, listModelsForDriver, loadDriver, registerDriver } from '../chunk-
|
|
5
|
+
export { AgentDriver, DRIVER_CATALOG, createDriver, getBridgeLogger, listDrivers, listModelsForDriver, loadDriver, registerDriver } from '../chunk-YOFKTALB.js';
|
|
6
6
|
import '../chunk-24UIWON4.js';
|
|
7
7
|
import '../chunk-NSBPE2FW.js';
|
|
8
8
|
//# sourceMappingURL=index.js.map
|
|
@@ -51,6 +51,17 @@ export declare class ClaudeSdkDriver extends AgentDriver {
|
|
|
51
51
|
private turnReject;
|
|
52
52
|
/** Guards against duplicate agent_end emissions per turn. */
|
|
53
53
|
private turnCompleted;
|
|
54
|
+
/**
|
|
55
|
+
* Mirror of the `_retryCount` argument of the in-flight {@link prompt} call.
|
|
56
|
+
* Read by {@link failTurn} to decide whether to defer the `agent-event:
|
|
57
|
+
* error` emission for a self-healable auth error. `0` means "first
|
|
58
|
+
* attempt"; `prompt()` increments to `1` before recursing on its
|
|
59
|
+
* `onAuthError` self-heal branch.
|
|
60
|
+
*
|
|
61
|
+
* Set unconditionally at the top of every {@link prompt} invocation; never
|
|
62
|
+
* reset elsewhere — the next call's set is the only legitimate transition.
|
|
63
|
+
*/
|
|
64
|
+
private currentRetryCount;
|
|
54
65
|
/** Tracks whether a session has been started (for continue: true). */
|
|
55
66
|
private hasSession;
|
|
56
67
|
/** Session ID from the SDK — used for streamInput messages. */
|
|
@@ -185,6 +196,17 @@ export declare class ClaudeSdkDriver extends AgentDriver {
|
|
|
185
196
|
* caller transitions even if the listener chain misbehaves; the emit is
|
|
186
197
|
* wrapped in try/catch so a listener failure cannot leak out.
|
|
187
198
|
*
|
|
199
|
+
* Self-heal deferral: when the failure is an {@link AuthError} on the
|
|
200
|
+
* first attempt (`currentRetryCount === 0`) AND the caller wired an
|
|
201
|
+
* `onAuthError` callback, the downstream `agent-event: error` emission
|
|
202
|
+
* is deferred. The rejected turn promise still travels to {@link prompt}'s
|
|
203
|
+
* catch block where the self-heal runs; if the retry succeeds the user
|
|
204
|
+
* never sees a 401, if the retry fails the second `failTurn` call (now
|
|
205
|
+
* with `currentRetryCount === 1`) emits the error normally. This stops
|
|
206
|
+
* the historical "401 flashes in the UI even though self-heal worked"
|
|
207
|
+
* misbehaviour where the bridge emitted the error event before the
|
|
208
|
+
* retry decision was known.
|
|
209
|
+
*
|
|
188
210
|
* Spec: `_devlog/specs/2026-05-07-unified-credential-mediation.md`
|
|
189
211
|
* § "Runner-side handling on 401" (the AI 401 mediation path that
|
|
190
212
|
* exposed this hang).
|