Skip to content

feat(graph-ui): dead-code filtering, node code preview & GitHub deep-links#789

Closed
brishtiteveja wants to merge 4 commits into
DeusData:mainfrom
brishtiteveja:feat/graph-dead-code-filter
Closed

feat(graph-ui): dead-code filtering, node code preview & GitHub deep-links#789
brishtiteveja wants to merge 4 commits into
DeusData:mainfrom
brishtiteveja:feat/graph-dead-code-filter

Conversation

@brishtiteveja

Copy link
Copy Markdown

Summary

Adds dead-code discovery and code navigation to the graph UI, plus a couple of sidebar fixes and a build fix.

Dead-code filtering + status coloring

  • layout3d classifies each node and emits status (dead | single | entry | test | exported | normal | structural) and in_calls.
  • Dead = Function/Method with zero incoming CALLS and zero USAGE that is not an entry point, route, test, or exported symbol.
  • Caller counts come from the full graph via cbm_store_batch_count_degrees (not the sampled render edges, which would falsely mark sampled-in functions as uncalled), batched in chunks of 500 to stay within the store's bound-IN-clause capacity.
  • FilterPanel gains a Dead code section: color-by-status, show-only-dead, hide-entry-points, hide-tests, and a live dead count. GraphTab recolors nodes by status when enabled.

Node code preview + GitHub deep-links

  • layout3d emits qualified_name, start_line, end_line per node.
  • New GET /api/repo-info?project= returns the indexed repo's git remote normalized to a web base + blob_base (https://host/org/repo/blob/<branch>), read via libgit2. Handles scp-style (git@host:org/repo.git), ssh://, and https:// remotes.
  • Hover tooltip enriched with file:lines, dead-code status, and caller count.
  • Node detail panel: Show code (fetches the snippet via the existing /rpc get_code_snippet tool) and Open on GitHub deep-link to the exact lines.

Sidebar fixes

  • Search is now a case-insensitive regex (matches name / file_path / qualified_name), falling back to literal substring on invalid regex, with an inline hint. Result cap raised 50 → 500.
  • Whole left sidebar scrolls as one region; the tree no longer nests its own scroll so the (now taller) filter panel can't clip the search/tree.

Fixes

  • restore 50k node render limit — the prior 2000-node cap collapsed stellar degree-coloring to uniform red and dropped nearly all edges. Restored to 50000 (tunable via CBM_UI_MAX_RENDER_NODES), which also makes dead-code classification meaningful.
  • include git2/sys/alloc.h for git_allocator — the git2.h umbrella header does not pull in sys/ headers, breaking the build under libgit2 1.9.

Verification

Built cbm-with-ui clean. Verified over /api/* on a 78k-node project: in_calls matches graph ground truth exactly, repo-info yields the correct GitHub base, layout nodes carry qn+lines, and get_code_snippet returns real source for a node's qualified_name.

azehady added 4 commits July 1, 2026 10:45
The git2.h umbrella header does not pull in the sys/ headers, so
git_allocator (used to bind libgit2 to mimalloc) was an unknown type
under libgit2 1.9. Include git2/sys/alloc.h explicitly.
Classify each node in the layout and surface it in the graph UI so
dead code is visible and filterable.

Backend (layout3d.c):
- Parse per-node flags (is_entry_point/is_test/is_exported/route_path)
  from properties_json and compute a `status`:
  dead | single | entry | test | exported | normal | structural.
- Dead = Function/Method with zero incoming CALLS and zero USAGE that
  is not an entry point, route, test, or exported symbol.
- Caller counts come from the full graph via cbm_store_batch_count_degrees,
  NOT the sampled render edges (which drop edges to off-screen nodes and
  would falsely mark sampled-in functions as uncalled). Batched in chunks
  of 500 to stay within the store's bound-IN-clause capacity.
- Emit `status` and `in_calls` in the layout JSON.

Frontend:
- GraphNode gains status/in_calls; colors.ts adds a status palette + legend.
- FilterPanel: "Dead code" section — color-by-status toggle, show-only-dead,
  hide-entry-points, hide-tests, and a live dead count.
- GraphTab wires the filters and recolors nodes by status when enabled.

Note: filters act on the rendered node sample (name-ordered, default 2000,
cap via CBM_UI_MAX_RENDER_NODES) like all existing filters.

Also gitignore the generated src/ui/embedded_assets.c build artifact.
Commit d9d7065 capped the graph render limit to 2000 nodes (hard max
10000). At that size almost every node has degree 0-1, so the stellar
degree-coloring collapses to uniform red and nearly all edges are dropped
(both endpoints must be in-sample), losing the connected overview.

Restore the pre-cap limit: DEFAULT_MAX_NODES and HARD_MAX_NODES back to
50000 and the frontend GRAPH_RENDER_NODE_LIMIT to 50000. On samay this
brings back the full 50,000-node / 120,755-edge view with varied stellar
colors, and makes the dead-code classification meaningful (913 dead vs 0
in the tiny sample). Tune down at runtime via CBM_UI_MAX_RENDER_NODES.
… regex search

Hovering/clicking a node now surfaces its code and location.

Backend:
- layout3d emits qualified_name, start_line, end_line per node.
- New GET /api/repo-info?project= returns the indexed repo's git remote
  normalized to a web base + blob_base (https://host/org/repo/blob/<branch>),
  read via libgit2. Handles scp-style (git@host:org/repo.git), ssh:// and
  https:// remotes; empty fields when there is no remote.

Frontend:
- Hover tooltip enriched: file:lines, dead-code status + caller count.
- NodeDetailPanel: file:line range, "Show code" (fetches the snippet via the
  existing /rpc get_code_snippet tool and renders it), and "Open on GitHub"
  deep-link to the exact lines. Code resets when the selected node changes.
- GraphTab fetches repo-info per project and passes it + project to the panel.

Sidebar fixes (reported):
- Search is now a case-insensitive regex (matches name, file_path,
  qualified_name), falling back to literal substring on invalid regex, with an
  inline hint. Result cap raised 50 -> 500 with a "refine the search" notice.
- Whole left sidebar scrolls as one region (overflow-y-auto); Sidebar gains an
  `inline` mode so the tree no longer nests its own scroll and the tall filter
  panel can't clip the search/tree.
@brishtiteveja brishtiteveja requested a review from DeusData as a code owner July 2, 2026 22:18
@phpmac

phpmac commented Jul 3, 2026

Copy link
Copy Markdown

v12 pls audit

@DeusData DeusData added enhancement New feature or request ux/behavior Display bugs, docs, adoption UX priority/normal Standard review queue; useful PR with ordinary maintainer urgency. labels Jul 3, 2026
@DeusData

DeusData commented Jul 3, 2026

Copy link
Copy Markdown
Owner

Thanks for the graph UI work. Triage: graph UI/UX enhancement, but this is larger than a pure frontend change because it also touches UI server/layout code and .gitignore.

Review will focus on bounded file/code preview behavior, dead-code classification against full graph degrees, path/link generation, and making sure the UI changes do not introduce unbounded reads or confusing external-link behavior. Please keep the scope tight around graph UI discovery/navigation.

pull Bot pushed a commit to sorajate/codebase-memory-mcp that referenced this pull request Jul 4, 2026
…inks

Distilled from DeusData#789 (safe features only). Adds backend dead-code classification
(status + in_calls in the layout JSON), a GET /api/repo-info endpoint for GitHub
deep-links, and the frontend dead-code filters, node code preview, and deep-links.

The render-cap revert was dropped (kept 2000 for DEFAULT_MAX_NODES/HARD_MAX_NODES
and GRAPH_RENDER_NODE_LIMIT); the sidebar regex-search refactor was omitted.

Security fixes over the original: repo-info strips credentials from any returned
remote_url; the legitimate https blob-URL construction is allow-listed so the
static gate passes; libgit2 is not re-initialized/shutdown per request (reuses the
process-wide init from cbm_alloc_init); deep-link path segments are URL-encoded.

Co-authored-by: Andy Zehady <azehady@ciroos.ai>
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
@DeusData

DeusData commented Jul 4, 2026

Copy link
Copy Markdown
Owner

Thank you, @brishtiteveja — this is a genuinely strong set of graph-UI improvements. The dead-code filtering, node code preview, and GitHub deep-links all shipped: we distilled them onto current main in #863, merged as b0b7d510. The one piece we intentionally left out is the node render-cap revert — keeping the cap protects the browser from locking up on very large graphs — but if you'd like to revisit that specific behavior, a focused follow-up PR would be very welcome. Closing this in favor of the shipped distill; full credit to you for the features and the UX work. Thanks so much! 🙏

@DeusData DeusData closed this Jul 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request priority/normal Standard review queue; useful PR with ordinary maintainer urgency. ux/behavior Display bugs, docs, adoption UX

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants