@clanker-cleanroom/claude 0.2.8-build.41 → 0.2.9-build.43

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.
@@ -161,7 +161,7 @@ const claudeBinding = {
161
161
  trajectoryKind: "claude",
162
162
  adaptEvents: adaptClaudeEvents,
163
163
  sessionDataPath: CLAUDE_CONTAINER_SESSION_PATH,
164
- command: ({ prompt, model, sessionId }) => {
164
+ command: ({ model, sessionId }) => {
165
165
  const claudeArgs = [
166
166
  "claude",
167
167
  "-p",
@@ -172,7 +172,6 @@ const claudeBinding = {
172
172
  ];
173
173
  if (sessionId !== void 0 && sessionId !== "") claudeArgs.push("--resume", sessionId);
174
174
  if (model !== void 0 && model !== "") claudeArgs.push("--model", model);
175
- claudeArgs.push("--", prompt);
176
175
  return claudeArgs;
177
176
  },
178
177
  prepare: async () => {
@@ -227,4 +226,4 @@ function describeErrorResult(result) {
227
226
  //#endregion
228
227
  export { CLAUDE_API_KEY_ENV as a, CLAUDE_IMAGE as c, resolveClaudeCredentials as i, CLAUDE_OAUTH_TOKEN_ENV as l, adaptClaudeEvents as n, CLAUDE_CONTAINER_CREDENTIALS_PATH as o, credentialsEnv as r, CLAUDE_CONTAINER_SESSION_PATH as s, claudeBinding as t, defaultClaudeHostCredentialsFile as u };
229
228
 
230
- //# sourceMappingURL=binding-DRnzgDU4.mjs.map
229
+ //# sourceMappingURL=binding-1hmUr1aZ.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"binding-DRnzgDU4.mjs","names":["fsConstants"],"sources":["../src/constants.ts","../src/credentials.ts","../src/trajectory.ts","../src/binding.ts"],"sourcesContent":["import { CONTAINER_HOME } from \"clanker-cleanroom\";\n\nexport const CLAUDE_IMAGE = \"clanker-cleanroom/claude\";\nexport const CLAUDE_CONTAINER_CREDENTIALS_PATH = `${CONTAINER_HOME}/.claude/.credentials.json`;\n/** Session transcripts for cwd `/workspace` (Claude encodes `/` as `-`). */\nexport const CLAUDE_CONTAINER_SESSION_PATH = `${CONTAINER_HOME}/.claude/projects/-workspace`;\n\n/** Long-lived OAuth token from `claude setup-token` (Claude subscription). */\nexport const CLAUDE_OAUTH_TOKEN_ENV = \"CLAUDE_CODE_OAUTH_TOKEN\";\n/** Anthropic API key (pay-as-you-go). */\nexport const CLAUDE_API_KEY_ENV = \"ANTHROPIC_API_KEY\";\n\n/** Linux hosts persist OAuth credentials here; macOS uses the Keychain instead. */\nexport const defaultClaudeHostCredentialsFile = (home: string): string =>\n `${home}/.claude/.credentials.json`;\n","import { access } from \"node:fs/promises\";\nimport { constants as fsConstants } from \"node:fs\";\nimport { homedir } from \"node:os\";\n\nimport {\n CLAUDE_API_KEY_ENV,\n CLAUDE_OAUTH_TOKEN_ENV,\n defaultClaudeHostCredentialsFile,\n} from \"./constants.js\";\n\n/**\n * How Claude Code authenticates inside the container. Env-backed kinds are forwarded\n * to `docker run` by name (never on argv); the file kind is bind-mounted read-only.\n * See `constants.ts` for which host setups produce each.\n */\nexport type ClaudeCredentials =\n | { kind: \"oauth-token\"; token: string }\n | { kind: \"api-key\"; apiKey: string }\n | { kind: \"credentials-file\"; file: string };\n\n/** Env OAuth token, then env API key, then a readable host credentials file. */\nexport async function resolveClaudeCredentials(\n options: { env?: NodeJS.ProcessEnv; home?: string } = {},\n): Promise<ClaudeCredentials> {\n const env = options.env ?? process.env;\n const home = options.home ?? homedir();\n\n const token = env[CLAUDE_OAUTH_TOKEN_ENV];\n if (token !== undefined && token !== \"\") {\n return { kind: \"oauth-token\", token };\n }\n\n const apiKey = env[CLAUDE_API_KEY_ENV];\n if (apiKey !== undefined && apiKey !== \"\") {\n return { kind: \"api-key\", apiKey };\n }\n\n const file = defaultClaudeHostCredentialsFile(home);\n try {\n await access(file, fsConstants.R_OK);\n } catch {\n throw new Error(\n `Claude Code credentials not found. Set ${CLAUDE_OAUTH_TOKEN_ENV} (run \\`claude setup-token\\` on the host) ` +\n `or ${CLAUDE_API_KEY_ENV}, or provide ${file} (Linux hosts; macOS keeps credentials in the Keychain).`,\n );\n }\n\n return { kind: \"credentials-file\", file };\n}\n\n/** Secret values for the docker CLI process, keyed by env names forwarded via envPassthrough. */\nexport function credentialsEnv(credentials: ClaudeCredentials): Record<string, string> {\n switch (credentials.kind) {\n case \"oauth-token\":\n return { [CLAUDE_OAUTH_TOKEN_ENV]: credentials.token };\n case \"api-key\":\n return { [CLAUDE_API_KEY_ENV]: credentials.apiKey };\n case \"credentials-file\":\n return {};\n }\n}\n","import {\n asRecord,\n extractTextContent,\n readString,\n readTokenCount,\n type TrajectoryEvent,\n} from \"clanker-cleanroom\";\n\nexport function adaptClaudeEvents(rawEvents: readonly unknown[]): TrajectoryEvent[] {\n const events: TrajectoryEvent[] = [];\n\n for (const raw of rawEvents) {\n const record = asRecord(raw);\n if (record === undefined) {\n events.push({ kind: \"other\", type: \"unknown\", raw });\n continue;\n }\n\n const type = readString(record.type) ?? \"unknown\";\n\n switch (type) {\n case \"system\":\n events.push({\n kind: \"system\",\n sessionId: readString(record.session_id),\n model: readString(record.model),\n raw,\n });\n break;\n case \"user\":\n events.push(...adaptClaudeUser(record, raw));\n break;\n case \"assistant\":\n events.push(...adaptClaudeAssistant(record, raw));\n break;\n case \"result\":\n events.push({\n kind: \"result\",\n text: readString(record.result) ?? \"\",\n isError: record.is_error === true,\n durationMs: readTokenCount(record.duration_ms),\n costUsd: readTokenCount(record.total_cost_usd),\n raw,\n });\n break;\n default:\n events.push({ kind: \"other\", type, raw });\n }\n }\n\n return events;\n}\n\nfunction adaptClaudeAssistant(\n record: Record<string, unknown>,\n raw: unknown,\n): TrajectoryEvent[] {\n const events: TrajectoryEvent[] = [];\n const text = extractTextContent(record.message);\n if (text !== \"\") {\n events.push({ kind: \"assistant\", text, raw });\n }\n\n for (const block of contentBlocks(record.message)) {\n if (block.type !== \"tool_use\") {\n continue;\n }\n events.push({\n kind: \"tool\",\n phase: \"started\",\n callId: readString(block.id) ?? \"\",\n name: readString(block.name) ?? \"unknown\",\n args: block.input ?? null,\n result: null,\n raw,\n });\n }\n\n if (events.length === 0) {\n events.push({ kind: \"assistant\", text: \"\", raw });\n }\n\n return events;\n}\n\nfunction adaptClaudeUser(record: Record<string, unknown>, raw: unknown): TrajectoryEvent[] {\n const events: TrajectoryEvent[] = [];\n const text = extractTextContent(record.message);\n const toolResults: TrajectoryEvent[] = [];\n\n for (const block of contentBlocks(record.message)) {\n if (block.type !== \"tool_result\") {\n continue;\n }\n toolResults.push({\n kind: \"tool\",\n phase: \"completed\",\n callId: readString(block.tool_use_id) ?? \"\",\n name: \"tool_result\",\n args: null,\n result: block.content ?? null,\n raw,\n });\n }\n\n if (text !== \"\" || toolResults.length === 0) {\n events.push({ kind: \"user\", text, raw });\n }\n events.push(...toolResults);\n return events;\n}\n\nfunction contentBlocks(message: unknown): Record<string, unknown>[] {\n const content = asRecord(message)?.content;\n if (!Array.isArray(content)) {\n return [];\n }\n return content.map((block) => asRecord(block)).filter((block) => block !== undefined);\n}\n","import {\n asRecord,\n parseAgentJsonOutput,\n readTokenCount,\n type AgentBinding,\n type AgentRunResult,\n type DockerVolumeMount,\n} from \"clanker-cleanroom\";\n\nimport { CLAUDE_CONTAINER_CREDENTIALS_PATH, CLAUDE_CONTAINER_SESSION_PATH, CLAUDE_IMAGE } from \"./constants.js\";\nimport { credentialsEnv, resolveClaudeCredentials } from \"./credentials.js\";\nimport { adaptClaudeEvents } from \"./trajectory.js\";\n\nexport const claudeBinding: AgentBinding = {\n image: CLAUDE_IMAGE,\n displayName: \"Claude\",\n trajectoryKind: \"claude\",\n adaptEvents: adaptClaudeEvents,\n sessionDataPath: CLAUDE_CONTAINER_SESSION_PATH,\n command: ({ prompt, model, sessionId }) => {\n const claudeArgs = [\n \"claude\",\n \"-p\",\n \"--output-format\",\n \"stream-json\",\n \"--verbose\",\n \"--dangerously-skip-permissions\",\n ];\n if (sessionId !== undefined && sessionId !== \"\") {\n claudeArgs.push(\"--resume\", sessionId);\n }\n if (model !== undefined && model !== \"\") {\n claudeArgs.push(\"--model\", model);\n }\n claudeArgs.push(\"--\", prompt);\n return claudeArgs;\n },\n prepare: async () => {\n const credentials = await resolveClaudeCredentials();\n const volumes: DockerVolumeMount[] = [];\n if (credentials.kind === \"credentials-file\") {\n volumes.push({\n host: credentials.file,\n container: CLAUDE_CONTAINER_CREDENTIALS_PATH,\n mode: \"ro\",\n });\n }\n return {\n volumes,\n env: credentialsEnv(credentials),\n };\n },\n parseResult: parseClaudeResult,\n describeFailure: describeClaudeFailure,\n};\n\nfunction parseClaudeResult(trajectory: string): AgentRunResult {\n const parsed = parseAgentJsonOutput(trajectory);\n if (isErrorResult(parsed)) {\n throw new Error(`Claude agent reported an error: ${describeErrorResult(parsed)}`);\n }\n\n const record = asRecord(parsed);\n const usage = asRecord(record?.usage);\n\n return {\n durationMs: readTokenCount(record?.duration_ms),\n costUsd: readTokenCount(record?.total_cost_usd),\n usage: {\n inputTokens: readTokenCount(usage?.input_tokens ?? usage?.inputTokens),\n outputTokens: readTokenCount(usage?.output_tokens ?? usage?.outputTokens),\n cacheReadTokens: readTokenCount(usage?.cache_read_input_tokens ?? usage?.cacheReadTokens),\n cacheWriteTokens: readTokenCount(\n usage?.cache_creation_input_tokens ?? usage?.cacheWriteTokens,\n ),\n },\n };\n}\n\nfunction describeClaudeFailure(trajectory: string): string | undefined {\n try {\n const parsed = parseAgentJsonOutput(trajectory);\n return isErrorResult(parsed) ? describeErrorResult(parsed) : undefined;\n } catch {\n return undefined;\n }\n}\n\ntype ClaudeErrorResult = {\n is_error: true;\n result: string;\n subtype?: string;\n terminal_reason?: string;\n};\n\nfunction isErrorResult(value: unknown): value is ClaudeErrorResult {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as { is_error?: unknown }).is_error === true\n );\n}\n\nfunction describeErrorResult(result: ClaudeErrorResult): string {\n const message = String(result.result);\n\n if (result.terminal_reason !== undefined && result.terminal_reason !== \"completed\") {\n return `${result.terminal_reason}: ${message}`;\n }\n\n if (result.subtype !== undefined && result.subtype !== \"success\") {\n return `${result.subtype}: ${message}`;\n }\n\n return message;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"binding-1hmUr1aZ.mjs","names":["fsConstants"],"sources":["../src/constants.ts","../src/credentials.ts","../src/trajectory.ts","../src/binding.ts"],"sourcesContent":["import { CONTAINER_HOME } from \"clanker-cleanroom\";\n\nexport const CLAUDE_IMAGE = \"clanker-cleanroom/claude\";\nexport const CLAUDE_CONTAINER_CREDENTIALS_PATH = `${CONTAINER_HOME}/.claude/.credentials.json`;\n/** Session transcripts for cwd `/workspace` (Claude encodes `/` as `-`). */\nexport const CLAUDE_CONTAINER_SESSION_PATH = `${CONTAINER_HOME}/.claude/projects/-workspace`;\n\n/** Long-lived OAuth token from `claude setup-token` (Claude subscription). */\nexport const CLAUDE_OAUTH_TOKEN_ENV = \"CLAUDE_CODE_OAUTH_TOKEN\";\n/** Anthropic API key (pay-as-you-go). */\nexport const CLAUDE_API_KEY_ENV = \"ANTHROPIC_API_KEY\";\n\n/** Linux hosts persist OAuth credentials here; macOS uses the Keychain instead. */\nexport const defaultClaudeHostCredentialsFile = (home: string): string =>\n `${home}/.claude/.credentials.json`;\n","import { access } from \"node:fs/promises\";\nimport { constants as fsConstants } from \"node:fs\";\nimport { homedir } from \"node:os\";\n\nimport {\n CLAUDE_API_KEY_ENV,\n CLAUDE_OAUTH_TOKEN_ENV,\n defaultClaudeHostCredentialsFile,\n} from \"./constants.js\";\n\n/**\n * How Claude Code authenticates inside the container. Env-backed kinds are forwarded\n * to `docker run` by name (never on argv); the file kind is bind-mounted read-only.\n * See `constants.ts` for which host setups produce each.\n */\nexport type ClaudeCredentials =\n | { kind: \"oauth-token\"; token: string }\n | { kind: \"api-key\"; apiKey: string }\n | { kind: \"credentials-file\"; file: string };\n\n/** Env OAuth token, then env API key, then a readable host credentials file. */\nexport async function resolveClaudeCredentials(\n options: { env?: NodeJS.ProcessEnv; home?: string } = {},\n): Promise<ClaudeCredentials> {\n const env = options.env ?? process.env;\n const home = options.home ?? homedir();\n\n const token = env[CLAUDE_OAUTH_TOKEN_ENV];\n if (token !== undefined && token !== \"\") {\n return { kind: \"oauth-token\", token };\n }\n\n const apiKey = env[CLAUDE_API_KEY_ENV];\n if (apiKey !== undefined && apiKey !== \"\") {\n return { kind: \"api-key\", apiKey };\n }\n\n const file = defaultClaudeHostCredentialsFile(home);\n try {\n await access(file, fsConstants.R_OK);\n } catch {\n throw new Error(\n `Claude Code credentials not found. Set ${CLAUDE_OAUTH_TOKEN_ENV} (run \\`claude setup-token\\` on the host) ` +\n `or ${CLAUDE_API_KEY_ENV}, or provide ${file} (Linux hosts; macOS keeps credentials in the Keychain).`,\n );\n }\n\n return { kind: \"credentials-file\", file };\n}\n\n/** Secret values for the docker CLI process, keyed by env names forwarded via envPassthrough. */\nexport function credentialsEnv(credentials: ClaudeCredentials): Record<string, string> {\n switch (credentials.kind) {\n case \"oauth-token\":\n return { [CLAUDE_OAUTH_TOKEN_ENV]: credentials.token };\n case \"api-key\":\n return { [CLAUDE_API_KEY_ENV]: credentials.apiKey };\n case \"credentials-file\":\n return {};\n }\n}\n","import {\n asRecord,\n extractTextContent,\n readString,\n readTokenCount,\n type TrajectoryEvent,\n} from \"clanker-cleanroom\";\n\nexport function adaptClaudeEvents(rawEvents: readonly unknown[]): TrajectoryEvent[] {\n const events: TrajectoryEvent[] = [];\n\n for (const raw of rawEvents) {\n const record = asRecord(raw);\n if (record === undefined) {\n events.push({ kind: \"other\", type: \"unknown\", raw });\n continue;\n }\n\n const type = readString(record.type) ?? \"unknown\";\n\n switch (type) {\n case \"system\":\n events.push({\n kind: \"system\",\n sessionId: readString(record.session_id),\n model: readString(record.model),\n raw,\n });\n break;\n case \"user\":\n events.push(...adaptClaudeUser(record, raw));\n break;\n case \"assistant\":\n events.push(...adaptClaudeAssistant(record, raw));\n break;\n case \"result\":\n events.push({\n kind: \"result\",\n text: readString(record.result) ?? \"\",\n isError: record.is_error === true,\n durationMs: readTokenCount(record.duration_ms),\n costUsd: readTokenCount(record.total_cost_usd),\n raw,\n });\n break;\n default:\n events.push({ kind: \"other\", type, raw });\n }\n }\n\n return events;\n}\n\nfunction adaptClaudeAssistant(\n record: Record<string, unknown>,\n raw: unknown,\n): TrajectoryEvent[] {\n const events: TrajectoryEvent[] = [];\n const text = extractTextContent(record.message);\n if (text !== \"\") {\n events.push({ kind: \"assistant\", text, raw });\n }\n\n for (const block of contentBlocks(record.message)) {\n if (block.type !== \"tool_use\") {\n continue;\n }\n events.push({\n kind: \"tool\",\n phase: \"started\",\n callId: readString(block.id) ?? \"\",\n name: readString(block.name) ?? \"unknown\",\n args: block.input ?? null,\n result: null,\n raw,\n });\n }\n\n if (events.length === 0) {\n events.push({ kind: \"assistant\", text: \"\", raw });\n }\n\n return events;\n}\n\nfunction adaptClaudeUser(record: Record<string, unknown>, raw: unknown): TrajectoryEvent[] {\n const events: TrajectoryEvent[] = [];\n const text = extractTextContent(record.message);\n const toolResults: TrajectoryEvent[] = [];\n\n for (const block of contentBlocks(record.message)) {\n if (block.type !== \"tool_result\") {\n continue;\n }\n toolResults.push({\n kind: \"tool\",\n phase: \"completed\",\n callId: readString(block.tool_use_id) ?? \"\",\n name: \"tool_result\",\n args: null,\n result: block.content ?? null,\n raw,\n });\n }\n\n if (text !== \"\" || toolResults.length === 0) {\n events.push({ kind: \"user\", text, raw });\n }\n events.push(...toolResults);\n return events;\n}\n\nfunction contentBlocks(message: unknown): Record<string, unknown>[] {\n const content = asRecord(message)?.content;\n if (!Array.isArray(content)) {\n return [];\n }\n return content.map((block) => asRecord(block)).filter((block) => block !== undefined);\n}\n","import {\n asRecord,\n parseAgentJsonOutput,\n readTokenCount,\n type AgentBinding,\n type AgentRunResult,\n type DockerVolumeMount,\n} from \"clanker-cleanroom\";\n\nimport { CLAUDE_CONTAINER_CREDENTIALS_PATH, CLAUDE_CONTAINER_SESSION_PATH, CLAUDE_IMAGE } from \"./constants.js\";\nimport { credentialsEnv, resolveClaudeCredentials } from \"./credentials.js\";\nimport { adaptClaudeEvents } from \"./trajectory.js\";\n\nexport const claudeBinding: AgentBinding = {\n image: CLAUDE_IMAGE,\n displayName: \"Claude\",\n trajectoryKind: \"claude\",\n adaptEvents: adaptClaudeEvents,\n sessionDataPath: CLAUDE_CONTAINER_SESSION_PATH,\n command: ({ model, sessionId }) => {\n const claudeArgs = [\n \"claude\",\n \"-p\",\n \"--output-format\",\n \"stream-json\",\n \"--verbose\",\n \"--dangerously-skip-permissions\",\n ];\n if (sessionId !== undefined && sessionId !== \"\") {\n claudeArgs.push(\"--resume\", sessionId);\n }\n if (model !== undefined && model !== \"\") {\n claudeArgs.push(\"--model\", model);\n }\n return claudeArgs;\n },\n prepare: async () => {\n const credentials = await resolveClaudeCredentials();\n const volumes: DockerVolumeMount[] = [];\n if (credentials.kind === \"credentials-file\") {\n volumes.push({\n host: credentials.file,\n container: CLAUDE_CONTAINER_CREDENTIALS_PATH,\n mode: \"ro\",\n });\n }\n return {\n volumes,\n env: credentialsEnv(credentials),\n };\n },\n parseResult: parseClaudeResult,\n describeFailure: describeClaudeFailure,\n};\n\nfunction parseClaudeResult(trajectory: string): AgentRunResult {\n const parsed = parseAgentJsonOutput(trajectory);\n if (isErrorResult(parsed)) {\n throw new Error(`Claude agent reported an error: ${describeErrorResult(parsed)}`);\n }\n\n const record = asRecord(parsed);\n const usage = asRecord(record?.usage);\n\n return {\n durationMs: readTokenCount(record?.duration_ms),\n costUsd: readTokenCount(record?.total_cost_usd),\n usage: {\n inputTokens: readTokenCount(usage?.input_tokens ?? usage?.inputTokens),\n outputTokens: readTokenCount(usage?.output_tokens ?? usage?.outputTokens),\n cacheReadTokens: readTokenCount(usage?.cache_read_input_tokens ?? usage?.cacheReadTokens),\n cacheWriteTokens: readTokenCount(\n usage?.cache_creation_input_tokens ?? usage?.cacheWriteTokens,\n ),\n },\n };\n}\n\nfunction describeClaudeFailure(trajectory: string): string | undefined {\n try {\n const parsed = parseAgentJsonOutput(trajectory);\n return isErrorResult(parsed) ? describeErrorResult(parsed) : undefined;\n } catch {\n return undefined;\n }\n}\n\ntype ClaudeErrorResult = {\n is_error: true;\n result: string;\n subtype?: string;\n terminal_reason?: string;\n};\n\nfunction isErrorResult(value: unknown): value is ClaudeErrorResult {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as { is_error?: unknown }).is_error === true\n );\n}\n\nfunction describeErrorResult(result: ClaudeErrorResult): string {\n const message = String(result.result);\n\n if (result.terminal_reason !== undefined && result.terminal_reason !== \"completed\") {\n return `${result.terminal_reason}: ${message}`;\n }\n\n if (result.subtype !== undefined && result.subtype !== \"success\") {\n return `${result.subtype}: ${message}`;\n }\n\n return message;\n}\n"],"mappings":"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"}
@@ -161,7 +161,7 @@ const claudeBinding = {
161
161
  trajectoryKind: "claude",
162
162
  adaptEvents: adaptClaudeEvents,
163
163
  sessionDataPath: CLAUDE_CONTAINER_SESSION_PATH,
164
- command: ({ prompt, model, sessionId }) => {
164
+ command: ({ model, sessionId }) => {
165
165
  const claudeArgs = [
166
166
  "claude",
167
167
  "-p",
@@ -172,7 +172,6 @@ const claudeBinding = {
172
172
  ];
173
173
  if (sessionId !== void 0 && sessionId !== "") claudeArgs.push("--resume", sessionId);
174
174
  if (model !== void 0 && model !== "") claudeArgs.push("--model", model);
175
- claudeArgs.push("--", prompt);
176
175
  return claudeArgs;
177
176
  },
178
177
  prepare: async () => {
@@ -286,4 +285,4 @@ Object.defineProperty(exports, "resolveClaudeCredentials", {
286
285
  }
287
286
  });
288
287
 
289
- //# sourceMappingURL=binding-BZPFUSsx.cjs.map
288
+ //# sourceMappingURL=binding-Df3GdqVB.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"binding-Df3GdqVB.cjs","names":["CONTAINER_HOME","homedir","access","fsConstants","asRecord","readString","readTokenCount","extractTextContent","parseAgentJsonOutput","asRecord","readTokenCount"],"sources":["../src/constants.ts","../src/credentials.ts","../src/trajectory.ts","../src/binding.ts"],"sourcesContent":["import { CONTAINER_HOME } from \"clanker-cleanroom\";\n\nexport const CLAUDE_IMAGE = \"clanker-cleanroom/claude\";\nexport const CLAUDE_CONTAINER_CREDENTIALS_PATH = `${CONTAINER_HOME}/.claude/.credentials.json`;\n/** Session transcripts for cwd `/workspace` (Claude encodes `/` as `-`). */\nexport const CLAUDE_CONTAINER_SESSION_PATH = `${CONTAINER_HOME}/.claude/projects/-workspace`;\n\n/** Long-lived OAuth token from `claude setup-token` (Claude subscription). */\nexport const CLAUDE_OAUTH_TOKEN_ENV = \"CLAUDE_CODE_OAUTH_TOKEN\";\n/** Anthropic API key (pay-as-you-go). */\nexport const CLAUDE_API_KEY_ENV = \"ANTHROPIC_API_KEY\";\n\n/** Linux hosts persist OAuth credentials here; macOS uses the Keychain instead. */\nexport const defaultClaudeHostCredentialsFile = (home: string): string =>\n `${home}/.claude/.credentials.json`;\n","import { access } from \"node:fs/promises\";\nimport { constants as fsConstants } from \"node:fs\";\nimport { homedir } from \"node:os\";\n\nimport {\n CLAUDE_API_KEY_ENV,\n CLAUDE_OAUTH_TOKEN_ENV,\n defaultClaudeHostCredentialsFile,\n} from \"./constants.js\";\n\n/**\n * How Claude Code authenticates inside the container. Env-backed kinds are forwarded\n * to `docker run` by name (never on argv); the file kind is bind-mounted read-only.\n * See `constants.ts` for which host setups produce each.\n */\nexport type ClaudeCredentials =\n | { kind: \"oauth-token\"; token: string }\n | { kind: \"api-key\"; apiKey: string }\n | { kind: \"credentials-file\"; file: string };\n\n/** Env OAuth token, then env API key, then a readable host credentials file. */\nexport async function resolveClaudeCredentials(\n options: { env?: NodeJS.ProcessEnv; home?: string } = {},\n): Promise<ClaudeCredentials> {\n const env = options.env ?? process.env;\n const home = options.home ?? homedir();\n\n const token = env[CLAUDE_OAUTH_TOKEN_ENV];\n if (token !== undefined && token !== \"\") {\n return { kind: \"oauth-token\", token };\n }\n\n const apiKey = env[CLAUDE_API_KEY_ENV];\n if (apiKey !== undefined && apiKey !== \"\") {\n return { kind: \"api-key\", apiKey };\n }\n\n const file = defaultClaudeHostCredentialsFile(home);\n try {\n await access(file, fsConstants.R_OK);\n } catch {\n throw new Error(\n `Claude Code credentials not found. Set ${CLAUDE_OAUTH_TOKEN_ENV} (run \\`claude setup-token\\` on the host) ` +\n `or ${CLAUDE_API_KEY_ENV}, or provide ${file} (Linux hosts; macOS keeps credentials in the Keychain).`,\n );\n }\n\n return { kind: \"credentials-file\", file };\n}\n\n/** Secret values for the docker CLI process, keyed by env names forwarded via envPassthrough. */\nexport function credentialsEnv(credentials: ClaudeCredentials): Record<string, string> {\n switch (credentials.kind) {\n case \"oauth-token\":\n return { [CLAUDE_OAUTH_TOKEN_ENV]: credentials.token };\n case \"api-key\":\n return { [CLAUDE_API_KEY_ENV]: credentials.apiKey };\n case \"credentials-file\":\n return {};\n }\n}\n","import {\n asRecord,\n extractTextContent,\n readString,\n readTokenCount,\n type TrajectoryEvent,\n} from \"clanker-cleanroom\";\n\nexport function adaptClaudeEvents(rawEvents: readonly unknown[]): TrajectoryEvent[] {\n const events: TrajectoryEvent[] = [];\n\n for (const raw of rawEvents) {\n const record = asRecord(raw);\n if (record === undefined) {\n events.push({ kind: \"other\", type: \"unknown\", raw });\n continue;\n }\n\n const type = readString(record.type) ?? \"unknown\";\n\n switch (type) {\n case \"system\":\n events.push({\n kind: \"system\",\n sessionId: readString(record.session_id),\n model: readString(record.model),\n raw,\n });\n break;\n case \"user\":\n events.push(...adaptClaudeUser(record, raw));\n break;\n case \"assistant\":\n events.push(...adaptClaudeAssistant(record, raw));\n break;\n case \"result\":\n events.push({\n kind: \"result\",\n text: readString(record.result) ?? \"\",\n isError: record.is_error === true,\n durationMs: readTokenCount(record.duration_ms),\n costUsd: readTokenCount(record.total_cost_usd),\n raw,\n });\n break;\n default:\n events.push({ kind: \"other\", type, raw });\n }\n }\n\n return events;\n}\n\nfunction adaptClaudeAssistant(\n record: Record<string, unknown>,\n raw: unknown,\n): TrajectoryEvent[] {\n const events: TrajectoryEvent[] = [];\n const text = extractTextContent(record.message);\n if (text !== \"\") {\n events.push({ kind: \"assistant\", text, raw });\n }\n\n for (const block of contentBlocks(record.message)) {\n if (block.type !== \"tool_use\") {\n continue;\n }\n events.push({\n kind: \"tool\",\n phase: \"started\",\n callId: readString(block.id) ?? \"\",\n name: readString(block.name) ?? \"unknown\",\n args: block.input ?? null,\n result: null,\n raw,\n });\n }\n\n if (events.length === 0) {\n events.push({ kind: \"assistant\", text: \"\", raw });\n }\n\n return events;\n}\n\nfunction adaptClaudeUser(record: Record<string, unknown>, raw: unknown): TrajectoryEvent[] {\n const events: TrajectoryEvent[] = [];\n const text = extractTextContent(record.message);\n const toolResults: TrajectoryEvent[] = [];\n\n for (const block of contentBlocks(record.message)) {\n if (block.type !== \"tool_result\") {\n continue;\n }\n toolResults.push({\n kind: \"tool\",\n phase: \"completed\",\n callId: readString(block.tool_use_id) ?? \"\",\n name: \"tool_result\",\n args: null,\n result: block.content ?? null,\n raw,\n });\n }\n\n if (text !== \"\" || toolResults.length === 0) {\n events.push({ kind: \"user\", text, raw });\n }\n events.push(...toolResults);\n return events;\n}\n\nfunction contentBlocks(message: unknown): Record<string, unknown>[] {\n const content = asRecord(message)?.content;\n if (!Array.isArray(content)) {\n return [];\n }\n return content.map((block) => asRecord(block)).filter((block) => block !== undefined);\n}\n","import {\n asRecord,\n parseAgentJsonOutput,\n readTokenCount,\n type AgentBinding,\n type AgentRunResult,\n type DockerVolumeMount,\n} from \"clanker-cleanroom\";\n\nimport { CLAUDE_CONTAINER_CREDENTIALS_PATH, CLAUDE_CONTAINER_SESSION_PATH, CLAUDE_IMAGE } from \"./constants.js\";\nimport { credentialsEnv, resolveClaudeCredentials } from \"./credentials.js\";\nimport { adaptClaudeEvents } from \"./trajectory.js\";\n\nexport const claudeBinding: AgentBinding = {\n image: CLAUDE_IMAGE,\n displayName: \"Claude\",\n trajectoryKind: \"claude\",\n adaptEvents: adaptClaudeEvents,\n sessionDataPath: CLAUDE_CONTAINER_SESSION_PATH,\n command: ({ model, sessionId }) => {\n const claudeArgs = [\n \"claude\",\n \"-p\",\n \"--output-format\",\n \"stream-json\",\n \"--verbose\",\n \"--dangerously-skip-permissions\",\n ];\n if (sessionId !== undefined && sessionId !== \"\") {\n claudeArgs.push(\"--resume\", sessionId);\n }\n if (model !== undefined && model !== \"\") {\n claudeArgs.push(\"--model\", model);\n }\n return claudeArgs;\n },\n prepare: async () => {\n const credentials = await resolveClaudeCredentials();\n const volumes: DockerVolumeMount[] = [];\n if (credentials.kind === \"credentials-file\") {\n volumes.push({\n host: credentials.file,\n container: CLAUDE_CONTAINER_CREDENTIALS_PATH,\n mode: \"ro\",\n });\n }\n return {\n volumes,\n env: credentialsEnv(credentials),\n };\n },\n parseResult: parseClaudeResult,\n describeFailure: describeClaudeFailure,\n};\n\nfunction parseClaudeResult(trajectory: string): AgentRunResult {\n const parsed = parseAgentJsonOutput(trajectory);\n if (isErrorResult(parsed)) {\n throw new Error(`Claude agent reported an error: ${describeErrorResult(parsed)}`);\n }\n\n const record = asRecord(parsed);\n const usage = asRecord(record?.usage);\n\n return {\n durationMs: readTokenCount(record?.duration_ms),\n costUsd: readTokenCount(record?.total_cost_usd),\n usage: {\n inputTokens: readTokenCount(usage?.input_tokens ?? usage?.inputTokens),\n outputTokens: readTokenCount(usage?.output_tokens ?? usage?.outputTokens),\n cacheReadTokens: readTokenCount(usage?.cache_read_input_tokens ?? usage?.cacheReadTokens),\n cacheWriteTokens: readTokenCount(\n usage?.cache_creation_input_tokens ?? usage?.cacheWriteTokens,\n ),\n },\n };\n}\n\nfunction describeClaudeFailure(trajectory: string): string | undefined {\n try {\n const parsed = parseAgentJsonOutput(trajectory);\n return isErrorResult(parsed) ? describeErrorResult(parsed) : undefined;\n } catch {\n return undefined;\n }\n}\n\ntype ClaudeErrorResult = {\n is_error: true;\n result: string;\n subtype?: string;\n terminal_reason?: string;\n};\n\nfunction isErrorResult(value: unknown): value is ClaudeErrorResult {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as { is_error?: unknown }).is_error === true\n );\n}\n\nfunction describeErrorResult(result: ClaudeErrorResult): string {\n const message = String(result.result);\n\n if (result.terminal_reason !== undefined && result.terminal_reason !== \"completed\") {\n return `${result.terminal_reason}: ${message}`;\n }\n\n if (result.subtype !== undefined && result.subtype !== \"success\") {\n return `${result.subtype}: ${message}`;\n }\n\n return message;\n}\n"],"mappings":"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"}
package/lib/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_binding = require("./binding-BZPFUSsx.cjs");
2
+ const require_binding = require("./binding-Df3GdqVB.cjs");
3
3
  let clanker_cleanroom = require("clanker-cleanroom");
4
4
  let node_path = require("node:path");
5
5
  let node_url = require("node:url");
package/lib/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { a as CLAUDE_API_KEY_ENV, c as CLAUDE_IMAGE, i as resolveClaudeCredentials, l as CLAUDE_OAUTH_TOKEN_ENV, n as adaptClaudeEvents, o as CLAUDE_CONTAINER_CREDENTIALS_PATH, r as credentialsEnv, s as CLAUDE_CONTAINER_SESSION_PATH, t as claudeBinding, u as defaultClaudeHostCredentialsFile } from "./binding-DRnzgDU4.mjs";
1
+ import { a as CLAUDE_API_KEY_ENV, c as CLAUDE_IMAGE, i as resolveClaudeCredentials, l as CLAUDE_OAUTH_TOKEN_ENV, n as adaptClaudeEvents, o as CLAUDE_CONTAINER_CREDENTIALS_PATH, r as credentialsEnv, s as CLAUDE_CONTAINER_SESSION_PATH, t as claudeBinding, u as defaultClaudeHostCredentialsFile } from "./binding-1hmUr1aZ.mjs";
2
2
  import { Agent } from "clanker-cleanroom";
3
3
  import { join } from "node:path";
4
4
  import { fileURLToPath } from "node:url";
package/lib/register.cjs CHANGED
@@ -1,4 +1,4 @@
1
- const require_binding = require("./binding-BZPFUSsx.cjs");
1
+ const require_binding = require("./binding-Df3GdqVB.cjs");
2
2
  //#region src/register.ts
3
3
  (0, require("clanker-cleanroom").registerBinding)("claude", require_binding.claudeBinding);
4
4
  //#endregion
package/lib/register.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { t as claudeBinding } from "./binding-DRnzgDU4.mjs";
1
+ import { t as claudeBinding } from "./binding-1hmUr1aZ.mjs";
2
2
  import { registerBinding } from "clanker-cleanroom";
3
3
  //#region src/register.ts
4
4
  registerBinding("claude", claudeBinding);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clanker-cleanroom/claude",
3
- "version": "0.2.8-build.41",
3
+ "version": "0.2.9-build.43",
4
4
  "description": "Claude Code agent binding for clanker-cleanroom",
5
5
  "keywords": [
6
6
  "agent",
@@ -115,7 +115,7 @@
115
115
  }
116
116
  },
117
117
  "dependencies": {
118
- "clanker-cleanroom": "0.2.8-build.41"
118
+ "clanker-cleanroom": "0.2.9-build.43"
119
119
  },
120
120
  "devDependencies": {
121
121
  "@types/node": "^26.2.0",
package/src/binding.ts CHANGED
@@ -17,7 +17,7 @@ export const claudeBinding: AgentBinding = {
17
17
  trajectoryKind: "claude",
18
18
  adaptEvents: adaptClaudeEvents,
19
19
  sessionDataPath: CLAUDE_CONTAINER_SESSION_PATH,
20
- command: ({ prompt, model, sessionId }) => {
20
+ command: ({ model, sessionId }) => {
21
21
  const claudeArgs = [
22
22
  "claude",
23
23
  "-p",
@@ -32,7 +32,6 @@ export const claudeBinding: AgentBinding = {
32
32
  if (model !== undefined && model !== "") {
33
33
  claudeArgs.push("--model", model);
34
34
  }
35
- claudeArgs.push("--", prompt);
36
35
  return claudeArgs;
37
36
  },
38
37
  prepare: async () => {
@@ -1 +0,0 @@
1
- {"version":3,"file":"binding-BZPFUSsx.cjs","names":["CONTAINER_HOME","homedir","access","fsConstants","asRecord","readString","readTokenCount","extractTextContent","parseAgentJsonOutput","asRecord","readTokenCount"],"sources":["../src/constants.ts","../src/credentials.ts","../src/trajectory.ts","../src/binding.ts"],"sourcesContent":["import { CONTAINER_HOME } from \"clanker-cleanroom\";\n\nexport const CLAUDE_IMAGE = \"clanker-cleanroom/claude\";\nexport const CLAUDE_CONTAINER_CREDENTIALS_PATH = `${CONTAINER_HOME}/.claude/.credentials.json`;\n/** Session transcripts for cwd `/workspace` (Claude encodes `/` as `-`). */\nexport const CLAUDE_CONTAINER_SESSION_PATH = `${CONTAINER_HOME}/.claude/projects/-workspace`;\n\n/** Long-lived OAuth token from `claude setup-token` (Claude subscription). */\nexport const CLAUDE_OAUTH_TOKEN_ENV = \"CLAUDE_CODE_OAUTH_TOKEN\";\n/** Anthropic API key (pay-as-you-go). */\nexport const CLAUDE_API_KEY_ENV = \"ANTHROPIC_API_KEY\";\n\n/** Linux hosts persist OAuth credentials here; macOS uses the Keychain instead. */\nexport const defaultClaudeHostCredentialsFile = (home: string): string =>\n `${home}/.claude/.credentials.json`;\n","import { access } from \"node:fs/promises\";\nimport { constants as fsConstants } from \"node:fs\";\nimport { homedir } from \"node:os\";\n\nimport {\n CLAUDE_API_KEY_ENV,\n CLAUDE_OAUTH_TOKEN_ENV,\n defaultClaudeHostCredentialsFile,\n} from \"./constants.js\";\n\n/**\n * How Claude Code authenticates inside the container. Env-backed kinds are forwarded\n * to `docker run` by name (never on argv); the file kind is bind-mounted read-only.\n * See `constants.ts` for which host setups produce each.\n */\nexport type ClaudeCredentials =\n | { kind: \"oauth-token\"; token: string }\n | { kind: \"api-key\"; apiKey: string }\n | { kind: \"credentials-file\"; file: string };\n\n/** Env OAuth token, then env API key, then a readable host credentials file. */\nexport async function resolveClaudeCredentials(\n options: { env?: NodeJS.ProcessEnv; home?: string } = {},\n): Promise<ClaudeCredentials> {\n const env = options.env ?? process.env;\n const home = options.home ?? homedir();\n\n const token = env[CLAUDE_OAUTH_TOKEN_ENV];\n if (token !== undefined && token !== \"\") {\n return { kind: \"oauth-token\", token };\n }\n\n const apiKey = env[CLAUDE_API_KEY_ENV];\n if (apiKey !== undefined && apiKey !== \"\") {\n return { kind: \"api-key\", apiKey };\n }\n\n const file = defaultClaudeHostCredentialsFile(home);\n try {\n await access(file, fsConstants.R_OK);\n } catch {\n throw new Error(\n `Claude Code credentials not found. Set ${CLAUDE_OAUTH_TOKEN_ENV} (run \\`claude setup-token\\` on the host) ` +\n `or ${CLAUDE_API_KEY_ENV}, or provide ${file} (Linux hosts; macOS keeps credentials in the Keychain).`,\n );\n }\n\n return { kind: \"credentials-file\", file };\n}\n\n/** Secret values for the docker CLI process, keyed by env names forwarded via envPassthrough. */\nexport function credentialsEnv(credentials: ClaudeCredentials): Record<string, string> {\n switch (credentials.kind) {\n case \"oauth-token\":\n return { [CLAUDE_OAUTH_TOKEN_ENV]: credentials.token };\n case \"api-key\":\n return { [CLAUDE_API_KEY_ENV]: credentials.apiKey };\n case \"credentials-file\":\n return {};\n }\n}\n","import {\n asRecord,\n extractTextContent,\n readString,\n readTokenCount,\n type TrajectoryEvent,\n} from \"clanker-cleanroom\";\n\nexport function adaptClaudeEvents(rawEvents: readonly unknown[]): TrajectoryEvent[] {\n const events: TrajectoryEvent[] = [];\n\n for (const raw of rawEvents) {\n const record = asRecord(raw);\n if (record === undefined) {\n events.push({ kind: \"other\", type: \"unknown\", raw });\n continue;\n }\n\n const type = readString(record.type) ?? \"unknown\";\n\n switch (type) {\n case \"system\":\n events.push({\n kind: \"system\",\n sessionId: readString(record.session_id),\n model: readString(record.model),\n raw,\n });\n break;\n case \"user\":\n events.push(...adaptClaudeUser(record, raw));\n break;\n case \"assistant\":\n events.push(...adaptClaudeAssistant(record, raw));\n break;\n case \"result\":\n events.push({\n kind: \"result\",\n text: readString(record.result) ?? \"\",\n isError: record.is_error === true,\n durationMs: readTokenCount(record.duration_ms),\n costUsd: readTokenCount(record.total_cost_usd),\n raw,\n });\n break;\n default:\n events.push({ kind: \"other\", type, raw });\n }\n }\n\n return events;\n}\n\nfunction adaptClaudeAssistant(\n record: Record<string, unknown>,\n raw: unknown,\n): TrajectoryEvent[] {\n const events: TrajectoryEvent[] = [];\n const text = extractTextContent(record.message);\n if (text !== \"\") {\n events.push({ kind: \"assistant\", text, raw });\n }\n\n for (const block of contentBlocks(record.message)) {\n if (block.type !== \"tool_use\") {\n continue;\n }\n events.push({\n kind: \"tool\",\n phase: \"started\",\n callId: readString(block.id) ?? \"\",\n name: readString(block.name) ?? \"unknown\",\n args: block.input ?? null,\n result: null,\n raw,\n });\n }\n\n if (events.length === 0) {\n events.push({ kind: \"assistant\", text: \"\", raw });\n }\n\n return events;\n}\n\nfunction adaptClaudeUser(record: Record<string, unknown>, raw: unknown): TrajectoryEvent[] {\n const events: TrajectoryEvent[] = [];\n const text = extractTextContent(record.message);\n const toolResults: TrajectoryEvent[] = [];\n\n for (const block of contentBlocks(record.message)) {\n if (block.type !== \"tool_result\") {\n continue;\n }\n toolResults.push({\n kind: \"tool\",\n phase: \"completed\",\n callId: readString(block.tool_use_id) ?? \"\",\n name: \"tool_result\",\n args: null,\n result: block.content ?? null,\n raw,\n });\n }\n\n if (text !== \"\" || toolResults.length === 0) {\n events.push({ kind: \"user\", text, raw });\n }\n events.push(...toolResults);\n return events;\n}\n\nfunction contentBlocks(message: unknown): Record<string, unknown>[] {\n const content = asRecord(message)?.content;\n if (!Array.isArray(content)) {\n return [];\n }\n return content.map((block) => asRecord(block)).filter((block) => block !== undefined);\n}\n","import {\n asRecord,\n parseAgentJsonOutput,\n readTokenCount,\n type AgentBinding,\n type AgentRunResult,\n type DockerVolumeMount,\n} from \"clanker-cleanroom\";\n\nimport { CLAUDE_CONTAINER_CREDENTIALS_PATH, CLAUDE_CONTAINER_SESSION_PATH, CLAUDE_IMAGE } from \"./constants.js\";\nimport { credentialsEnv, resolveClaudeCredentials } from \"./credentials.js\";\nimport { adaptClaudeEvents } from \"./trajectory.js\";\n\nexport const claudeBinding: AgentBinding = {\n image: CLAUDE_IMAGE,\n displayName: \"Claude\",\n trajectoryKind: \"claude\",\n adaptEvents: adaptClaudeEvents,\n sessionDataPath: CLAUDE_CONTAINER_SESSION_PATH,\n command: ({ prompt, model, sessionId }) => {\n const claudeArgs = [\n \"claude\",\n \"-p\",\n \"--output-format\",\n \"stream-json\",\n \"--verbose\",\n \"--dangerously-skip-permissions\",\n ];\n if (sessionId !== undefined && sessionId !== \"\") {\n claudeArgs.push(\"--resume\", sessionId);\n }\n if (model !== undefined && model !== \"\") {\n claudeArgs.push(\"--model\", model);\n }\n claudeArgs.push(\"--\", prompt);\n return claudeArgs;\n },\n prepare: async () => {\n const credentials = await resolveClaudeCredentials();\n const volumes: DockerVolumeMount[] = [];\n if (credentials.kind === \"credentials-file\") {\n volumes.push({\n host: credentials.file,\n container: CLAUDE_CONTAINER_CREDENTIALS_PATH,\n mode: \"ro\",\n });\n }\n return {\n volumes,\n env: credentialsEnv(credentials),\n };\n },\n parseResult: parseClaudeResult,\n describeFailure: describeClaudeFailure,\n};\n\nfunction parseClaudeResult(trajectory: string): AgentRunResult {\n const parsed = parseAgentJsonOutput(trajectory);\n if (isErrorResult(parsed)) {\n throw new Error(`Claude agent reported an error: ${describeErrorResult(parsed)}`);\n }\n\n const record = asRecord(parsed);\n const usage = asRecord(record?.usage);\n\n return {\n durationMs: readTokenCount(record?.duration_ms),\n costUsd: readTokenCount(record?.total_cost_usd),\n usage: {\n inputTokens: readTokenCount(usage?.input_tokens ?? usage?.inputTokens),\n outputTokens: readTokenCount(usage?.output_tokens ?? usage?.outputTokens),\n cacheReadTokens: readTokenCount(usage?.cache_read_input_tokens ?? usage?.cacheReadTokens),\n cacheWriteTokens: readTokenCount(\n usage?.cache_creation_input_tokens ?? usage?.cacheWriteTokens,\n ),\n },\n };\n}\n\nfunction describeClaudeFailure(trajectory: string): string | undefined {\n try {\n const parsed = parseAgentJsonOutput(trajectory);\n return isErrorResult(parsed) ? describeErrorResult(parsed) : undefined;\n } catch {\n return undefined;\n }\n}\n\ntype ClaudeErrorResult = {\n is_error: true;\n result: string;\n subtype?: string;\n terminal_reason?: string;\n};\n\nfunction isErrorResult(value: unknown): value is ClaudeErrorResult {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as { is_error?: unknown }).is_error === true\n );\n}\n\nfunction describeErrorResult(result: ClaudeErrorResult): string {\n const message = String(result.result);\n\n if (result.terminal_reason !== undefined && result.terminal_reason !== \"completed\") {\n return `${result.terminal_reason}: ${message}`;\n }\n\n if (result.subtype !== undefined && result.subtype !== \"success\") {\n return `${result.subtype}: ${message}`;\n }\n\n return message;\n}\n"],"mappings":"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"}