← wiregraph

How to use it

Stand a graph up, then let Claude drive it.

Index once and wiregraph keeps itself fresh β€” Claude queries the graph instead of re-reading your tree. This guide walks the getting-started flow, shows how to link two separately-indexed repos so a cross-repo wire lights up, and documents every one of the 16 commands.

Getting started

Three lines to install. One to index.

Install the plugin from Claude Code, then point /wiregraph-init at a workspace. It finds every repo under the root, indexes them into one graph, and re-indexes as you edit.

1

Install the plugin

Add the marketplace, install wiregraph, reload. Public repo β€” native bits are prebuilt and vendored for Linux / macOS / Windows, so there's no build step.

claude-code
/plugin marketplace add kaleLetendre/wiregraph
/plugin install wiregraph@wiregraph
/reload-plugins
2

Index the workspace

Run /wiregraph-init once per workspace. It confirms scope, infers contracts for a multi-compartment root before a single build, installs the CLAUDE.md navigation directive, and turns on balanced auto-update.

claude-code
/wiregraph-init ~/log-server
3

Put Claude to work

That's it. You never call the graph tools yourself β€” Claude does, on every task, and the auto-update hooks keep the graph fresh as you edit. Reach for /wiregraph-status any time you want to confirm it's healthy.

βš‘
Auto-update postures. off disables everything; conservative catches up at session start and nudges toward the graph; balanced (the default) also re-indexes on edit; aggressive adds optional git post-commit / post-merge hooks. A fanned-out linked peer skips only off. Change it anytime with /wiregraph-posture <level>.
off conservative balanced Β· default aggressive

The new capability

Join two graphs so the wire between them lights up.

Contract detection needs the two sides seen together. Repos indexed separately can't see a route they share β€” until you /wiregraph-link one into the other. Linking is symmetric (recorded in both graphs' configs), keeps one db per graph, and re-infers contracts over the union on every link and unlink.

βš‘
The seam fires only on a shared distinctive literal token β€” at least 5 characters, not a generic like /api or /health, and not a dynamically-built URL. /api/logs qualifies, and it must appear as a literal on both sides. Every link and unlink ends in a full rebuild + re-infer, never an incremental β€” cross-member WIRE is a full-rebuild backstop, so the two mirrored databases are eventually consistent, not lock-step.
βœ“ disjoint paths βœ• ancestor of self βœ• descendant of self βœ• basename collision βœ• nested in another index

Basename uniqueness is a hard requirement: compartment ids are compartment:<basename>, so two members named api would silently merge β€” the guard blocks it rather than warn.

Walkthrough

Two repos, no shared code β€” joined by a wire.

edge-app is an edge terminal that uploads logs over HTTP to /api/logs; log-server is the server that defines that route. Nothing calls across β€” only the wire connects them. Indexed separately, path_between returns nothing. Here's how linking joins them.

1

Index the edge repo

Stand edge-app's own graph up first. Linking never auto-initializes the near side β€” the directory you're standing in must already be indexed.

~/edge-app
/wiregraph-init
2

Link the server graph

From inside edge-app, link ~/log-server. The guard checks the paths, a dry-run preview states plainly that a second, unrelated repo will be written to, the peer graph is auto-created if it has no .wiregraph/, mutual link records are written to both sides, then contracts re-infer over the union and each graph full-rebuilds.

~/edge-app
/wiregraph-link ~/log-server
3

The seam traces across separate graphs

Now Claude's graph tools cross the boundary. path_between threads a chain through the contract node, and get_source on the far symbol reads straight out of the external member's real path.

MCP tools
path_between edge-app:uploadLogs log-server:handleLogsPost
get_source log-server:handleLogsPost
4

Confirm membership

/wiregraph-list gives the mutual view graph_stats can't β€” your own root and its compartments, then each linked root grouped beneath it, with a per-link health flag.

~/edge-app
/wiregraph-list
5

Later, sever it

/wiregraph-unlink removes the link from both graphs, prunes the member's shas on both sides, and full-rebuilds each over the reduced union so the seam disappears. Because log-server was auto-created and has no other links, it offers to remove that graph entirely.

~/edge-app
/wiregraph-unlink ~/log-server

Measured savings

See what it actually saved. Measured, not guessed.

/wiregraph-stats prints a local accounting of the tokens wiregraph kept out of your context β€” built entirely from what your own sessions logged, never a headline guess. It's 100% local: the log lives beside the graph and nothing is uploaded.

1

Every graph read logs what it saved

Each time Claude answers from the graph instead of opening files β€” get_source, trace_callers, path_between β€” wiregraph appends one line recording the counterfactual: the tokens it would have cost to read the files, minus the tokens the graph actually returned. That difference is the saving for that read.

2

Turns and boundaries mark the timeline

Each prompt logs a turn; each session start, /clear, and compaction logs a boundary. A boundary is where resident context resets, so this records how long a saved read stays useful. Reads are segmented per session β€” a boundary between two sessions stops one session's reads from ever borrowing the next session's turns.

3

The dashboard replays it into two numbers

One-time is what you'd have paid to read that code once. Recurring is that same context re-saved on every turn it stayed resident before the next boundary β€” because staying out of the prompt saves those tokens again each turn until context resets. The output is deterministic and relayed verbatim.

~/edge-app
/wiregraph-stats

Where the data lives β€” plain JSON-lines, one event per line, under the gitignored .wiregraph/ folder:

Reference

Every command. One graph.

All 16 slash commands, grouped by lifecycle. Each entry gives what it does, when to reach for it, its arguments, and a representative effect. The newer commands β€” the three for linking, plus review β€” are marked NEW.

01

Setup

Stand a graph up β€” from nothing to queryable.
/wiregraph-tutorial [target-dir] NEW
setup Β· learn

A guided walkthrough that reads your actual layout and teaches the mental model β€” most importantly where to init (usually the parent of your repos, so cross-repo contracts light up) and how contracts work. Explains; changes nothing until you say so.

When Before your first /wiregraph-init, or any time the compartment / contract model isn't clicking. Ends by offering to run init at the right directory for your setup.

Args optional target-dir (defaults to cwd; it inspects this and its parent to make the advice concrete)

$ /wiregraph-tutorial you're in a single repo β€” its siblings client/ and server/ live in ~/work β†’ init at ~/work so the wire seam between them can be traced
/wiregraph-init [target-dir]
setup Β· end-to-end

Sets a project up end to end β€” installs deps, builds the cross-compartment call graph, installs the CLAUDE.md navigation directive, turns on balanced auto-update.

When First time you point wiregraph at a repo or workspace. Also the command Claude reroutes you to if a graph is missing. Detects an existing setup and offers Rebuild / Update / Re-initialize instead of blindly redoing it.

Args optional target-dir (defaults to $CLAUDE_PROJECT_DIR, else cwd)

$ /wiregraph-init ~/log-server scope: MULTI (3 compartments) Β· 1 contract inferred building… 412 files Β· 5 180 symbols Β· directive installed
02

Daily use

Keep it fresh and check on it as you work.
/wiregraph-update
daily Β· incremental

Incrementally re-indexes only the files changed since the last index (git diff + uncommitted edits) β€” not a full rebuild.

When After normal editing β€” the cheap, everyday refresh. Hooks do this automatically at balanced+; this is the manual trigger. Prefers the update_graph tool with no arguments.

Worktree-safe A git worktree add inside an indexed project no longer forces a full rebuild, and a rebase / amend that orphans the stored sha reconciles the affected repo by on-disk content instead of tearing the graph down. A content-hash tiebreaker confirms every mtime+size match, so a same-size edit can't slip through as unchanged.

Args none β€” acts on the active project

$ /wiregraph-update re-indexed 4 changed files Β· advanced git shas
/wiregraph-status
daily Β· doctor

Doctor β€” graph health + freshness, is the directive present, posture, whether hooks are firing, contract coverage; with a one-line fix for anything off.

When "Is my graph healthy / fresh / wired up correctly?" Triage before trusting a trace.

Args none β€” active project

$ /wiregraph-status graph: indexed Β· 412 files Β· 5 180 symbols freshness: STALE: 2 changed β†’ run /wiregraph-update posture: balanced Β· hooks active
/wiregraph-stats [--local]
daily Β· savings

Prints the measured token-savings dashboard β€” graph-tool usage, one-time tokens saved, the measured recurring-context savings replayed from your logged sessions, and the adoption gap. Deterministic; relayed verbatim. Default is machine-wide (every graph you've init'd or linked); --local scopes it to only the current project.

When "How much is wiregraph actually saving me?" Reporting or curiosity. The numbers are local counterfactuals the script itself labels β€” don't reformat them. Add --local for one project's numbers on their own.

How Every graph read (get_source, trace_*) logs the tokens it saved versus opening the files; each prompt logs a turn, and each session start, /clear, or compaction logs a boundary. The dashboard replays that log β€” one-time is reading the code once, recurring is that same context multiplied by how many turns it stayed resident before the next boundary (staying out of the prompt re-saves it on every turn until context resets). Reads are segmented per session, so one session never borrows another's turns.

Logs Plain JSON-lines at <project>/.wiregraph/metrics.jsonl β€” gitignored, never leaves your machine. On update, any pre-measurement log is archived once to metrics.v1.jsonl and ignored by the dashboard, so measurement starts clean.

Args optional --local scopes to the active project (resolved from any subdirectory); no args aggregates every graph on the machine

$ /wiregraph-stats graph-tool calls: 218 Β· est. tokens saved: ~1.24M session context: ~1.24M once β†’ ~5.2M recurring (measured) adoption: 82% of navigation via graph
/wiregraph-visualize [dir] [--functions|--all|--contract "<name>"]
daily Β· visualize

Renders the graph as a standalone offline HTML page (d3 force layout, one color cluster per repo, Contract nodes as the bridges in the middle) and opens it.

When You want to see which repos touch which contracts, or a full call graph. Everything is inlined β€” no network requests.

Args default (per-repo contract view), --functions, --all, --contract "<name>"

$ /wiregraph-visualize --contract "/api/logs" 42 nodes Β· 61 links β†’ ~/log-server/.wiregraph/graph.html (opened)
/wiregraph-linearize <Class.method|method|ClassName> [--breadth tight|medium|full] [--depth N] [--out <path>]
daily Β· reading aid

Flattens a vertical call slice into one top-to-bottom pseudo-source file β€” follows the CALLS graph from a root symbol and inlines each reachable body once, in reading order, with a file:line banner and a back-reference on repeats.

When A flow is smeared across many files or deep call chains and you'd rather read it as a single script. It's a reading aid β€” the output doesn't compile. Language-agnostic and multi-compartment: it reads whatever the graph indexed, from each symbol's own compartment root.

Args root (required); --breadth tight/medium/full (how far across compartments), --depth, --file to disambiguate, --out to write a file

$ /wiregraph-linearize ProcessOrderUseCase.execute --breadth medium inlined 37 symbols Β· depth 9 β†’ one top-to-bottom slice
/wiregraph-posture <off|conservative|balanced|aggressive>
daily Β· posture

Sets how aggressively the graph self-updates β€” from off (hooks no-op) through balanced (re-index on edit) to aggressive (adds git commit / merge hooks). Writes state.json; no rebuild.

When Dial a noisy repo down to conservative, or turn a hot one up to aggressive. Also how a linked peer opts out of fanned-in edits (off).

Args <posture> (required); optional target-dir, else the active project

$ /wiregraph-posture aggressive set autoUpdate posture to "aggressive"
03

Graph & contract ops

Rebuilds, seams, and the AsyncAPI draft.
/wiregraph-rebuild [target-dir]
ops Β· full rebuild

Full from-scratch rebuild β€” the correctness backstop. Routes through the union-aware full build, so it preserves linked members.

When After big refactors or renames (incremental is approximate for incoming edges to renamed / removed symbols), or whenever a trace looks wrong. Prefers update_graph { full: true }.

Args optional target-dir (defaults to active project)

$ /wiregraph-rebuild full reset over 2 members (log-server + linked edge-app) 5 180 symbols Β· 1 contract Β· 2 WIRE (members preserved)
/wiregraph-contracts [target-dir]
ops Β· infer seams

Infers cross-compartment wire seams (an endpoint one compartment defines and another calls) and proposes an AsyncAPI contract linking producer β†’ consumer.

When A multi-compartment workspace where you want trace_contract / path_between to follow the wire. Attribution needs the compartments indexed together β€” repos indexed separately need /wiregraph-link.

Args optional target-dir; scan β†’ confirm β†’ apply

$ /wiregraph-contracts scan: 1 wire seam Β· HTTP /api/logs wrote contracts/wiregraph-inferred.asyncapi.yaml
/wiregraph-review [target-dir]NEW
ops Β· doc-vs-reality drift

Reviews a compartments-and-contracts project for drift between its documentation and its reality β€” the directory tree, the per-compartment whoami.md files, the contract index, and the structure document β€” and fixes what the spec already settles.

When The architecture is cheap to design but comes apart quietly β€” a compartment gets added and never reaches the index, a contract is written and never listed. A script finds every finding as a set difference or stat; Claude never re-derives drift, only relays the findings and edits the files the script names.

Args optional target-dir (defaults to the active project); --structure <path> if the structure doc isn't project-structure.md

$ /wiregraph-review parsed 14 index rows Β· 3 findings: 1 compartment unlisted, 2 contract paths off
βš‘
CALLS edges are within-compartment by design. Cross-compartment links flow only through Contract nodes β€” so a rename on one side of a seam shows up as the contract's two edges no longer agreeing, which a plain call graph never records.
05

Teardown

Back out cleanly β€” pause, or fully uninstall.
/wiregraph-teardown [target-dir]
teardown Β· soft

Soft-remove β€” strips the managed CLAUDE.md block and sets posture off so hooks no-op; leaves graph.db + state.json for instant re-init.

When Pausing wiregraph on a project but you'll likely come back β€” no need to rebuild later.

Args optional target-dir

$ /wiregraph-teardown removed managed CLAUDE.md block Β· posture β†’ off left intact: .wiregraph/ β€” re-init is instant
/wiregraph-remove [target-dir]
teardown Β· hard

Hard-uninstall β€” deletes the .wiregraph/ folder, the managed directive block, the .gitignore entry, and a dangling ~/.wiregraph symlink. Nothing else touched.

When Done with wiregraph on this project entirely. Destructive β€” previews with --dry-run and requires explicit confirmation.

Args optional target-dir

$ /wiregraph-remove --dry-run would remove: .wiregraph/ Β· directive Β· .gitignore line proceed? β€Ί yes Β· source untouched

teardown

pause β€” you'll come back
  • βœ“ keeps graph.db + state.json
  • βœ“ re-init is instant
  • βœ“ posture set to off (hooks no-op)
  • βœ“ managed CLAUDE.md block removed

remove

done β€” uninstall entirely
  • βœ• deletes the whole .wiregraph/ folder
  • βœ• deletes graph.db, state.json, refresh.log
  • βœ• removes the .gitignore entry
  • βœ• removes the directive block + symlink

Ready

Index once. Then link the seams.

Stand a graph up with /wiregraph-init, join separately-indexed repos with /wiregraph-link, and Claude traces producer β†’ contract β†’ consumer across every boundary β€” at about half the tokens.

Install wiregraph  β†’