Skip to content

Latest commit

 

History

History
508 lines (381 loc) · 18.3 KB

File metadata and controls

508 lines (381 loc) · 18.3 KB

Usage Examples

A tour of repomap by task. Each example is a real command with real output — copy, run, adapt.

repomap exists to answer one question better than ls -R or grep ever could: given a token budget, what should I read first, and how much should I trust it? That framing matters most for LLM agents, which pay for every token and have to decide what to load before they can reason. The examples below walk from a cold first look through task-focused selection, trust calibration, impact analysis, and machine-readable output.

Every command assumes you're at the root of a git repository.


Choosing an output mode

Mode Invocation What it emits Best for
enriched (default) (no -f) exported symbols + signatures + godoc first line + struct fields, budget-trimmed the everyday "read me first" map
compact -f compact exported symbol names only, no signatures/docs/fields wide orientation — more files fit the same budget
verbose -f verbose all symbols in whole files selected by the CLI's complete-output budget, grouped by kind, names only a broad CLI inventory
detail -f detail selected whole files with full signatures + struct fields the richest CLI text mode
lines -f lines actual source lines read from disk, budget-trimmed reading code, not summaries
xml -f xml structured XML: dependency graph + <file>/<symbols>/<sym> (name, kind, line, span, params, implements) machine consumption
json-structured --json-structured structured JSON repository map (files, symbols, call sites, scores; tier breakdown after explain) programmatic ranking/selection

Gotchas. The default (enriched) is richer than -f compact — compact is names only. -f verbose is wider but shallower per selected file than the default: it drops signatures, while the CLI still omits whole files as needed to fit -t. And --intent reranks files silently — add --explain to see why files ranked.

The header now reports ~T tokens (e.g. ## Repository Map · enriched (168 files, 874 symbols, ~1496 tokens)), so an orchestrating agent can scale -t from the estimate.


1. Get oriented in an unfamiliar repo

The default run is the one you'll use most. No flags: repomap discovers source files, ranks them, and prints the most important ones until it hits the token budget (default 2048).

repomap
## Repository Map (162 files, 880 symbols)

### Flow
entry: cmd/repomap/main.go
spine: repomap.go, types.go, calls.go, ranker.go, budget.go

### Dependencies
repomap → repomap/internal/lsp
repomap/cmd/repomap → repomap/internal/cli
repomap/internal/cli → repomap, repomap/internal/lsp

calls.go [imported by 17, imports: 1]
  type CallsConfig{Threshold int, Limit int, IncludeTests bool}
    // controls --calls mode behaviour
  type CallsStats{OK int, Timeout int, Error int}
    // holds counters from a call-expansion run

Two lines orient you before the file list:

  • ### Flow names the detected entry point and the spine — the top behavioral files (rank-ordered implementation files with exported functions or methods). It answers "where does this start, and what's the backbone?" before you read a single symbol.
  • The map leads with implementation. Test files are demoted by default, so _test.go never crowds out the code it covers. When you're working on the tests, rank them at full weight with --include-tests:
repomap --include-tests ./src

Need a wider or narrower view? Move the budget:

repomap -t 4096            # more files / more detail
repomap -t 512             # just the load-bearing files

When you only want names for orientation — no signatures, no docs — drop to compact:

repomap -f compact
calls.go [imported by 17, imports: 1]
  types: CallsConfig, CallsStats, Location, SymbolCallers
  interfaces: RefsQuerier
  funcs: CheckGopls, CheckLspq, DefaultCallsConfig, DefaultQuerier, ExpandCallers
  methods: Refs, Refs

The format ladder is compact → (default enriched) → verbosedetail, trading breadth for depth. The CLI applies -t to the complete encoded response for every format, so a small budget may omit whole files even in verbose or detail; detail adds full signatures and struct fields for the files that fit.


2. Rank for the task at hand

A generic map ranks by structural importance. When you have a task, tell repomap — it re-ranks with BM25 so the files relevant to your query rise to the top of the same budget.

repomap --intent "parse php class methods"
repomap -i "retry with exponential backoff"

Intent matching reads file paths, package names, symbol names, imports, signatures — and doc comments. A function documented as // Retry implements exponential backoff will surface for -i "exponential backoff" even if nothing in its name says so.


3. See why a file ranked — and how much to trust it

repomap's score is a sum of heuristic signals, and not all signals are equally trustworthy. --explain annotates each file with a per-tier breakdown so you can tell a verified fact from a lexical guess.

repomap --explain
calls.go [imported by 17, imports: 1] # score 203 · structural:203

The tiers, from most to least trustworthy:

Tier Means Backed by
confirmed verified references semantic Go analysis (--calls) or LSP commands
structural parsed structure & import graph always available
lexical by-name match, may be coincidental --symbol-refs
contextual depends on your query / session --intent, --consumed

Tiers only appear when their signal is active. Combine flags to light up more of them:

repomap --explain --symbol-refs --intent "ranking score"
find.go [imported by 17] # score 368 · structural:184 contextual:184

To drill into a single file, use the explain subcommand — it shows the total, the chosen detail level, and every component grouped by tier:

repomap explain ranker.go
ranker.go
  score: 199
  detail: 1
  structural
    imports      +170
    symbols      +19
    transitive   +10

Want it as data? repomap explain ranker.go --json adds score_by_tier and component_tiers fields.


4. Stop re-reading what you've already seen

Mid-investigation, an agent has usually read a few files already. Tell repomap, and it downranks those files while upranking the things that import them — pushing fresh, adjacent context into the budget instead of repeating yourself.

repomap --consumed ranker.go,budget.go -i "detail level assignment"

5. Build a bounded implementation handoff

When the next step is implementation rather than another general map, use task. It creates a goal-specific packet with selected targets, task-match evidence, relationship/effect provenance, confidence, source excerpts, read-next ranges, verification commands, diagnostics, and explicit truncation accounting.

repomap task --tokens=4096 --consumed budget.go,internal/cli/render.go \
  "fix token budget overshoot" .

GOAL is required and DIRECTORY is optional (default .). --tokens/-t defaults to 4096 and must be greater than zero. --json emits the schema-versioned TaskReport; use the root --artifact flag to write that complete output atomically:

repomap --artifact task.json task --json --tokens=4096 \
  --consumed budget.go,internal/cli/render.go \
  "fix token budget overshoot" .

--consumed accepts comma-separated paths under the task root. They are downranked while their importers are upranked; a selected consumed target is marked consumed: true and does not receive a source excerpt, keeping the packet focused on unread code. Blank goals, non-positive CLI token limits, and consumed paths outside the root are errors. If the report must omit metadata, relationships, source, or targets to fit, its truncations records what was shown and why; a follow_up_commands entry suggests a larger rerun.


6. Scope a change before you make it

Before editing a symbol, find out what leans on it. impact reports deterministic local facts and workflow guidance — importers, tests, risk, check-next files, likely Go test commands, and bounded read-next source ranges — for a file:

repomap impact ranker.go
repomap impact ranker.go --markdown
repomap impact ranker.go --json

Use --markdown for a compact human handoff and --json for tooling.

For database ownership work, start with the map, then ask for the boundary answer and exact DB-effect paths:

repomap --intent "PostgreSQL database psql pgx migrations schema queries" --explain
repomap inventory --boundary Postgres --json
repomap audit effects --kind database --paths-only

For a symbol-level view with bounded source and its blast radius, use context:

repomap context RankFiles
repomap context RankFiles --calls --max-source-lines 120

7. Trace callers and references

--calls expands exported symbols with receiver-qualified callers from one in-process Go semantic graph (verified references — the confirmed tier):

repomap --calls
repomap --calls --calls-threshold 1 --calls-limit 20 --calls-include-tests

The graph uses go/packages, SSA, and Class Hierarchy Analysis and is built only for caller-dependent commands. Add --calls-include-tests to load test variants. The deprecated --precise compatibility flag includes callers regardless of --calls-threshold:

repomap --calls --precise
repomap context RankFiles --calls --precise

For pinpoint navigation, the LSP subcommands take FILE LINE SYMBOL (1-based line):

repomap refs ranker.go 52 RankFiles      # every reference
repomap def  ranker.go 52 RankFiles      # jump to definition
repomap hover ranker.go 52 RankFiles     # type + docs
repomap symbols ranker.go                # everything defined in a file

8. Find a symbol by name

When you know the name but not the file:

repomap find RankFiles
repomap find Config --kind struct
repomap find Parse --file parser --limit 5
repomap find ExpandCallers --format json

9. Output for machines

Agents usually want structured output, not prose. Three shapes:

repomap --json              # schema-versioned envelope of rendered lines
repomap --json-structured   # structured repository map (files, symbols, call sites, scores)
repomap -f lines            # actual source lines instead of a symbol summary

--json-structured is the richest: it carries per-file scores, structural call-site records when parser-backed extraction is available, and, after an explain, the tier breakdown — ideal for an agent that ranks and selects programmatically. Under -t, its files array contains only whole selected records, while totals remains the full repository count and files_omitted/files_omitted_reason account for the rest. Every CLI format limits the complete encoded stdout response to ceil(bytes / 4) tokens; if its minimum valid envelope cannot fit, the command fails without a partial response.


10. Prepare commits

repomap can analyze a changeset, group related files, and flag breaking changes — a workflow built for an agent assembling a clean PR.

repomap commit analyze                   # emit a structured commit plan as JSON
repomap commit prep                      # full pre-commit pipeline → JSON payload
repomap commit auto                      # prep + finish when ready, else report

analyze accepts --confidence to tune how aggressively files cluster into groups; execute/finish apply a plan (optionally --push, --tag).


11. Seed a deep audit

Before a broad review, ask repomap for deterministic leads instead of loading the whole tree into a model:

repomap audit brief --json --limit 20
repomap audit hygiene --json
repomap audit risks --json --limit 20
repomap audit surface --json --limit 20
repomap audit effects --json --limit 20
repomap audit effects --kind database --paths-only

audit brief builds the map once and emits risks, surface, effects, a grouped first-read queue, and a review_plan for workflow tools. The review_plan projects the first-read queue into per-lane review obligations — each lane lists the files to cover, the gates to discharge, suggested verify commands (Go-specific commands appear only when Go sources are detected), and why the lane matters — so deep-audit tools get coverage targets without inventing findings. Use the narrower commands when you only need one packet. audit hygiene catches tracked-vs-worktree drift such as ignored source files. It suppresses dependency/archive noise from paths such as node_modules/, vendor/, .work/archive/, and archive/, while retaining suppressed counts in JSON. audit risks groups central files, entrypoints, boundary files, and large symbols into repo-audit lanes. audit surface extracts the user-facing contract: commands, flags, env vars, config keys, JSON schema fields, routes, and output paths. audit effects extracts side-effect boundaries such as filesystem writes, subprocesses, HTTP, DB calls, serialization, secrets, crypto, time, and randomness. Treat these outputs as audit packets: promote a lead only after source, docs, runtime, or command corroboration. Use --top-files N as a clearer alias for --limit N on audit packets.

Risk packets remain at schema_version 2. Surface, effects, and brief packets use schema_version 3 with structured truncation accounting. Each carries a stable id (e.g. repomap:risk:internal-cli-audit-go) for citation, an evidence_class (import_graph, ast, git_history, or heuristic) with a derived confidence tier, and a per-file verify_cmd for Go targets. Signals blind to out-of-repo callers — dead code, untested exports — carry a caveat and are capped at low confidence. Empty file lists serialize as [] (never null) with a files_omitted_reason, and truncated packets report an omitted_reason.


12. Set up a project

Scaffold a .repomap.yaml and install a post-commit hook that keeps the cache warm:

repomap init
repomap init --no-hook        # config only
repomap init --force          # overwrite existing

The config file lets you blocklist noisy method names, restrict or exclude paths, and pin specific files to a detail level. See Configuration. The post-commit hook runs repomap cache warm . in the background; re-running init upgrades older marker-owned hooks without --force and preserves foreign hooks.


13. Start a warm JSON-RPC server

For coding agents and editors that ask many small questions, repomap serve keeps one map warm per project root instead of rebuilding on every invocation. It starts a long-lived JSON-RPC 2.0 server on stdin/stdout using NDJSON framing — one JSON object per line — so map and symbol queries can answer in microseconds after the startup build.

repomap serve . 2>/dev/null <<'EOF'
{"jsonrpc":"2.0","id":1,"method":"map/status","params":{}}
{"jsonrpc":"2.0","id":2,"method":"symbol/find","params":{"query":"kind:struct:Map"}}
EOF
Method Params Result
map/render {"format":""} or compact, verbose, detail, lines, xml, structured {"content":"..."}
map/status {} {"built_at":"<RFC3339>","stale":false,"root":"<abs path>"}
symbol/find {"query":"[kind:<kind>:][file:<path>:]<name>"} {"matches":[...]}
file/explain {"path":"<rel>"} ExplainResult JSON
file/context {"query":"...","kind":"...","file":"...","max_source_lines":120} SymbolContext JSON

symbol/find and file/context share the positional query syntax: [kind:<kind>:][file:<path>:]<name>. Qualifiers may appear in either order; the remaining token is the symbol name.

Each request checks whether the map is stale. The mtime check is debounced for 30s; when stale, serve rebuilds synchronously before answering. Close stdin (EOF) to shut it down. Lifecycle messages such as build, ready, rebuild, and shutdown go to stderr only; stdout stays JSON-RPC. JSON-RPC errors use -32700 parse error, -32601 method not found, -32602 invalid params, and -32000 server error.


14. Trace a route to its handler, callees, and tests

The endpoint verb answers a web-service question in a single call: what handles this route, what does the handler call, and which tests touch it? It detects chi/v5 verb methods (.Get/.Post/…) and net/http Handle/HandleFunc (including the Go 1.22+ "METHOD /path" form).

List every detected route as a table:

repomap endpoint ./internal/server
METHOD  PATTERN        HANDLER      FRAMEWORK  FILE:LINE
GET     /users/{id}    getUser      chi        routes.go:14
POST    /users         createUser   net/http   routes.go:22

Pass a pattern to get the full vertical slice — route registration, resolved handler, direct callee names, and the tests touching the handler:

repomap endpoint "GET /users/{id}" ./internal/server
routes.go:14  GET /users/{id}  getUser  [chi]

handler: getUser(w http.ResponseWriter, r *http.Request)
  routes.go:30

callees:
  db.FindUser
  json.NewEncoder
  render.Status

tests:
  handlers_test.go:18:2

impact:
routes.go
  imported by: server.go
  tests: handlers_test.go

Add --json for the machine-readable bundle. A repo with no detected routes prints no routes found and exits 0, so endpoint is safe to run anywhere.


A worked agent loop

Putting it together — how an agent might use repomap across a single task ("fix the token budget overshoot"):

# 1. Orient, focused on the task.
repomap -i "token budget overshoot" -t 3072

# 2. Inspect why the top suspect ranked, and trust its signals.
repomap explain budget.go

# 3. Before editing, learn the blast radius.
repomap impact budget.go

# 4. After reading budget.go and ranker.go, refocus without repeating them.
repomap --consumed budget.go,ranker.go -i "enriched cost estimate" -t 2048

Each step narrows the context the agent loads next — which is the whole point: spend the budget on what matters, and know how much to trust it.


See also: Quick Start · Output Formats · Configuration · Ranking.