Commands reference
All commands run against the current directory. Run stacklit <command> --help for the built-in help.
| Command | Purpose |
|---|---|
init |
First-time scan, write all outputs, open the visual map |
generate |
Regenerate the outputs from current source |
view |
Rebuild stacklit.html from stacklit.json and open it |
diff |
Check whether the index is stale |
derive |
Print the compact navigation map, or inject it into an agent config file |
export |
Render the index as markdown, or export the graph as GraphML, Cypher, JSON, DOT, Mermaid, an Obsidian vault or a markdown wiki |
setup |
Configure detected AI tools and install the git hook |
serve |
Run the MCP server over stdio |
graph, query, explain, impact, path, hubs, communities, report, slice, watch |
Symbol-level graph and token-budgeted queries |
doctor |
Diagnose config, hooks, a stale index and parse errors |
ingest |
Add docs, OpenAPI, SQL schemas and ownership to stacklit.context.json |
check |
Enforce layer boundaries, cycles, fan-in and fan-out limits and orphans (exit code 3 on violation) |
merge-graphs |
Merge symbol graphs from several repos and link them by package names |
completion |
Shell completions for bash, zsh, fish and PowerShell |
Global flags: --version, --help.
stacklit init
stacklit init [--hook] [--summary] [--multi FILE] [--workspace PATH]
Scans the current directory, writes stacklit.json, DEPENDENCIES.md and stacklit.html, then opens the HTML in your default browser.
| Flag | Description |
|---|---|
--hook |
Install a git post-commit hook that runs stacklit generate --quiet and stages stacklit.json and the configured mermaid file (DEPENDENCIES.md by default). An existing hook is appended to, never replaced. (The flag’s built-in help text says “pre-commit”; the hook that is installed is post-commit.) |
--summary |
Add an AI-written architecture narrative to the index. This is the only opt-in feature that sends data anywhere, see Summary. |
--multi FILE |
Polyrepo mode: scan every repo path listed in FILE. See Polyrepo scanning. |
--workspace PATH |
Accepted but currently has no effect on the scan. Monorepo workspaces are detected automatically. |
stacklit generate
stacklit generate [--quiet]
Same scan and outputs as init, without opening a browser. Use this in scripts, hooks and CI.
| Flag | Description |
|---|---|
--quiet |
Suppress progress output |
stacklit view
stacklit view
Reads stacklit.json, rewrites stacklit.html and opens it. It does not rescan the source, so run generate first if the code changed.
The HTML is one self-contained file with four views:
- Graph: force-directed dependency map. Click a node for exports, types and files.
- Tree: collapsible directory hierarchy with file and line counts.
- Table: sortable module table with search.
- Flow: top-down dependency flow from entrypoints to leaves.
A Share button downloads a standalone copy.
stacklit diff
stacklit diff
Recomputes a content hash (Merkle hash) of the current source files and compares it with the merkle_hash stored in stacklit.json. It prints either “Index is up to date” or tells you to run generate. It exits with status 0 in both cases, so scripts should compare the output text or use the GitHub Action’s check mode. Requires an index that has a merkle_hash field.
stacklit derive
stacklit derive [--inject claude|cursor|aider]
Prints a compact navigation map built from stacklit.json: one header line, an entry and test line, one line per module with its purpose and key dependencies, hot files, the add-feature hint and do-not-touch paths. Size grows with the number of modules: 122 tokens for a 6-module Go repo, 1,122 for a 72-module TypeScript repo (see bench/RESULTS.md).
| Flag | Description |
|---|---|
--inject TARGET |
Insert or replace the map, between marker comments, in CLAUDE.md (claude), .cursorrules (cursor) or .aider.conf.yml (aider). The file is created if missing. Re-running replaces the previous block. |
stacklit export
stacklit export [--format md] [--source FILE] [-o FILE]
Renders the index as markdown for people: a PR description, an issue, a chat message.
| Flag | Default | Description |
|---|---|---|
--format |
md |
md, or a graph format: graphml, cypher, json, dot, mermaid, obsidian, markdown-wiki |
--scope |
auto | Graph scope for single-file graph formats: modules or symbols. Auto picks symbols when stacklit.graph.json exists. |
--graph |
stacklit.graph.json |
Symbol graph file for graph formats |
--budget |
2000 | Token budget per markdown-wiki page. Env: STACKLIT_EXPORT_PAGE_TOKENS. |
--source |
stacklit.json |
Index file to read |
-o, --output |
stdout | Write to this file (one-file formats) or directory (obsidian, markdown-wiki) instead |
The markdown contains the project title and totals, a language and framework table, entrypoints and key directories, a modules table, collapsible per-module export lists, the dependency edges with most-depended and isolated modules, hot files when git data exists, and the hints. Output is deterministic: the same stacklit.json always gives byte-identical markdown.
Graph formats
Graph formats print to stdout unless you pass -o, and never write into the repo on their own. Every node carries source_file, and symbol edges carry their confidence (EXTRACTED, INFERRED or EXACT) and score.
| Format | Output |
|---|---|
graphml |
One GraphML file (Gephi, yEd, NetworkX) |
cypher |
CREATE and MATCH ... CREATE statements for Neo4j and compatible stores |
json |
{scope, nodes, edges} |
dot |
Graphviz. Inferred edges are dashed. Capped to the highest-degree nodes (STACKLIT_EXPORT_MAX_NODES, default 300). |
mermaid |
Mermaid flowchart with the same cap |
obsidian |
A vault folder: Index.md plus one note per module with [[wikilinks]] to dependencies, and symbol headings that other notes link to as [[module#Symbol]] |
markdown-wiki |
index.md plus modules/<module>.md, each page cut off at the token budget with a ”… N more” line. Same input gives identical files. |
stacklit export --format graphml -o /tmp/graph.graphml
stacklit export --format obsidian -o ~/vault/myproject
stacklit export --format markdown-wiki --budget 1500 -o /tmp/wiki
stacklit setup
stacklit setup [claude|cursor|aider]
Uses the existing stacklit.json, or generates one if none exists, then configures AI tools:
| Target | Detected by | What it changes |
|---|---|---|
claude |
claude on PATH or a CLAUDE.md file |
injects the map into CLAUDE.md, adds the stacklit server to .mcp.json |
cursor |
a .cursor directory or .cursorrules |
injects the map into .cursorrules, adds .cursor/mcp.json |
aider |
aider on PATH or .aider.conf.yml |
injects the map into .aider.conf.yml |
With no argument it configures every detected tool and installs the post-commit hook. If no tool is detected it prints the map to stdout so you can paste it. .mcp.json is listed in this repository’s .gitignore because it is user-specific; decide for your own repo whether to commit it.
Claude Code crawl guard (opt in): stacklit setup claude --crawl-guard[=nudge|redirect|off] installs a PreToolUse hook that recognises repo-wide crawls (find ., ls -R, tree, grep -r or rg on the root, Glob **/*, a Read of a directory, generic “explore the codebase” subagent prompts). A bare --crawl-guard means nudge; pass a mode with =. nudge adds a pointer to the stacklit command. redirect denies with a reason naming the command, at most twice in a row per session and only while the index is current. off removes the hook, as does --uninstall. Supports --dry-run. Details in docs/SESSIONS.md.
stacklit guide
stacklit guide [--json]
Prints the agent usage guide (rules, command list, examples). It is the same text the strict rules block (steering d) uses, so you can paste it into any tool.
stacklit refresh, digest and stats
Session plumbing, see docs/SESSIONS.md for the design.
stacklit refresh --files a.go,b.go [--json] # or: --stdin with a hook payload
stacklit digest [--check] [--session ID]
stacklit stats [--json] [--since 7d]
refreshupdatesstacklit.json(andstacklit.graph.jsonwhen it exists) for just the named files. Unchanged files are skipped by content hash, concurrent callers coalesce behind a lock, and writes are atomic. The result matches a fullgenerate.digestprints the structure hash (module names, edges and exported names only).--checkexits 0 when it equals what a session was given, 1 when it changed, 2 when nothing was recorded.statsreports the opt-in local usage log (STACKLIT_STATS=1).servedis measured (bytes/4);replaced_estis an estimate of whole-file read cost, not a measured saving.
Claude Code hooks (opt-in, written to .claude/settings.json, or ~/.claude with --global):
| Flag | Installs |
|---|---|
--session-hook |
SessionStart for startup, resume, clear and compact; SubagentStart for Explore and Plan |
--refresh-hook |
async PostToolUse on Edit, Write, MultiEdit and NotebookEdit |
stacklit serve
stacklit serve
Starts the MCP server on stdio. Run it from the repo root: it reads stacklit.json from the working directory. See MCP server.
Symbol graph commands
stacklit graph # build stacklit.graph.json (query commands build it in memory if it is missing)
stacklit query "where is auth checked?" # scoped subgraph for a question, hard limit via --budget (default 2000 tokens)
stacklit explain <symbol> # definition, location, callers, callees (--budget, default 1500)
stacklit impact <symbol|file> # everything that depends on it (--depth, default 4)
stacklit path <from> <to> # shortest path between two symbols
stacklit hubs -n 15 # most connected symbols
stacklit communities # deterministic file clusters with labels
stacklit report -o GRAPH_REPORT.md # key concepts, surprising links, suggested questions
stacklit slice <symbol> # only that symbol's source, with line numbers
stacklit watch # keep the graph current as files change
query prints files in relevance order: each file group is numbered (1. path) by the best score among its symbols (ties by path), symbols inside a file go by score then line, and a best match: <file>:<line> <symbol> line names the top result. Output is byte-stable between runs, and the --budget limit drops the lowest ranked results first. --order relevance|path picks the layout; path is the older alphabetical grouping with no numbers (default from STACKLIT_QUERY_ORDER, otherwise relevance). With --json each file has rank (1 is best) and score (0 to about 1.2, relative to the best seed), each symbol has its own score, and files stay in the printed order. The MCP query_graph and query tools return the same text. Two scoring knobs: STACKLIT_AUX_PENALTY (default 0.6) multiplies the score of files under test, example, benchmark or fixture directories unless the question mentions them (1 turns it off), and STACKLIT_IDENT_TOKEN_BOOST (default 0.5) raises symbols named exactly like a camelCase or snake_case word in the question.
All of them accept --root, --graph, --include-tests (keep test files in the graph; also STACKLIT_GRAPH_INCLUDE_TESTS=1) and (except watch) --json. Twenty languages produce symbols and call, import and inheritance edges; the per-language table is in docs/ARCHITECTURE.md. STACKLIT_GRAPH_MAX_PARSE_BYTES (default 196608) sets the largest file parsed with tree-sitter, and STACKLIT_PARSE_MEMORY_MB bounds concurrent parse memory. watch uses fsnotify and falls back to polling above STACKLIT_WATCH_MAX directories (default 4096); STACKLIT_WATCH_POLL_MS sets the polling interval.
stacklit doctor
stacklit doctor [path] [--json] [--strict]
Checks the config file, git hook, index freshness and parse errors. --strict also fails on warnings.
stacklit ingest
stacklit ingest [--docs] [--api] [--schema] [--owners] [--git-owners]
Writes stacklit.context.json next to the index and leaves stacklit.json untouched. With no connector flag, all but --git-owners run. Limits: STACKLIT_INGEST_MAX_BYTES, STACKLIT_INGEST_MAX_ITEMS.
Adapters
stacklit ingest --adapter "<command>" [--adapter-name NAME] [--adapter-files GLOBS] [--into-graph]
Runs your command with file paths on stdin (one per line, relative to the root) and reads JSON Lines back: {"type":"node","id","name","kind","summary","source_file"} and {"type":"edge","from","to","kind"}. Use it for concepts from PDFs, images, audio or anything else stacklit does not parse. Results are stored in stacklit.context.json as concepts and concept_links, always tagged INFERRED with a source field, and a rerun replaces that adapter’s earlier output. --into-graph also adds them to stacklit.graph.json as concept nodes. Stacklit makes no network or model calls itself. Limits: STACKLIT_ADAPTER_TIMEOUT_SEC (60), STACKLIT_ADAPTER_MAX_BYTES (4 MiB), STACKLIT_ADAPTER_MAX_ITEMS (5000). The full contract and an example are in examples/adapters.
SCIP
stacklit ingest --scip index.scip [--graph stacklit.graph.json]
Reads a SCIP index (from scip-go, scip-typescript and similar) with a built-in decoder and upgrades INFERRED graph edges to EXACT where the index shows a reference from the edge’s source to a symbol defined at its target. It never adds or removes edges and rewrites the graph file in place. Size cap: STACKLIT_SCIP_MAX_BYTES (512 MiB).
stacklit check
stacklit check [--root DIR] [--source stacklit.json] [--json]
Evaluates the check block of .stacklitrc.json against the module graph. Exit code 3 when any rule is violated, 0 otherwise, so it works as a CI step.
{
"check": {
"forbidden": [{ "from": "ui/**", "to": "core/db", "reason": "go through the service layer" }],
"cycles": true,
"max_fan_in": 12,
"max_fan_out": 8,
"orphans": true
}
}
Patterns are module paths with * wildcards; dir/** matches dir and everything below it. With no check block the command passes. --json prints {ok, violations:[{rule, message, modules}]}.
stacklit merge-graphs
stacklit merge-graphs a/stacklit.graph.json b/stacklit.graph.json -o merged.json [--multi stacklit-multi.json]
Combines symbol graphs from several repos. Node IDs get a repo: prefix, each node keeps its source_file and gets a repo field. Name a repo explicitly with name=path.json. With --multi (the output of generate --multi), repo nodes and depends_on edges are added for repos that depend on each other through manifest package names, plus import edges from the importing files to the provider repo.
Generated from docs/USAGE.md in the repository, the single source of truth.