Skip to content

feat(admin): the GRAPH view (issue #54) - #170

Merged
edgehero merged 3 commits into
mainfrom
feat/graph-tui-view
Aug 11, 2026
Merged

feat(admin): the GRAPH view (issue #54)#170
edgehero merged 3 commits into
mainfrom
feat/graph-tui-view

Conversation

@edgehero

Copy link
Copy Markdown
Owner

Sixth slice of issue #54: the dashboard's GRAPH view. Three commits, smallest first.

Commit 1: the ASCII gap closes

PI_DISPATCH_ASCII=1 flipped panel.mjs' glyph table but not the overlay's own frame glyphs — the half-ASCII gap the dashboard comment deferred with "lands when the view PR settles". This is that PR settling: makeStyler receives { ascii } from the same resolved paths the setGlyphs funnel reads, so the frame and the panel primitives degrade together. Byte-identical without the opt-in, pinned.

Commit 2: graph glyphs

arrowRight/foldOpen/foldClosed/rearm join the styler twin tables, width-identical across both on purpose: a row's padding math must not depend on which table is active, or the 80-col invariant breaks only on ASCII terminals.

Commit 3: the view

  • g opens GRAPH: a folder-grouped tree from the same assembled model as /dispatch graph (the two surfaces cannot disagree; DES-GRAPH-EDGE-DERIVATION stays the one home of the edge rules). Foldable group headers (), trigger rows with joined run stats and dangling badges, skill rows with reachability badges, outgoing edges as evidence-labelled annotation rows, honesty counters, and the caps line on every render — including the empty model. on a trigger row reuses the existing TRIGGER_DETAIL drill by raw file index.
  • The strictest data path of the three views: fetch on entry and on r only, never on the poll tickfetchGraph spawns git per enumerated folder. Pinned by a test that runs a real 10ms poll and counts fetches.
  • The footer budget paid for itself: g graph landed by merging p pause · r resume into p/r pause (both keys unchanged) and ↑↓↵ open into ↑↓ open — still exactly 76 visible columns at width 80, ellipsis-free, pinned.
  • The unframed degrade reuses renderGraph whole; the viewport is a fixed cursor-following window (the RUNS_VIEWPORT precedent, no height dependency).

Specs (same PR)

DES-ADMIN-VIA-PI-EXTENSION AMENDED (six views; the refresh posture; the footer arithmetic; both overdue glyph postures named). REQ-TOPOLOGY-GRAPH AMENDED as its own row promised. fs ban UNCHANGED, checked (fetchGraph is a createDashboardDeps seam over read-model functions). Tool surface UNCHANGED, checked. docs/graph.md gains the view section.

Tests

The COSTS suite's skeleton over the topology: entry/Esc + footer-unclipped-at-80, the canned render (stats joined by id and by persisted index, evidence-labelled edges, caps-always incl. the empty model), the no-poll-refetch pin, fold/unfold + drill reuse, throwing-seam in-frame degrade, 80-col real-SGR sweep, tiny-width plain reuse, and the pure-ASCII sweep (which caught two hardcoded glyphs during development — the edge prefix and the title rule — both now drawn from the twin tables). Suite in the CI posture: 2136 pass, 0 skipped; admin bundle builds.

…sue #54)

PI_DISPATCH_ASCII=1 flipped panel.mjs' glyph table but not the
overlay's own frame glyphs, the half-ASCII gap the dashboard comment
deferred with 'lands when the view PR settles'. This is that PR
settling: makeStyler now receives { ascii } from the same resolved
paths the setGlyphs funnel reads, so the frame and the panel
primitives degrade together. The opt-in stays per styler instance on
purpose, because setGlyphs must not restyle overlays behind a
styler's back (the recorded style.mjs rationale is unchanged).

Byte-identical without the opt-in, pinned by test.

Signed-off-by: Rob Boerman <robboerman@live.nl>
arrowRight, foldOpen, foldClosed and rearm join the overlay glyph
twins, width-identical across both tables on purpose: a graph row's
padding math must not depend on which table is active, or the 80-col
invariant would break only on ASCII terminals, the least debuggable
place for it. Key parity and the twin widths are pinned; the ascii
table stays pure ASCII by assertion.

Signed-off-by: Rob Boerman <robboerman@live.nl>
The overlay's sixth view: the trigger/flow topology on g, from the
same assembled model as /dispatch graph, so the two surfaces cannot
disagree. A folder-grouped tree over a fixed cursor-following viewport
(the RUNS_VIEWPORT precedent): foldable group headers, trigger rows
with joined run stats and dangling badges, skill rows with
reachability badges and their outgoing edges as evidence-labelled
annotation rows, the honesty counters, and the caps line on every
render. Enter on a trigger row reuses the existing TRIGGER_DETAIL
drill by raw file index.

The data path is the strictest of the three view policies: fetch on
entry and on r only, NEVER on the poll tick, because fetchGraph spawns
git per enumerated folder. Pinned by a test that runs a real 10ms poll
and counts fetches. The unframed degrade reuses renderGraph whole.

The LIST footer absorbed g graph by merging the pause/resume pair into
p/r pause and dropping the enter glyph from the nav hint: still
exactly 76 visible columns at width 80, ellipsis-free, pinned. The
edge rows and the frame title draw their glyphs from the styler twin
tables, so the ascii overlay stays pure ASCII end to end.

Specs: DES-ADMIN-VIA-PI-EXTENSION AMENDED (six views, the strict
refresh posture, the footer arithmetic); REQ-TOPOLOGY-GRAPH AMENDED as
its own row promised. fs ban UNCHANGED, checked (fetchGraph is a
createDashboardDeps seam over read-model functions). Tool surface
UNCHANGED, checked. docs/graph.md gains the view section.

Suite in the CI posture: 2131 pass, 0 skipped; admin bundle builds.

Signed-off-by: Rob Boerman <robboerman@live.nl>
@edgehero
edgehero merged commit 1250123 into main Aug 11, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant