/** * Plan mode — plan-then-execute latch with observer subscribe, policy * wrapper, and before-tool hook factory. * * Mirrors `python/src/adk_fluent/_plan_mode/`. The latch is the dynamic * half (state flips as the LLM calls `enter_plan_mode` / `exit_plan_mode`); * `PlanModePolicy` is the glue that makes a base `PermissionPolicy` deny * mutating tools while the latch is planning; `planModeBeforeToolHook` * enforces the same rule at the tool-call layer for harnesses that don't * consult a `PermissionPolicy` directly. */ import { PermissionMode } from "./permissions.js"; import type { PermissionDecision, PermissionPolicy } from "./permissions.js"; import { type HarnessTool } from "./types.js"; export type PlanState = "off" | "planning" | "executing"; export declare const MUTATING_TOOLS: ReadonlySet; export type PlanObserver = (state: PlanState, plan: string) => void; /** * Three-state plan-mode latch with observer subscribe. Transitions fire * every subscriber synchronously; exceptions raised by an observer are * swallowed so one broken listener cannot break the latch. */ export declare class PlanMode { private state_; private plan_; private readonly observers; get current(): PlanState; get currentPlan(): string; get isPlanning(): boolean; get isExecuting(): boolean; /** Classify a tool name as mutating (write/edit/exec). */ static isMutating(toolName: string): boolean; enter(): void; exit(plan: string): void; reset(): void; /** Subscribe an observer. Returns an unsubscribe function. */ subscribe(callback: PlanObserver): () => void; private notify; /** LLM-callable `enter_plan_mode` / `exit_plan_mode` pair. */ tools(): HarnessTool[]; } /** Build the `enter_plan_mode` / `exit_plan_mode` tool pair bound to a latch. */ export declare function planModeTools(latch: PlanMode): HarnessTool[]; /** * Frozen wrapper that ties a base `PermissionPolicy` to a `PlanMode` latch. * While the latch is planning, `check()` routes through a policy forced * into `PermissionMode.PLAN`; otherwise it delegates to the base. */ export declare class PlanModePolicy { readonly base: PermissionPolicy; readonly latch: PlanMode; constructor(base: PermissionPolicy, latch: PlanMode); check(toolName: string, args?: Record): PermissionDecision; /** Shim for callers expecting the plain `decide()` API. */ decide(toolName: string): "allow" | "ask" | "deny"; get mode(): PermissionMode; get allow(): ReadonlySet; get deny(): ReadonlySet; get ask(): ReadonlySet; private effective; } export interface PlanModeHookResult { error: string; planModeState: PlanState; } /** * Build a before-tool callback that blocks mutating tools while the latch * is planning. Returns `null` (meaning "proceed") otherwise. Use with any * harness tool layer that accepts an async `(toolName) => Promise<...>` * gate. */ export declare function planModeBeforeToolHook(latch: PlanMode): (toolName: string) => PlanModeHookResult | null; //# sourceMappingURL=plan-mode.d.ts.map