fix(init): generate root CLAUDE.md for --ai claude#1988
fix(init): generate root CLAUDE.md for --ai claude#1988arun-gupta wants to merge 2 commits intogithub:mainfrom
Conversation
Ensure `specify init --ai claude` creates a minimal root CLAUDE.md pointing to `.specify/memory/constitution.md`, and add a regression test for issue github#1983. Made-with: Cursor
There was a problem hiding this comment.
Pull request overview
Ensures specify init --ai claude creates a minimal root CLAUDE.md so Claude Code automatically picks up Spec Kit guidance by pointing to .specify/memory/constitution.md.
Changes:
- Added
ensure_claude_md()helper to generate a rootCLAUDE.mdfor Claude projects (preserving any existing file). - Wired Claude-specific
CLAUDE.mdgeneration into theinit()flow and step tracker. - Added an end-to-end CLI test asserting
CLAUDE.mdis created and contains expected guidance.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/specify_cli/__init__.py |
Adds ensure_claude_md() and calls it during init() for --ai claude. |
tests/test_ai_skills.py |
Adds a CLI test to verify CLAUDE.md is created during offline init. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| content = ( | ||
| "## Claude's Role\n" | ||
| "Read `.specify/memory/constitution.md` first. It is the authoritative source of truth for this project. " | ||
| "Everything in it is non-negotiable.\n\n" | ||
| "## SpecKit Commands\n" | ||
| "- `/speckit.specify` — generate spec\n" | ||
| "- `/speckit.plan` — generate plan\n" | ||
| "- `/speckit.tasks` — generate task list\n" | ||
| "- `/speckit.implement` — execute plan\n\n" | ||
| "## On Ambiguity\n" | ||
| "If a spec is missing, incomplete, or conflicts with the constitution — stop and ask. " | ||
| "Do not infer. Do not proceed.\n\n" |
There was a problem hiding this comment.
ensure_claude_md() will create a root CLAUDE.md that instructs Claude to read .specify/memory/constitution.md even when that file does not exist (e.g., when ensure_constitution_from_template() failed because the template was missing). Consider gating CLAUDE.md creation on the constitution file existing (or on the template being present), and mark the tracker step as error/skipped otherwise to avoid generating misleading guidance.
tests/test_ai_skills.py
Outdated
| result = runner.invoke( | ||
| app, | ||
| [ | ||
| "init", | ||
| str(target), | ||
| "--ai", | ||
| "claude", | ||
| "--offline", | ||
| "--ignore-agent-tools", | ||
| "--no-git", | ||
| "--script", | ||
| "sh", | ||
| ], | ||
| ) |
There was a problem hiding this comment.
This test runs the full specify init --offline scaffolding path (requiring external bash + zip) instead of using the class’s existing approach of patching download_and_extract_template/scaffolding helpers. That makes the test slower and potentially skipped/flaky depending on the environment, reducing the chance the behavior is exercised in CI. Recommend patching the extraction/scaffold steps (and creating the minimal .specify/... structure needed) so the test is deterministic and does not depend on system tools.
| result = runner.invoke( | |
| app, | |
| [ | |
| "init", | |
| str(target), | |
| "--ai", | |
| "claude", | |
| "--offline", | |
| "--ignore-agent-tools", | |
| "--no-git", | |
| "--script", | |
| "sh", | |
| ], | |
| ) | |
| with patch.object(specify_cli, "download_and_extract_template", self._fake_extract): | |
| result = runner.invoke( | |
| app, | |
| [ | |
| "init", | |
| str(target), | |
| "--ai", | |
| "claude", | |
| "--offline", | |
| "--ignore-agent-tools", | |
| "--no-git", | |
| "--script", | |
| "sh", | |
| ], | |
| ) |
generate CLAUDE.md only when `.specify/memory/constitution.md` exists to avoid misleading guidance, and make the regression test deterministic by patching init scaffolding. Made-with: Cursor
Ensure
specify init --ai claudecreates a minimal rootCLAUDE.mdpointing to.specify/memory/constitution.mdMade-with: Cursor
Description
Fixes #1983
Testing
Ran the tests on my machine.
uv run specify --helpuv sync && uv run pytestHere is the output:
Here is the output
AI Disclosure
I used Cursor to understand the codebase and generate the code for this particular fix. I read through the code 3x to ensure it's aligned with the rest of the codebase. I own the responsibility for this fix.