* feat(installer): multi-target — Claude Code, Cursor, Codex CLI, opencode
Closes the Claude-locked installer behind issue #137. The runtime MCP
server was already agent-agnostic (stdio); only the installer was
locked. After this refactor, `codegraph install` can write per-agent
MCP config + instructions for any combination of supported agents.
## What ships
Four agent targets, each implementing the new `AgentTarget` interface:
- **Claude Code** — `~/.claude.json`, `~/.claude/settings.json`,
`~/.claude/CLAUDE.md` (or local equivalents). Behavior preserved
from the original installer; existing installs upgrade in place.
- **Cursor** — `~/.cursor/mcp.json` (g) or `./.cursor/mcp.json` (l)
+ project-local `./.cursor/rules/codegraph.mdc`.
- **Codex CLI** — `~/.codex/config.toml` with `[mcp_servers.codegraph]`
+ `~/.codex/AGENTS.md`. Global only. Hand-rolled TOML serializer
scoped to the table we own — siblings + array-of-tables preserved.
- **opencode** — `~/.config/opencode/opencode.json` (XDG) or
`./opencode.json`.
Adding a 5th agent is a new file in `src/installer/targets/` plus
one entry in `registry.ts`.
## CLI changes
```
codegraph install # interactive multi-select
codegraph install --yes # auto-detect, install global
codegraph install --target=cursor,claude --yes # explicit list
codegraph install --target=auto --location=local # detected, project-local
codegraph install --target=none # skip agent writes entirely
codegraph install --print-config codex # dump snippet, no writes
```
## Backwards compat
Every export from the old `config-writer.ts` (`writeMcpConfig`,
`writePermissions`, `writeClaudeMd`, `hasMcpConfig`, `hasPermissions`,
`hasClaudeMdSection`) is preserved as a `@deprecated` shim that
delegates to per-file helpers in `targets/claude.ts`. Existing Claude
users see byte-identical on-disk layout — `detect()` reports
`alreadyConfigured: true`, re-running is a no-op.
## Tests
+47 new tests in `__tests__/installer-targets.test.ts`:
- Parameterized contract test across all 4 targets × supported
locations (install → unchanged on re-run, sibling preservation,
uninstall reverses install, printConfig writes nothing).
- Codex partial-state recovery, locked-block contract for the
codegraph table, full TOML serializer suite.
- Registry: getTarget, resolveTargetFlag (auto/all/none/csv).
`__tests__/installer.test.ts` relaxed one assertion: the new code
returns `unchanged` for byte-identical re-runs instead of `updated`;
the surrounding-custom-content contract is unchanged.
## Uninstall behavior change
`bin/uninstall.ts` now loops `ALL_TARGETS.uninstall('global')` on
`npm uninstall -g`. A user who manually configured
`~/.codex/config.toml` with our block will have only that block
removed on package uninstall — we only touch the dotted-key table
we own.
Based on andreinknv/codegraph@c5165e4. Issue #137.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* chore(scripts): add local-install.sh for hands-on branch testing
Builds the current branch and `npm link`s it as the global
`codegraph` binary. `--undo` unlinks and reinstalls the published
version. Mirrors the style of scripts/release.sh.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(installer): move agent picker to the first prompt
Reorders runInstallerWithOptions so the multi-select for agents
(Claude / Cursor / Codex / opencode) is step 1 — before the
global-npm-install confirm and before the location prompt. Bare
`npx @colbymchenry/codegraph` now opens with "Which agents should
CodeGraph configure?", which is the answer most users want first.
Side effects of the reorder:
- Early exit if zero targets selected — skips global-install and
location prompts entirely, exits with "nothing to do."
- Multiselect labels drop the per-location "will skip" hint (location
isn't known yet) and replace it with a static "global only" badge
for targets like Codex that have no project-local config concept.
- If every selected target is global-only, the location prompt is
skipped and global is forced (no point asking).
- Detection probes the user-provided location if known via flag,
else 'global' as the most common default — labels are a hint
about what's installed locally, not load-bearing.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(installer): disambiguate "global" wording in install prompts
Two prompts both said "global" but meant different things — users
read them as duplicates. Renamed for clarity:
- Step 2 (npm install -g): "Install codegraph globally?" →
"Install the codegraph CLI on your PATH? (Required so agents can
launch the MCP server)". Spinner messages match.
- Step 3 (config location): "Where would you like to install?" with
"Global"/"Local" → "Apply agent configs to all your projects, or
just this one?" with "All projects" (~/.claude, ~/.cursor, etc.)
/ "Just this project" (./.claude, ./.cursor, etc.).
- All-global-only fallback: "Using global install" → "Writing
user-wide configs (selected agents have no project-local config)."
Underlying `Location` values ('global' / 'local') unchanged; only
the UI strings shift, so no test or flag breakage.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(installer/cursor): inject --path so workspace-aware queries work
Cursor launches MCP-server subprocesses with cwd != workspace root,
AND does not pass rootUri or workspaceFolders in the MCP initialize
call. The codegraph MCP server's process.cwd() fallback misses the
workspace's .codegraph/ and reports "not initialized" on every tool
call. Codex and Claude don't have this issue (Codex launches with
cwd=workspace, Claude passes rootUri).
Fix: inject `--path` into the args we write for Cursor.
- local install (./.cursor/mcp.json): hardcode the absolute project
path — known at install time.
- global install (~/.cursor/mcp.json): use `${workspaceFolder}` so
Cursor expands it per-workspace. One global config now drives
every project the user opens, without per-project re-install.
No test breakage — the parameterized contract tests check
idempotency / sibling preservation, not the exact args content.
File-header comment documents the rationale so the next person
doesn't strip the arg as boilerplate.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(init): auto-wire project-local agent surfaces
Closes the global-Cursor UX gap: `~/.cursor/mcp.json` registers the
MCP server, but Cursor's agent only learns to *prefer* codegraph
over native grep when it sees `.cursor/rules/codegraph.mdc` — a
project-local file that global install can't write. Previously the
user had to re-run `codegraph install --target=cursor --location=local`
for every new project. Now `codegraph init` does it automatically.
## What changed
- New optional `AgentTarget.wireProjectSurfaces()` returning a
WriteResult of project-local files to drop. Most targets omit
it (their global config is complete). Cursor implements it to
write the rules file.
- New `wireProjectSurfacesForGlobalAgents()` orchestrator in
installer/index.ts — iterates ALL_TARGETS, detects which are
configured globally, calls their wireProjectSurfaces, returns
what was written.
- `codegraph init` calls the orchestrator in both branches:
- Fresh init: write surfaces after CodeGraph.init succeeds.
- Already-initialized re-init: write surfaces too, so re-running
`init` is the documented recovery path for a project missing
its rules file.
## Steady-state UX
1. Once, ever: `codegraph install` (writes global agent configs)
2. Per project: `codegraph init -i` (builds the index + auto-wires
project-local agent surfaces — currently Cursor's rules file)
No new tests — wireProjectSurfaces delegates to writeRulesEntry,
which is already covered by the parameterized contract tests.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(installer): agent-agnostic instructions template
The old template was inherited from the Claude-only era and
prescribed "ALWAYS spawn an Explore agent" — a Claude Code-specific
concept (subagents via the Task tool). When Cursor's agent read
this it had no Explore agent to spawn, got confused, and fell back
to native grep/read even for structural queries the codegraph MCP
tools answer in one call.
This rewrite:
- Frames each tool by the question it answers (search vs callers
vs impact vs context vs explore vs node vs files vs status).
- Tells the agent explicitly to TRUST codegraph results and not
re-verify them with grep — the over-grep-after-codegraph
behavior was the main symptom we saw on Cursor.
- Reframes "spawn Explore agent" as an OPTIONAL pattern for
harnesses that support parallel subagents — Claude Code still
gets the hint, Cursor / Codex / opencode just skip it.
- Trims the "if not initialized" section to one prescriptive line.
Same marker delimiters (`<!-- CODEGRAPH_START/END -->`) so existing
installs upgrade in place via the marker-based section swap. No
test changes needed — the parameterized contract tests check
marker placement + sibling preservation, not the literal body.
Effective surfaces: ~/.claude/CLAUDE.md (Claude), .cursor/rules/
codegraph.mdc (Cursor, project-local), ~/.codex/AGENTS.md (Codex).
Users get the new copy by re-running `codegraph install` for
global writes, or `codegraph init` for Cursor's project rules.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* docs(readme): reflect multi-agent support at the top + accurate flow
- Tagline now reads "Supercharge Claude Code, Cursor & Codex" instead
of Claude-only — multi-agent support is what the PR is about, the
README should say so above the fold.
- New badge row (Claude Code / Cursor / Codex CLI / opencode) in the
same shields.io style as the OS row.
- Install-flow bullets reordered to match the actual prompt order
(agent picker first, then PATH install, then location).
- `codegraph init -i` step now mentions that init wires up
project-local agent surfaces (Cursor rules file etc.) so global
install works in every project without a re-run.
- Agent-agnostic phrasing in the closing line ("your agent" not
"Claude Code").
Headline-level brand decision left intentionally in this PR — the
existing Claude-only positioning predates multi-agent support.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: andreinknv <andrei.nknv@outlook.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>