TL;DR One line in the project's
.claude/settings.json,"plansDirectory": "./plans", and the plan lives next to the code: you find it next session, you@-mention it, and it ships with the PR.
Every plan you approve in plan mode is already a markdown file. Claude Code has written it to disk by the time you approve, so there's nothing to ask for. And that file comes back whole after compaction: the docs put it on the same row as your root CLAUDE.md, re-injected from disk. The opposite of what happens to paths: rules and nested CLAUDE.md files.
The catch is where it lands.
Where your plan lives
By default, in ~/.claude/plans: one folder shared by every project, with generated file names.
$ ls -t ~/.claude/plans
expressive-chasing-frost.md
docs-craft-logout-plan-md-pure-plum.md
docs-craft-logout-plan-md-humble-honey.md
docs-craft-logout-plan-md-zany-avalanche.md
...
Mine holds 12 plans. The newest belongs to the wmedia site and sits between plans from another repo, and no file name tells you which project it came from. During the session that doesn't matter, because Claude knows which one is its own. Once you close it, finding last week's plan means opening files one at a time.
One line, and it lives in your repo
1. Point plansDirectory at a folder in the project
// .claude/settings.json
{
"plansDirectory": "./plans"
}
The path resolves against the project root. If it points outside the project, Claude Code ignores it and keeps using ~/.claude/plans.
2. Plan as usual
I tried it in a scratch repo: plan mode, and a task to add a subtract function with tests. Claude created the folder and saved the plan inside:
$ find . -path ./.git -prune -o -name "*.md" -print
./plans/plan-adding-a-subtract-eventual-cat.md
The file holds the full plan: context, changes file by file, and how to verify them. That output comes from a -p --permission-mode plan run.
3. Commit the plan with the code
The plan says why the change exists, so it belongs in the same PR. Your reviewer reads the intent first and the diff second. And next session you pick it up with an @plans/... mention instead of digging through a global folder.
The file is the handoff
One setting makes that obvious. With "showClearContextOnPlanAccept": true, the approval menu gets a new first option, Yes, clear context and …: it approves the plan, wipes the conversation, and Claude implements from the file alone. Planning burns a lot of context, and that option throws all of it away and keeps the one thing that matters. It's off by default.
Without it you get much the same: if the session compacts halfway through implementation, the plan comes back from disk. The task list on newer models disappears into the summary. The plan doesn't.
If you're new to plan mode, start with what it does and what it doesn't. And if you approve every plan anyway, a hook can approve them for you.
Official docs: plansDirectory · What survives compaction · Review and approve a plan
Tested on Claude Code v2.1.284, October 1, 2026.