Codebase orientation tool
Open a codebase you didn't write. Claude draws it as a diagram. Click a box, ask a question, get the next diagram — every earlier one stays on screen, and every flag stays clickable.
Built for one question: is this the decision I would have taken?
Card, flag, next card — the strip is the lineage, root on the left.
| Interface | Local web app, one browser tab, served by FastAPI + server-sent events |
| Rendering | ASCII grid → geometry → hand-drawn SVG, one renderer, server-side |
| Storage | SQLite — a trail is a rooted tree of cards, kept across restarts |
| Engine | claude -p, one CLI turn per card, children fork their parent's session |
| Requires | uv and a logged-in claude CLI |
| Default port | 127.0.0.1:8420 |
Fast, shallow opening sketch — not an audit.
Ask a question; what you clicked rides along.
Redrawn at whatever depth the question called for.
Re-flag an old card and it branches from there.
# from the project root ./run.sh # -> http://127.0.0.1:8420 # run the test suite uv run --extra dev python -m pytest -q
| Variable | Effect | Default |
|---|---|---|
| SID_PORT | Port the app binds to | 8420 |
| SID_DB | Path to the SQLite trail database | ./diagrams.db |
| SID_OPEN | Set to 0 to skip auto-launching a browser tab | 1 |
The app exists to answer questions about code you did not write, so it is built to not ask for faith.
| Property | Mechanism |
|---|---|
| Watchable | A running card shows an elapsed clock, each file as it's opened, and a live line of what's being drawn |
| Receipted | Every card lists every file read and search run, in order, with cost and wall time; blocked calls are shown as blocked, not dropped |
| Source-true | One click swaps the picture for the exact ASCII it was mechanically drawn from |
| Read-only by default | An allowlist, not a denylist: Read, Glob, Grep, read-only git/ls/find. Writes and shell redirects are refused |
| Editing is opt-in | Tick let it edit files on one remark; only that turn runs with write access, and the resulting card is badged wrote code |
| Failures are filed, not patched | A bad render goes to training-data/ with your description and both the raw and repaired ASCII — nothing quietly edits the renderer |
| asciigrid.py | ASCII grid → geometry, plus repair() and audit() |
| sketch.py | Geometry → hand-drawn SVG; also a standalone CLI |
| claude_cli.py | Drives claude -p, streams progress, retries a broken drawing |
| prompts.py | The drawing contract, output schema, depth ladder |
| models.py | SQLite; a trail is a rooted tree of cards |
| web.py | FastAPI + SSE; renders each card server-side |
| Depth | Model | Effort |
|---|---|---|
| Opening sketch | Sonnet | Low |
| Follow-up flag | Sonnet → Opus | Rising |
| Deep question | Opus | High |
Every card records the model and effort that produced it; both are overridable before asking.
repair() before audit(). Repair straightens boxes deterministically; only a box that still won't close earns a redraw turn.