[FEATURE] Allow setting plan naming scheme per-repo

Status Open
Maintainer reply ✓ Yes — bcherny
Activity 10 comments · opened Nov 28, 2025
💡 Likely answer: A maintainer (bcherny, collaborator) responded on this thread — see the highlighted reply below.

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

I have established a discipline around using plan files:

  • I place them in a plans/ directory in my repo
  • I name them PLAN-xxxx-some-description.md
  • I leave them around and refer to them by name in future prompts even after completion: "In PLAN-XYZU we did this in a certain way, lets do it again that way"
  • I have workspace directions around this discipline: "If you are working on a plan, REMEMBER which plan during compaction summarization and re-read the plan afterward", "Plans are places in plans/PLAN-xxxx-some-thing.md", etc.
  • I keep them checked in and can refer to how they've changed over time
  • I can review and iterate them before actually implementing them
  • I often work with these plan files in plan mode to keep Claude Code focused

This has worked very well for me, and I often work with plans in plan mode this way.

The new plans feature places plans in a hidden my home directory with meaningless names, it also places them outside the repo where I am doing work, and plan mode now seems confused when I refer to "plan files" in planning mode, thinking I am referencing the home directory location.

Proposed Solution

I think the new planning mode would be perfect if, instead of writing the plan to a random location, we could give it a location and name pattern in the repo .claude/settings.json (or could just be moved there). Making meaningful, non-colliding names is a very easy task for Haiku, so I think implementing this could be done cheaply in terms of token budget. This would allow very easy tracking, editing, and long-term reference to plan files as well.

Alternative Solutions

I will probably experiment with renaming my files to "designs", but I am still somewhat bothered by the placement of plans in the ~/.claude location - this is not a convenient place to edit or review files that I'm managing as part of a workspace or development flow.

It is still very informative to see the contents of this file within my workspace under any circumstance, and the placement in ~/.claude in such a disorganized way is very inconvenient.

If the plans directory has been made in this way with some sincere design conviction, it would also be helpful to just have documentation of what the intended practice is around plan file editing and management. Is this meant to feed into a UI or editing flow an a way that I don't understand?

Priority

Medium - Would be very helpful

Feature Category

Interactive mode (TUI)

Use Case Example

_No response_

Additional Context

_No response_

View original on GitHub ↗

10 Comments

uebber · 8 months ago

I've run into this issue several times and I'm honestly shocked about the architectural choice to store project/repo-specific state globally. Sometimes Claude Code creates a total mess and you're happy to have git, so that you can git reset --hard. Obvious user expectation would be: we're starting fresh again. But no, your old, totally opaque plan.md files, with dead-end thought traces, still haunt you and lead Claude again astray. Please add at least the storage setting for plan files, as many others have requested.

g-kartik · 7 months ago

Much required feature.

Jihad · 7 months ago

Oh i've been fighting claude code for two weeks now to keep the plans inside the local .claude/plans folder of the repo. It fits perfectly with code review/audit hooks on commits, having the plan.md included in the commit.

vzakharov · 6 months ago

Pardon... Multiple GH issues here _asking for plan names to be semantic_ instead of random have been auto-closed as duplicates ultimately leading to this one issue, which seems to be the only one that was NOT auto-closed.

But this issue is about a different thing, concerning locations rather than naming. So, @bcherny et al, what would be the proper way to address this?

I imagine the solution to be dead-simple by just providing Claude with a "slug" argument to "EnterPlanMode" tool — you can even make it optional if you want full backwards compatibility.

But I feel the fact that there’s at least a dozen issues to the same, ALL auto-closed due to a duplicate chain which ultimately leads to a non-related issue, makes this one in sort of a blind zone for the team.

Thanks for your attention.

specul8 · 6 months ago

Just posted a workaround that has zero-friction operation here: https://github.com/anthropics/claude-code/issues/21342#issuecomment-3853266585

Features:

  1. Session plan file naming convention can be anything (I use my project folder name, can be constructed to a predictable pattern)
  2. Manages session plan name changes between Claude restarts, while consistently writing to a common plan location for the project
  3. Stored in Project Repo
  4. Built with Serena MCP usage (but not required, can target any folder - including team-shared folder locations)
  5. Automatically "Takes out the trash" (deletes session plan files from previous sessions)

Hope it helps someone else like it helped me (I run multiple worktree projects simultaneously, so Claude can work on one problem while I create a new prompt for a different problem in a different worktree - reduces downtime)

Perlover · 6 months ago

I suggest we close this ticket because, for example, I am currently using the latest version (v2.1.62), and everything is working as intended. I have the following settings in Claude Code Settings for the project ("plansDirectory": "./.claude/plans" in .claude/settings.json), and the plans are being placed within the project.

I believe the bug no longer exists.

alfredo-rgzm · 6 months ago

Your naming discipline is exactly right — plans should be meaningful artifacts, not throwaway temp files. But even with configurable paths and names, the core gap remains: plans have no status, no awareness of each other, and no way to survive context compression. What's needed alongside a plansDir setting is a lightweight registry that tracks plan state (draft/approved/completed) and lets new plans reference old ones. I wrote up the full picture in #29445 — naming is one piece, but lifecycle and chaining are what make plans actually persistent across sessions.

bcherny collaborator · 5 months ago

The directory half of this shipped in v2.1.9 — use the plansDirectory setting:

~~~json
// .claude/settings.json (project-scoped)
{ "plansDirectory": "./plans" }
~~~

Path is relative to the project root. Default is ~/.claude/plans.

The naming scheme part isn't configurable yet. Leaving this open to track the naming-scheme request specifically — retitling accordingly.

dolphinspired · 5 months ago

While the official solution being developed, I've shared my own solution here that anyone is welcome to use: https://github.com/dolphinspired/claude-plan-mirror

tl;dr - It's a bash script that hooks into the Write/Edit tools. If the directory is ~/.claude/plans, it determines a timestamped filename and appends it to the file, like this:

<!-- mirror-plan-to: {project_dir_name}_{timestamp}.md -->

The script then copies that plan to Claude's current working directory in the "plans" subfolder. Claude always calls Write for new plans, which will overwrite the global session plan file, causing a new filename to be generated. Plan revisions always call the Edit tool, which will leave the HTML comment marker intact, so the script will write to that filename rather than generating a new one.

Best of all, this is a deterministic, zero-token way to ensure your plans are copied to the project folder. No extra context added for Claude. 🎉

yurukusa · 5 months ago

Until this gets built natively, you can achieve most of what you're describing with a PostToolUse hook that auto-syncs plan files into your repo with meaningful names.

INPUT=$(cat)
TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null)
[[ "$TOOL" != "Write" ]] && exit 0
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null)
[[ -z "$FILE" ]] && exit 0
if ! echo "$FILE" | grep -qE "$HOME/\.claude.*(plan|PLAN)"; then
    exit 0
fi
git rev-parse --git-dir &>/dev/null || exit 0
PLAN_DIR="plans"
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
[[ -z "$REPO_ROOT" ]] && exit 0
mkdir -p "$REPO_ROOT/$PLAN_DIR"
if [ -f "$FILE" ]; then
    TITLE=$(grep -m1 '^#' "$FILE" 2>/dev/null | sed 's/^#\+\s*//' | head -c 60)
    [ -z "$TITLE" ] && TITLE=$(grep -m1 '.' "$FILE" 2>/dev/null | head -c 60)
    SLUG=$(echo "$TITLE" | tr '[:upper:]' '[:lower:]' | tr ' ' '-' \
         | sed 's/[^a-z0-9-]//g' | sed 's/--\+/-/g' | sed 's/^-\|-$//g' | head -c 40)
    [ -z "$SLUG" ] && SLUG=$(basename "$FILE" .md)
    LAST_NUM=$(ls "$REPO_ROOT/$PLAN_DIR"/PLAN-*.md 2>/dev/null \
             | sed 's/.*PLAN-\([0-9]\+\).*/\1/' | sort -n | tail -1)
    NEXT_NUM=$(printf "%04d" $(( ${LAST_NUM:-0} + 1 )))
    DEST="$REPO_ROOT/$PLAN_DIR/PLAN-${NEXT_NUM}-${SLUG}.md"
    EXISTING=$(grep -rl "<!-- source: $FILE -->" "$REPO_ROOT/$PLAN_DIR" 2>/dev/null | head -1)
    if [ -n "$EXISTING" ]; then
        cp "$FILE" "$EXISTING"
        echo "<!-- source: $FILE -->" >> "$EXISTING"
    else
        cp "$FILE" "$DEST"
        echo "<!-- source: $FILE -->" >> "$DEST"
    fi
fi
exit 0
// .claude/settings.json
{
  "hooks": {
    "PostToolUse": [{
      "matcher": "Write",
      "hooks": [{ "type": "command", "command": ".claude/hooks/plan-repo-sync.sh" }]
    }]
  }
}

Or one-liner install: npx cc-safe-setup --install-example plan-repo-sync
Every time Claude writes/updates a plan file in ~/.claude/, this hook automatically copies it to ./plans/PLAN-0001-descriptive-name.md in your repo. The name is derived from the plan's first heading. Subsequent updates to the same plan overwrite in place (tracked via a source comment).
This gives you exactly the workflow you described — plans versioned in your repo with meaningful names you can reference across sessions.