import type { LlmToolDef, LlmToolUse, LlmClient, LlmRequest, LlmResponse } from "@slowcook-ai/core"; /** * Key-less Claude adapter: drives the `claude` CLI's headless print mode, * authenticated by the machine's Claude Code subscription — no * ANTHROPIC_API_KEY anywhere. Implements the same `LlmClient` contract as * `AnthropicClient`, so agents (refine, testgen, …) run unchanged on either. * * Runs as a PURE text model: our system prompt replaces Claude Code's * (`--system-prompt`) and all tools are disallowed (`--disallowedTools '*'`) * — the CLI can never touch the host from here. * * Proven pattern: this mirrors the dash server's claude-cli provider * (dogfooded 2026-07 on the rewo box; a subscription login or a * CLAUDE_CODE_OAUTH_TOKEN from `claude setup-token` is all it needs). * * Text-only: `LlmMessage.content` block arrays (images) need the API * adapter — this one refuses them explicitly rather than dropping data. */ /** shell-out seam, injectable so tests never spawn a process. */ export type CliRunner = (args: string[], stdin: string) => Promise; /** the transcript folded into one prompt — the CLI is single-shot per call. */ export declare function renderCliPrompt(messages: LlmRequest["messages"]): string; /** * Tool-protocol emulation (2026-08-23, Amin's ruling: every agent runs on * the same CLI subscription auth). The API speaks tool_use natively; the * CLI is a pure text model, so the protocol is emulated: the tool catalog * is appended to the system prompt, the model emits calls as one fenced * JSON block, the adapter parses them into LlmToolUse entries, and the * caller's tool_result blocks travel back as structured text (above). */ export declare function toolProtocolSystemSuffix(tools: LlmToolDef[]): string; export declare function parseEmulatedToolCalls(text: string): { text: string; toolUses: LlmToolUse[]; }; /** * WHOSE LOGIN, AND WHERE? (dovizir handover §6) * * A not-logged-in CLI backend surfaced the child process's own words verbatim: * "Not logged in · Please run /login". `/login` is a slash command inside an * interactive Claude session — an operator reading it from a slowcook log has * no session to type it into, and no clue which host or which account is * meant. Name all three. */ export declare function annotateCliError(subtype: string | undefined, detail: string): string; export declare class ClaudeCliClient implements LlmClient { private readonly run; constructor(run?: CliRunner); complete(args: LlmRequest): Promise; } /** * Environment-decided adapter selection (the dash-proven pattern): * SLOWCOOK_LLM=claude-cli → key-less subscription runtime * ANTHROPIC_API_KEY set → the API adapter * neither → a helpful error naming BOTH options */ export declare function createLlmClient(env?: NodeJS.ProcessEnv): Promise; //# sourceMappingURL=claude-cli.d.ts.map