Files
codegraph/site
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
..

Starlight Starter Kit: Basics

Built with Starlight

npm create astro@latest -- --template starlight

🧑‍🚀 Seasoned astronaut? Delete this file. Have fun!

🚀 Project Structure

Inside of your Astro + Starlight project, you'll see the following folders and files:

.
├── public/
├── src/
│   ├── assets/
│   ├── content/
│   │   └── docs/
│   └── content.config.ts
├── astro.config.mjs
├── package.json
└── tsconfig.json

Starlight looks for .md or .mdx files in the src/content/docs/ directory. Each file is exposed as a route based on its file name.

Images can be added to src/assets/ and embedded in Markdown with a relative link.

Static assets, like favicons, can be placed in the public/ directory.

🧞 Commands

All commands are run from the root of the project, from a terminal:

Command Action
npm install Installs dependencies
npm run dev Starts local dev server at localhost:4321
npm run build Build your production site to ./dist/
npm run preview Preview your build locally, before deploying
npm run astro ... Run CLI commands like astro add, astro check
npm run astro -- --help Get help using the Astro CLI

👀 Want to learn more?

Check out Starlight’s docs, read the Astro documentation, or jump into the Astro Discord server.