diff --git a/CHANGELOG.md b/CHANGELOG.md index cde40af..4e30677 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to this project will be documented in this file, per [the Ke ## [Unreleased] +### Changed + +- Write Claude Code project context to `CLAUDE.local.md` instead of `CLAUDE.md`, so teams with a committed `CLAUDE.md` are no longer affected. `CLAUDE.local.md` is Claude Code's native local-override file for machine-specific, uncommitted instructions (props [@rickalee](https://github.com/rickalee) via [#77](https://github.com/10up/localwp-agent-tools/issues/77)). +- On first enable or regenerate, any Agent Tools marker block previously written to `CLAUDE.md` is automatically migrated out (the block is removed, leaving the rest of `CLAUDE.md` intact). + ## [0.2.1] - 2026-03-19 ### Fixed diff --git a/src/main.ts b/src/main.ts index 0a77c3c..571c344 100644 --- a/src/main.ts +++ b/src/main.ts @@ -46,8 +46,8 @@ const AGENT_TARGETS: Record = { label: 'Claude Code', mcpConfigPath: '.mcp.json', mcpConfigTopLevelKey: 'mcpServers', - contextFilePath: 'CLAUDE.md', - gitignoreEntries: ['.mcp.json', 'CLAUDE.md'], + contextFilePath: 'CLAUDE.local.md', + gitignoreEntries: ['.mcp.json', 'CLAUDE.local.md'], }, cursor: { label: 'Cursor', @@ -397,6 +397,27 @@ async function updateGitignore(dirPath: string, agents: AgentTarget[]): Promise< await fs.writeFile(gitignorePath, content, 'utf-8'); } +// --------------------------------------------------------------------------- +// Migration Helpers +// --------------------------------------------------------------------------- + +/** + * Removes any Agent Tools marker block from CLAUDE.md left by older versions + * that wrote context there instead of CLAUDE.local.md. + */ +async function migrateClaude(projectPath: string): Promise { + const legacyPath = path.join(projectPath, 'CLAUDE.md'); + if (!(await fs.pathExists(legacyPath))) return; + + const content = await fs.readFile(legacyPath, 'utf-8'); + const markerRegex = new RegExp( + `${escapeRegex(CONTEXT_MARKER_START)}[\\s\\S]*?${escapeRegex(CONTEXT_MARKER_END)}`, + ); + if (!markerRegex.test(content)) return; + + await removeContextFile(legacyPath, 'claude'); +} + // --------------------------------------------------------------------------- // Core Functions // --------------------------------------------------------------------------- @@ -415,10 +436,15 @@ async function setupSite(site: Local.Site, notifier: any, projectDir: string, ag const siteConfig = await buildSiteConfig(site); siteConfigRegistry.register(siteConfig); - // 2. Generate project context + // 2. Migrate legacy CLAUDE.md content to CLAUDE.local.md (no-op if already clean) + if (agents.includes('claude')) { + await migrateClaude(projectPath); + } + + // 3. Generate project context const contextContent = generateProjectContext(site); - // 3. For each selected agent, write configs + // 4. For each selected agent, write configs for (const agent of agents) { const agentConfig = AGENT_TARGETS[agent]; @@ -607,6 +633,11 @@ async function regenerateConfig(site: Local.Site): Promise { const siteConfig = await buildSiteConfig(site); siteConfigRegistry.register(siteConfig); + // Migrate legacy CLAUDE.md content on regenerate (no-op if already clean) + if (agents.includes('claude')) { + await migrateClaude(projectPath); + } + const contextContent = generateProjectContext(site); for (const agent of agents) {