Scadrial · Seeker Cross-repo · Code graph

forge

Sight across repos, not just one. Burn bronze to query the code graph of every repo in your forge. Cross-repo code graph for Claude Code. Query every repo in your group from one call.

One feature of metalmind, split into its own page because it's a different job from memory recall. Use the forge when Claude needs to answer "which service calls this handler?" across five repos without you pasting code between windows.


What the forge is

A forge is a named group of repo paths. Each repo already has its own per-repo code graph (nodes = functions/classes/routes, edges = calls + imports) via graphify. metalmind adds a merge layer that unions those graphs and infers three kinds of cross-repo edges:

INFERRED_NAME
Same identifier in two repos → candidate cross-repo reference. Cheap to compute, high recall, medium precision. Use when chasing a renamed helper or a shared DTO.
INFERRED_ROUTE
HTTP caller in repo A matched to HTTP handler in repo B on (method, path). High precision when specs are available. Three tiers of extraction drive this — see below.
INFERRED_URL_LITERAL
Opt-in fallback. Path-shaped string literals found in any text file, matched to handlers. Lower precision but catches references the other tiers miss. Flagged with its own confidence marker so Claude knows to double-check.

Every inferred edge carries its confidence tag in the payload. Claude reads the tag and decides how much weight to give it — INFERRED_ROUTE from an OpenAPI spec is near-ground-truth; INFERRED_URL_LITERAL from a regex match is "worth checking."


How cross-repo route edges get built

Three tiers, most-trustworthy first. The forge runs each against both the caller and handler sides, then joins on (method, path-after-template-canonicalization).

  1. Tier 1 — OpenAPI specs on the metalmind shelf. metalmind forge capture-spec <repo> <url-or-file> downloads or copies the spec to ~/.metalmind/specs/<repo-basename>.{yaml,json}. Specs never live inside your repo — this is a metalmind-owned shelf, not a commit-able file. The single-dev-in-a-team constraint made this a hard requirement: the tool has to work without polluting shared repos. When a spec is present, every route in it becomes a first-class handler node that cross-repo callers match against.
  2. Tier 2 — Java caller extraction. Regex-based parser for the three client patterns real codebases actually use: RestTemplate (getForObject, postForEntity, exchange), WebClient fluent chains (.get().uri(), .method(HttpMethod.X).uri()), and Feign interfaces (@GetMapping inside a @FeignClient). Adds call-sites to the graph that Tier 1 handlers can bind to. No LSP, no compiler — runs over source.
  3. Tier 3 — URL-literal fallback (opt-in via --include-literals). Scans ~15 text extensions for path-shaped string literals. Filters static-asset extensions (.png · .jpg · .css · .js · .html · .md · .yaml · .log · .tmp · .bak · .lock · .txt · .xml · .pdf) to cut noise. Every edge it produces is tagged INFERRED_URL_LITERAL — a louder "trust-but-verify" marker than INFERRED_ROUTE.

Results are cached per repo under ~/.metalmind/forge/routes/ keyed by sha1(repo, includeLiterals-flag). Cache staleness fingerprint combines the repo's graphify-out/graph.json mtime with the shelf spec mtime, so refreshing a spec via forge capture-spec automatically busts the cache. Orphan entries (cache files whose repo path no longer exists) are pruned on every call.


Commands

Metal Command Description
Forge $ metalmind forge create <g> $ metalmind group create <g> Define a new forge (group of repo paths).
Forge $ metalmind forge add <g> <repo> $ metalmind group add <g> <repo> Add a repo to the forge.
Forge $ metalmind forge capture-spec <repo> <url> $ metalmind group capture-spec <repo> <url> Seed the OpenAPI shelf for a repo (enables Tier 1).
Forge $ metalmind forge spec-list $ metalmind group spec-list List specs currently on the shelf.
Bronze $ metalmind burn bronze "<q>" --forge <g> $ metalmind graph "<q>" --group <g> Query across every repo in the forge. Add --include-literals for Tier 3.
Iron $ metalmind burn iron <sym> $ metalmind symbol <sym> Pull a symbol + its neighbors (callers, callees, module). LSP-backed via Serena.
Steel $ metalmind burn steel <old> <new> $ metalmind rename <old> <new> Coordinated rename through Serena's LSP.
Zinc $ metalmind burn zinc "<bug>" $ metalmind debug "<bug>" Dispatch /team-debug with the code graph pre-primed.
Pewter $ metalmind burn pewter $ metalmind reindex Force-rebuild the code graph for the current repo.

Who should NOT use the forge


Under the forge Under the hood

graphify
Per-repo code graph via tree-sitter AST. Clusters, god nodes, call paths. Zero LLM cost for the graph itself.
Serena
LSP-backed symbol lookup and coordinated renames. Same backend Claude Code's own tooling can reach, invoked as a subprocess.
OpenAPI shelf
~/.metalmind/specs/. Off-repo, single-dev, mtime-fingerprinted into the forge cache so refreshes invalidate correctly.
forge merge
Unions per-repo graphs, derives INFERRED_NAME / INFERRED_ROUTE / INFERRED_URL_LITERAL edges, caches the result. Orphan cache entries get pruned on every call.