All notable changes to repomap are documented here.
- Public repository hygiene — remove accidentally tracked local Claude
settings and
.work/QA artifacts, ignore both local directories, and drop their obsolete documentation, recipe, and artifact-presence test. - Codebase reduction — remove two unreferenced commit fixtures and an uncalled internal safe-filesystem wrapper pair.
- Commit mutation APIs are now internal. Go integrations that called
ExecuteCommit, prep, rewrite, release, or verification helpers must invoke the correspondingrepomap commit …CLI command. Public analysis APIs, includingAnalyzeCommit, remain available fromrepomap.
- No-tree-sitter builds — the documented parser fallback builds and tests when tree-sitter and CGO are disabled, while tree-sitter fidelity thresholds remain scoped to normal builds.
- Rooted repository rewrites and secret snapshots — commit workflows reject escaping, symlinked, non-regular, and oversized repository paths, preserve target permissions during atomic rewrites, and scan bounded private snapshots instead of reopening repository files through a symlink farm.
- Contributor workflow and toolchain — contributor documentation now names the supported Go toolchain and local checks, and the standard verification path enforces repository-wide Go formatting.
repomap task "<goal>" [directory]— composes task-relevant owners, symbols, bounded source, consumers, callers, tests, side effects, applicable rules, dirty overlap, and verification commands into one schema-versioned implementation packet. Supports--tokens,--json,--consumed, and the global atomic--artifactoutput.repomap cache warm [directory]— builds, persists, and verifies a fresh cache entry. Generated post-commit hooks now use the same command.
- Complete-output token budgets — bounded text, JSON, structured JSON, XML,
verbose, detail, lines, caller, and task output now count the fully encoded
stdout using
ceil(UTF-8 bytes / 4). Structured values are never byte-cut, and an undersized minimum envelope fails before output is written. - CLI output and validation contracts — invalid enums, bounds, and
conflicting modes fail before execution;
--artifactreplaces regular files atomically; output and flush failures propagate; JSON modes stay prose-free; and human searches report an explicit no-result state. - Audit packet completeness — Kong commands and flags are inventoried, schema-v3 packets account for every aggregate and per-file truncation, and filtered effects retain correct kind, lane, and omission totals.
- Dirty-worktree cache safety — cache version 15 binds entries to a strict Git worktree-content digest, handles renames and unusual filenames, and fails closed on malformed, conflicted, deleted, or semantically changed inputs.
- Repository analysis safety — repository rewrites reject traversal, symlink, directory, and non-regular targets while preserving permissions; generic Go callers, deletion invalidation, concurrent symbol lookup, and oversized JSON-RPC frame handling now retain their intended invariants.
- Compact CLI help output — Kong help now uses compact command trees and summaries, with commands listed before flags at root, nested, and leaf levels.
- Expanded high-level coverage — added tests for the top-level CLI, repomap methods, Go analysis, LSP URI handling, and fallback parsers.
- Canonical Go semantic analysis — caller-dependent and structured-output commands load active Go packages in-process with
go/packagesandgo/types, while ordinary maps and build-excluded or invalid files use the fast syntax-onlygo/astpath. Structured JSON now reportsbuild_activeandanalysis_mode, and cache entries retain semantic callers and diagnostics. - Semantic caller expansion by default — top-level
--calls,context --calls, and endpoint test discovery reuse one receiver-qualified SSA/CHA graph, removing their normal dependency ongoplsand preventing same-named methods from sharing callers. Call-graph construction stays lazy and runs only for caller-dependent commands.
- CLI parsing now uses Kong instead of Cobra while preserving repomap's owned command, flag, output-writer, artifact, help, and exit-code contracts. Cobra's generated
completioncommand is no longer provided. --preciseand--no-cacheare compatibility flags for existing invocations.--preciseincludes semantic callers regardless of--calls-threshold;--no-cacheis ignored because callers are built with the map instead of a separate caller cache.- Go test callers load independently from test ranking —
--calls-include-testsno longer requires the unrelated--include-testsranking flag.
repomap endpoint— new vertical-slice query verb for web-service work: given a route pattern it resolves the route registration, the handler symbol, the handler's direct callee names, and the tests touching the handler in one call. Detects chi/v5 verb methods (.Get/.Post/…) and net/httpHandle/HandleFunc(including the Go 1.22+"METHOD /path"form). List mode (repomap endpoint ./dir) prints all detected routes as a table; single-pattern mode (repomap endpoint "GET /users/{id}") returns the full route → handler → callees → tests bundle, with--jsonfor machine output.
- Opt-in precise call graph — added
--preciseonrepomap --callsandrepomap context --callsto build a type-checked, whole-program Go call graph (go/packages + Class Hierarchy Analysis) instead of per-symbol gopls queries. It resolves callers for every symbol in one pass — not just exported symbols in files above--calls-threshold— disambiguates same-named methods by receiver, and falls back to the gopls--callstier automatically when packages fail to load, so it never turns a working--callsrun into an error.
- Commit substitutions verify line content before applying — a finding's replacement is now checked against the current line text before it's written; a line that drifted since
commit prepabortscommit finishwith a "stale finding(s)" error instead of silently substituting the wrong line. - Mid-loop commit failures report landed commits and retry cleanly — if a commit group fails partway through
commit execute, the result now lists which commits already landed; re-running skips groups with no pending changes instead of re-committing them. - Prep state is bound to HEAD and file content —
commit finishnow rejects a prep token if HEAD moved or any planned file changed sincecommit prep("stale prep state... re-run commit prep"), and deletes the prep-state file once finish succeeds. - Incremental rebuilds apply the same rank passes as full builds — an incrementally-updated map previously could rank files differently than a full rebuild of the same tree.
- Cache validity is keyed on a config fingerprint — token budget, intent, method blocklist, and other build-affecting settings (including
.repomap.yaml) are now part of the cache key, so a config change can no longer produce a stale cache hit. atomicWriteFileis safe under concurrent writers — unique temp file names plus fsync-before-rename prevent torn writes when multiple processes write the same path.Stale()detects newly created files — previously only modified/deleted files triggered a rebuild; new files in the tracked tree now do too.commit prepaborts when applying fix-findings fails — previously the error was swallowed and prep could report success against a partially-redacted working tree.- Ambiguous review-finding identities are rejected — two findings sharing the same
file:lineno longer resolve by silently picking the last one. - Rune-safe snippet truncation — review-item snippets no longer truncate mid-UTF-8-rune.
commit execute's workspace-clean check parsesgit status --porcelain -zcorrectly — filenames with spaces and rename records no longer produce false "unplanned" aborts.- Dropped never-populated
byte_offset/byte_lengthfields from thecommit prepJSON payload.
- Postgres ownership inventory — added
repomap inventory --boundary Postgresto summarize constructors, writers, readers, migrations, tests, and docs for database-oriented review. - Compact impact handoffs — added
repomap impact --markdownfor human-readable blast-radius summaries without the verbosity of JSON. - Focused audit effects — added
repomap audit effects --kind database --paths-onlyand--top-filesaliases for audit packet limits. - Artifact output — added global
--artifact <path>support so long command outputs can be written directly without shell redirection.
- Audit hygiene is quieter by default — dependency and archive paths such as
node_modules/,vendor/,.work/archive/, andarchive/are suppressed from hygiene source leads while retaining suppressed counts in JSON. - Impact path resolution is more robust — file/root symlinks are normalized before computing impact paths, fixing macOS
/varversus/private/vartemp-path mismatches.
- Structural non-Go call-site evidence — tree-sitter-backed files now record parser-derived call expressions in structured JSON and use them as a bounded ranking signal, helping behavior files rise above passive type or data barrels in TypeScript, JavaScript, Python, Rust, C-family, Java, Ruby, and PHP projects.
- Tree-sitter parsing reuses runtime state safely — non-Go parsing now uses a build-scoped tree-sitter runtime that caches language objects, deduplicates first-use initialization, and reuses parser instances across the parallel parse pool.
- Docs reflect the current parser surface — language support,
parse_methodvalues, structured JSON call-site fields, ranking signals, and tree-sitter troubleshooting now match the implementation. - Coverage guards parser/runtime and docs drift — added tests for call-site extraction, structural ranking evidence, runtime language caching, and language documentation consistency.
repomap briefadds a Likely ownership routing section — derived from the already-ranked files, the brief now clusters the top files by owning parent directory, labels each cluster by its deepest meaningful path segment (skipping generic segments such aslib/src/internal/pkg), and shows the per-cluster file count plus a few top exported symbols (e.g.internal/cli/ — cli (38 files: Execute, Run, Write)). Capped at five clusters, requires ≥2 files per cluster, and omitted entirely for flat or single-area repos so it adds no noise — giving an agent an immediate sense of which packages own the surface before opening files.
- Ranking rebalances toward behavior over type-only barrels — the imported-by score now uses diminishing returns past a knee of 8 importers (full weight below, +1 each beyond) instead of an uncapped linear
count × 10, so a heavily-imported hub no longer monopolises the ranking and symbol/behavior bonuses break ties among hubs. The DTO penalty additionally now applies to pure data-only files (100% type/struct/interface/enum kinds, zero exported funcs/methods) regardless of the prior ≥4-symbol cluster floor, demoting lone-typebarrel files that previously topped the map. In a large multi-file TypeScript project this moves entry points and behavior-rich files above single-typetypes.tsbarrels in the brief. A file imported by exactly one other file still contributes the same +10 as before.
repomap briefmap is leaner — the embedded repository map is now capped to the top-ranked files (top 20) with an honest+N more files — runrepomapfor the full mapfooter, instead of dumping every file. The uniformimported by Nannotation is suppressed when every shown file shares the same importer count (the single-package degenerate case where that metric carries no per-file signal), roughly halving the digest length while preserving the high-signal header (Verify / State / Rules / Flow / Dependencies).
Map.StringBriefMap(maxFiles int) (body string, total int)— renders the enriched map for the topmaxFilesranked files and reports the total ranked-file count, for callers building bounded digests.
repomap brief— new top-level agent boot digest command. Prints a time-aware greeting, a project-specific Verify chain (build/test/vet, pluslintonly when a golangci config is present), a State section (branch, dirty-file count with the changed paths, recent commit subjects), a Rules section flagging agent-convention docs such asCLAUDE.md, and a warning when an active.repomap.yamlis filtering the map — followed by the enriched repository map. Makefile/justfile targets are verified to exist before being advertised.[dead]annotation — exported symbols with no detected references are marked[dead]in the default output.- Richer level-1 summaries — summary-level file blocks now list their top exported symbol names instead of bare counts.
- Per-symbol content hashing —
--json-structuredemits a per-symbol content hash so consumers can detect which individual symbols changed; cache version bumped to 9. - audit — extract job, model, and policy framework-role surfaces.
- audit: every audit packet (
risks,surface,effects,brief) is self-describing atschema_version2 — a stableidfor citation (e.g.repomap:risk:<path>), anevidence_class(import_graph/ast/git_history/heuristic) with a derivedconfidencetier, a per-fileverify_cmdfor Go targets, and an external-consumercaveat(capped tolowconfidence) on signals blind to out-of-repo callers such as dead code and untested exports. - audit: empty file lists serialize as
[]instead ofnulland carry afiles_omitted_reason; truncated packets report anomitted_reason. Additive and backward-compatible apart from thenull→[]fix. - structured JSON: add top-level parser coverage metrics and per-file relation evidence so consumers can distinguish exact Go import graph signals from heuristic non-Go basename and symbol-reference signals.
- commit: collapse finding placeholder replacement into a focused helper with coverage for generic project paths and placeholder-shaped test credentials.
- audit:
audit brief --jsonnow emits a boundedreview_planprojecting the first-read queue into per-lane review obligations (files, gates, suggested verify commands, why). Go-specific verify commands appear only when Go sources are detected. Derived deterministically from existing packets; additive and backward-compatible. - serve: stdio JSON-RPC 2.0 server for warm map queries (NDJSON; map/render, map/status, symbol/find, file/explain, file/context)
- Add cache and context inspection subcommands.
- Preserve exported API compatibility while keeping context-aware cache and commit-prep internals.
- Serialize LSP startup retries after failed language-server launches.
- Unwrap commit execute exit codes with
errors.As.
- Document cache, context, and
--json-structuredusage. - Add CLI cache/explain coverage and modernize test loops.
- Extract commit finish I/O helpers and simplify commit flow.
- Clean up incremental cache and commit-prep internals.
PHP files now render at the same fidelity as Go: full signatures with visibility, types, defaults; class headers with extends / implements; properties and constants visible; PHPDoc first sentences inlined.
- Tree-sitter PHP parser replacing the regex fallback. Covers PHP 8.x grammar: classes, interfaces, traits, enums (including backed enums and cases), functions, methods, properties, constants, namespaces.
- Visibility-in-signature —
public function foo(): string,private readonly LoggerInterface $logger. No schema change; visibility lives where it renders. - Constructor property promotion extracted as real properties —
private readonly LoggerInterface $logger = new NullLogger()appears in the property list, signatures byte-identical to non-promoted declarations. - PHPDoc extraction — first sentence of
/** */blocks rendered as subtitle; @-tags stripped. No[doc: n/a]noise on PHP files. - Kind-weighted ordering for PHP: class/interface first, then trait, enum, function, method, case, property, const.
Before (v0.7.0) vs after (v0.8.0) on LLPhant src/Chat/OpenAIChat.php:
# v0.7.0
src/Chat/OpenAIChat.php [untested] [doc: n/a]
func __construct
func generateText
func getLastResponse
type OpenAIChat
# v0.8.0
src/Chat/OpenAIChat.php [untested]
class OpenAIChat implements ChatInterface [440L]
public function __construct(OpenAIConfig $config = new OpenAIConfig(), private readonly LoggerInterface $logger = new NullLogger())
public function generateText(string $prompt): string
public function getLastResponse(): ?CreateResponse
public ?FunctionInfo $lastFunctionCalled = null
Symbol count on the same codebase: 968 → 1398 (+44%) within the same 2048-token budget.
Default output is now richer within the same token budget. An LLM reading repomap . no longer needs to open source files to generate correct call sites.
- Full typed Go signatures —
func Foo(ctx context.Context, id int) (*User, error)instead offunc Foo. The 40-char truncation cap is removed. - Typed struct fields —
{Name string, ID int}inline for exported structs instead of bare field names. - Leading godoc sentence inlined after each exported symbol:
// BudgetFiles assigns a DetailLevel to each RankedFile within the token budget. [doc: n/a]tag on file header lines for non-Go files — explicit signal that the language tier does not extract doc comments (not that docs are absent).- Kind-weighted symbol ordering within each file block: structs and interfaces first, then types, functions, methods, constants, and vars. Highest architectural signal at the top.
-f compactformat — lean orientation mode: file paths + exported symbol names, no signatures, no godoc, no struct fields. Use for first-pass codebase scans when you need inventory without detail. The old default (category summaries) is replaced by this named mode.- JSON schema envelope —
--jsonnow emits{"schema_version": 1, "lines": [...]}instead of a bare[]string. Downstream consumers should parse.lines. Use--json-legacyto get the pre-v0.7.0 bare array for scripts that cannot be updated immediately.
- All-or-nothing per-file budget invariant — files never truncate mid-symbol. Fallback chain on budget pressure: full enriched rendering (level 2) → summary (level 1) → omit. A half-shown file is worse than an omitted one: the footer now reports
(N files omitted — increase -t or use -f compact). - 5
nilerrbugs wherereturn nilsilently swallowed non-nil errors:inventory_scan.go(×3),init.go(×1),gitstate.go(×1). - 3
pw.Close()error drops incalls.gothat could hang a reader goroutine.
- Default JSON output changed from
[...]to{"schema_version":1,"lines":[...]}. Consumers must parse.lines. Use--json-legacyfor bare-array compatibility. - Default non-JSON output is richer (signatures, godoc, typed struct fields). Scripts asserting exact default output will need updating. To get the old terse output, use
-f compact.