/** * Plan mode — explicit pre-execution preview. * * Flow: * 1. User runs `/plan ` — we ask the LLM for a numbered plan * (no tool calls, no file changes) and surface it to the user. * 2. We hold the (task, plan) pair as the *pending* plan. Each * conversation has its own: callers that serve several at once (ACP * threads) pass a scope, and everything else shares the default one. * 3. User runs `/go` to execute, or `/plan ` to refine. * `/go` hands the original task + approved plan to the regular * agent loop as a single prompt, so the existing tool execution, * verification, and permission paths apply unchanged. * * Why this design (MVP): * - Zero changes to the agent loop, MCP wiring, or ACP server. * - Plan rendering reuses the chat markdown renderer (no new TUI * panel to maintain). * - Edit flow is just "/plan " — generates a new plan * that replaces the pending one; user pays one extra LLM call but * gets human-readable revision history in the chat above. * - When we ship a proper plan-mode UI later (TUI panel with * Accept/Edit/Reject buttons + per-step progress), it can keep * using this module as the backend. */ export interface PendingPlan { task: string; plan: string; createdAt: number; } /** The scope of callers that hold one conversation per process (the TUI). */ export declare const DEFAULT_PLAN_SCOPE = "default"; /** * Ask the model for a plan for the given task. Stores the (task, plan) * pair as the pending plan of `scope` so a subsequent `/go` there can * execute it. Throws on chat failure — caller renders the error. * `abortSignal` cancels the request; a cancelled plan is not stored. */ export declare function generatePlan(task: string, onChunk?: (text: string) => void, scope?: string, abortSignal?: AbortSignal): Promise; export declare function getPendingPlan(scope?: string): PendingPlan | null; /** Replace the pending plan of `scope`; `null` clears it. */ export declare function setPendingPlan(plan: PendingPlan | null, scope?: string): void; export declare function clearPendingPlan(scope?: string): void; /** * Compose the prompt the agent loop receives when the user runs `/go`. * The agent treats this as a normal task, so tool calls / verification / * permissions / hooks all flow through the existing paths — we just * front-load the plan as context so the model doesn't re-plan * implicitly. */ export declare function composeExecutionPrompt(plan: PendingPlan): string;