feat(viz): code-graph lands on a connected hub neighbourhood + server-backed file search#29
Conversation
…-backed file search The code-graph tab dumped the first 800 files (an arbitrary, unreadable black wall) for any sizeable repo — the last viz hairball from the cold-start validation pass. Replace it with a legible landing: - collectCode ranks files by coupling DEGREE and grows a CONNECTED neighbourhood from the densest hubs (each hub + its neighbours) up to CODE_LANDING_CAP (80) — so the landing shows real coupling structure, not 800 dots and not (top-degree-alone) isolated hubs. Small repos (≤80 files) still show in full. Note: "Showing the 80 most-connected files of N — double-click to expand, or search to load any file." - New searchFiles (parameterized $q path-CONTAINS) + /api/search route so the UI search reaches files OUTSIDE the landing set; doSearch highlights loaded matches instantly, then debounced- fetches and ADDS matching files to the graph (double-click then expands their neighbours). Verified on a healthy graph (reviewer: 80 nodes / 293 edges — connected hub-and-spoke, file paths readable). (Playright renders edgeless because its index is the incomplete one from the generated-file Symbol-PK crash — a separate known bug, not this change.) Tests: ui.test asserts the search wiring; the Kùzu-backed collectCode is exercised by the manual serve E2E (no Kùzu in a .test.ts, ADR-17). 553 unit green; typecheck + build green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…eview) Address items 1–3 of the Plex review of PR #29 (all in doSearch/fetchSearch): 1. BUG: a stale debounced response re-highlighted against the OLD query — the 250ms debounce cancelled the pending timer but not an in-flight fetch, so a slow/out-of-order response faded the current matches and added nodes for a superseded query. Now a `searchGen` token is bumped on every keystroke; fetchSearch captures its gen and drops the response if `gen !== searchGen`, and re-highlights against the CURRENT input (`currentQuery()`), never the captured q. 2. IMPROVEMENT: repeated searches grew the graph unboundedly (every fetch added ≤40 nodes, never evicted, re-layouting an ever-larger graph). Search-added nodes now carry a `searched` class and the previous batch is evicted before the next is added — the landing + double-click expansions are untouched, so growth is bounded. 3. IMPROVEMENT: a 503 set the shared "Repo busy — retrying…" status but never retried (the message lied). fetchSearch now actually retries with a bounded backoff (≤5 attempts), gated on the gen so a superseded query stops retrying. Tests: ui.test asserts the gen-guard, the eviction, the current-input re-highlight, and the retry (string-presence — the client JS has no DOM/cytoscape harness here). Verified at runtime: search loads a non-hub file, a rapid query switch hits the gen path, no page errors. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ary (PR #29 review) Address items 4–5 of the Plex review of PR #29 (collectCode landing): 4. MINOR: the landing note claimed "most-connected files" even on an edgeless graph (0 coupling edges → the loop just takes the first N). It now reads "Showing N of M files (no import/co-change edges indexed yet) — search to load any file." when there are no edges. 5. MINOR: a hub could land as an isolated dot when the cap was hit right after adding it but before any neighbour. The growth loop now skips adding a hub-WITH-neighbours when there's no room left to also include a neighbour (a degree-0 file can still fill the final slot — it has no edge to show). Tests: not unit-testable (collectCode opens Kùzu, ADR-17). Verified manually — the edgeless note fires on a 0-edge graph, and the connected-landing rendering (reviewer: 80 nodes / 293 edges) is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Plex review feedback addressed — ready for re-review. The Plex review (run in-session; not posted as GitHub threads) raised 1 bug + 2 improvements + 2 nits. All five are fixed; two flagged risks came back clean.
Verified clean (no change): Tests: items 1–3 — Checks: No GitHub review threads existed to reply to/resolve (the review was in-session). |
What changed
The code-graph tab dumped the first 800 files (an arbitrary, unreadable black wall) for any sizeable repo — the last viz hairball from the cold-start validation pass. It now lands on a connected hub neighbourhood:
collectCoderanks files by coupling degree and grows a connected neighbourhood from the densest hubs (each hub + its neighbours) up toCODE_LANDING_CAP(80). This shows real coupling structure — not 800 dots, and not isolated hubs (top-degree-alone are edgeless, since hubs connect to leaves, not each other). Small repos (≤80 files) still show in full. Note reads "Showing the 80 most-connected files of N — double-click to expand, or search to load any file."searchFiles(parameterized$qpath-CONTAINS, never string-concatenated) +/api/searchroute so the UI search reaches files outside the landing set.doSearchhighlights loaded matches instantly, then debounced-fetches and adds matching files to the graph; double-click then expands their neighbours.Verification
Reviewer (healthy graph): 80 nodes / 293 edges, connected structure, file paths legible. Search verified:
daemon→ loadsdaemon.ts/daemon.test.ts(not in the landing set).How to test
pnpm test:unit(553) —ui.testasserts the search wiring (fetchSearch+/api/search). The Kùzu-backedcollectCodeis exercised by the manualplex serveE2E (no Kùzu in a.test.ts, ADR-17).pnpm typecheck+pnpm buildgreen.plex serve→ Code graph tab on a real repo → connected hub view; type a non-hub filename → it loads.Notes
This closes the "seeing the graph" track (all three tabs — Knowledge, Review history, Code graph — now legible). The playright edgeless-index bug (generated-file Symbol PK) remains a separate launch-checklist item.
🤖 Generated with Claude Code