Plan Mode
Plan mode is a structured planning phase: the agent explores the codebase and designs an implementation approach before writing any code. Use it for tasks with genuine ambiguity about the right approach, where getting your input before coding prevents significant rework.
What Plan Mode Does
When plan mode is active, the agent:
- Reads and searches the codebase to understand existing patterns and architecture
- Designs an implementation approach and writes it to the plan file
- May use
ask_user_questionto clarify specific questions - Calls
exit_plan_modeto present the plan for your approval
Plan mode is read-only except for the plan file: edits to the current episode's plan file are auto-approved, and edits to any other file are rejected outright — the tool call fails with a short message naming the plan file as the only editable path. That includes plan files from earlier episodes: only the current one is writable. This holds in every permission mode, including always-approve. Separating planning from implementation lets you review and correct the approach before any code is written.
How to Enter Plan Mode
Agent-Initiated Entry
The agent enters plan mode when it determines a task has genuine ambiguity. It calls the enter_plan_mode tool, which requires your approval before plan mode activates. If you decline, the agent stays in normal mode.
Good triggers for plan mode:
- "Add user authentication to the app" -- genuinely ambiguous (session vs JWT, token storage, middleware structure)
- "Redesign the data pipeline" -- major restructuring where the wrong approach wastes significant effort
- "Add caching to the API" -- multiple reasonable approaches (Redis vs in-memory vs file-based)
- "Add real-time updates" -- architectural decision (WebSockets vs SSE vs polling)
Not appropriate for plan mode:
- "Add a delete button to the user profile" -- clear implementation path
- "Fix the typo in the README" -- straightforward
- "Update the error handling in the API" -- start working, ask specific questions if needed
- "Can we work on the search feature?" -- user wants to get started, not plan
User-Initiated Entry
You can enter plan mode yourself in two ways:
/plan-- Enter plan mode. Plan mode activates when you send your next prompt. Run/plan <description>to enter plan mode and start a turn with that description in one step.- Shift+Tab -- Cycle the session mode: Normal, then Plan, then Always-approve, then back to Normal. From Normal, a single press lands on Plan.
After a plan exists, run /view-plan (aliases /show-plan, /plan-view) to reopen the preview of the current episode's plan.
The Plan File
Each planning episode gets its own file, so a later plan never overwrites an earlier one: ~/.cook/sessions/<cwd>/<session-id>/plans/<UTC timestamp>.md while the episode is running, published to plans/<slug>-<UTC timestamp>.md when the episode ends (approve, abandon, or toggle plan mode off). <cwd> is an encoded directory name, not the literal path. A session that has not started a planning episode yet (and one saved before episodes were separate files) uses ~/.cook/sessions/<cwd>/<session-id>/plan.md.
The slug is a short kebab-case prefix taken from the plan's # Plan: <title> heading. The UTC token stays in the name so two plans remain distinct and the list can still sort newest first.
A new file is allocated when plan mode activates — your first prompt after /plan or Shift+Tab, or the agent's enter_plan_mode. Everything inside one episode keeps working on the same file:
- Requesting changes (and inline comments) revises the current file in place (the UTC name, so the path the model was told stays valid).
- Approving, quitting, or toggling plan mode off ends the episode; the file is renamed from its heading and stays on disk as the record of that plan, and the next
/planstarts a new one.
The TUI and the desktop header chip show the plan's heading, not the UTC filename. The TUI shows one plan at a time — the current episode. The desktop app lists every plan file of the session under the header chip, marks the current episode, and can copy a plan or its path and delete a plan it is no longer using (never the one a running episode holds).
The plan file contains:
A short
# Plan: <title>heading (5–10 words, no file paths) so the list can name the episodeA Context section explaining why the change is being made
The recommended approach (not every alternative)
The paths of critical files to modify
Existing functions and utilities to reuse, with their file paths
A verification section describing how to test the changes end to end
Plan Approval
When the agent finishes planning, it calls the exit_plan_mode tool. The tool reads the plan file from disk, and the TUI opens a scrollable preview of the plan with an action bar along the bottom.
If the agent exits without writing a plan (empty or missing plan file), the same approval surface still opens with a clear empty-state message so you can approve and start implementing, request changes (send the agent back to planning), or quit. In minimal mode the empty notice is committed into scrollback and the controls strip header reads No plan written yet.
Reviewing the Plan
Scroll the plan with the arrow keys or j/k. The action bar shows these shortcuts:
| Shortcut | Action |
|---|---|
a |
Approve the plan and start building. With pending comments, this reads approve w/ comments and sends them alongside the approval. |
r |
Approve and run clean: freeze the plan and start implementation after clearing the earlier planning conversation. |
g |
Approve the plan and run it as an autonomous goal, using the approved plan as its baseline contract instead of starting a normal implement turn. Requires goal mode; if goal mode is disabled, the request is rejected and the plan stays in review. |
s |
Request changes. Focus moves to the prompt so you can type revision notes; press Enter to send them. |
c |
Comment on the selected line or line range. |
y |
Copy the full plan to the clipboard. |
Y |
Copy the absolute plan file path to the clipboard. |
q |
Quit plan -- abandon the plan without approving and turn plan mode off. |
Press Tab to move focus between the plan preview and the prompt.
The r action is part of this plan-review screen, not a slash command. It freezes the approved plan, removes the earlier planning conversation from model history, and begins implementation with the system prompt, project instructions, and a plan-file anchor. Review comments are included in the handoff, and the transcript shows a context-cleared marker.
While the plan approval view is open you can switch the model before approving: on the prompt, run /model <id> (or any slash command — the overlay stays open, then a, r, or g still work), or press Ctrl+P (command palette → model) / Ctrl+M from the preview. The new model applies to the implement turn after approval. In the approval preview, / starts a slash command on the prompt instead of in-plan search; in-plan search/filter remains on f.
Providing Feedback
The approval view has three focus states:
- Preview: Scroll the plan and select lines to comment on.
- Commenting: Add an inline comment to the selected line range (press
c, orEnteron a line). - Prompt: Type freeform revision notes.
Press Tab to switch between the preview and the prompt. When you send feedback -- inline comments, freeform notes, or both -- the agent receives it and revises the plan. Plan mode stays active so you can iterate. A complete pager command typed in the prompt (for example /feedback <text> or /compact) runs as a command instead of being sent as notes; the review stays open. Pressing a while such a command sits in the prompt is refused until you run it with Enter or delete it.
Leaving the Approval View
Press Esc to return focus from the prompt to the plan preview. To dismiss the approval without approving or sending feedback, press q to quit the plan. Quitting abandons the proposed plan and turns plan mode off.
Plan Mode Lifecycle
The plan mode state machine has four states:
| State | Description |
|---|---|
Inactive |
Normal operating mode. No plan mode constraints. |
Pending |
Client toggled plan mode ON, but no prompt has been sent yet. |
Active |
Plan mode is active. Plan-file edits are auto-approved; edits to other files are rejected. |
ExitPending |
User toggled plan mode OFF while a turn is in-flight. |
Transitions:
Inactive --> Active (enter_plan_mode tool called and approved -- skips Pending)
Inactive --> Pending (you toggle plan mode on with /plan or Shift+Tab)
Pending --> Active (your first prompt activates plan mode)
Active --> Inactive (exit_plan_mode approved, or you toggle plan mode off when idle)
Active --> ExitPending (you toggle plan mode off while a turn is in-flight)
ExitPending --> Inactive (after the turn completes)
Plan mode state is persisted to disk and survives process restarts. Transient states (Pending, ExitPending) are collapsed to Inactive on restart since they depend on in-flight interactions.
Edits During Plan Mode
During active plan mode, edits to the plan file are auto-approved without prompting, so the agent can iterate on the plan freely. Edits to any other file are rejected before they run — the agent receives a short message naming the plan file as the only editable path.
This enforcement is independent of the permission mode:
- Always-approve (yolo) stays armed underneath plan mode. Non-edit tools (bash commands, reads, MCP tools) still auto-run, but file edits are blocked until you approve exiting plan mode. Once the plan is approved, always-approve resumes for implementation.
- Bash commands are not inspected for file writes — plan mode blocks the edit tools, not shell redirection.
- Subagent spawns are gated by the same read-only rule. During plan mode the task tool only accepts subagent types that resolve to a genuinely read-only definition (for example
explore): spawning one of these — several in parallel, for codebase exploration and read-only measurements — is allowed, and the child stays limited by its own toolset. Spawning a write-capable subagent (general-purpose,codex, or any type whose toolset includes edit/bash tools) is rejected before it runs, with a short message naming the plan file as the only editable path and redirecting to read-only types. Unknown subagent types are also rejected (fail-closed). Write-capable subagent work is deferred until after exiting plan mode.
The status flag shows plan while plan mode is active. If always-approve is enabled underneath, its flag reappears when plan mode exits.
Plan Mode and Compaction
When /compact runs during an active plan mode session, the plan mode state is preserved. The compacted context includes a reminder that plan mode is active, so the agent continues planning after compaction.
When Plan Mode is Appropriate
Use plan mode for:
- Tasks with significant architectural ambiguity (multiple reasonable approaches)
- Unclear requirements that need exploration before implementation
- High-impact restructuring where the wrong approach wastes significant effort
Skip plan mode for:
- Tasks with a clear implementation path
- Bug fixes where the fix is obvious once you understand the bug
- Adding features that follow existing conventions
- Straightforward modifications (renaming, formatting, adding tests)
- Research and exploration tasks (use subagents instead)