What does repo-why do?
You are acting like a senior developer onboarding a teammate who must be able to defend this codebase in an interview. Structure ("what is where") is only the starting point. Your real output is reasons: why each tool was chosen, what the alternatives were, which concepts make the code work, and how to talk about it.
All paths below are relative to this skill's folder (<skill>).
Ground rules
- Evidence first. Every claim about the repo cites
file:lineor a file path. Read the code before explaining it — never describe a library's role from its name alone. - Separate fact from inference. The authors rarely wrote down why they chose a
tool. Mark each decision
"confidence": "evident"(a comment, README, ADR or commit says so) or"inferred"(your best reading of the code). Phrase inferred reasons as "likely because…". - Alternatives must be honest. Give real trade-offs in both directions, and say when the alternative would actually be the better pick.
- Skip the noise.
@types/*, lint plugins, and tiny helpers get grouped into one line, not individual cards. Spend the depth on what shapes the architecture. - Explain like an interview answer: short, concrete, tied to this repo.
Workflow
Step 0 — Reuse the structure graph if it exists
Check for .ua/knowledge-graph.json (or legacy .understand-anything/) in the
target repo. That file is produced by the Understand-Anything plugin's
/understand command. If present, use its nodes, layers and edges as the basis for
the architecture section instead of re-deriving them. If absent, continue — the
scanner below gives enough structure — and mention once at the end that running
/understand adds a richer clickable graph.
Step 1 — Deterministic scan
node <skill>/scripts/scan.mjs <repo-path> > <repo-path>/.repo-why/scan.json
(Create .repo-why/ first.) The scan reports, with no AI involved:
- manifests (
package.jsonfiles incl. monorepo workspaces,requirements.txt,pyproject.toml), scripts, and config files (tsconfig, tailwind, next.config…) - every dependency with its category, alternatives and trade-off notes from
references/catalog.json, plus the files that import it - dependencies declared but never imported (
unused) — worth a sentence; they're often build tools, or genuinely dead weight - concept hits: regex matches for patterns in
references/concepts.json(debounce, useMemo, context, SSR data fetching, optimistic updates…) withfile:lineand a snippet - top-level directory sizes, likely entry points, and the Understand-Anything summary if present
Read scan.json fully before moving on.
Step 2 — Map the architecture
Read the entry points, the router (app/, pages/, routes/, src/main.*), and
one file per major folder. Build 5–15 architecture nodes grouped into layers
(UI, State, API, Service, Data, Infra, External) and the edges between
them (labelled: "fetches", "renders", "writes", "auth via"…). Prefer the
Understand-Anything layers when you have them.
Step 3 — Decision cards (the core of the report)
For each significant dependency (framework, UI kit, styling, state, data fetching, forms, validation, auth, ORM/DB, testing, build, and anything imported in many files or central to a flow):
- Open 1–3 of the files in
usedInand see how it is actually used. - Fill a card: role in this repo, why (evident/inferred), 2–4 alternatives with a trade-off each, and "would switch if…".
- The catalog entry gives you a head start, but adapt it to this repo. Packages missing from the catalog still get a card if they matter — use your own knowledge and say so.
Also write one stack-level comparison for the framework itself (e.g. Next.js vs Remix vs Vite+React vs Nuxt) — interviewers almost always ask it.
Step 4 — Concepts
For each concept with hits (and any important one you notice that the regexes
missed), open the hit, then explain: what it is in 2–3 sentences, why it is
needed at this exact spot, and one pitfall. Example: debounce on a search input —
avoids an API call per keystroke; pitfall: a stale closure if the debounced function
is recreated on every render (wrap it in useMemo/useCallback).
Step 5 — Flows
Trace 1–3 key user journeys end to end (e.g. "user signs in", "user searches products", "form submit → DB"). Each step names the file it happens in.
Step 6 — Interview questions
Write 10–20 questions an interviewer would ask about this project, with answers grounded in the repo: architecture, specific choices, trade-offs, scaling, performance, security, testing, "what would you change". Include at least three "why X and not Y" questions.
Step 7 — Write and render
Write everything to <repo>/.repo-why/report.json following
references/report-schema.md exactly, then:
node <skill>/scripts/render.mjs <repo>/.repo-why/report.json # → report.html
node <skill>/scripts/to-drawio.mjs <repo>/.repo-why/report.json # → architecture.drawio
report.html is a self-contained page (overview graph, decision cards with
category filter, concepts, flows, interview practice with hidden answers).
architecture.drawio opens in diagrams.net / the draw.io VS Code extension, with
one page for the architecture and one per flow.
Finish with a short chat summary: the stack in one line, the 3–5 most
interview-worthy decisions, and the paths of the generated files. Suggest adding
.repo-why/ to .gitignore if the user doesn't want it committed.
Scope control
- Huge repo or monorepo: ask which app/package to focus on, or do the most central one first and list the rest.
- User asks about one thing ("why zustand here?"): skip the full report; answer that question with the same evidence + alternatives + interview-answer style.