Skip to content
This repository was archived by the owner on May 26, 2026. It is now read-only.

feat(KR-P2-DASHBOARD-V2): expand dashboard with 4 newer surface cards + footer aggregate#95

Merged
rafe-walker merged 1 commit into
mainfrom
feat/kora-KR-P2-DASHBOARD-V2
May 22, 2026
Merged

feat(KR-P2-DASHBOARD-V2): expand dashboard with 4 newer surface cards + footer aggregate#95
rafe-walker merged 1 commit into
mainfrom
feat/kora-KR-P2-DASHBOARD-V2

Conversation

@rafe-walker

Copy link
Copy Markdown
Owner

Summary

Single-file FE-only addition to `DashboardPage.tsx`. v1 row 1 untouched (Health hero + 6 cards: Operational / Cost / Sea / STOP-KORA / Last boot / DR). Adds row 2 with 4 cards for surfaces shipped after DASHBOARD v1 (#63 4d1bc11): Capabilities / Charter / Recent events / Runbooks.

No new backend endpoints. No new api.ts types. Reuses existing `DashboardCard` component, `isStubbed` helper, and per-card error fallback pattern.

Layout

Row Layout (lg) Cards
Health hero full-width overall + control-plane + worker badges
Row 1 3-col grid (v1, unchanged) Operational / Cost / Sea Tickets / STOP-KORA / Last boot / DR
Row 2 4-col grid (new) Capabilities / Charter / Recent events / Runbooks
Bottom strip wrap-row (v1, unchanged) links to Sessions / Skills / Plugins / etc.
Footer center text `Kora — Dashboard v2. {N} live sources / {M} stubbed sources.`

Mobile collapses both rows to single column.

New card body renderers

  • `CapabilitiesCardBody` — `total_tools` + `total_caps` headline + success/warning badge based on `unmapped_count`. KR-P2-CAP-PANEL still surfaces all 17 cap_* groups as unmapped until KR-P2-N closes the C2 mirror gap; v1 dashboard had no visibility into that.
  • `CharterCardBody` — `revision_id` (mid-truncated, hover-full title), `rules_hash` truncated, `loaded_at` relative. "Rules pending" badge when `rules_available` is false (Charter v1 fallback mode).
  • `RecentEventsCardBody` — last 5 chain events; relative timestamp in a fixed-width column + truncated `event_type` ("kora." prefix stripped for density).
  • `RunbooksCardBody` — available vs pending counts + most-recently-modified available runbook (best proxy for "what's currently maintained").

Refactors

  • `isStubbed` loosened to `LoadStatus` — `CapabilitiesResponse` and `RunbooksManifest` don't carry a `stub` field (always-live by design); the v1 `LoadStatus<{stub?:boolean}>` generic would have rejected them at the type layer. Property-check approach keeps runtime behaviour identical for sources that DO have the flag.
  • `ALL_SOURCES` array consolidates the dashboard's 11 fetched sources for `anyStubbed` + footer aggregate. Replaces the v1 inlined 7-source `||` chain.

Footer aggregate

  • live = `ready && !stub` — counts sources that returned successfully with real data (or sources without a stub flag by design)
  • stubbed = `ready && stub` — counts sources returning the fallback shape
  • loading/error excluded from both — only resolved states tallied

Footer count is 11 sources total (the dashboard's actual fetches). Spec said "13 sources" but that includes DIAG-BUNDLE button + DASHBOARD itself as "surfaces", not endpoint-backed counters. Footer reports the truthful number to avoid drift.

Diag bundle button

Unchanged. Spec mentioned an optional `(13 sources)` subtitle — skipped to avoid drift (DIAG-BUNDLE actually aggregates 11 sources per PR #89; the literal "13" would be wrong).

Test plan

  • No new tests (pure FE composition over already-tested endpoint shapes)
  • `npx tsc -b` on `web/` — clean (one TS narrowing issue caught + fixed in the `isStubbed` signature)
  • `npx vite build` on `web/` — clean
  • 150/151 admin-panel tests pass. 1 failure pre-existing:

Manual smoke targets

  • Navigate to `/`, verify row 1 is byte-identical to v1
  • Verify row 2 renders 4 cards in a 4-col grid on desktop / single column on mobile
  • Click each row-2 card → confirm navigation to `/capabilities`, `/charter`, `/chain-events`, `/runbooks` respectively
  • Verify per-card error fallback (red border + Retry) works by stopping the backend mid-load
  • Verify footer shows correct live/stubbed counts (today: probably ~3 live + ~8 stubbed depending on which flips have landed)

🤖 Generated with Claude Code

… + footer aggregate

Single-file FE-only addition to DashboardPage. v1 row 1 (Health hero
+ 6 cards: Operational / Cost / Sea / STOP-KORA / Last boot / DR)
stays AS-IS. Adds row 2 with 4 new cards for surfaces shipped after
DASHBOARD #63: Capabilities / Charter / Recent events / Runbooks.
Each click-throughs to its detail panel; per-card error fallback
inherits v1's red-bordered Retry pattern (DashboardCard component
reused unchanged).

Layout:
  Row 1 (3-col on lg): 6 v1 cards — operational-critical "is Kora
    alive" scanability stays at the top, no visual reflow.
  Row 2 (4-col on lg): 4 new cards. Equal-weight grid since each
    surface is smaller and operator scans them as a group.
  Mobile: both rows collapse to single column.

New card body renderers:
  * CapabilitiesCardBody — total_tools + total_caps headline + a
    success/warning badge depending on whether unmapped_count > 0
    (KR-P2-CAP-PANEL still surfaces all 17 cap_* groups as unmapped
    until KR-P2-N closes the C2 mirror gap; v1 dashboard had no
    visibility into that).
  * CharterCardBody — revision_id (mid-truncated, hover-full title
    for click-to-copy on detail page), rules_hash truncated,
    loaded_at relative. "Rules pending" badge when rules_available
    is false (Charter v1 fallback mode).
  * RecentEventsCardBody — last 5 chain events; relative timestamp
    in a fixed-width column + truncated event_type (the "kora."
    prefix stripped for density).
  * RunbooksCardBody — count of available vs pending + most-recently-
    modified available runbook (best proxy for "what's currently
    maintained"; falls back to "no available runbooks yet" when
    none are present).

Refactors:
  * isStubbed loosened to LoadStatus<unknown> — capabilities +
    runbooks responses don't carry a stub field (always-live by
    design); the v1 LoadStatus<{stub?:boolean}> generic would have
    rejected them. Property-check approach keeps the runtime
    behaviour identical for sources that DO have the flag.
  * ALL_SOURCES array consolidates the dashboard's 11 fetched
    sources for anyStubbed + footer aggregate. Replaces the
    inlined 7-source ||-chain.

Footer addition:
  * Subtle "Kora — Dashboard v2. {N} live source(s) / {M} stubbed
    source(s)." Aggregates across all 11 sources the dashboard
    fetches. Loading/error excluded from both counts (only ready
    states tallied). live = ready && !stub; stubbed = ready && stub.
  * Spec said "13 sources" — the dashboard actually fetches 11
    endpoint-backed sources (the 10 panel sources + chain-events
    + runbooks; DIAG-BUNDLE and DASHBOARD itself aren't counted).
    Footer reports the truthful count.

Diag bundle button:
  * Unchanged. Spec mentioned an optional "(13 sources)" subtitle —
    skipped to avoid drift (DIAG-BUNDLE actually aggregates 11
    sources per PR #89; the literal "13" would be wrong).

Tests: no new tests (pure FE composition over already-tested
endpoint shapes). 150/151 admin-panel tests pass; the 1 failure
is pre-existing (test_get_runbook_content_404_for_unauthored_manifest_entry
from PR #84 pinned dr_runbook as unavailable, but PR #86
KR-P2-RUNBOOKS-AUTHOR has since vendored it — exact "auto-improvement
as runbooks land" behaviour my RUNBOOKS-PANEL PR body predicted,
just no one updated the now-stale test). Out of scope here.
tsc -b + vite build clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@rafe-walker rafe-walker merged commit f3163be into main May 22, 2026
@rafe-walker rafe-walker deleted the feat/kora-KR-P2-DASHBOARD-V2 branch May 22, 2026 03:03
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant