Skip to content

fix(upgrade): refresh installer-written agent surfaces after a binary upgrade (#1238)#1239

Open
xuing wants to merge 2 commits into
colbymchenry:mainfrom
xuing:upgrade-refresh-installed-surfaces
Open

fix(upgrade): refresh installer-written agent surfaces after a binary upgrade (#1238)#1239
xuing wants to merge 2 commits into
colbymchenry:mainfrom
xuing:upgrade-refresh-installed-surfaces

Conversation

@xuing

@xuing xuing commented Jul 10, 2026

Copy link
Copy Markdown

Fixes #1238.

Problem

codegraph upgrade updates the binary, but never revisits what earlier installs wrote into the agents. On a machine using CodeGraph since 0.9.x, every upgrade through 1.3.1 left the marker-fenced CLAUDE.md / AGENTS.md sections exactly as the 0.9.x installer wrote them: a nine-tool decision table telling agents to reach for codegraph_context first — a tool 1.0.0 removed — and for six other tools that no longer appear on the default MCP surface. Agents follow the file, get "unknown tool", and conclude CodeGraph is broken. Full timeline in #1238.

Every write in the install path is already an idempotent, self-healing upsert (the pre-#529 long-block heal, the pre-0.8 hook cleanup, the pre-#207 local-MCP migration) — but nothing ever invokes it on upgrade, so all that healing only reaches users who happen to re-run codegraph install by hand.

Approach

Extends the precedent already in the upgrade path: runUpgrade self-heals the Claude prompt hook after a successful swap. This PR does the same for the rest of the installed surfaces, with one twist the prompt hook didn't need: the instruction templates are baked into the binary, so the heal must be executed by the new binary — the still-running old process would only rewrite its own stale copy, the exact staleness being healed.

  • codegraph install --refresh — a non-interactive sweep (same shape as uninstallTargets, exposed and unit-tested the same way) that re-runs install() for every target that is already configured. Never a first install: unconfigured agents are skipped, permissions aren't written (autoAllow: false), and the prompt hook is left as the user chose it (promptHook: undefined). Sweeps global + local unless --location narrows it.
  • codegraph upgrade spawns codegraph install --refresh after a successful binary swap — PATH resolves to the fresh install at that point. Gated on codegraph being resolvable (an npm-local install isn't), opt-out via CODEGRAPH_NO_INSTALL_REFRESH=1, and never fatal to the upgrade.

Nothing changes on a machine that's already current: every underlying write is the targets' own byte-compare upsert, so the sweep reports unchanged across the board and prints one quiet line.

What it looks like

$ codegraph upgrade
…
✓ Upgrade complete.
Refreshing agent instruction sections and config written by previous versions…
  Claude Code: refreshed /home/user/.claude/CLAUDE.md
  Codex CLI: refreshed /home/user/.codex/AGENTS.md

On an already-current machine:

$ codegraph install --refresh
All configured agent surfaces are already current.

Tests

  • 6 new runUpgrade orchestration tests: the refresh is spawned last (after the swap, so the new binary writes); Windows runs the .cmd launcher through cmd.exe; skipped when codegraph isn't on PATH; skipped by the kill-switch; a failing refresh warns without failing the upgrade; no refresh after a failed upgrade.
  • 4 new refreshTargets sweep tests: rewrites a planted stale block and reports refreshed; never performs a first install; preserves a hand-trimmed permissions list; second sweep is all-unchanged.
  • Targeted installer/upgrade suites: 193 passed / 0 failed; TypeScript build passed.
  • Manual e2e: fresh build, fake $HOME, install -t claude -l global -y → plant the 0.9.x section → install --refresh rewrites it to the current template → second --refresh reports already-current.

Not in this PR

Old codex installers also wrote per-tool approval_mode blocks ([mcp_servers.codegraph.tools.*]) that can reference tools which no longer exist; install() doesn't own those keys today, so the sweep doesn't clean them. That would be a target-level cleanup in the codex target, same pattern as the existing legacy-hook cleanup — happy to follow up if wanted.

🤖 Proudly generated using Fable 5, and reviewed with GPT5.6 sol.

… upgrade

codegraph upgrade swapped the binary but never revisited what earlier
installs wrote into CLAUDE.md / AGENTS.md / GEMINI.md and the agent
configs, so sections written by a pre-1.0 installer kept teaching agents
a multi-tool surface (including tools that no longer exist) months of
releases later. The install path already self-heals everything it owns,
but nothing ever called it on upgrade.

- codegraph install --refresh: non-interactive sweep that re-runs
  install() for already-configured targets only — never a first
  install; permissions and prompt-hook choices are preserved.
- codegraph upgrade spawns it via the freshly-installed binary after a
  successful swap (the still-running old process would only rewrite its
  own stale template). Gated on PATH resolution and the
  CODEGRAPH_NO_INSTALL_REFRESH=1 kill-switch; never fatal to the
  upgrade.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR ensures that after codegraph upgrade swaps in a new binary, any agent-facing surfaces previously written by older installers (marker-fenced instruction blocks and MCP entries) are refreshed so they match the tool surface and templates of the newly-installed version.

Changes:

  • Add a refresh-only sweep (codegraph install --refresh) that re-runs per-target install() only for already-configured targets, preserving permissions and prompt-hook choices.
  • Invoke that sweep automatically at the end of a successful codegraph upgrade (non-fatal, PATH-gated, opt-out via CODEGRAPH_NO_INSTALL_REFRESH=1).
  • Add unit tests covering upgrade orchestration and refresh sweep behavior/idempotency.

Reviewed changes

Copilot reviewed 5 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/upgrade/index.ts Spawns codegraph install --refresh after successful upgrades (with platform-specific Windows handling and kill-switch).
src/installer/index.ts Introduces refreshTargets() and RefreshReport to refresh already-configured targets only.
src/bin/codegraph.ts Adds codegraph install --refresh CLI flag and wires it to refreshTargets().
CHANGELOG.md Documents the new upgrade-time refresh behavior and manual install --refresh usage.
tests/upgrade.test.ts Adds orchestration tests verifying refresh spawn timing, Windows invocation, gating, kill-switch, and non-fatal failure behavior.
tests/installer-targets.test.ts Adds refresh sweep tests for stale block rewrite, “no first install”, permissions preservation, and idempotency.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/installer/index.ts
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Upgrading CodeGraph leaves old agent instructions in place

2 participants