fix(upgrade): stop npm installs self-shadowing on upgrade; verify the resolved version after every upgrade#1245
Merged
Conversation
… resolved version after every upgrade (#1238, #1071) Two fixes to make `codegraph upgrade` trustworthy in the terminal it ran in: 1. detectInstallMethod checked the bundle layout before the node_modules path check, but the npm thin-installer's per-platform package IS a complete bundle inside node_modules — so every npm install misdetected as a standalone bundle, and upgrade curled install.sh into ~/.codegraph: a second install that never wins the PATH race against npm's shim, leaving `codegraph -v` permanently on the old version. Path-based checks (_npx, node_modules) now win over layout sniffing, so npm installs upgrade through npm again, in place. 2. After a successful swap, runUpgrade now probes the PATH-resolved `codegraph --version` and reports the real outcome: a green confirmation that this terminal already serves the new version, a loud shadow warning naming the fix (`which -a codegraph`) on mismatch, or the old soft new-terminal hint only when the probe is inconclusive. Replaces the unconditional "open a new terminal if the version looks unchanged" hedge. Skipped for npm-local installs, whose binary PATH never serves. Companion to #1239: the misdetection also broke its post-upgrade `install --refresh` for npm users (the spawn resolved the stale shim). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Owner
Author
Cross-platform validationLinux (Docker,
Windows (Parallels VM, win32-arm64, Node 24, fresh
🤖 Generated with Claude Code |
colbymchenry
added a commit
to xuing/codegraph
that referenced
this pull request
Jul 10, 2026
…he version probe Conflict resolution after colbymchenry#1245 landed, plus the integration it called for: runUpgrade now runs the PATH version probe first and skips spawning `codegraph install --refresh` on a 'mismatch' — a shadowed stale binary would rewrite the agent surfaces with the very templates the refresh exists to heal. The skip logs a pointer to run the refresh manually once the PATH is fixed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Companion to #1239 / #1238. Together they make three guarantees hold after
codegraph upgrade: hooks refreshed, agent instruction files refreshed (#1239), and — this PR —codegraph -vin the same terminal provably serving the new version.Problem 1 — npm installs self-shadow on upgrade (found while validating #1239)
Reproduced live in a sandboxed
$HOME: install 1.3.1 vianpm i -g, runcodegraph upgrade— andcodegraph --versionreports 1.3.1 forever, in that terminal and every future one.Root cause: the npm thin-installer's per-platform package (
@colbymchenry/codegraph-<platform>-<arch>) is itself a complete bundle — vendorednode+bin/launcher — living insidenode_modules.detectInstallMethodchecked the bundle layout before thenode_modulespath, so every npm install misdetected as a standalone bundle andupgradecurled install.sh into~/.codegraph: a second install that never wins the PATH race against npm's shim. The #1071 shadow pile-up, manufactured byupgradeitself.This also silently broke #1239 for npm users (the issue author's own environment): its post-upgrade
codegraph install --refreshspawn resolves the stale npm shim, which doesn't know--refresh.Fix: path-based checks (
/_npx/,/node_modules/) now run before the layout sniff — where the file lives is authoritative about how the user installed, whatever the artifact inside looks like. npm installs upgrade throughnpm install -g …@latestagain: same shim path, so the same terminal picks up the new version immediately. The shim's GitHub-download self-heal cache (~/.codegraph, issue #303) is outsidenode_modulesand still detects as a bundle.Problem 2 — nothing ever verified the upgrade took
The unix-bundle path ended with "✓ Upgrade complete. Open a new terminal if the version looks unchanged (PATH cache)" — an unconditional hedge for a failure mode we can detect. After a successful swap,
runUpgradenow probes the PATH-resolvedcodegraph --version(throughcmd.exeon Windows for the.cmdlauncher) and reports the real outcome:✓ codegraph on your PATH now reports v1.4.0 — this terminal is already using it.which -a codegraph/where codegraphto find it. Warn-only; the upgrade itself still exits 0.codegraphon PATH, probe fails or output unparsable) → the old soft new-terminal hint, never a scare.Skipped for npm-local installs, whose binary PATH never serves. New
capturedep onUpgradeDeps(piped stdio, 30s timeout) keeps it unit-testable; probe parsing takes the last non-empty stdout line so a stray runtime warning can't spoil it.Validation
cmd.exerouting / npm-local skip / no probe after a failed upgrade.$HOME: bundle 1.3.1 → upgrade → same-shell-v= 1.4.0 with the green confirmation; simulated shadow prints the warning. (The npm misdetection itself was reproduced live pre-fix: upgrade curled install.sh and left the shim at 1.3.1.)Interaction with #1239
Independent — either can merge first; whichever lands second has a trivial conflict in
runUpgrade's post-success block and the CHANGELOG. Ordering note for the rebase: the version probe should run (and ideally gate) before theinstall --refreshspawn, so the refresh never executes through a shadowed stale binary.🤖 Generated with Claude Code