Skip to main content

Web UI

braito includes a local single-page application for browsing generated notes.

Start

bun src/cli/index.ts ui --root ./
# → http://localhost:7842

Custom port:

bun src/cli/index.ts ui --root ./ --port 3000

Features

  • Search — filter files by path as you type
  • Min score filter — show only files above a criticality threshold (default 0.5+)
  • Domain grouping — files grouped by folder domain, sorted by max score descending
  • Stale badge — ⚠ indicator for notes older than staleThresholdDays
  • Score badge — color-coded: red (≥0.7), yellow (≥0.4), green (<0.4)

Note tab

Shows the six semantic fields for the selected file:

FieldContent
PurposeWhat the file does and why it exists
InvariantsContracts and assumptions that must hold
Important DecisionsArchitectural choices backed by real signals
Known PitfallsFailure modes from TODOs, risky commits, and co-changes
Sensitive DependenciesExternal packages, env vars, high-fanout consumers
Impact ValidationWhere to verify before deploying a change

Each field shows observed items (from static analysis) and inferred items (from LLM, in italics).

Debug tab

Reveals the full analysis behind each note:

SectionContent
Score breakdownPer-signal bars showing each contribution to the criticality score with +X.XX labels
Evidence trailAll evidence[] items across every field, with type badges (code, git, test, graph, comment, doc)
Co-changed filesFiles that frequently change together with this one (from git history), sorted by co-change count
ChangelogLast 10 commits for the file: short hash, date, message, author

The Debug tab is especially useful for understanding why a file has a high score — you can see exactly what signals drove the result.

Tests tab

Shows test coverage signals for the selected file:

SectionContent
Status badgeCovered ✓ (green) or Uncovered ✗ (red) based on related test file detection
Coverage barLine coverage percentage with color-coded bar (green ≥70%, yellow ≥40%, red <40%)
Related test filesTest files associated with this source file
Raw signalshasTests, coveragePct, churnScore, authorCount from debugSignals

Uncovered files with consumers incur a higher criticality penalty (+0.15 vs +0.05), making the Tests tab a useful guide for where to add tests first.

Graph tab

Interactive force-directed dependency graph powered by D3.js:

FeatureDescription
Node colorsEach domain gets a unique color from a 12-color palette
Node sizeProportional to criticalityScore (range: 4–16px radius)
Directed edgesArrow markers show import direction (importer → imported)
Global / Focus modeToggle between the full graph and an ego-network around the currently selected file
Depth sliderIn Focus mode, expands the ego-network to 1, 2, or 3 hops
Edge direction colorsUpstream edges blue, downstream edges red, cycle edges red with ringed members
Domain legendCheckbox per domain to hide/show its nodes without re-running generate
HoverHighlights the hovered node and its direct neighbors; dims everything else; tooltip shows path, score, domain, ego-hop, and cycle membership
ClickLoads the clicked file's note in the detail panel
DragReposition individual nodes in the force simulation
Zoom/PanMouse wheel to zoom, drag background to pan
Min-score filterSlider to hide nodes below a criticality threshold — useful for large graphs with 300+ nodes
LabelsFile names shown for nodes with score >= 0.5 (all nodes in Focus mode)
Analysis panelRight-side pane with per-file graph stats: in/out degree, transitive consumers/deps, cycle membership with sibling list, neighbor domain breakdown, hotspot flag, and signals (score, churn, tests)

The graph loads data from GET /api/graph (serves .ai-notes/graph.json, falls back to reconstructing from index.json dependents). Cycles come from GET /api/graph/cycles (iterative Tarjan SCC) and per-file analysis from GET /api/graph/analysis?path=X.

Hotspot detection: a file is flagged as a hotspot when criticalityScore ≥ 0.6, it has ≥ 5 transitive consumers, and it has no associated tests — a fast signal for where to add tests or refactor first.

Test coverage stats

A stats strip above the file list shows global test coverage at a glance:

  • files — total number of generated notes
  • covered — files with at least one related test detected
  • uncovered — files with no tests
  • avg cov — average line coverage across files that have coverage data

Running generate from the UI

The ▶ Run generate button in the header triggers the full pipeline directly from the browser without opening a terminal.

▶ Run generate   [ ] --force

A log panel slides up from the bottom showing each step in real time:

12:04:01 · braito.context.md loaded — injecting project context…
12:04:01 📂 Found 24 files
12:04:02 🔍 Analyzing files…
12:04:03 💾 Reused 18 cached analyses (skipped ts-morph parse)
12:04:03 🕸 Building dependency graph…
12:04:04 ✍ Writing notes…
12:04:05 ✅ Generated 6 notes in .ai-notes/
12:04:05 ⏭ Skipped 18 unchanged files (use --force to reprocess)

Check --force to bypass the cache and reprocess all files. Check --verbose to see per-file signal detail (see below). The file list and coverage stats refresh automatically when the run completes.

Verbose mode

When --verbose is checked, the log panel shows a detailed line for every processed file:

0.82  src/core/types/ai-note.ts  deps=0 consumers=8 churn=12  [no-tests LLM]
0.71 src/core/output/buildBasicNote.ts deps=6 consumers=3 churn=8 [ext-imports LLM]
0.45 src/core/utils/logger.ts deps=1 consumers=5 churn=3 []

Each line shows: criticality score · file path · dependency and consumer counts · churn · active signal flags.

At the end of the run, verbose mode also prints:

  • Top 5 files by consumers — the most-imported files in the graph (high blast radius)
  • Top 5 files by score — the files with the highest criticality
  • Files without tests — count of untested files vs total

Use verbose mode to understand why scores are high, spot bottlenecks, and decide where to add tests or reduce coupling.