Files
codegraph/__tests__
Colby MchenryandClaude Opus 5.5 0abae11959 fix(installer): a symlinked instructions or config file is written through, not replaced (#2768)
Root cause: every installer write goes through one helper that writes
`<path>.tmp.<pid>` and renames it onto the path. A rename replaces a
symbolic link itself, not the file it points to. So a `~/.codex/AGENTS.md`
or `~/.claude.json` linked from a dotfiles repo became a detached regular
copy on install: the shared file never got CodeGraph's settings, and later
edits to it no longer reached the agent. This held for every target (Claude
Code, Codex, opencode, Cursor, Gemini, Antigravity, Kiro, Hermes and the
Copilot family) and for install, the refresh that `codegraph upgrade` runs,
and uninstall. Uninstall also deleted a link whose file it had emptied,
leaving CodeGraph's entry behind in the shared file.

Fix:
- The write helper resolves a link to the file at the end of its chain and
  writes and renames there, so the link stays exactly as it was, relative
  or absolute.
- A link to a file that doesn't exist yet gets that file created, but only
  in a folder that already exists, as writing through it in a shell would.
  No folder is ever created where a link points.
- A dangling chain is followed hop by hop from the real folder holding each
  link, so a relative link under a linked folder lands where the OS would
  put it.
- When the linked file can't be written (a read-only file, a folder that
  doesn't exist), the error names the link and its target and nothing
  changes.
- Where uninstall used to delete a user's file it had emptied (an
  instructions file, Codex's config.toml, Copilot CLI's mcp-config.json,
  the legacy project .claude.json), a link is kept and the emptied content
  is written through it.
- The refresh sweep catches a failure per agent, reports it, still
  refreshes the others, and exits non-zero, so the upgrade warns.

Decided: links to CodeGraph's own legacy files (Cursor's codegraph.mdc,
Kiro's steering doc), which install only ever deletes, are still removed.

Validation:
- 28 new tests. 25 are in installer-targets.test.ts:
  - every target and location: install and uninstall keep each of its
    files that is a link (18 cases);
  - the shared files' content through install and uninstall for Claude
    Code, Codex, opencode (two agents sharing one AGENTS.md) and Cursor;
  - relative links under a linked folder;
  - a link into a missing folder;
  - a link to a read-only file;
  - uninstall emptying through links;
  - a failing link in a refresh;
  - a folder link guard.
  The other 3:
  - 1 in upgrade.test.ts, where the refresh runs the built CLI;
  - 2 in a new installer-links-simulated.test.ts, which simulates the
    link with spied lstat/realpath/readlink, so it runs on machines that
    can't create file symlinks.
  With main's sources put back, 27 fail; the folder-link guard passes on
  both. All pass with the fix. The real-link tests are skipped, with the
  reason in their names, where file symlinks can't be created (Windows
  without Developer Mode or admin).
- This Windows machine has Developer Mode on, so the real-link tests ran
  for real.
- The real CLI against a private home (`install --yes`, `install
  --refresh`, `uninstall --yes --keep-cli`), 10 linked files for five
  agents plus relative, dangling and read-only links:
  - on main, all 29 link checks found the link replaced by a copy;
  - with the fix, none did, every link's text was unchanged, the shared
    files got CodeGraph's settings and lost them again on uninstall, and
    the missing-folder and read-only cases exited 1 with the new message
    and changed nothing.

Fixes #2721

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 01:06:12 +00:00
..