[BIG FEATURE] Rework Plan Mode into a 1st-Class Plan System (Plan Tools + Draft Mode + Plan TUI)
Preflight Checklist
- [x] I have searched existing requests and this feature hasn't been requested yet
- [x] This is a single feature request (not multiple features)
Problem Statement
Current plan mode is a modal state that restricts Claude to thinking-only — but the plan
itself has no persistence, no identity, no execution semantics. You can't name plans, manage
multiple plans, revisit past plans, or configure how a plan gets executed. Plans vanish when
you exit plan mode or compact context.
There's no orchestration layer above existing primitives. Claude has Agent, TeamCreate,
EnterWorktree, and Task tools — but no structured way to coordinate them under a unified
strategy. Users who need multi-step, multi-agent workflows manually sequence everything.
There's also no structured way to provide feedback on a plan before execution. Users either
accept the plan wholesale or re-prompt from scratch. No middle ground for "this is 90% right
but here are my concerns."
Claude's current plan body structure has known weaknesses: no visual distinction between
modify/create/delete, no out-of-scope boundary to prevent drift, no risks section, flat
ordering that doesn't communicate dependencies, and bloat on large changesets with no
compression strategy.
Proposed Solution
OVERVIEW
Introduce a Plan system — 6 new Plan tools, a renamed Draft Mode, a Plan TUI interaction
layer, and a recommended plan body template. Plans are persistent, named, plural objects that
orchestrate existing Claude Code primitives (Agent, TeamCreate, EnterWorktree, Task tools).
No new execution engine — Plans are a conductor for what already exists.
================================================================================
- DRAFT MODE (formerly Plan Mode)
================================================================================
Renamed to convey "nothing is live yet." Pure reasoning sandbox — Claude won't auto-proceed.
Plan tools ARE available in Draft Mode. Draft Mode and Plan tools are orthogonal — use either
independently or together.
================================================================================
- PLAN TOOLS (6)
================================================================================
── PlanCreate ──────────────────────────────────────────────────────────────────
Creates a new plan — a persistent, named document that describes a strategy and optionally
defines tasks to orchestrate. Use it when starting a refactor, kicking off a multi-file
feature, or capturing a complex approach before executing. For simple ideas, just pass
title + body (quick plan). For orchestrated work, add task definitions with dependencies,
execution modes, and approval gates. Use from to clone an archived plan as a starting
template.
Param Type Required Description
─────────────────────────────────────────────────────────────────────────────
title string yes Human-readable plan name
body string yes Markdown body — strategy, context, intent
from string no Existing plan ID to clone as template
tags string[] no Filterable tags
naming string no Override naming convention
orchestration object no Omit for quick plans
orchestration.tasks array yes* Each entry: { name, description, mode?,
depends_on?, approval_gate?,
timeout_minutes? }
(* required if orchestration is provided)
orchestration.default_mode enum no "inline" | "clean" | "forked"
Default task execution mode. Default: "inline"
orchestration.team boolean no Use TeamCreate for multi-agent coordination.
Default: false. Gated behind
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1.
orchestration.retry object no { max_attempts?, backoff? }
Transient failure handling. If a forked agent
gets rate limited or hits a network timeout,
it retries instead of dying.
backoff: "exponential" | "linear" | "fixed"
orchestration.waits_for object no { plan, tasks? }
Cross-plan sequencing — don't start this plan
until another plan's tasks finish.
Validates for circular dependencies at creation time. Warns if file scope overlaps with an
active plan.
── PlanList ────────────────────────────────────────────────────────────────────
Browse and filter plans. Shows all active plans by default. Pass an ID to get the full
contents of a specific plan including its ledger state. Tree view renders the task dependency
graph as ASCII art. Use it to check what's active, find archived plans to reuse, spot stale
plans, or visualize dependencies before executing.
Param Type Required Description
─────────────────────────────────────────────────────────────────────────────
id string no Get a specific plan (returns full plan + ledger)
status enum no "active" | "archived" | "all". Default: "active"
tags string[] no Filter by tags
date_range object no { after?, before? }
view enum no "summary" | "tree". Default: "summary"
Shows last activity date and stale indicator for abandoned plans.
── PlanUpdate ──────────────────────────────────────────────────────────────────
Modify an existing plan. Change its body, title, tags, or orchestration config. Only pending
tasks are editable — running and completed tasks are locked. Can also pass numbered concerns
from the TUI Edit Plan flow, where Claude interprets your feedback into concrete changes.
Behavior depends on planning.editMode setting: "apply" writes immediately, "confirm" shows a
diff first, "iterate" goes back and forth until you're satisfied.
Param Type Required Description
─────────────────────────────────────────────────────────────────────────────
id string yes Plan to modify
title string no New title
body string no New markdown body
orchestration object no Same shape as PlanCreate. Only pending tasks mutable.
tags string[] no Replace tags
concerns string[] no Numbered concerns from TUI Edit Plan flow
── PlanExecute ─────────────────────────────────────────────────────────────────
Runs the plan. First validates file references against the current working tree (catches
renamed, deleted, or diverged files via git rename detection and content hashing). Checks for
cross-plan file scope conflicts. Resolves task dependencies. Then executes using existing
Claude Code primitives — Claude works directly for inline tasks, spawns Agents for forked
tasks (with briefing + plan file), and uses TeamCreate for multi-agent coordination when
applicable. Creates Task tool entries for progress tracking. Forked agents run autonomously —
they receive a context summary and plan file and that's enough. Supports partial execution,
resume after failure, and dry run simulation.
Param Type Required Description
─────────────────────────────────────────────────────────────────────────────
id string yes Plan to execute
mode enum no "inline" | "clean" | "forked"
Global override (overrides all per-task modes)
tasks string[] no Subset of task names to execute. Default: all pending.
resume boolean no Skip completed, restart failed/cancelled/timed_out.
Default: false.
dry_run boolean no Simulate — show what would happen, estimated cost.
Default: false.
Pre-execution pipeline:
- File reference validation (hard stale, soft stale via git rename, content stale via hash)
- Cross-plan file scope overlap check
- Circular dependency validation
- TUI prompts for any warnings/conflicts before proceeding
When adaptiveExecution is true, Claude decides at execution time whether to use solo agents
or TeamCreate based on plan complexity and context — orchestration.team is ignored. When
false, follows the explicit config.
Execution modes:
- inline: Claude works directly in current context. "Do this here, I'm watching."
- clean: Agent spawned with minimal meta-context preamble (premise, goal, specifics) +
plan file + prior task outputs. Cold start with just enough orientation.
- forked: Agent spawned with richer context summary + plan file + prior task outputs.
Warm start, non-blocking. Results written to ledger/outputs on completion.
Context depth is fixed per mode, not configurable. Forked = summary. Clean = minimal.
── PlanStatus ──────────────────────────────────────────────────────────────────
Check execution progress. Shows per-task status, token usage, and any file conflicts needing
resolution. Drill into a specific task for its execution log, output summary, errors, and
file modifications — pulls from TaskGet under the hood. Use it to monitor forked background
work, diagnose failures, or resolve conflicts between concurrent tasks.
Param Type Required Description
─────────────────────────────────────────────────────────────────────────────
id string yes Plan to check
task string no Specific task name for detail
Task statuses: pending / running / completed / failed / blocked / cancelled / timed_out /
queued.
Surfaces cross-plan conflicts, fork-fork and fork-user file conflicts with resolution TUI.
── PlanArchive ─────────────────────────────────────────────────────────────────
Terminates a plan. Either delete it entirely or archive it with a completion report. The
report covers what was planned vs what actually happened — drift from original plan, duration
per task, failures, file modifications. Archived plans live in the archive subdirectory and
can be browsed via PlanList or cloned as a template via PlanCreate's from param. If the
plan has running tasks when you archive, TUI prompts: wait for completion, force kill, or
cancel.
Param Type Required Description
─────────────────────────────────────────────────────────────────────────────
id string yes Plan to archive
action enum yes "archive" | "delete"
report string no Custom completion report (auto-generated if omitted)
================================================================================
- PLAN FORMAT & STORAGE
================================================================================
Hybrid format — markdown body with YAML frontmatter for orchestration config.
Directory-per-plan structure:
~/.claude/plans/combat-refactor/
plan.md # definition (markdown + YAML frontmatter)
ledger.yaml # runtime state, task mapping, file scope, snapshot
outputs/
task-1.md # summarized output for forwarding to dependent tasks
Archived plans move to ~/.claude/plans/archive/.
Example plan.md:
---
id: 2026-03-03-combat-refactor
status: active
created: 2026-03-03T10:00:00Z
orchestration:
default_mode: forked
team: false
retry:
max_attempts: 3
backoff: exponential
waits_for:
plan: vfx-overhaul
tasks: [cleanup]
tasks:
- name: extract-counter-module
description: Pull counter swap logic into its own module
mode: inline
approval_gate: false
- name: refactor-hit-pipeline
description: Restructure hit processing pipeline
mode: forked
approval_gate: true
timeout_minutes: 60
- name: verify-integration
description: Full integration verification
mode: clean
depends_on: [extract-counter-module, refactor-hit-pipeline]
naming: "{date}-{title}"
tags: [combat, refactor]
---
# Combat System Refactor
## Context
...
## Approach
...
## Scope
...
## Changes
- [modify] src/combat/HitPipeline.lua — ...
- [create] src/combat/CounterModule.lua — ...
- [delete] src/combat/OldSwap.lua — ...
## Risks
...
## Reuse
...
## Verification
...
Ledger.yaml tracks:
- Per-task status, timestamps, Task tool ID mapping
- File scope declarations (explicit or auto-inferred)
- Snapshot metadata (commit hash, per-file content hashes at creation time)
- Original plan definition (for drift comparison at archive time)
================================================================================
- PLAN BODY TEMPLATE
================================================================================
Default template for orchestrated plans (quick plans are freeform):
# {title}
## Context
Why this change exists. The problem, what prompted it, intended outcome.
## Approach
The recommended strategy. Not alternatives — the pick.
## Scope
What's in scope. What's explicitly out of scope. Prevents drift.
## Changes
File-by-file breakdown with action tags:
- [modify] path/to/file.luau — what changes and why
- [create] path/to/new.luau — what this file does
- [delete] path/to/old.luau — why it's being removed
## Risks
Things that could go wrong, edge cases to watch, areas needing extra care.
## Reuse
Existing functions/utilities to leverage (with file paths).
## Verification
How to test end-to-end — commands, MCP tools, manual checks.
Configurable via planning.bodyTemplate — "default" for the built-in template or a path to
a custom template file.
================================================================================
- TUI INTERACTION LAYER
================================================================================
── Plan Action Menu ────────────────────────────────────────────────────────────
╭─────────────────────────────────────────────╮
│ Plan: combat-refactor (4 tasks) │
│ Ready to execute. │
╰─────────────────────────────────────────────╯
❯ Execute Plan
❯ Inline (current context)
Clean (fresh context)
Forked (parallel, non-blocking)
Edit Plan
View Plan
Cancel
── Edit Plan ───────────────────────────────────────────────────────────────────
Multi-concern input mode. User adds numbered concerns (Enter to submit, Ctrl+A for new
concern). Gives Claude separated, actionable feedback rather than one text blob.
Behavior controlled by planning.editMode:
- "apply": Claude interprets concerns and applies immediately
- "confirm": Claude shows proposed diff, user approves or re-edits
- "iterate": Claude and user go back and forth until user is satisfied
── Pre-Execution Validation ────────────────────────────────────────────────────
Stale file references:
╭─ Pre-execution validation ────────────────────╮
│ ⚠ 2 file references need attention: │
│ │
│ Task 1: src/combat/HitPipeline.lua │
│ → renamed to src/systems/HitProcessor.lua │
│ (detected via git history) │
│ │
│ Task 3: src/combat/CounterSwap.lua │
│ → file not found (deleted) │
╰────────────────────────────────────────────────╯
❯ Auto-remap and continue
Edit Plan
Abort
Cross-plan overlap:
❯ Execute anyway
Queue after "vfx-overhaul" completes
View overlap details
Cancel
── Failure/Timeout Surfacing ───────────────────────────────────────────────────
Plan execution pauses and explains what happened:
╭─ Plan Paused: combat-refactor ──────────────╮
│ │
│ ⚠ refactor-pipeline timed out after 32m │
│ │
│ What happened: │
│ Agent got stuck resolving circular │
│ dependencies in DamageCalc.lua. Last │
│ action was editing line 142, no progress │
│ for 8 minutes before timeout. │
│ │
│ Impact: │
│ → verify-integration is blocked │
│ (depends on refactor-pipeline) │
│ │
╰─────────────────────────────────────────────╯
❯ Retry task
Retry with more time (60m)
Edit plan and retry
Skip task and unblock dependents
Abort plan
Same pattern for any failure — timeout, error, conflict, rate limit exhaustion.
── File Conflict Resolution ────────────────────────────────────────────────────
Clean merges (non-overlapping changes) auto-resolve silently:
✓ Auto-merged: src/combat/HitProcessor.lua
refactor-pipeline: lines 45-62
extract-counter: lines 120-135
No overlapping changes.
Messy merges pause with explanation:
╭─ File Conflict ─────────────────────────────╮
│ src/combat/HitProcessor.lua │
│ │
│ refactor-pipeline rewrote processHit() │
│ (lines 45-80) │
│ │
│ extract-counter also modified processHit() │
│ (lines 52-68) to move the counter swap │
│ │
│ Both changed the same function body. │
╰─────────────────────────────────────────────╯
❯ Keep refactor-pipeline's version
Keep extract-counter's version
Open diff and resolve manually
Re-run task against other's output
── Archive with Running Tasks ──────────────────────────────────────────────────
❯ Wait for completion, then archive
Force archive (kills running steps)
Cancel
── Ctrl+C ──────────────────────────────────────────────────────────────────────
Single Ctrl+C = cancel current task, plan goes paused. Resumable.
Double Ctrl+C = abort entire plan, all running tasks killed. Resumable.
================================================================================
- CROSS-PLAN CONFLICT RESOLUTION
================================================================================
Each plan's file scope is tracked in the ledger — declared explicitly in orchestration config
or auto-inferred from task descriptions.
Detection at three points:
- PlanCreate — warn on overlap with active plans
- PlanExecute — warn + prompt before running
- Task completion — check if other plans modified same files since fork time
Running tasks hold soft locks on their file scope. Advisory only — other tasks/plans get
warned but not blocked.
Explicit cross-plan dependency via orchestration.waits_for for intentional sequencing.
================================================================================
- STALE FILE REFERENCE HANDLING
================================================================================
Plans snapshot commit hash + per-file content hashes at creation time in the ledger.
Pre-execution validation:
- Hard stale — file deleted. Flagged immediately.
- Soft stale — file renamed/moved. Git rename detection suggests updated paths.
- Content stale — file exists but content diverged significantly. Hash comparison warns.
TUI surfaces issues with auto-remap, edit plan, or abort options.
================================================================================
- TASK OUTPUT FORWARDING
================================================================================
When task B depends on task A, task A's output summary (stored in outputs/task-a.md) gets
injected into task B's context preamble. Dependencies are information flow, not just ordering
constraints.
For clean mode tasks: meta-context preamble + prior task outputs.
For forked mode tasks: richer context summary + prior task outputs.
================================================================================
- FAILURE & RECOVERY
================================================================================
Transient failures (rate limit, network timeout) auto-retry with configurable backoff via
orchestration.retry. Default: 3 attempts, exponential backoff.
Non-transient failures mark task "failed", dependents go "blocked". Plan execution pauses
and surfaces what happened, why, impact, and actionable options via TUI.
Resume (PlanExecute with resume: true) restarts failed/cancelled/timed_out tasks from
scratch, skips completed tasks.
Plan state survives context compaction and session boundaries via ledger on disk. After
compaction, Claude re-reads the plan from disk and resumes using ledger state.
Per-task timeout configurable in orchestration config, global default via planning.taskTimeout.
Rate limit graceful degradation: forked task goes "queued" with backoff retry instead of
failing.
================================================================================
- FORKED EXECUTION — ADDITIONAL CONTEXT
================================================================================
Forked execution spawns a parallel Agent session. The forked agent receives:
- Briefing: a context summary generated at fork time — targeted to the plan's scope,
richer than clean mode's minimal meta-context
- The plan file (plan.md)
- Prior task outputs (from outputs/ directory)
That's enough for autonomous execution.
How forked tasks run:
- Separate Claude Code session/process with its own context window
- Results written to ledger + outputs on disk as tasks complete (survives session boundaries)
- Multiple forked tasks can run concurrently, bounded by planning.maxForks
Conflict handling:
- Optimistic (default): forked task writes directly to working tree. Conflicts detected
after the fact at task completion via git diff or mtime comparison.
- Branch: forked task runs in a git worktree via EnterWorktree. Fully isolated. User
merges results back.
Clean merges (non-overlapping changes to the same file) auto-resolve. Messy merges (overlapping
lines, semantic conflicts) pause the plan with an explanation and resolution options.
Fork-user conflicts (user edits a file that a forked task is also modifying) detected the
same way — forked task tracks modified files, checks against working tree state at completion.
================================================================================
- QUICK PLANS
================================================================================
PlanCreate with just title + body. No orchestration config. Freeform markdown. Progressive
disclosure — users graduate from quick plans to orchestrated plans as complexity demands.
Not everything needs task definitions, dependencies, and execution modes.
================================================================================
- DRY RUN
================================================================================
PlanExecute with dry_run: true. Shows what would happen without executing:
- Which agents/teams would be spawned
- Execution order based on dependency resolution
- Estimated context cost per task
- File scope per task
Trust-building before committing to a multi-forked execution.
================================================================================
- SECURITY
================================================================================
Plans created via PlanCreate are trusted. Plans manually placed in the plans directory by
external means (git pull, teammate commit) get a confirmation prompt before execution:
"This plan was not created in your session. Review before executing?"
Same security model as CLAUDE.md loading.
================================================================================
- PLAN ABANDONMENT
================================================================================
PlanList shows last activity date per plan. Plans with no activity in X days show a "stale"
indicator. Optional ttl_days per plan in the plan config. Visibility only — no auto-deletion.
User decides when to archive or delete.
================================================================================
- NAMING COLLISIONS
================================================================================
Same-day same-title plans get an incrementing counter appended:
2026-03-03-combat-refactor → 2026-03-03-combat-refactor-2
================================================================================
- SETTINGS
================================================================================
All plan-related settings under a single "planning" key in settings.json:
{
"planning": {
"directory": "~/.claude/plans",
"naming": "{date}-{title}",
"editMode": "confirm",
"adaptiveExecution": true,
"taskTimeout": 30,
"autoArchive": false,
"maxForks": 3,
"bodyTemplate": "default"
}
}
<html><head></head><body>
Setting | Type | Default | Description
-- | -- | -- | --
directory | string | ~/.claude/plans | Where plans live on disk
naming | string | {date}-{title} | Naming template. Tokens: {date}, {time}, {datetime}, {title}, {id}
editMode | apply \| confirm \| iterate | confirm | How plan edits work. apply = immediate. confirm = show diff first. iterate = back and forth until satisfied.
adaptiveExecution | boolean | true | Claude picks execution pattern at runtime (solo vs team). When false, follows orchestration.team.
taskTimeout | number | 30 | Default per-task timeout in minutes. Overridable per-task in orchestration config.
autoArchive | boolean | false | Auto-archive plans on clean completion.
maxForks | number | 3 | Max concurrent forked executions across all plans.
bodyTemplate | string | "default" | "default" for built-in template, or path to custom template file.
</body></html>
Alternative Solutions
- Recursive agent spawning (agents creating agents) — solves the depth problem but
introduces unbounded recursion, resource management nightmares, and difficult-to-debug
execution trees. Plans as an orchestration layer over existing primitives gives the same
depth benefit with a clean two-level ceiling.
- Enhancing current plan mode with persistence only (save/load plans as files) — addresses
the "plans are ephemeral" problem but misses orchestration, execution semantics, and
structured feedback. Plans without execution are just saved notes.
- Adding a "run in forked context" button to current plan mode — the original spark for
this idea. Solves one execution mode but doesn't address multiple concurrent plans,
naming, archival, structured editing, or orchestration config. This proposal subsumes
that as one of three execution modes.
- Free-text plan editing (user re-prompts with corrections) — current approach. Loses the
separation between distinct concerns, no confirmation step, no diff view. The numbered
concern input + configurable edit mode gives structure without over-engineering.
- Building a new execution engine for plans — unnecessary. Claude Code already has Agent,
TeamCreate, EnterWorktree, and Task tools. Plans should orchestrate these existing
primitives, not reinvent them.
Priority
Critical - Blocking my work
Feature Category
CLI commands and flags
Use Case Example
A developer is refactoring a combat system across multiple modules:
- Enters Draft Mode to reason without executing
- Uses PlanCreate to define "combat-refactor" with a body following the default template
(Context, Approach, Scope, Changes with [modify]/[create]/[delete] tags, Risks, Reuse,
Verification) and an orchestration config with 3 tasks and dependencies
- TUI presents the Plan Action Menu — developer selects "Edit Plan"
- Developer adds concerns via numbered input:
- counter swap should be extracted first, before any dispatch logic
- verify-integration needs to depend on both prior tasks
- add an approval gate before the pipeline refactor runs
- editMode is "confirm" — Claude shows proposed diff, developer approves
- Developer selects "Execute Plan" → "Forked (parallel, non-blocking)"
- Pre-execution validation catches a renamed file — git rename detection suggests the
updated path, developer selects "Auto-remap and continue"
- PlanExecute creates Task tool entries for tracking, spawns Agents for forked tasks
with briefing + plan file
- While tasks run in background, developer continues other work
- A task times out — plan pauses, surfaces what happened, why, and impact. Developer
selects "Retry with more time (60m)"
- Two forked tasks modified the same file — non-overlapping changes auto-merge silently.
PlanStatus shows "✓ Auto-merged: src/combat/HitProcessor.lua"
- All tasks complete. PlanArchive generates a completion report showing drift from original
plan and archives for future reference.
Next month, developer uses PlanList to browse archived plans, clones the combat refactor
via PlanCreate with from: "2026-03-03-combat-refactor", edits via TUI, and executes.
Additional Context
This proposal reframes plans from a UX restriction (can't execute) into a first-class
orchestration primitive. Key insights:
- CONDUCTOR, NOT ENGINE — Plans orchestrate existing Claude Code primitives (Agent,
TeamCreate, EnterWorktree, Task tools). Zero new execution infrastructure. The value is
in the coordination, persistence, and structured decision-making — not in how code runs.
- DEPTH WITHOUT RECURSION — Plans coordinate Agents/Teams which use Tools. Clean two-level
ceiling without recursive agent spawning.
- CONTEXT AS A FIRST-CLASS CONCERN — Execution modes control what context each task gets.
Inline preserves current context. Clean provides minimal meta-context. Forked carries a
richer summary. Fixed behavior per mode, no configuration knobs.
- STRUCTURED HUMAN FEEDBACK — The TUI concern-input pattern bridges "accept everything"
and "re-prompt from scratch." Numbered concerns give Claude separated, actionable
feedback. The configurable editMode (apply/confirm/iterate) lets users dial friction.
- PLANS THAT TALK TO YOU — When something goes wrong (timeout, failure, conflict), the plan
pauses and explains what happened, why, what's affected, and what you can do. Not a silent
ledger update — an interactive decision point.
- PROGRESSIVE DISCLOSURE — Quick plans (just title + body) for simple ideas. Orchestrated
plans for complex work. Users graduate naturally.
- FORKED EXECUTION — Agents receive a briefing + plan file and run autonomously. Clean
merges auto-resolve. Messy merges pause with explanation. Branch isolation via
EnterWorktree available per-task.
- TEAMS INTEGRATION — Plans use TeamCreate when multi-agent coordination is needed. Gated
behind existing CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 env var. No new flags.
- ADAPTIVE EXECUTION — When planning.adaptiveExecution is true, Claude decides at runtime
whether a plan needs solo agents or full team coordination. Orchestration config is
declarative intent, not rigid instruction.
This issue has 7 comments on GitHub. Read the full discussion on GitHub ↗