@frmwrkd/snag-repomap
v0.1.3
Published
Codebase graph for Snag: routes, imports, API handlers and data models.
Readme
@frmwrkd/snag-repomap
Builds .snag/map.json — routes, imports, API handlers and data models.
Licence: Apache-2.0
Spec: docs/02-BACKEND-SPEC.md §3. Do not relitigate locked decisions in docs/00-MASTER-BUILD-PLAN.md §7.
What it answers
"What else does this touch" — the context you currently type by hand:
/cart → src/app/cart/page.tsx → CartPage.tsx → PromoField.tsx
→ POST /api/promo → src/app/api/promo/route.ts
→ Promotion @ prisma/schema.prisma:18Use
snag-repomap # writes ./.snag/map.json
snag-repomap ../myapp --json # print instead of write
snag-repomap --no-cache # force a cold build
snag-repomap --strict # exit 1 if any analyser degraded (CI only)import { buildRepoMap, writeRepoMap, blastRadius, relatedFiles } from '@frmwrkd/snag-repomap';
const { map, graph, warnings } = await buildRepoMap({ root: process.cwd() });
await writeRepoMap(map, process.cwd());The output shape is owned by @frmwrkd/snag-core (RepoMapSchema) and is validated
before it is returned. It carries v, never version.
Tiers, and what happens when one fails
| Tier | Source | On failure |
|---|---|---|
| framework | package.json, then router conventions | { name: "unknown" } |
| imports | dependency-cruiser, then a regex scanner | empty graph |
| routes | Next build manifests, then file-router conventions | [] |
| components / api / models | one ts-morph visit per file | that file contributes nothing |
| owners | CODEOWNERS | [] |
| churn | git log --numstat over 30 days | 0 |
Every tier is wrapped individually. A failure costs that tier, produces a
warning, and never fails the caller's build (doc 02 §3.2). --strict is the
only way to turn a warning into a non-zero exit.
Derived values (doc 02 §3.3)
blastRadius(graph, file) — distinct files one hop away, capped at 20.
relatedFiles({...}) — anchor, imports, API handler, model file; capped at 8.
files(task) / conflictSet(a, b) — re-exported from @frmwrkd/snag-core.
related_filesis context for the agent and is never a conflict input. Including it in conflict detection would make almost every pair of tasks conflict through a shared import and collapse every wave to a single task.
Caching
Per-file content hash (sha1) in <root>/.snag/cache/repomap-cache.json.
Everything cached is a pure function of one file's bytes — which is why prop
types are resolved within a file only. A warm rebuild of a 1,000-file repo runs
well inside the 3 seconds doc 02 §3.2 asks for (~150 ms with nothing changed,
~850 ms after a one-file edit). The cache is a rebuildable index: deleting it is
always safe, and a corrupt one degrades to a cold build.
