@gullabs/claude-cli 0.6.1 → 0.16.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/NOTICE +6 -0
- package/README.md +97 -13
- package/dist/index.cjs +311 -47
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +48 -18
- package/dist/index.d.ts +48 -18
- package/dist/index.js +309 -47
- package/dist/index.js.map +1 -1
- package/package.json +18 -8
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/runner.ts","../src/adapter.ts","../src/models.ts","../src/provider.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * ClaudeCliRunner — the process-execution seam for @gullabs/claude-cli.\n *\n * Adapters depend on the {@link ClaudeCliRunner} interface only.\n * {@link buildClaudeCliRunner} is the sole factory that touches\n * `node:child_process`; committed tests inject a hand-written fake instead of\n * exercising it, so no real `claude` subprocess is ever spawned in CI.\n *\n * @module\n */\n\nimport { spawn } from 'node:child_process'\n\n/**\n * The result of a single `claude` CLI invocation.\n */\nexport interface ClaudeCliRunResult {\n stdout: string\n stderr: string\n exitCode: number | null\n}\n\n/**\n * Options accepted by {@link ClaudeCliRunner.run}.\n */\nexport interface ClaudeCliRunOptions {\n /** Working directory for the subprocess (the adapter owns tmpdir lifecycle). */\n cwd: string\n /** Kill the subprocess if it has not exited within this many milliseconds. */\n timeoutMs?: number\n /** Kill the subprocess if this signal fires. */\n signal?: AbortSignal\n}\n\n/**\n * The process-execution seam consumed by {@link claudeCliAdapter}.\n *\n * Implementations run the `claude` binary with `args`, write `input` to its\n * stdin (the rendered prompt), and resolve with captured stdout/stderr/exit\n * code. Implementations must never throw for a non-zero exit code — that is\n * the adapter's error-classification job; the one exception is a spawn-time\n * failure (e.g. `ENOENT` when the binary is missing), which should reject.\n */\nexport interface ClaudeCliRunner {\n run(\n args: string[],\n input: string,\n opts: ClaudeCliRunOptions,\n ): Promise<ClaudeCliRunResult>\n}\n\n/**\n * Build the real {@link ClaudeCliRunner}, backed by `node:child_process`.\n *\n * Never exercised by committed tests — only the real dev workflow invokes\n * this factory; tests inject a hand-written fake implementing\n * {@link ClaudeCliRunner} instead.\n *\n * @param claudePath - Path or bare command name for the `claude` binary.\n * Defaults to `'claude'`, resolved via `PATH`.\n */\nexport function buildClaudeCliRunner(claudePath = 'claude'): ClaudeCliRunner {\n return {\n run(args, input, opts) {\n return new Promise((resolve, reject) => {\n if (opts.signal?.aborted === true) {\n const err = new Error('claude-cli call aborted')\n err.name = 'AbortError'\n reject(err)\n return\n }\n\n // NOTE: the argv itself (including the `--safe-mode` vs `--bare`\n // choice) is owned by the adapter (see adapter.ts) — this runner is\n // a dumb pipe. We repeat the rule here only as a pointer: never pass\n // `--bare`, it disables OAuth/keychain auth.\n const child = spawn(claudePath, args, {\n cwd: opts.cwd,\n stdio: ['pipe', 'pipe', 'pipe'],\n })\n\n let stdout = ''\n let stderr = ''\n let settled = false\n // Set once a timeout/abort has begun killing the child. The\n // returned promise is NOT rejected with this until the child's\n // 'close' event actually fires — the caller (the adapter) must\n // never observe settlement while the OS process may still be\n // alive and writing to its scratch cwd.\n let pendingError: Error | undefined\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined\n let killTimeoutHandle: ReturnType<typeof setTimeout> | undefined\n\n const cleanupTimers = (): void => {\n if (timeoutHandle !== undefined) clearTimeout(timeoutHandle)\n if (killTimeoutHandle !== undefined) clearTimeout(killTimeoutHandle)\n }\n\n const cleanup = (): void => {\n cleanupTimers()\n if (opts.signal !== undefined) {\n opts.signal.removeEventListener('abort', onAbort)\n }\n }\n\n const killChild = (): void => {\n child.kill('SIGTERM')\n killTimeoutHandle = setTimeout(() => {\n child.kill('SIGKILL')\n }, 5_000)\n }\n\n const beginReject = (err: Error): void => {\n if (settled || pendingError !== undefined) return\n pendingError = err\n cleanupTimers()\n killChild()\n }\n\n const onAbort = (): void => {\n const err = new Error('claude-cli call aborted')\n err.name = 'AbortError'\n beginReject(err)\n }\n\n // The pre-aborted case is handled above, before `spawn` — by this\n // point `opts.signal`, if present, is guaranteed not yet aborted.\n if (opts.signal !== undefined) {\n opts.signal.addEventListener('abort', onAbort, { once: true })\n }\n\n if (opts.timeoutMs !== undefined) {\n timeoutHandle = setTimeout(() => {\n const err = new Error(`claude-cli call exceeded ${opts.timeoutMs}ms timeout`)\n err.name = 'TimeoutError'\n beginReject(err)\n }, opts.timeoutMs)\n }\n\n child.stdout.on('data', (chunk: Buffer) => {\n stdout += chunk.toString('utf8')\n })\n child.stderr.on('data', (chunk: Buffer) => {\n stderr += chunk.toString('utf8')\n })\n\n child.once('error', (err) => {\n if (settled) return\n settled = true\n cleanup()\n reject(pendingError ?? err)\n })\n\n child.once('close', (exitCode) => {\n if (settled) return\n settled = true\n cleanup()\n if (pendingError !== undefined) {\n reject(pendingError)\n } else {\n resolve({ stdout, stderr, exitCode })\n }\n })\n\n child.stdin.end(input, 'utf8')\n })\n },\n }\n}\n","/**\n * claudeCliAdapter — @gullabs/claude-cli provider adapter.\n *\n * Pure request⇄response mapping over the locally-authenticated `claude`\n * (Claude Code) CLI, via {@link ClaudeCliRunner}. Never persists, never\n * computes cost, never retries, never reads `process.env`.\n *\n * DEV-ONLY: this adapter requires `ctx.auth = { cliSession: true }` — it\n * shells out to a `claude` binary that owns its own local login/session\n * state. It is never usable in a production/serverless environment because\n * there is no interactive CLI login there by construction.\n *\n * @module\n */\n\nimport { mkdtemp, rm } from 'node:fs/promises'\nimport { tmpdir } from 'node:os'\nimport { join } from 'node:path'\n\nimport { LlmError } from '@gullabs/core'\nimport type {\n ProviderAdapter,\n ResolvedRequest,\n AdapterCtx,\n AdapterResult,\n Usage,\n Warning,\n FinishReason,\n JsonValue,\n Message,\n Part,\n} from '@gullabs/core'\nimport { buildClaudeCliRunner } from './runner.js'\nimport type { ClaudeCliRunner, ClaudeCliRunResult } from './runner.js'\n\n// ---------------------------------------------------------------------------\n// Captured CLI envelope shape (see repo notes for the two captured fixtures)\n// ---------------------------------------------------------------------------\n\n/**\n * The `usage` object nested inside the `claude -p --output-format json`\n * result envelope. Only the fields this adapter consumes are typed here;\n * the full object is preserved verbatim in `Usage.raw`.\n */\nexport interface ClaudeCliUsageShape {\n input_tokens: number\n output_tokens: number\n cache_read_input_tokens?: number\n cache_creation_input_tokens?: number\n [key: string]: unknown\n}\n\n/**\n * The top-level JSON envelope emitted on stdout by\n * `claude -p ... --output-format json` on completion (success or error).\n */\nexport interface ClaudeCliEnvelope {\n type: string\n subtype?: string\n is_error?: boolean\n result?: string\n stop_reason?: string\n session_id?: string\n total_cost_usd?: number\n num_turns?: number\n usage?: ClaudeCliUsageShape\n [key: string]: unknown\n}\n\n// ---------------------------------------------------------------------------\n// Tiny in-file semaphore — adapter-internal concurrency control\n// ---------------------------------------------------------------------------\n\nclass Semaphore {\n private available: number\n private readonly queue: Array<() => void> = []\n\n constructor(max: number) {\n this.available = max\n }\n\n async acquire(): Promise<() => void> {\n if (this.available > 0) {\n this.available -= 1\n return () => {\n this.release()\n }\n }\n await new Promise<void>((resolve) => {\n this.queue.push(resolve)\n })\n this.available -= 1\n return () => {\n this.release()\n }\n }\n\n private release(): void {\n this.available += 1\n const next = this.queue.shift()\n if (next !== undefined) next()\n }\n}\n\n// ---------------------------------------------------------------------------\n// FinishReason mapping\n// ---------------------------------------------------------------------------\n\nfunction mapFinishReason(stopReason: string | undefined): FinishReason | undefined {\n if (stopReason === undefined) return undefined\n switch (stopReason) {\n case 'end_turn':\n return 'stop'\n case 'tool_use':\n // The CLI's own final answer, not a caller-visible tool call — treat\n // as a successful completion for our purposes.\n return 'stop'\n default:\n return 'other'\n }\n}\n\n// ---------------------------------------------------------------------------\n// Usage mapping — GROSS convention\n//\n// `totalTokens` is not reported by the claude-cli usage payload — it is\n// derived as `inputTokens + outputTokens` whenever a usage payload was\n// present; left undefined when there was no usage payload at all.\n// ---------------------------------------------------------------------------\n\nfunction mapUsage(usage: ClaudeCliUsageShape | undefined): Usage {\n const inputTokens = usage?.input_tokens ?? 0\n const outputTokens = usage?.output_tokens ?? 0\n const cachedInputTokens = usage?.cache_read_input_tokens\n const totalTokens = usage !== undefined ? inputTokens + outputTokens : undefined\n\n const details: Record<string, number> = {\n input: inputTokens,\n output: outputTokens,\n ...(cachedInputTokens !== undefined ? { cached: cachedInputTokens } : {}),\n ...(totalTokens !== undefined ? { total: totalTokens } : {}),\n }\n\n const raw: JsonValue = usage !== undefined ? (usage as unknown as JsonValue) : null\n\n return {\n inputTokens,\n outputTokens,\n details,\n raw,\n ...(cachedInputTokens !== undefined ? { cachedInputTokens } : {}),\n ...(totalTokens !== undefined ? { totalTokens } : {}),\n }\n}\n\n// ---------------------------------------------------------------------------\n// Prompt serialization\n// ---------------------------------------------------------------------------\n\nfunction partText(part: Part): string {\n if (part.kind !== 'text') {\n throw new LlmError(\n 'claude-cli is text-only; non-text message parts (inline media, file URIs, tool-call, tool-result) are not supported',\n {\n kind: 'bad_request',\n retryable: false,\n provider: 'claude-cli',\n },\n )\n }\n return part.text\n}\n\nfunction messageText(msg: Message): string {\n return msg.parts.map(partText).join('')\n}\n\n/**\n * Serialize `req.messages` into the single string sent to the CLI over\n * stdin.\n *\n * - Single user message, single text part → the text verbatim.\n * - Otherwise → a role-labelled transcript, blocks separated by a blank line.\n */\nfunction buildPrompt(messages: Message[]): string {\n if (messages.length === 1 && messages[0]?.parts.length === 1) {\n return partText(messages[0].parts[0] as Part)\n }\n\n return messages\n .map((msg) => {\n const label = msg.role === 'assistant' ? 'Assistant' : 'User'\n return `${label}:\\n${messageText(msg)}`\n })\n .join('\\n\\n')\n}\n\n// ---------------------------------------------------------------------------\n// Error classification\n// ---------------------------------------------------------------------------\n\nfunction looksAuthy(text: string): boolean {\n return /login|auth|unauthorized/i.test(text)\n}\n\nfunction looksRateLimited(text: string): boolean {\n return /rate limit|429/i.test(text)\n}\n\nfunction classifyRunFailure(\n envelope: ClaudeCliEnvelope | undefined,\n result: ClaudeCliRunResult,\n): LlmError {\n const combinedText = `${envelope?.subtype ?? ''} ${result.stderr}`\n\n if (looksAuthy(combinedText)) {\n return new LlmError(\n `claude CLI reported an authentication failure: ${result.stderr.slice(-500)}`,\n { kind: 'invalid_auth', retryable: false, provider: 'claude-cli' },\n )\n }\n\n if (looksRateLimited(combinedText)) {\n return new LlmError(\n `claude CLI reported rate limiting: ${result.stderr.slice(-500)}`,\n {\n kind: 'rate_limited',\n retryable: true,\n provider: 'claude-cli',\n },\n )\n }\n\n if (envelope?.is_error === true) {\n return new LlmError(\n `claude CLI reported an error (subtype: ${envelope.subtype ?? 'unknown'}): ${result.stderr.slice(-500)}`,\n { kind: 'server', retryable: false, provider: 'claude-cli' },\n )\n }\n\n const stderrTail = result.stderr.slice(-500)\n return new LlmError(\n `claude CLI exited with code ${String(result.exitCode)}: ${stderrTail}`,\n { kind: 'unknown', retryable: false, provider: 'claude-cli' },\n )\n}\n\n// ---------------------------------------------------------------------------\n// Adapter options\n// ---------------------------------------------------------------------------\n\nexport interface ClaudeCliAdapterOptions {\n /** Inject a runner (real or fake). Defaults to `buildClaudeCliRunner()`. */\n runner?: ClaudeCliRunner\n /** Path or bare command name for the `claude` binary. Defaults to `'claude'`. */\n claudePath?: string\n /** Max concurrent CLI invocations. Defaults to `2`. */\n maxConcurrency?: number\n}\n\n// ---------------------------------------------------------------------------\n// claudeCliAdapter factory\n// ---------------------------------------------------------------------------\n\n/**\n * Create a dev-only Claude Code CLI provider adapter.\n *\n * Requires `ctx.auth = { cliSession: true }` — see module docs.\n */\nexport function claudeCliAdapter(opts?: ClaudeCliAdapterOptions): ProviderAdapter {\n // Constructed eagerly but never invoked unless `opts.runner` is absent —\n // `buildClaudeCliRunner` only closes over `node:child_process`, it does not\n // spawn anything until `.run()` is called.\n const runner: ClaudeCliRunner = opts?.runner ?? buildClaudeCliRunner(opts?.claudePath)\n\n const semaphore = new Semaphore(opts?.maxConcurrency ?? 2)\n\n return {\n id: 'claude-cli',\n\n async run(req: ResolvedRequest, ctx: AdapterCtx): Promise<AdapterResult> {\n // ------------------------------------------------------------------\n // 1. Auth — CliSessionAuth only.\n // ------------------------------------------------------------------\n const hasCliSession = 'cliSession' in ctx.auth && ctx.auth.cliSession\n if (!hasCliSession) {\n throw new LlmError(\n '@gullabs/claude-cli requires auth: { cliSession: true } — these dev-only providers route through a locally-authenticated `claude` CLI session, not an API key',\n { kind: 'invalid_auth', retryable: false, provider: 'claude-cli' },\n )\n }\n\n if (req.provider !== 'claude-cli') {\n throw new LlmError(\n `@gullabs/claude-cli received a request routed for provider \"${req.provider}\" — this adapter only serves \"claude-cli\"`,\n { kind: 'bad_request', retryable: false, provider: 'claude-cli' },\n )\n }\n if (req.tools !== undefined && req.tools.length > 0) {\n throw new LlmError(\n 'claude-cli does not support LlmRequest.tools; CLI runtimes are out of the function-calling seam.',\n { kind: 'bad_request', retryable: false, provider: 'claude-cli' },\n )\n }\n\n const warnings: Warning[] = []\n const model = req.model\n const config = req.config\n\n // ------------------------------------------------------------------\n // 2. Prompt serialization (throws bad_request on non-text parts).\n // ------------------------------------------------------------------\n const prompt = buildPrompt(req.messages)\n\n // ------------------------------------------------------------------\n // 3. Invariant argv — adapter-owned, never caller-configurable.\n //\n // We use --safe-mode, NEVER --bare: --bare disables OAuth/keychain\n // auth and would break subscription-based Claude Code auth — the\n // exact mechanism that lets these dev-only providers work with zero\n // API-key configuration at all.\n // ------------------------------------------------------------------\n const args: string[] = [\n '-p',\n '--output-format',\n 'json',\n '--safe-mode',\n '--tools',\n '',\n '--disable-slash-commands',\n '--no-session-persistence',\n ]\n\n args.push('--model', model)\n\n const effort = config.reasoning?.effort\n if (effort !== undefined) {\n // `effort` was already validated against this package's own zod\n // schema at the config layer before the engine called us — forward\n // verbatim, no re-validation, no `any` cast.\n args.push('--effort', String(effort))\n }\n\n if (req.system !== undefined) {\n args.push('--system-prompt', req.system)\n }\n\n if (req.outputJsonSchema !== undefined) {\n args.push('--json-schema', JSON.stringify(req.outputJsonSchema))\n }\n\n // ------------------------------------------------------------------\n // 4. Timeout + scratch dir + runner invocation.\n // ------------------------------------------------------------------\n const timeoutMs = req.attemptTimeoutMs ?? config.timeoutMs\n\n // The runner owns timeout/abort enforcement end-to-end: it only\n // settles (resolve OR reject) once the child process has actually\n // exited (its 'close' event fired). We deliberately do NOT race an\n // independent timer against `runner.run(...)` here — doing so could\n // let this adapter move on (and release the semaphore / rm the\n // scratch dir) while the real OS child process is still alive and\n // possibly still writing into `cwd`. We simply await the runner\n // promise and classify whatever it settles with.\n const cwd = await mkdtemp(join(tmpdir(), 'claude-cli-'))\n const release = await semaphore.acquire()\n let result: ClaudeCliRunResult\n try {\n result = await runner.run(args, prompt, {\n cwd,\n ...(timeoutMs !== undefined ? { timeoutMs } : {}),\n ...(ctx.signal !== undefined ? { signal: ctx.signal } : {}),\n })\n } catch (rawErr) {\n release()\n await rm(cwd, { recursive: true, force: true })\n\n if (rawErr instanceof LlmError) throw rawErr\n\n if (\n typeof rawErr === 'object' &&\n rawErr !== null &&\n 'code' in rawErr &&\n (rawErr as { code?: unknown }).code === 'ENOENT'\n ) {\n throw new LlmError(\n 'claude CLI not found on PATH — install Claude Code and run `claude auth login`',\n { kind: 'unknown', retryable: false, provider: 'claude-cli' },\n )\n }\n\n if (rawErr instanceof Error && rawErr.name === 'AbortError') {\n throw new LlmError(rawErr.message || 'claude-cli call aborted', {\n kind: 'aborted',\n retryable: false,\n provider: 'claude-cli',\n })\n }\n\n if (rawErr instanceof Error && rawErr.name === 'TimeoutError') {\n throw new LlmError(rawErr.message || 'claude-cli call timed out', {\n kind: 'timeout',\n retryable: true,\n provider: 'claude-cli',\n })\n }\n\n throw new LlmError(\n `claude-cli runner failed: ${rawErr instanceof Error ? rawErr.message : String(rawErr)}`,\n { kind: 'unknown', retryable: false, provider: 'claude-cli', cause: rawErr },\n )\n }\n release()\n await rm(cwd, { recursive: true, force: true })\n\n // ------------------------------------------------------------------\n // 5. Parse the envelope from stdout.\n // ------------------------------------------------------------------\n let envelope: ClaudeCliEnvelope | undefined\n try {\n envelope = JSON.parse(result.stdout) as ClaudeCliEnvelope\n } catch {\n envelope = undefined\n }\n\n if (\n result.exitCode !== 0 ||\n envelope?.is_error === true ||\n envelope === undefined\n ) {\n throw classifyRunFailure(envelope, result)\n }\n\n // ------------------------------------------------------------------\n // 6. Map result → AdapterResult.\n // ------------------------------------------------------------------\n const text = envelope.result ?? ''\n\n let rawStructured: unknown\n if (req.outputJsonSchema !== undefined) {\n try {\n rawStructured = JSON.parse(text)\n } catch {\n warnings.push({\n type: 'other',\n message: 'claude-cli: failed to parse structured output as JSON',\n })\n }\n }\n\n const usage = mapUsage(envelope.usage)\n const finishReason = mapFinishReason(envelope.stop_reason)\n\n const providerMetadata: Record<string, JsonValue> = {\n ...(envelope.total_cost_usd !== undefined\n ? { totalCostUsd: envelope.total_cost_usd }\n : {}),\n ...(envelope.session_id !== undefined ? { sessionId: envelope.session_id } : {}),\n ...(envelope.subtype !== undefined ? { subtype: envelope.subtype } : {}),\n ...(envelope.num_turns !== undefined ? { numTurns: envelope.num_turns } : {}),\n }\n\n const adapterResult: AdapterResult = {\n model,\n usage,\n warnings,\n ...(text.length > 0 ? { text } : {}),\n ...(rawStructured !== undefined ? { rawStructured } : {}),\n ...(finishReason !== undefined ? { finishReason } : {}),\n ...(Object.keys(providerMetadata).length > 0 ? { providerMetadata } : {}),\n }\n\n return adapterResult\n },\n }\n}\n","/**\n * Model config schemas + registry for @gullabs/claude-cli.\n *\n * DEVIATION FROM CONVENTION: `@gullabs/core`'s `packages/core/src/model-config/`\n * only carries config schemas for production API providers (Gemini/Gemma).\n * This dev-only CLI provider intentionally keeps its own model config schemas\n * and registry local to this package instead — core stays free of any\n * knowledge of the local-CLI dev workflow.\n *\n * @module\n */\n\nimport { z } from 'zod'\nimport type { ModelDescriptor, ModelRegistry } from '@gullabs/core'\nimport {\n createModelRegistry,\n toConfigJsonSchema,\n zodToStandardSchema,\n} from '@gullabs/core'\n\n// ---------------------------------------------------------------------------\n// Model ids\n// ---------------------------------------------------------------------------\n\n/** Every model id `@gullabs/claude-cli` knows how to route. */\nexport type ClaudeCliModelId =\n 'claude-fable-5' | 'claude-opus-4-8' | 'claude-sonnet-5' | 'claude-haiku-4-5-20251001'\n\nconst CLAUDE_CLI_MODEL_IDS: readonly ClaudeCliModelId[] = [\n 'claude-fable-5',\n 'claude-opus-4-8',\n 'claude-sonnet-5',\n 'claude-haiku-4-5-20251001',\n]\n\n/**\n * Reasoning effort levels admitted by the `claude` CLI's `--effort` flag.\n *\n * A strict superset of `@gullabs/core`'s `ReasoningEffort` union (which is\n * `'none' | 'low' | 'medium' | 'high' | 'xhigh'`) — `'max'` is the extra\n * value the CLI supports that core's engine-level type does not know about.\n * Because of this mismatch, `admittedReasoningEfforts` (typed\n * `ReadonlyArray<ReasoningEffort>` in `ModelDescriptor.capabilities`) is\n * intentionally OMITTED below rather than cast — this package's own zod\n * schema is the sole validator for `reasoning.effort`, so the field is\n * advisory-only and safe to skip.\n */\nconst CLAUDE_CLI_EFFORTS = ['low', 'medium', 'high', 'xhigh', 'max'] as const\n\n/**\n * Build the strict per-model config schema for a `claude-cli` model.\n *\n * No `temperature`/`topP`/`topK`/`maxOutputTokens`/`stopSequences` fields —\n * the CLI does not support tuning any of these, and `z.strictObject` rejects\n * any unknown key outright (reject, don't map/clamp).\n */\nfunction buildClaudeCliConfigSchema(modelName: string): z.ZodType {\n return z\n .strictObject({\n reasoning: z\n .strictObject({\n effort: z.enum(CLAUDE_CLI_EFFORTS).meta({\n title: 'Reasoning Effort',\n description: `Reasoning effort forwarded to the claude CLI's --effort flag for ${modelName}.`,\n }),\n })\n .optional()\n .meta({\n title: 'Reasoning',\n description: `Reasoning configuration for ${modelName}.`,\n }),\n timeoutMs: z.number().int().positive().max(1_800_000).optional().meta({\n title: 'Timeout',\n description:\n 'Logical request timeout in milliseconds; forwarded to the CLI runner.',\n }),\n })\n .meta({\n title: `${modelName}Config`,\n description: `Strict claude-cli config for model ${modelName}. Text-only, no sampling knobs, effort-based reasoning.`,\n })\n}\n\nexport const ClaudeFable5ConfigSchema = buildClaudeCliConfigSchema('claude-fable-5')\nexport const ClaudeOpus48ConfigSchema = buildClaudeCliConfigSchema('claude-opus-4-8')\nexport const ClaudeSonnet5ConfigSchema = buildClaudeCliConfigSchema('claude-sonnet-5')\nexport const ClaudeHaiku45ConfigSchema = buildClaudeCliConfigSchema(\n 'claude-haiku-4-5-20251001',\n)\n\nconst CONFIG_SCHEMAS: Record<ClaudeCliModelId, z.ZodType> = {\n 'claude-fable-5': ClaudeFable5ConfigSchema,\n 'claude-opus-4-8': ClaudeOpus48ConfigSchema,\n 'claude-sonnet-5': ClaudeSonnet5ConfigSchema,\n 'claude-haiku-4-5-20251001': ClaudeHaiku45ConfigSchema,\n}\n\n// ---------------------------------------------------------------------------\n// Descriptors + registry\n// ---------------------------------------------------------------------------\n\nexport const claudeCliModelDescriptors: ModelDescriptor[] = CLAUDE_CLI_MODEL_IDS.map(\n (id): ModelDescriptor => {\n const configSchema = CONFIG_SCHEMAS[id]\n return {\n model: id,\n provider: 'claude-cli',\n capabilities: {\n structuredOutput: true,\n nativeStructuredOutput: true,\n reasoningApi: 'level',\n sampling: 'fixed',\n vision: false,\n },\n configSchema,\n configJsonSchema: toConfigJsonSchema(configSchema),\n validateConfig: zodToStandardSchema(configSchema),\n }\n },\n)\n\nexport const claudeCliRegistry: ModelRegistry = createModelRegistry(\n claudeCliModelDescriptors,\n)\n","/**\n * `claudeCliProvider` — {@link ProviderPlugin} factory for @gullabs/claude-cli.\n *\n * Bundles the dev-only Claude CLI adapter with its model descriptors. This\n * provider is unpriced by design (dev-only CLI, $0 API spend) — the returned\n * plugin has no `pricingSource`.\n *\n * @module\n */\n\nimport type { ProviderPlugin } from '@gullabs/core'\n\nimport { claudeCliAdapter } from './adapter.js'\nimport type { ClaudeCliAdapterOptions } from './adapter.js'\nimport { claudeCliModelDescriptors } from './models.js'\n\n/**\n * Create a {@link ProviderPlugin} for the dev-only Claude Code CLI provider.\n *\n * Unpriced by design: the returned plugin omits `pricingSource` entirely.\n *\n * @param opts - Forwarded to {@link claudeCliAdapter}.\n * @returns A plugin bundling the Claude CLI adapter and its model descriptors.\n *\n * @example\n * ```ts\n * import { createClient, composeProviders } from '@gullabs/core'\n * import { claudeCliProvider } from '@gullabs/claude-cli'\n *\n * const client = createClient({\n * ...composeProviders([claudeCliProvider()]),\n * })\n * ```\n */\nexport function claudeCliProvider(opts?: ClaudeCliAdapterOptions): ProviderPlugin {\n return {\n adapter: claudeCliAdapter(opts),\n modelDescriptors: claudeCliModelDescriptors,\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/env.ts","../src/runner.ts","../src/adapter.ts","../src/models.ts","../src/provider.ts"],"names":["LlmError"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * The environment the runner gives the `claude` child.\n *\n * `claude -p` uses `ANTHROPIC_API_KEY` whenever it is present, instead of the\n * subscription login (https://code.claude.com/docs/en/env-vars: \"In\n * non-interactive mode (`-p`), the key is always used when present\"). A host that\n * also uses an Anthropic API key would therefore bill every call made through this\n * package to that key while the ledger records an unpriced call. So the child gets\n * an allowlisted copy of the host environment, never the whole of it: credential\n * and provider-routing variables are not on the list. A host that wants a variable\n * passed on says so with the adapter's `env` option.\n *\n * @module\n */\n\nimport { LlmError } from '@gullabs/core'\n\n/** Exact names the child inherits (matched case-insensitively on Windows only). */\nconst INHERITED_NAMES: ReadonlySet<string> = new Set([\n // Process basics.\n 'PATH',\n 'HOME',\n 'USER',\n 'LOGNAME',\n 'LANG',\n 'LANGUAGE',\n 'TERM',\n 'TMPDIR',\n 'TEMP',\n 'TMP',\n 'SHELL',\n 'TZ',\n // Windows equivalents of the above.\n 'SYSTEMROOT',\n 'SYSTEMDRIVE',\n 'WINDIR',\n 'COMSPEC',\n 'PATHEXT',\n 'USERPROFILE',\n 'APPDATA',\n 'LOCALAPPDATA',\n 'PROGRAMDATA',\n 'HOMEDRIVE',\n 'HOMEPATH',\n // Network: proxies and trust roots.\n 'HTTPS_PROXY',\n 'HTTP_PROXY',\n 'ALL_PROXY',\n 'NO_PROXY',\n 'https_proxy',\n 'http_proxy',\n 'all_proxy',\n 'no_proxy',\n 'NODE_EXTRA_CA_CERTS',\n 'SSL_CERT_FILE',\n 'SSL_CERT_DIR',\n // The CLI's own documented settings that keep the subscription login usable:\n // where its login lives, the long-lived subscription token from\n // `claude setup-token`, and client certificates for an mTLS proxy.\n 'CLAUDE_CONFIG_DIR',\n 'CLAUDE_CODE_OAUTH_TOKEN',\n 'CLAUDE_CODE_CLIENT_CERT',\n 'CLAUDE_CODE_CLIENT_KEY',\n 'CLAUDE_CODE_CLIENT_KEY_PASSPHRASE',\n 'CLAUDE_CODE_PROXY_RESOLVES_HOSTS',\n])\n\n/** Prefixes the child inherits (`LC_*` locale, `XDG_*` base directories). */\nconst INHERITED_PREFIXES: readonly string[] = ['LC_', 'XDG_']\n\nfunction isInherited(name: string, windows: boolean): boolean {\n // Windows environment names are case-insensitive; elsewhere only the exact\n // spellings above (and the lower-case proxy ones) count.\n const key = windows ? name.toUpperCase() : name\n if (INHERITED_NAMES.has(key)) return true\n return INHERITED_PREFIXES.some((prefix) => key.startsWith(prefix))\n}\n\n/**\n * Build the child's environment: the allowlisted part of `parent`, then `extra`\n * on top. `extra` wins (on Windows whatever the spelling of the name), and is passed\n * through unfiltered, because it is the host's explicit choice.\n */\nexport function buildChildEnv(\n parent: NodeJS.ProcessEnv,\n extra: Readonly<Record<string, string>> | undefined,\n windows: boolean,\n): Record<string, string> {\n const env: Record<string, string> = {}\n for (const [name, value] of Object.entries(parent)) {\n if (value !== undefined && isInherited(name, windows)) env[name] = value\n }\n if (extra !== undefined) {\n if (windows) {\n // Windows names are case-insensitive and the OS hands the child only the\n // first match: an inherited `PATH` would beat the host's `Path`. Drop the\n // inherited spelling of every name the host sets.\n const overridden = new Set(Object.keys(extra).map((name) => name.toUpperCase()))\n for (const name of Object.keys(env)) {\n if (overridden.has(name.toUpperCase())) delete env[name]\n }\n }\n Object.assign(env, extra)\n }\n return env\n}\n\nfunction badEnv(message: string): LlmError {\n return new LlmError(message, {\n kind: 'bad_request',\n retryable: false,\n provider: 'claude-cli',\n })\n}\n\n/**\n * Check a host-supplied `env` option and return a frozen copy. Names and values\n * must be strings the OS accepts: a non-string, an empty name, `=` in a name or a\n * NUL anywhere is a `bad_request` here instead of a spawn failure on the first call.\n */\nexport function parseExtraEnv(\n env: unknown,\n): Readonly<Record<string, string>> | undefined {\n if (env === undefined) return undefined\n if (env === null || typeof env !== 'object' || Array.isArray(env)) {\n throw badEnv('claudeCliAdapter: `env` must be an object of string values')\n }\n const copy: Record<string, string> = {}\n for (const [name, value] of Object.entries(env)) {\n if (name === '' || name.includes('=') || name.includes('\\0')) {\n throw badEnv(`claudeCliAdapter: \\`env\\` has an invalid name \"${name}\"`)\n }\n if (typeof value !== 'string' || value.includes('\\0')) {\n throw badEnv(\n `claudeCliAdapter: \\`env.${name}\\` must be a string without NUL characters`,\n )\n }\n copy[name] = value\n }\n return Object.freeze(copy)\n}\n","/**\n * ClaudeCliRunner — the process-execution seam for @gullabs/claude-cli.\n *\n * Adapters depend on the {@link ClaudeCliRunner} interface only.\n * {@link buildClaudeCliRunner} is the sole factory that touches\n * `node:child_process`; adapter tests inject a hand-written fake, and the\n * runner's own tests spawn only the current Node executable, so no real\n * `claude` subprocess is ever spawned in CI.\n *\n * @module\n */\n\nimport { spawn } from 'node:child_process'\nimport { StringDecoder } from 'node:string_decoder'\n\nimport { buildChildEnv } from './env.js'\n\n/**\n * Most stdout the runner buffers: 32 MiB. A call that prints more is killed and\n * rejected, so a runaway process cannot exhaust the host's memory. stderr is\n * diagnostic only: the runner keeps its last {@link MAX_STDERR_CHARS}.\n */\nexport const MAX_STDOUT_BYTES = 32 * 1024 * 1024\n\n/** Most stderr text kept (the tail); the adapter only reads its end. */\nexport const MAX_STDERR_CHARS = 1024 * 1024\n\n/**\n * The result of a single `claude` CLI invocation.\n */\nexport interface ClaudeCliRunResult {\n stdout: string\n stderr: string\n exitCode: number | null\n}\n\n/**\n * Options accepted by {@link ClaudeCliRunner.run}.\n */\nexport interface ClaudeCliRunOptions {\n /** Working directory for the subprocess (the adapter owns tmpdir lifecycle). */\n cwd: string\n /** Kill the subprocess if it has not exited within this many milliseconds. */\n timeoutMs?: number\n /** Kill the subprocess if this signal fires. */\n signal?: AbortSignal\n /**\n * Variables added to (and winning over) the allowlisted environment the child\n * gets. The host's own environment is not passed on whole; see `env.ts`.\n */\n env?: Readonly<Record<string, string>>\n}\n\n/**\n * The process-execution seam consumed by {@link claudeCliAdapter}.\n *\n * Implementations run the `claude` binary with `args`, write `input` to its\n * stdin (the rendered prompt), and resolve with captured stdout/stderr/exit\n * code. Implementations must never throw for a non-zero exit code — that is\n * the adapter's error-classification job; the one exception is a spawn-time\n * failure (e.g. `ENOENT` when the binary is missing), which should reject.\n */\nexport interface ClaudeCliRunner {\n run(\n args: string[],\n input: string,\n opts: ClaudeCliRunOptions,\n ): Promise<ClaudeCliRunResult>\n}\n\n/**\n * Build the real {@link ClaudeCliRunner}, backed by `node:child_process`.\n *\n * The adapter tests inject a hand-written fake; `runner.test.ts` runs this\n * factory against the current Node executable (no `claude` binary needed).\n *\n * The child leads its own process group, and a timeout, abort or output-cap\n * kill signals the whole group, so a grandchild holding the pipes cannot keep a\n * call hung. When the leader closes after such a kill, the group gets one more\n * SIGKILL, so a member that ignored SIGTERM and does not hold the pipes (a tool\n * server the CLI started) does not outlive the call. A host that is interrupted\n * (Ctrl-C) does not forward the signal to the CLI, which then runs to its own\n * timeout.\n *\n * The child's environment is an allowlisted copy of `process.env` plus\n * `opts.env` (see `env.ts`): `ANTHROPIC_API_KEY` and the provider-routing\n * variables are not passed on, so the subscription login is what the CLI uses.\n *\n * @param claudePath - Path or bare command name for the `claude` binary.\n * Defaults to `'claude'`, resolved via `PATH`.\n */\nexport function buildClaudeCliRunner(claudePath = 'claude'): ClaudeCliRunner {\n return {\n run(args, input, opts) {\n return new Promise((resolve, reject) => {\n if (opts.signal?.aborted === true) {\n const err = new Error('claude-cli call aborted')\n err.name = 'AbortError'\n reject(err)\n return\n }\n\n // NOTE: the argv itself (including the `--safe-mode` vs `--bare`\n // choice) is owned by the adapter (see adapter.ts) — this runner is\n // a dumb pipe. We repeat the rule here only as a pointer: never pass\n // `--bare`, it disables OAuth/keychain auth.\n // `detached` makes the child the leader of its own process group, so a\n // kill reaches every process it started (a grandchild that inherited\n // the pipes would otherwise hold `close` open past the timeout or the\n // output cap). Not on Windows, which has no process groups.\n const child = spawn(claudePath, args, {\n cwd: opts.cwd,\n stdio: ['pipe', 'pipe', 'pipe'],\n detached: process.platform !== 'win32',\n env: buildChildEnv(process.env, opts.env, process.platform === 'win32'),\n })\n\n // Chunks can split a multibyte UTF-8 character, so each stream keeps\n // a decoder that holds the partial bytes until the rest arrives.\n const stdoutDecoder = new StringDecoder('utf8')\n const stderrDecoder = new StringDecoder('utf8')\n let stdout = ''\n let stdoutBytes = 0\n let stderr = ''\n let settled = false\n // Set once a timeout/abort has begun killing the child. The\n // returned promise is NOT rejected with this until the child's\n // 'close' event actually fires — the caller (the adapter) must\n // never observe settlement while the OS process may still be\n // alive and writing to its scratch cwd.\n let pendingError: Error | undefined\n let timeoutHandle: ReturnType<typeof setTimeout> | undefined\n let killTimeoutHandle: ReturnType<typeof setTimeout> | undefined\n\n const cleanupTimers = (): void => {\n if (timeoutHandle !== undefined) clearTimeout(timeoutHandle)\n if (killTimeoutHandle !== undefined) clearTimeout(killTimeoutHandle)\n }\n\n const cleanup = (): void => {\n cleanupTimers()\n if (opts.signal !== undefined) {\n opts.signal.removeEventListener('abort', onAbort)\n }\n }\n\n // Signals the whole process group (`-pid`), falling back to the child\n // alone where that is not possible.\n const signalTree = (signal: 'SIGTERM' | 'SIGKILL'): void => {\n if (process.platform !== 'win32' && child.pid !== undefined) {\n try {\n process.kill(-child.pid, signal)\n return\n } catch {\n // The group is gone or was never made; signal the child below.\n }\n }\n child.kill(signal)\n }\n\n const killChild = (): void => {\n signalTree('SIGTERM')\n killTimeoutHandle = setTimeout(() => {\n signalTree('SIGKILL')\n // A process that left the group can still hold the pipes: closing\n // our ends lets `close` fire without waiting for it.\n child.stdout.destroy()\n child.stderr.destroy()\n }, 5_000)\n }\n\n // One SIGKILL for the group, after the leader has closed. The 5 s timer\n // above is cancelled by `close`, so without this a group member that\n // ignores SIGTERM and holds none of our pipes would never be killed.\n // ESRCH (the group is already empty) is the normal outcome.\n const sweepGroup = (): void => {\n if (process.platform === 'win32' || child.pid === undefined) return\n try {\n process.kill(-child.pid, 'SIGKILL')\n } catch {\n // Nothing left in the group.\n }\n }\n\n const beginReject = (err: Error): void => {\n if (settled || pendingError !== undefined) return\n pendingError = err\n cleanupTimers()\n killChild()\n }\n\n const onAbort = (): void => {\n const err = new Error('claude-cli call aborted')\n err.name = 'AbortError'\n beginReject(err)\n }\n\n // The pre-aborted case is handled above, before `spawn` — by this\n // point `opts.signal`, if present, is guaranteed not yet aborted.\n if (opts.signal !== undefined) {\n opts.signal.addEventListener('abort', onAbort, { once: true })\n }\n\n if (opts.timeoutMs !== undefined) {\n timeoutHandle = setTimeout(() => {\n const err = new Error(`claude-cli call exceeded ${opts.timeoutMs}ms timeout`)\n err.name = 'TimeoutError'\n beginReject(err)\n }, opts.timeoutMs)\n }\n\n child.stdout.on('data', (chunk: Buffer) => {\n // Once a kill is under way the output no longer matters.\n if (pendingError !== undefined) return\n stdoutBytes += chunk.length\n if (stdoutBytes > MAX_STDOUT_BYTES) {\n const err = new Error(\n `claude-cli stdout exceeded ${MAX_STDOUT_BYTES} bytes; the process was killed`,\n )\n err.name = 'OutputLimitError'\n beginReject(err)\n return\n }\n stdout += stdoutDecoder.write(chunk)\n })\n child.stderr.on('data', (chunk: Buffer) => {\n stderr = (stderr + stderrDecoder.write(chunk)).slice(-MAX_STDERR_CHARS)\n })\n\n // A CLI that exits before reading its stdin (a bad flag, expired auth)\n // makes the write fail with EPIPE. Without a listener that stream\n // error is unhandled and crashes the host process; the exit code and\n // stderr already carry the real failure.\n child.stdin.on('error', () => {})\n\n child.once('error', (err) => {\n if (settled) return\n settled = true\n cleanup()\n reject(pendingError ?? err)\n })\n\n child.once('close', (exitCode) => {\n if (settled) return\n settled = true\n cleanup()\n if (pendingError !== undefined) {\n sweepGroup()\n reject(pendingError)\n } else {\n stdout += stdoutDecoder.end()\n stderr = (stderr + stderrDecoder.end()).slice(-MAX_STDERR_CHARS)\n resolve({ stdout, stderr, exitCode })\n }\n })\n\n child.stdin.end(input, 'utf8')\n })\n },\n }\n}\n","/**\n * claudeCliAdapter — @gullabs/claude-cli provider adapter.\n *\n * Pure request⇄response mapping over the locally-authenticated `claude`\n * (Claude Code) CLI, via {@link ClaudeCliRunner}. Never persists, never\n * computes cost, never retries, never reads `process.env` (the real runner builds\n * the child's environment from an allowlist; see `env.ts`).\n *\n * DEV-ONLY: this adapter requires `ctx.auth = { cliSession: true }` — it\n * shells out to a `claude` binary that owns its own local login/session\n * state. It is never usable in a production/serverless environment because\n * there is no interactive CLI login there by construction.\n *\n * @module\n */\n\nimport { mkdtemp, rm } from 'node:fs/promises'\nimport { tmpdir } from 'node:os'\nimport { join } from 'node:path'\n\nimport { LlmError } from '@gullabs/core'\nimport type {\n ProviderAdapter,\n ResolvedRequest,\n AdapterCtx,\n AdapterResult,\n Usage,\n Warning,\n FinishReason,\n JsonValue,\n Message,\n Part,\n} from '@gullabs/core'\nimport { parseExtraEnv } from './env.js'\nimport { buildClaudeCliRunner } from './runner.js'\nimport type { ClaudeCliRunner, ClaudeCliRunResult } from './runner.js'\n\n// ---------------------------------------------------------------------------\n// Captured CLI envelope shape (see repo notes for the two captured fixtures)\n// ---------------------------------------------------------------------------\n\n/**\n * The `usage` object nested inside the `claude -p --output-format json`\n * result envelope. Only the fields this adapter consumes are typed here;\n * the full object is preserved verbatim in `Usage.raw`.\n */\nexport interface ClaudeCliUsageShape {\n input_tokens: number\n output_tokens: number\n cache_read_input_tokens?: number\n cache_creation_input_tokens?: number\n output_tokens_details?: { thinking_tokens?: number }\n [key: string]: unknown\n}\n\n/**\n * The top-level JSON envelope emitted on stdout by\n * `claude -p ... --output-format json` on completion (success or error).\n */\nexport interface ClaudeCliEnvelope {\n type: string\n subtype?: string\n is_error?: boolean\n result?: string\n stop_reason?: string\n session_id?: string\n total_cost_usd?: number\n num_turns?: number\n usage?: ClaudeCliUsageShape\n /** Per-model usage, checked for an exact requested-model match on success. */\n modelUsage?: Record<string, unknown>\n [key: string]: unknown\n}\n\n// ---------------------------------------------------------------------------\n// Tiny in-file semaphore — adapter-internal concurrency control\n// ---------------------------------------------------------------------------\n\nfunction abortError(): Error {\n const err = new Error('claude-cli call aborted')\n err.name = 'AbortError'\n return err\n}\n\nclass Semaphore {\n private available: number\n private readonly waiters: Array<() => void> = []\n\n constructor(max: number) {\n this.available = max\n }\n\n /**\n * Take a slot. A caller that has to wait leaves the queue, and rejects with an\n * `AbortError`, as soon as `signal` fires: a call the engine already gave up\n * on must not hold a place in line.\n */\n acquire(signal?: AbortSignal): Promise<() => void> {\n if (signal?.aborted === true) return Promise.reject(abortError())\n if (this.available > 0) {\n this.available -= 1\n return Promise.resolve(() => {\n this.release()\n })\n }\n return new Promise((resolve, reject) => {\n const grant = (): void => {\n signal?.removeEventListener('abort', onAbort)\n resolve(() => {\n this.release()\n })\n }\n const onAbort = (): void => {\n const at = this.waiters.indexOf(grant)\n if (at >= 0) this.waiters.splice(at, 1)\n reject(abortError())\n }\n signal?.addEventListener('abort', onAbort, { once: true })\n this.waiters.push(grant)\n })\n }\n\n // A freed slot goes straight to the next waiter, so a new caller cannot\n // overtake it between the release and the waiter's wake-up.\n private release(): void {\n const next = this.waiters.shift()\n if (next !== undefined) next()\n else this.available += 1\n }\n}\n\n// ---------------------------------------------------------------------------\n// FinishReason mapping\n// ---------------------------------------------------------------------------\n\nfunction mapFinishReason(stopReason: string | undefined): FinishReason | undefined {\n if (stopReason === undefined) return undefined\n switch (stopReason) {\n case 'end_turn':\n return 'stop'\n case 'refusal':\n return 'content_filter'\n case 'tool_use':\n // The CLI's own final answer, not a caller-visible tool call — treat\n // as a successful completion for our purposes.\n return 'stop'\n default:\n return 'other'\n }\n}\n\n// ---------------------------------------------------------------------------\n// Usage mapping — GROSS convention\n//\n// Anthropic's `input_tokens` counts only the tokens that are neither read from\n// nor written to the prompt cache. GROSS input is therefore\n// `input_tokens + cache_read_input_tokens + cache_creation_input_tokens`\n// (live fixture `model-refresh-p-a1.json`: `input_tokens: 2` beside\n// `cache_creation_input_tokens: 4011`). `cachedInputTokens` is the cache-read\n// part, and the cache-write part is kept as `details.cacheWrite`.\n// `output_tokens` already includes thinking, whose own count\n// (`output_tokens_details.thinking_tokens`) is `thinkingTokens`.\n//\n// `totalTokens` is not reported by the claude-cli usage payload — it is\n// derived as `inputTokens + outputTokens` whenever a usage payload was\n// present; left undefined when there was no usage payload at all.\n// ---------------------------------------------------------------------------\n\nfunction mapUsage(usage: ClaudeCliUsageShape | undefined): Usage {\n const cacheRead = usage?.cache_read_input_tokens\n const cacheWrite = usage?.cache_creation_input_tokens\n const inputTokens = (usage?.input_tokens ?? 0) + (cacheRead ?? 0) + (cacheWrite ?? 0)\n const outputTokens = usage?.output_tokens ?? 0\n const cachedInputTokens = cacheRead\n const thinkingTokens = usage?.output_tokens_details?.thinking_tokens\n const totalTokens = usage !== undefined ? inputTokens + outputTokens : undefined\n\n const details: Record<string, number> = {\n input: inputTokens,\n output: outputTokens,\n ...(cachedInputTokens !== undefined ? { cached: cachedInputTokens } : {}),\n ...(cacheWrite !== undefined ? { cacheWrite } : {}),\n ...(thinkingTokens !== undefined ? { thinking: thinkingTokens } : {}),\n ...(totalTokens !== undefined ? { total: totalTokens } : {}),\n }\n\n const raw: JsonValue = usage !== undefined ? (usage as unknown as JsonValue) : null\n\n return {\n inputTokens,\n outputTokens,\n details,\n raw,\n ...(cachedInputTokens !== undefined ? { cachedInputTokens } : {}),\n ...(thinkingTokens !== undefined ? { thinkingTokens } : {}),\n ...(totalTokens !== undefined ? { totalTokens } : {}),\n }\n}\n\n// ---------------------------------------------------------------------------\n// Prompt serialization\n// ---------------------------------------------------------------------------\n\nfunction partText(part: Part): string {\n if (part.kind !== 'text') {\n throw new LlmError(\n 'claude-cli is text-only; non-text message parts (inline media, file URIs, tool-call, tool-result) are not supported',\n {\n kind: 'bad_request',\n retryable: false,\n provider: 'claude-cli',\n },\n )\n }\n return part.text\n}\n\nfunction messageText(msg: Message): string {\n return msg.parts.map(partText).join('')\n}\n\n/**\n * Serialize `req.messages` into the single string sent to the CLI over\n * stdin.\n *\n * - Single user message, single text part → the text verbatim.\n * - Otherwise → a role-labelled transcript, blocks separated by a blank line.\n */\nfunction buildPrompt(messages: Message[]): string {\n if (messages.length === 1 && messages[0]?.parts.length === 1) {\n return partText(messages[0].parts[0] as Part)\n }\n\n return messages\n .map((msg) => {\n const label = msg.role === 'assistant' ? 'Assistant' : 'User'\n return `${label}:\\n${messageText(msg)}`\n })\n .join('\\n\\n')\n}\n\n// ---------------------------------------------------------------------------\n// Error classification\n// ---------------------------------------------------------------------------\n\n// Word-anchored: a bare `auth` would match \"author\" and \"authority\", and a bare\n// `429` a port or a timestamp. `oauth` is kept as a word of its own because an\n// expired subscription token reports itself that way.\nconst AUTH_FAILURE = /\\b(?:log ?in|auth|oauth|authentication|unauthori[sz]ed|401)\\b/i\nconst RATE_LIMITED =\n /\\brate[ -]?limit(?:ed|s|ing)?\\b|\\btoo many requests\\b|(?<![\\w.:/-])429(?![\\w-]|\\.\\d)/i\n\nfunction looksAuthy(text: string): boolean {\n return AUTH_FAILURE.test(text)\n}\n\nfunction looksRateLimited(text: string): boolean {\n return RATE_LIMITED.test(text)\n}\n\nfunction assertServedModel(envelope: ClaudeCliEnvelope, requestedModel: string): void {\n const modelUsage: unknown = envelope.modelUsage\n if (\n modelUsage === null ||\n typeof modelUsage !== 'object' ||\n Array.isArray(modelUsage)\n ) {\n throw new LlmError('claude CLI did not report a valid modelUsage object.', {\n kind: 'server',\n retryable: false,\n provider: 'claude-cli',\n })\n }\n for (const served of Object.keys(modelUsage)) {\n if (served !== requestedModel) {\n throw new LlmError(\n `claude CLI served model \"${served}\" but the request asked for \"${requestedModel}\".`,\n { kind: 'server', retryable: false, provider: 'claude-cli' },\n )\n }\n }\n if (!Object.hasOwn(modelUsage, requestedModel)) {\n throw new LlmError(\n `claude CLI did not report the requested model \"${requestedModel}\" in modelUsage.`,\n { kind: 'server', retryable: false, provider: 'claude-cli' },\n )\n }\n}\n\nfunction classifyRunFailure(\n envelope: ClaudeCliEnvelope | undefined,\n result: ClaudeCliRunResult,\n): LlmError {\n if (envelope?.stop_reason === 'refusal') {\n return new LlmError('claude CLI refused the prompt (stop_reason: refusal).', {\n kind: 'content_filter',\n retryable: false,\n provider: 'claude-cli',\n })\n }\n\n const combinedText = `${envelope?.subtype ?? ''} ${result.stderr}`\n\n // An explicit rate-limit signal wins over an incidental mention of auth.\n if (looksRateLimited(combinedText)) {\n return new LlmError(\n `claude CLI reported rate limiting: ${result.stderr.slice(-500)}`,\n {\n kind: 'rate_limited',\n retryable: true,\n provider: 'claude-cli',\n },\n )\n }\n\n if (looksAuthy(combinedText)) {\n return new LlmError(\n `claude CLI reported an authentication failure: ${result.stderr.slice(-500)}`,\n { kind: 'invalid_auth', retryable: false, provider: 'claude-cli' },\n )\n }\n\n if (envelope?.is_error === true) {\n return new LlmError(\n `claude CLI reported an error (subtype: ${envelope.subtype ?? 'unknown'}): ${result.stderr.slice(-500)}`,\n { kind: 'server', retryable: false, provider: 'claude-cli' },\n )\n }\n\n const stderrTail = result.stderr.slice(-500)\n return new LlmError(\n `claude CLI exited with code ${String(result.exitCode)}: ${stderrTail}`,\n { kind: 'unknown', retryable: false, provider: 'claude-cli' },\n )\n}\n\n// ---------------------------------------------------------------------------\n// Adapter options\n// ---------------------------------------------------------------------------\n\nexport interface ClaudeCliAdapterOptions {\n /** Inject a runner (real or fake). Defaults to `buildClaudeCliRunner()`. */\n runner?: ClaudeCliRunner\n /** Path or bare command name for the `claude` binary. Defaults to `'claude'`. */\n claudePath?: string\n /** Max concurrent CLI invocations. Defaults to `2`. */\n maxConcurrency?: number\n /**\n * Variables handed to the `claude` child on top of the allowlisted copy of the\n * host environment (PATH, HOME, locale, proxy, the CLI's own config and\n * subscription-token variables). They win over the allowlisted ones. The host's\n * `ANTHROPIC_API_KEY` and provider-routing variables are never inherited, so the\n * CLI uses the subscription login; passing one here is the explicit opt-in, and\n * the call is then billed to it while the ledger still records it as unpriced.\n * Values must be strings, else `bad_request` at construction.\n */\n env?: Readonly<Record<string, string>>\n}\n\n// ---------------------------------------------------------------------------\n// claudeCliAdapter factory\n// ---------------------------------------------------------------------------\n\n/**\n * Create a dev-only Claude Code CLI provider adapter.\n *\n * Requires `ctx.auth = { cliSession: true }` — see module docs.\n */\nexport function claudeCliAdapter(opts?: ClaudeCliAdapterOptions): ProviderAdapter {\n // Constructed eagerly but never invoked unless `opts.runner` is absent —\n // `buildClaudeCliRunner` only closes over `node:child_process`, it does not\n // spawn anything until `.run()` is called.\n const runner: ClaudeCliRunner = opts?.runner ?? buildClaudeCliRunner(opts?.claudePath)\n\n const semaphore = new Semaphore(opts?.maxConcurrency ?? 2)\n const env = parseExtraEnv(opts?.env)\n\n return {\n id: 'claude-cli',\n\n async run(req: ResolvedRequest, ctx: AdapterCtx): Promise<AdapterResult> {\n // ------------------------------------------------------------------\n // 1. Auth — CliSessionAuth only.\n // ------------------------------------------------------------------\n const hasCliSession = 'cliSession' in ctx.auth && ctx.auth.cliSession\n if (!hasCliSession) {\n throw new LlmError(\n '@gullabs/claude-cli requires auth: { cliSession: true } — these dev-only providers route through a locally-authenticated `claude` CLI session, not an API key',\n { kind: 'invalid_auth', retryable: false, provider: 'claude-cli' },\n )\n }\n\n if (req.provider !== 'claude-cli') {\n throw new LlmError(\n `@gullabs/claude-cli received a request routed for provider \"${req.provider}\" — this adapter only serves \"claude-cli\"`,\n { kind: 'bad_request', retryable: false, provider: 'claude-cli' },\n )\n }\n if (req.tools !== undefined && req.tools.length > 0) {\n throw new LlmError(\n 'claude-cli does not support LlmRequest.tools; CLI runtimes are out of the function-calling seam.',\n { kind: 'bad_request', retryable: false, provider: 'claude-cli' },\n )\n }\n\n const warnings: Warning[] = []\n const model = req.model\n const config = req.config\n\n if (\n req.modelDescriptor?.model !== model ||\n req.modelDescriptor.provider !== 'claude-cli'\n ) {\n throw new LlmError(`No matching Claude model descriptor for \"${model}\".`, {\n kind: 'bad_request',\n retryable: false,\n provider: 'claude-cli',\n })\n }\n if (req.transientProviderState !== undefined) {\n throw new LlmError(`Model \"${model}\" does not admit transientProviderState.`, {\n kind: 'bad_request',\n retryable: false,\n provider: 'claude-cli',\n })\n }\n if (\n config.reasoning !== undefined &&\n req.modelDescriptor.capabilities?.reasoningApi === undefined\n ) {\n throw new LlmError(`Model \"${model}\" does not admit reasoning.`, {\n kind: 'bad_request',\n retryable: false,\n provider: 'claude-cli',\n })\n }\n\n // ------------------------------------------------------------------\n // 2. Prompt serialization (throws bad_request on non-text parts).\n // ------------------------------------------------------------------\n const prompt = buildPrompt(req.messages)\n\n // ------------------------------------------------------------------\n // 3. Invariant argv — adapter-owned, never caller-configurable.\n //\n // We use --safe-mode, NEVER --bare: --bare disables OAuth/keychain\n // auth and would break subscription-based Claude Code auth — the\n // exact mechanism that lets these dev-only providers work with zero\n // API-key configuration at all.\n // ------------------------------------------------------------------\n const args: string[] = [\n '-p',\n '--output-format',\n 'json',\n '--safe-mode',\n '--tools',\n '',\n '--disable-slash-commands',\n '--no-session-persistence',\n '--settings',\n '{\"switchModelsOnFlag\":false}',\n ]\n\n args.push('--model', model)\n\n const effort = config.reasoning?.effort\n if (effort !== undefined) {\n // `effort` was already validated against this package's own zod\n // schema at the config layer before the engine called us — forward\n // verbatim, no re-validation, no `any` cast.\n args.push('--effort', String(effort))\n }\n\n if (req.system !== undefined) {\n args.push('--system-prompt', req.system)\n }\n\n if (req.outputJsonSchema !== undefined) {\n args.push('--json-schema', JSON.stringify(req.outputJsonSchema))\n }\n\n // ------------------------------------------------------------------\n // 4. Timeout + scratch dir + runner invocation.\n // ------------------------------------------------------------------\n const timeoutMs = req.attemptTimeoutMs ?? config.timeoutMs\n\n // The runner owns timeout/abort enforcement end-to-end: it only\n // settles (resolve OR reject) once the child process has actually\n // exited (its 'close' event fired). We deliberately do NOT race an\n // independent timer against `runner.run(...)` here — doing so could\n // let this adapter move on (and release the semaphore / rm the\n // scratch dir) while the real OS child process is still alive and\n // possibly still writing into `cwd`. We simply await the runner\n // promise and classify whatever it settles with.\n let release: () => void\n try {\n release = await semaphore.acquire(ctx.signal)\n } catch (waitErr) {\n throw new LlmError(\n waitErr instanceof Error ? waitErr.message : 'claude-cli call aborted',\n { kind: 'aborted', retryable: false, provider: 'claude-cli' },\n )\n }\n // The scratch directory is made only once a slot is held: a queued call owns\n // nothing to clean up.\n let cwd: string\n try {\n cwd = await mkdtemp(join(tmpdir(), 'claude-cli-'))\n } catch (mkdirErr) {\n release()\n throw mkdirErr\n }\n let result: ClaudeCliRunResult\n try {\n result = await runner.run(args, prompt, {\n cwd,\n ...(timeoutMs !== undefined ? { timeoutMs } : {}),\n ...(ctx.signal !== undefined ? { signal: ctx.signal } : {}),\n ...(env !== undefined ? { env } : {}),\n })\n } catch (rawErr) {\n release()\n await rm(cwd, { recursive: true, force: true })\n\n if (rawErr instanceof LlmError) throw rawErr\n\n if (\n typeof rawErr === 'object' &&\n rawErr !== null &&\n 'code' in rawErr &&\n (rawErr as { code?: unknown }).code === 'ENOENT'\n ) {\n throw new LlmError(\n 'claude CLI not found on PATH — install Claude Code and run `claude auth login`',\n { kind: 'unknown', retryable: false, provider: 'claude-cli' },\n )\n }\n\n if (rawErr instanceof Error && rawErr.name === 'AbortError') {\n throw new LlmError(rawErr.message || 'claude-cli call aborted', {\n kind: 'aborted',\n retryable: false,\n provider: 'claude-cli',\n })\n }\n\n if (rawErr instanceof Error && rawErr.name === 'TimeoutError') {\n throw new LlmError(rawErr.message || 'claude-cli call timed out', {\n kind: 'timeout',\n retryable: true,\n provider: 'claude-cli',\n })\n }\n\n throw new LlmError(\n `claude-cli runner failed: ${rawErr instanceof Error ? rawErr.message : String(rawErr)}`,\n { kind: 'unknown', retryable: false, provider: 'claude-cli', cause: rawErr },\n )\n }\n release()\n await rm(cwd, { recursive: true, force: true })\n\n // ------------------------------------------------------------------\n // 5. Parse the envelope from stdout.\n // ------------------------------------------------------------------\n let envelope: ClaudeCliEnvelope | undefined\n try {\n envelope = JSON.parse(result.stdout) as ClaudeCliEnvelope\n } catch {\n envelope = undefined\n }\n\n if (\n result.exitCode !== 0 ||\n envelope?.is_error === true ||\n envelope === undefined\n ) {\n throw classifyRunFailure(envelope, result)\n }\n\n assertServedModel(envelope, model)\n\n // ------------------------------------------------------------------\n // 6. Map result → AdapterResult.\n // ------------------------------------------------------------------\n const text = envelope.result ?? ''\n\n let rawStructured: unknown\n if (req.outputJsonSchema !== undefined) {\n try {\n rawStructured = JSON.parse(text)\n } catch {\n warnings.push({\n type: 'other',\n message: 'claude-cli: failed to parse structured output as JSON',\n })\n }\n }\n\n const usage = mapUsage(envelope.usage)\n const finishReason = mapFinishReason(envelope.stop_reason)\n\n const providerMetadata: Record<string, JsonValue> = {\n ...(envelope.total_cost_usd !== undefined\n ? { totalCostUsd: envelope.total_cost_usd }\n : {}),\n ...(envelope.session_id !== undefined ? { sessionId: envelope.session_id } : {}),\n ...(envelope.subtype !== undefined ? { subtype: envelope.subtype } : {}),\n ...(envelope.num_turns !== undefined ? { numTurns: envelope.num_turns } : {}),\n }\n\n const adapterResult: AdapterResult = {\n model,\n message: {\n role: 'assistant',\n parts: text.length > 0 ? [{ kind: 'text', text }] : [],\n },\n usage,\n warnings,\n ...(text.length > 0 ? { text } : {}),\n ...(rawStructured !== undefined ? { rawStructured } : {}),\n ...(finishReason !== undefined ? { finishReason } : {}),\n ...(Object.keys(providerMetadata).length > 0 ? { providerMetadata } : {}),\n }\n\n return adapterResult\n },\n }\n}\n","/**\n * Model config schemas + registry for @gullabs/claude-cli.\n *\n * DEVIATION FROM CONVENTION: `@gullabs/core`'s `packages/core/src/model-config/`\n * only carries config schemas for production API providers (Gemini/Gemma).\n * This dev-only CLI provider intentionally keeps its own model config schemas\n * and registry local to this package instead — core stays free of any\n * knowledge of the local-CLI dev workflow.\n *\n * @module\n */\n\nimport { z } from 'zod'\nimport type { ModelDescriptor, ModelLimits, ModelRegistry } from '@gullabs/core'\nimport {\n createModelRegistry,\n toConfigJsonSchema,\n toConfigKeys,\n zodToStandardSchema,\n} from '@gullabs/core'\n\n// ---------------------------------------------------------------------------\n// Model ids\n// ---------------------------------------------------------------------------\n\n/** Every model id `@gullabs/claude-cli` knows how to route. */\nexport type ClaudeCliModelId =\n 'claude-fable-5-1' | 'claude-opus-5-5' | 'claude-sonnet-5' | 'claude-haiku-4-5-20251001'\n\nexport const CLAUDE_CLI_MODEL_IDS: readonly ClaudeCliModelId[] = [\n 'claude-fable-5-1',\n 'claude-opus-5-5',\n 'claude-sonnet-5',\n 'claude-haiku-4-5-20251001',\n]\n\n/**\n * Reasoning effort levels admitted by the `claude` CLI's `--effort` flag.\n *\n * The CLI admits `low` through `max` on Fable, Opus, and Sonnet. Haiku drops\n * `--effort`, so its descriptor advertises an empty admitted set.\n */\nexport const CLAUDE_CLI_EFFORTS = ['low', 'medium', 'high', 'xhigh', 'max'] as const\n\n/**\n * Build the strict per-model config schema for a `claude-cli` model that\n * admits `--effort`.\n *\n * No `temperature`/`topP`/`topK`/`maxOutputTokens`/`stopSequences` fields —\n * the CLI does not support tuning any of these, and `z.strictObject` rejects\n * any unknown key outright (reject, don't map/clamp).\n */\nfunction buildEffortConfigSchema(modelName: string): z.ZodType {\n return z\n .strictObject({\n reasoning: z\n .strictObject({\n effort: z.enum(CLAUDE_CLI_EFFORTS).meta({\n title: 'Reasoning Effort',\n description: `Reasoning effort forwarded to the claude CLI's --effort flag for ${modelName}.`,\n }),\n })\n .optional()\n .meta({\n title: 'Reasoning',\n description: `Reasoning configuration for ${modelName}.`,\n }),\n timeoutMs: z.number().int().positive().max(1_800_000).optional().meta({\n title: 'Timeout',\n description:\n 'Logical request timeout in milliseconds; forwarded to the CLI runner.',\n }),\n })\n .meta({\n title: `${modelName}Config`,\n description: `Strict claude-cli config for model ${modelName}. Text-only, no sampling knobs, effort-based reasoning.`,\n })\n}\n\n/**\n * Haiku 4.5 silently drops `--effort`. Accepting a reasoning key would be a\n * silent map, so the schema has no reasoning field.\n */\nfunction buildHaikuConfigSchema(): z.ZodType {\n return z\n .strictObject({\n timeoutMs: z.number().int().positive().max(1_800_000).optional().meta({\n title: 'Timeout',\n description:\n 'Logical request timeout in milliseconds; forwarded to the CLI runner.',\n }),\n })\n .meta({\n title: 'claude-haiku-4-5-20251001Config',\n description:\n 'Strict claude-cli config for claude-haiku-4-5-20251001. No reasoning key: the CLI drops --effort.',\n })\n}\n\nexport const ClaudeFable51ConfigSchema = buildEffortConfigSchema('claude-fable-5-1')\nexport const ClaudeOpus55ConfigSchema = buildEffortConfigSchema('claude-opus-5-5')\nexport const ClaudeSonnet5ConfigSchema = buildEffortConfigSchema('claude-sonnet-5')\nexport const ClaudeHaiku45ConfigSchema = buildHaikuConfigSchema()\n\nconst CONFIG_SCHEMAS: Record<ClaudeCliModelId, z.ZodType> = {\n 'claude-fable-5-1': ClaudeFable51ConfigSchema,\n 'claude-opus-5-5': ClaudeOpus55ConfigSchema,\n 'claude-sonnet-5': ClaudeSonnet5ConfigSchema,\n 'claude-haiku-4-5-20251001': ClaudeHaiku45ConfigSchema,\n}\n\n// ---------------------------------------------------------------------------\n// Descriptors + registry\n// ---------------------------------------------------------------------------\n\n/**\n * Context window and maximum output per model, as the CLI itself reports them in\n * the captured `modelUsage` of every registered id\n * (`__fixtures__/model-refresh-p-a1.json`, Claude Code 2.1.282). The CLI exposes no\n * output-size knob, so the limit a call runs under is the CLI's, not the API's:\n * Fable 5.1 reports 64 000 and Haiku 4.5 reports 32 000, below the API maxima in\n * the Anthropic models overview (`https://platform.claude.com/docs/en/about-claude/models/overview`,\n * read 2026-10-03: Fable 5.1 \"128K tokens\", Haiku 4.5 \"64K tokens\"). Opus 5.5 and\n * Sonnet 5 report 128 000, equal to the documented value. The context windows\n * agree with the documentation.\n */\nconst CLAUDE_CLI_LIMITS: Record<ClaudeCliModelId, ModelLimits> = {\n 'claude-fable-5-1': { contextWindow: 1_000_000, maxOutputTokens: 64_000 },\n 'claude-opus-5-5': { contextWindow: 1_000_000, maxOutputTokens: 128_000 },\n 'claude-sonnet-5': { contextWindow: 1_000_000, maxOutputTokens: 128_000 },\n 'claude-haiku-4-5-20251001': { contextWindow: 200_000, maxOutputTokens: 32_000 },\n}\n\nexport const claudeCliModelDescriptors: ModelDescriptor[] = CLAUDE_CLI_MODEL_IDS.map(\n (id): ModelDescriptor => {\n const configSchema = CONFIG_SCHEMAS[id]\n return {\n model: id,\n provider: 'claude-cli',\n limits: CLAUDE_CLI_LIMITS[id],\n capabilities: {\n // The CLI runs text-only: the adapter rejects every non-text part.\n inputMimeTypes: [],\n structuredOutput: true,\n nativeStructuredOutput: true,\n ...(id !== 'claude-haiku-4-5-20251001' ? { reasoningApi: 'level' as const } : {}),\n admittedReasoningEfforts:\n id === 'claude-haiku-4-5-20251001' ? [] : CLAUDE_CLI_EFFORTS,\n sampling: 'fixed',\n },\n configSchema,\n configKeys: toConfigKeys(configSchema),\n configJsonSchema: toConfigJsonSchema(configSchema),\n validateConfig: zodToStandardSchema(configSchema),\n }\n },\n)\n\nexport const claudeCliRegistry: ModelRegistry = createModelRegistry(\n claudeCliModelDescriptors,\n)\n","/**\n * `claudeCliProvider` — {@link ProviderPlugin} factory for @gullabs/claude-cli.\n *\n * Bundles the dev-only Claude CLI adapter with its model descriptors. This\n * provider is unpriced by design (dev-only CLI, $0 API spend) — the returned\n * plugin has no `pricingSource`.\n *\n * @module\n */\n\nimport type { ProviderPlugin } from '@gullabs/core'\n\nimport { claudeCliAdapter } from './adapter.js'\nimport type { ClaudeCliAdapterOptions } from './adapter.js'\nimport { claudeCliModelDescriptors } from './models.js'\n\n/**\n * Create a {@link ProviderPlugin} for the dev-only Claude Code CLI provider.\n *\n * Unpriced by design: the returned plugin omits `pricingSource` entirely.\n *\n * @param opts - Forwarded to {@link claudeCliAdapter}.\n * @returns A plugin bundling the Claude CLI adapter and its model descriptors.\n *\n * @example\n * ```ts\n * import { createClient, composeProviders } from '@gullabs/core'\n * import { claudeCliProvider } from '@gullabs/claude-cli'\n *\n * const client = createClient({\n * ...composeProviders([claudeCliProvider()]),\n * })\n * ```\n */\nexport function claudeCliProvider(opts?: ClaudeCliAdapterOptions): ProviderPlugin {\n return {\n adapter: claudeCliAdapter(opts),\n modelDescriptors: claudeCliModelDescriptors,\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gullabs/claude-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
4
|
"description": "Dev-only Claude Code CLI provider adapter for any-llm — routes calls through a locally-authenticated `claude` CLI session for $0 API spend during workflow iteration. NOT for production use.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -14,20 +14,30 @@
|
|
|
14
14
|
"types": "./dist/index.d.ts",
|
|
15
15
|
"exports": {
|
|
16
16
|
".": {
|
|
17
|
-
"
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
"import": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"default": "./dist/index.js"
|
|
20
|
+
},
|
|
21
|
+
"require": {
|
|
22
|
+
"types": "./dist/index.d.cts",
|
|
23
|
+
"default": "./dist/index.cjs"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"./package.json": "./package.json"
|
|
21
27
|
},
|
|
22
28
|
"files": [
|
|
23
|
-
"dist"
|
|
29
|
+
"dist",
|
|
30
|
+
"NOTICE"
|
|
24
31
|
],
|
|
25
32
|
"dependencies": {
|
|
26
|
-
"@gullabs/core": "0.14.1",
|
|
27
33
|
"zod": "^4.6.5"
|
|
28
34
|
},
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"@gullabs/core": "0.16.0"
|
|
37
|
+
},
|
|
29
38
|
"devDependencies": {
|
|
30
|
-
"@gullabs/
|
|
39
|
+
"@gullabs/core": "0.16.0",
|
|
40
|
+
"@gullabs/testing": "0.16.0"
|
|
31
41
|
},
|
|
32
42
|
"engines": {
|
|
33
43
|
"node": ">=22.12.0"
|