✨ feat(playbook): auto-create CLAUDE.md with path discovery
sync_claude_md now: - Checks project root CLAUDE.md first, then .claude/CLAUDE.md - Auto-creates if neither exists (default: project root) - Supports playbook.claude_md config to override location - Update test to verify auto-creation behavior Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
6ec9a45a83
commit
6518f0f554
|
|
@ -721,18 +721,30 @@ def sync_agents_template(context: dict) -> int:
|
|||
date_value,
|
||||
playbook_scripts,
|
||||
)
|
||||
sync_claude_md(project_root)
|
||||
sync_claude_md(project_root, context.get("config", {}))
|
||||
return 0
|
||||
|
||||
|
||||
_CLAUDE_BLOCK_START = "<!-- playbook:claude:start -->"
|
||||
_CLAUDE_BLOCK_END = "<!-- playbook:claude:end -->"
|
||||
|
||||
_CLAUDE_MD_CANDIDATES = ["CLAUDE.md", ".claude/CLAUDE.md"]
|
||||
|
||||
def sync_claude_md(project_root: Path) -> None:
|
||||
claude_md = project_root / "CLAUDE.md"
|
||||
if not claude_md.exists():
|
||||
return
|
||||
|
||||
def sync_claude_md(project_root: Path, config: dict) -> None:
|
||||
claude_md_config = config.get("playbook", {}).get("claude_md")
|
||||
|
||||
claude_md: Path | None = None
|
||||
if claude_md_config:
|
||||
claude_md = project_root / claude_md_config
|
||||
else:
|
||||
for candidate in _CLAUDE_MD_CANDIDATES:
|
||||
path = project_root / candidate
|
||||
if path.exists():
|
||||
claude_md = path
|
||||
break
|
||||
if claude_md is None:
|
||||
claude_md = project_root / "CLAUDE.md"
|
||||
|
||||
block_lines = [
|
||||
_CLAUDE_BLOCK_START,
|
||||
|
|
@ -743,6 +755,12 @@ def sync_claude_md(project_root: Path) -> None:
|
|||
_CLAUDE_BLOCK_END,
|
||||
]
|
||||
|
||||
if not claude_md.exists():
|
||||
ensure_dir(claude_md.parent)
|
||||
claude_md.write_text("\n".join(block_lines) + "\n", encoding="utf-8")
|
||||
log(f"Created {claude_md.relative_to(project_root)} with playbook block.")
|
||||
return
|
||||
|
||||
text = claude_md.read_text(encoding="utf-8")
|
||||
|
||||
if _CLAUDE_BLOCK_START in text:
|
||||
|
|
|
|||
|
|
@ -487,7 +487,7 @@ skills = ["style-cleanup"]
|
|||
root, agents_home, f"{CUSTOM_DEPLOY_ROOT}/docs"
|
||||
)
|
||||
|
||||
def test_sync_claude_md_skips_when_no_claude_md(self):
|
||||
def test_sync_claude_md_creates_when_no_claude_md(self):
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
config_body = f"""
|
||||
[playbook]
|
||||
|
|
@ -503,7 +503,11 @@ project_name = "Demo"
|
|||
result = run_cli("-config", str(config_path))
|
||||
|
||||
self.assertEqual(result.returncode, 0)
|
||||
self.assertFalse((Path(tmp_dir) / "CLAUDE.md").exists())
|
||||
claude_md = Path(tmp_dir) / "CLAUDE.md"
|
||||
self.assertTrue(claude_md.exists())
|
||||
text = claude_md.read_text(encoding="utf-8")
|
||||
self.assertIn("@AGENTS.md", text)
|
||||
self.assertIn("<!-- playbook:claude:start -->", text)
|
||||
|
||||
def test_sync_claude_md_appends_block_to_existing_claude_md(self):
|
||||
with tempfile.TemporaryDirectory() as tmp_dir:
|
||||
|
|
|
|||
Loading…
Reference in New Issue