Commit Graph
11 Commits
Author SHA1 Message Date
Colby MchenryandClaude Opus 5.5 9bfdd09238 feat(cli): codegraph cycles lists the files that import each other in a circle (#3099)
New `codegraph cycles [path] [--json]` prints the groups of files that
all reach each other through imports. It exits 1 when there are any and
0 when there are none, so `codegraph cycles || exit 1` works as a
pre-commit or CI check.

The command stays a thin wrapper over CodeGraph.findCircularDependencies(),
but the method itself had to change. It had no callers, and on real
repos its walk wasn't fit to print:
- It reported one list per back edge, so the number depends on the walk:
  1,490 overlapping lists on excalidraw, 87 on gin, 44 on flask.
- It left out files. A walk that meets a visited file stops there, so a
  file whose loop closes through one is never listed (now pinned by a
  test: a>b, b>a, a>c, c>b).
- It counted every edge kind, and most of the graph's edges aren't
  imports. An interface's call fans out to a test's fake, so
  src/extraction/parse-pool.ts "depended" on its own test. Two Next.js
  pages that link to each other were a cycle. gin's files were a 55-file
  knot, though Go forbids import cycles. With exit 1 those are failures
  nobody can fix.

The method now takes the strongly connected components of the file
import graph, one group per knot. The Tarjan pass moves from the
viewer's map into src/graph/file-cycles.ts and both surfaces use it, so
the viewer's "Circular imports between files" panel, which was reading
every edge too, now reports the same groups. Dependent counts on the map
keep their own edge list.

Validation: new cli-cycles and file-cycles suites, plus cycles in the
read-commands suite (mid-rebuild, and old schema indexes); 4 of the 10
findCircularDependencies and finder tests fail with main's method and
all 15 pass with this one. Against the TypeScript compiler's own module
resolver over the same files (kit oracle): excalidraw 3 groups, 369
files, all identical; codegraph's src/ 3 of 4 identical, and the fourth
needs src/resolution/name-matcher.ts, which at 1.6 MB is over the
default size limit and so isn't parsed. flask reports 2 groups and gin
none. It runs in under a second on each. Type-only imports count, as
they aren't told apart in the graph.

The MCP tool from PR #889 is left out on purpose: a new tool is rarely
picked up, and this needs no agent steering.

Reimplements PR #1012 by @jiangyq9, with the exit code from the CLI in
PR #889 by @goutham80808.

Fixes #888

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 19:53:53 +00:00
Colby MchenryandClaude Opus 5.5 cb7fb61e76 fix(docs): agent and command lists match the code; worktree warning drops init -i (#3067)
The warning for a git worktree answered from another checkout's index
still said to run "codegraph init -i", a flag that has done nothing
since init started indexing by default. Its one-line form is prepended
to every read-tool result and codegraph_status embeds the long form, so
both told the agent to build the index, which the server instructions
rule out ("Indexing is the user's decision ... don't run it yourself").
The CLI's codegraph status now says: Run "codegraph init" in this
worktree. What an agent reads (the read-tool notice, which also reaches
it through the prompt hook and the explore/node CLI, and
codegraph_status) says the user can run "codegraph init" there.

Docs that no longer matched the code:
- AGENTS.md listed 4 of the 11 installer targets, called a new one "a
  5th agent", said the contract suite covers "all 4" targets, and listed
  11 of the 24 subcommands. It now lists every target and subcommand,
  and names the hidden ones (serve --mcp, prompt-hook, and ui/web unless
  CODEGRAPH_UI=1).
- README's Supported Agents section said no instructions file is
  written, but Claude Code, Codex CLI, Gemini CLI and opencode get the
  short CodeGraph section. Its Codex entry now says the Codex IDE
  extension reads the same config: $CODEX_HOME/config.toml (default
  ~/.codex/config.toml) for a global install, and .codex/config.toml,
  used only in a trusted project, for a local one.
- README's WSL2 "Transport closed" entry named only the in-process
  fallback. The daemon also moves its socket to the temp directory when
  the project's filesystem can't host one.
- init -i and -iv leftovers in internal docs, scripts, the add-lang
  skill and the repo's own Cursor rule, which now also leaves indexing
  to the user. Two stay on purpose: scripts/agent-eval/audit.sh can
  audit a published version older than 0.9.8, where init built the
  index only with -i (now commented there), and
  docs/benchmarks/codegraph-ab-matrix.md records a 0.9.4 run.

Validation:
- worktree-detection.test.ts: on main 61776927's worktree.ts and
  tools.ts, 4 of its 20 tests fail (the CLI wording, the agent wording,
  the read-tool notice and codegraph_status). With only the worktree.ts
  fix, the codegraph_status test still fails. All 20 pass here, and so
  do mcp-nested-repo-projectpath.test.ts's 13.
- Full suite on this patch over 61776927 (CODEGRAPH_KERNEL_EXPECT=1,
  4 workers): 815 files (809 passed, 6 skipped), 9608 tests passed,
  0 failed, 86 skipped.
- Rebased unchanged onto f67eafcb. Its three new commits share only
  CHANGELOG.md with this PR, in other bullets. On the rebased tree these
  pass (81 tests): worktree-detection, mcp-nested-repo-projectpath, and
  the new commits' default-export-declaration,
  rust-path-attribute-modules, rust-path-super-glob,
  search-special-characters and strip-comments.

Reimplements #549 by @ashishpatel26, #651 by @GaoSSR, #885 and #886 by @Dashsoap, and #1083 by @zengwenliang416.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-30 13:47:59 +00:00
Eric MinishandClaude Opus 5.5 18248d191e docs(agents): describe the instructions-file block the installer writes again (#1962)
AGENTS.md said the installer no longer writes an instructions-file block,
but since PR #704 the Claude, Codex, Gemini and opencode targets write a
short one again, while Cursor and Kiro only strip an old one. The
architecture notes and house rules now describe that block and keep tool
guidance in server-instructions.ts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 04:23:19 +00:00
Colby MchenryandClaude Opus 5.5 cd97bb37d2 fix(context): call paths label synthesized hops like explore, not as events (#2428)
Two surfaces label a synthesized (dynamic-dispatch) `calls` hop:
codegraph_explore's Flow and dynamic-dispatch links plus the
codegraph_node trail (`dynamic: interface → impl @file:line`), and
ContextBuilder's "## Call paths", which `codegraph context` prints
(`→[…]`). Each kept its own list. The call paths' list stopped at
callback, react-render, jsx-render, vue-handler, http-client, queue-job
and socket messages, so every other synthesizer fell through to
`event ${m.event ?? ''}`: an interface-impl hop read
`→[event  @src/pdf-exporter.ts:5]`, and so did a C++ override, a redux
thunk, a gin middleware chain or a closure collection.

The wording now lives once, in src/graph/synthesized-hop.ts
(`describeSynthesizedHop`: a summary, the detail only the call paths
print, and the wiring site), as AGENTS.md asks of a derivation two
surfaces render. ToolHandler renders `dynamic: <summary> @site`, the
call paths `<summary><detail> @site`. Explore and the node trail print
exactly what they printed before; the call paths keep their wording for
the kinds they already labelled, including the queue name, a socket's
direction and the HTTP clause, and now name the rest the way explore
does. A bus event reads `bus event` there too, and the section's
footnote no longer says hops are marked `[callback/event …]`.

The helper also holds the wording #2414 gives a Go method a struct gets
by embedding (`metadata.promotedInto`), so that arm moves here too. The
unused long `label` form of ToolHandler.synthEdgeNote (last read by the
removed codegraph_trace) is dropped.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 01:51:29 +00:00
Colby MchenryandClaude Opus 5.5 70fe0ecc52 fix(windows): helper threads never end mid-start or with GC marking in flight (#2309)
On Windows a worker thread that ends - terminate(), its own process.exit(),
or the process exiting - while V8's concurrent marker is marking its heap
crashes the whole process (exit 3221225477 / 0xC0000005, no error, no dump).
Bisected on the Windows 11 ARM64 VM: --no-concurrent-marking alone stops it
(18/480 -> 0/480; no other concurrency flag does), but it costs about a third
of indexing speed, so CodeGraph avoids the dangerous moments instead:

- src/worker-teardown.ts: owners terminate a worker only once it has started
  (its first message, posted after its modules load - mid-load is by far the
  worst moment), and a worker about to exit runs a full collection first,
  which finishes any marking in flight (gc reached at runtime, never global).
- Resolver pool / store writer: the worker collects before exiting on
  'close' (the normal path - main 21/480 crashed on the VM, now 2/1200), and
  the 5 s close fallback never terminates a worker still starting.
- codegraph_status change counts: the worker posts 'loaded' after its heavy
  require and collects before answering; a deadline answers unknown at once
  but terminates only once loaded (3/720 -> 0/1440), and MCPEngine.stop()
  waits for measurements in flight.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 21:58:28 +00:00
Colby MchenryandClaude Opus 5.5 7bbc1fb7f6 fix(tests): the test suite no longer writes to the developer's real home dir (#2275) (#2295)
Running the suite on a machine with Claude Code configured could wire the
CodeGraph prompt hook into the developer's own ~/.claude/settings.json:
every upgrade test whose fake upgrade succeeded ran the real post-upgrade
prompt-hook self-heal, which detected the real global Claude profile and
wrote it. Daemon suites likewise left records in the real
~/.codegraph/daemons. On Windows a HOME-only redirect would not have
helped, since os.homedir() reads USERPROFILE there.

- The prompt-hook writer is now injected through UpgradeDeps
  (wirePromptHook); the CLI passes the real defaultWirePromptHook and the
  upgrade tests a recorder. New tests pin that a successful upgrade calls
  the recorder and that the real writer never touches a configured profile.
- A vitest setupFiles entry gives every engine test file a throwaway home:
  HOME/USERPROFILE (plus HOMEDRIVE/HOMEPATH/APPDATA/LOCALAPPDATA on
  Windows), XDG_CONFIG_HOME, and GIT_CONFIG_GLOBAL (seeded with a dummy
  identity) point into it, and CLAUDE_CONFIG_DIR/CODEX_HOME/COPILOT_HOME/
  HERMES_HOME are cleared. Spawned CLI/MCP children inherit it. A sandbox
  test asserts os.homedir(), the Claude profile, the daemon registry, a
  child process and git's global config all resolve inside it.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 06:18:46 +00:00
Colby MchenryandClaude Opus 5.5 2b9f2f47ef chore(ui): version the component package with the engine (1.6.1) (#2098)
The 1.6.1 bump changed package.json only, as AGENTS.md said was enough, so
ui-package.test.ts ("is versioned with the engine") has failed on main since.
Bump ui/package.json to match, and say in AGENTS.md that a version bump
touches both files.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 16:00:25 +00:00
Colby MchenryandClaude Opus 5.5 2c4d4eb9e4 release: withhold codegraph ui until the viewer launches; hold its changelog entries (#2089)
* feat(cli): withhold `codegraph ui` until the viewer launches (CODEGRAPH_UI=1 opts in)

The viewer has been exercised on Expo apps only, not on API, Laravel,
Spring, Angular or Swift projects, so it stays out of this release. `ui` and
its alias `web` — also as `help ui` or `ui --help` — are refused before any
startup work, and the command is hidden from `--help`, unless CODEGRAPH_UI=1
is set, which keeps it usable for the people testing it. The viewer assets
still ship, so the opt-in works on a released build.

Reverting this commit is the launch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(site): say the viewer is not in a release yet

The viewer pages have been live on the docs site since they landed, and
1.6.0 answers `codegraph ui` with "unknown command" (#1816, #1900). Until the
viewer launches, the guide, the CLI reference and the next-steps link say so.

Reverting this commit is part of the launch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(changelog): hold the viewer's entries for its launch; new Highlights for the fixes release

53 entries that describe `codegraph ui` and its screens move, verbatim, to
docs/viewer-launch-changelog.md along with the launch Highlights. 12 entries
whose graph and `codegraph_explore` half ships now (the router navigation
edges, the cross-tier hops, explore's `when` conditions, SvelteKit layouts,
wrapped Express handlers, …) are reworded around the graph; their original
wording is kept in the holding file for the launch. A few kept entries lose a
viewer clause. The Highlights are rewritten for this release.

prepare-release.mjs promotes the section and extract-release-notes.mjs reads
it back with no mention of the viewer; the released sections are untouched.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 05:01:34 +00:00
Colby MchenryandClaude Opus 5.5 1cbac0afaa docs(agents): update the Windows test baseline after #2053 (#2054)
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 16:26:35 +00:00
Colby MchenryandColby McHenry a983a1bb68 fix(installer): write OpenCode 2 native MCP shape with codemode:false (#1698) (#1768)
OpenCode 2 exposes MCP tools through Code Mode by default; `codemode: false`
only survives on `mcp.servers.<name>` with `disabled`. The installer wrote the
v1 `mcp.codegraph` + `enabled` shape, so the opt-out was dropped on normalize.

Write `mcp.servers.codegraph` with `disabled: false` and `codemode: false`,
migrate a leftover v1 entry on re-install, uninstall either shape, and keep
printConfig / README / AGENTS.md in sync.

Co-authored-by: Colby McHenry <colbymchenry@users.noreply.github.com>
2026-09-08 08:41:01 -05:00
Colby MchenryandColby McHenry 72869f2d9e docs: make AGENTS.md the canonical agent guide for Codex/Astra (#1742)
Codex reads AGENTS.md by default, not CLAUDE.md. Move project guidance to
AGENTS.md (trim/nest long validation notes under docs/AGENTS.md), leave
CLAUDE.md as a thin @AGENTS.md wrapper for Claude Code, and document the
Codex project_doc_max_bytes raise needed for the ~35KiB root file.

Co-authored-by: Colby McHenry <colbymchenry@users.noreply.github.com>
2026-09-07 22:58:05 -05:00