fix(installer): stop duplicating agent instructions; MCP server is the single source of truth (#529) (#538)

The installer wrote a `## CodeGraph` usage block into each agent's
instructions file (CLAUDE.md / AGENTS.md / GEMINI.md / .cursor/rules /
Kiro steering) that duplicated, almost verbatim, the guidance the MCP
server already emits in its `initialize` response — so agents that
surface MCP instructions (Claude Code) read the same playbook twice
every turn.

All 6 instruction-writing targets (claude, cursor, codex, opencode,
gemini, kiro) now stop writing the block. install self-heals by
stripping a block a previous version wrote (uninstall already did), so
the next `codegraph install`/`uninstall` cleans up existing installs;
upgrading the package alone does not (the leftover block is harmless).
server-instructions.ts is now the single source of truth — the two
steers unique to the old template ("trust codegraph, don't re-verify
with grep" and the not-initialized -> `init -i` hint) are ported there.

Removes the now-dead INSTRUCTIONS_TEMPLATE / CLAUDE_MD_TEMPLATE,
claude-md-template.ts, writeClaudeMd / hasClaudeMdSection, and the
Cursor-only wireProjectSurfaces bootstrap. The install log learned a
"Removed" verb. Tests rewritten to the new contract + self-heal
coverage (140/140 installer tests pass).

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Colby Mchenry
2026-05-28 15:13:23 -05:00
committed by GitHub
co-authored by Claude Opus 4.8
parent cea78ceb1b
commit a9c9e76d8c
18 changed files with 282 additions and 593 deletions
-23
View File
@@ -429,15 +429,6 @@ program
if (isInitialized(projectPath)) {
clack.log.warn(`Already initialized in ${projectPath}`);
clack.log.info('Use "codegraph index" to re-index or "codegraph sync" to update');
// Re-run agent surface wiring so re-running `init` is the
// documented way to recover a project that's missing its
// Cursor rules file (or future per-agent project surfaces).
try {
const { wireProjectSurfacesForGlobalAgents } = await import('../installer');
for (const { target, file } of wireProjectSurfacesForGlobalAgents()) {
clack.log.success(`${target.displayName}: ${file.action} ${file.path}`);
}
} catch { /* non-fatal */ }
try {
const { offerWatchFallback } = await import('../installer');
await offerWatchFallback(clack, projectPath);
@@ -450,20 +441,6 @@ program
const cg = await CodeGraph.init(projectPath, { index: false });
clack.log.success(`Initialized in ${projectPath}`);
// Bootstrap project-local surfaces for any agent that's
// configured globally (Cursor needs ./.cursor/rules/codegraph.mdc
// to actually prefer codegraph over native grep). Silent when
// there's nothing to write.
try {
const { wireProjectSurfacesForGlobalAgents } = await import('../installer');
for (const { target, file } of wireProjectSurfacesForGlobalAgents()) {
clack.log.success(`${target.displayName}: ${file.action} ${file.path}`);
}
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
clack.log.warn(`Skipped wiring project-local agent surfaces: ${msg}`);
}
if (options.index) {
let result: IndexResult;