Commit Graph

354 Commits

Author SHA1 Message Date
Jordan Ritter f69697b4c8 fix(showcase): result-aware probe icons + browser history navigation (#4438)
## Summary

- **Inflight/historical icons now differentiate pass vs fail**: Running
panel and historical run chips show result-specific icons (green=✅,
yellow=⚠️, red=❌). Previously all completed services showed ✅ regardless
of result, making failing tests look like passes.
- **Inflight tally counts yellow (degraded) as failure**: The summary
table's inflight branch now counts `result === "yellow"` services as
failures alongside red, fixing undercounted fail tallies.
- **Browser back/forward navigation works**: All tab switches, overlay
toggles, preset changes, and probe drilldowns now create browser history
entries via pushState. Added popstate listener to sync state. Probe
detail encoded in URL hash (`#ops:probe=<id>`).

## Test plan

- [x] Trigger an e2e-deep probe run with mixed results; verify inflight
panel shows ❌ for red services (not ✅)
- [x] Verify summary tally matches inflight panel counts
- [x] Switch tabs Matrix→Ops, press Back, verify returns to Matrix
- [x] Open probe detail, press Back, verify returns to Ops overview
- [x] Toggle overlays, press Back, verify previous overlay state
restores
- [x] Direct URL navigation to `#ops:probe=<id>` opens detail panel
2026-04-29 11:47:58 -07:00
Jordan Ritter 728ebae0a1 fix(showcase): result-aware icons and tally for inflight and
historical probe services

Running panel and historical run chips now show result-specific
icons: green=checkmark, yellow=warning, red=X. Previously all
completed services showed a checkmark regardless of result, making
it look like failing tests passed. Also fix inflight tally to count
yellow (degraded) results as failures alongside red.
2026-04-29 11:47:31 -07:00
Jordan Ritter b9a511560c fix(showcase): browser history navigation for dashboard tabs,
overlays, and probe drilldown

Replace replaceState with pushState for user-initiated navigation
(tab switches, overlay toggles, preset changes, probe selection).
Add popstate listener to sync React state on back/forward. Encode
probe detail drilldown in URL hash (#ops:probe=<id>) so the back
button closes the detail panel and returns to the ops overview.
2026-04-29 11:47:25 -07:00
Jordan Ritter 430fd995e0 fix(showcase): expandable historical run rows with per-service results (#4437)
## Summary

- Persist per-service probe results from the tracker snapshot into
PocketBase `summary.services` when a run finishes
- Dashboard historical run rows with service data show a chevron —
clicking expands a detail row with service chips matching the inflight
panel pattern
- Existing runs (pre-deploy) render without the expand affordance; only
new runs populate service data

## Test plan

- [x] Verify new runs after harness deploy populate `summary.services`
in PocketBase
- [x] Verify historical run rows with service data show expand chevron
- [x] Verify clicking chevron expands/collapses the service chip grid
- [x] Verify old runs (no service data) render without chevron as before
2026-04-29 11:37:21 -07:00
Jordan Ritter dfa35f4286 fix(showcase): expandable historical run rows with per-service results
Persist per-service probe results from the tracker snapshot into
PocketBase summary.services when a run finishes. Dashboard runs-list
rows with service data now show a chevron — clicking expands a detail
row with a service chip grid matching the inflight panel's pattern.

Existing runs (before this deploy) won't have service data and will
render without the expand affordance.
2026-04-29 11:36:45 -07:00
Sam Julien e20df1f86c fix(showcase/shell-dashboard): cell docs links fall back to feature defaults; drop /unselected/ prefix
Two bugs in DocsRow's link construction surfaced after PR #4395 + #4419:

1. **No feature-default fallback for shell_docs_path.** The component
   only read `integration.docs_links.features[fid].shell_docs_path`. If
   no per-integration override existed, the link rendered as 'missing'
   even when the feature-registry had a valid default. The og_docs_url
   path already had this fallback; shell_docs_path didn't.

   Fix: same `hasOverride ? override : feature_default` chain that
   og_docs_url uses. Explicit `null` overrides still mean opt-out
   (rendered with the 'opt-out' tooltip variant). Missing override
   inherits the feature default.

2. **Obsolete /unselected/ prefix in URL construction.** The shell-docs
   IA restructure (commit c11976819) retired the `unselected/`
   directory. The dashboard was still building URLs as
   `<framework>/unselected<path>`. Shell-docs's route handler tolerates
   the legacy shape (it strips the prefix), but the URLs are
   misleading. Dropped the SHELL_UNSELECTED_PATH constant and emit
   canonical `<framework><path>` URLs.

After: 0 broken (404) shell-docs links across 720 cells (was 8). 577
cells now resolve cleanly to a docs page; the remaining 143 are
features that genuinely don't have a shell-docs page yet (some have
upstream docs.copilotkit.ai pages, some don't — see follow-up ticket).
2026-04-29 09:22:02 -07:00
Alem Tuzlak 1de1556be3 fix(showcase): D5-green bypass for missing/red D3 in depth walk
The contiguous depth walk in deriveDepth previously short-circuited at
D2 whenever the D3 (e2e) row was missing or red, even when the D5
(e2e-deep) row was green. Per the harness model the e2e-deep driver
only emits a green d5:<slug>/<featureType> row after D3 + D4 probes
have passed, so a green D5 is sufficient evidence that D3/D4 implicitly
passed at some point.

After the D2 (agent) gate now passes, deriveDepth checks D5 first. If
D5 is green it sets achieved = 5 and proceeds to the D6 check; otherwise
it falls through to the existing D3 -> D4 -> D5 walk. D1 and D2 are
still hard gates -- D5 cannot bypass health/agent.

Adds 7 new tests covering: D3-missing+D5-green, D3-red+D5-green,
D3-missing+D5-missing (unchanged D2), D1-red+D5-green (must stay D0),
D2-red+D5-green (must stay D1), D6 via D5-bypass, and isRegression
when bypass lifts cell from D2 to D5 at max_depth=5.

Resolves the 13 live-dashboard cells (8 with e2e=? + 5 with e2e=red)
that should have shown D5 but were stuck at D2.
2026-04-29 17:27:00 +02:00
Jordan Ritter e5ec2066ff fix(showcase): live inflight tally in Ops probe summary table (#4429)
## Summary
- When a probe is running, the summary table now computes a live tally
from `inflight.services` instead of showing stale results from the last
completed run.
- Last Run and Duration columns also update to reflect the in-progress
run's start time and elapsed duration.
- Result shows "X/Y pass — running" while inflight, with amber tone for
in-progress and red if any failures detected.

## Test plan
- Trigger a probe run, watch the summary row update in real-time as
services complete.
- Once the run finishes, verify the row switches back to showing the
completed run's final results.
2026-04-29 08:21:20 -07:00
Jordan Ritter d7e6429c6a fix(showcase): show live inflight tally in probe summary table instead of stale last-run 2026-04-29 08:20:54 -07:00
Jordan Ritter 82ae68d5f7 fix(showcase): increase zebra stripe visibility (#4428)
## Summary
- Previous 94%/6% color-mix was invisible (white vs near-white). Changed
to 50/50 mix between `--bg-surface` and `--bg-muted` for actually
visible alternating rows.

## Test plan
- Alternating rows should have a subtle but visible tint difference.
2026-04-29 08:13:13 -07:00
Jordan Ritter e391f19c4f fix(showcase): increase zebra stripe contrast from 6% to 50% mix 2026-04-29 08:12:50 -07:00
Jordan Ritter 360cfb9a73 fix(showcase): subtle zebra striping on feature matrix (#4427)
## Summary
- Adds subtle alternating row backgrounds to the feature matrix using
`color-mix(in srgb, var(--bg-surface) 94%, var(--bg-muted))` on odd
rows. Sticky feature-name column matches the stripe. Theme-aware via CSS
variables.

## Test plan
- Visual: alternating rows should have a barely-noticeable tint
difference.
- Sticky column background should match the row stripe when scrolling
horizontally.
2026-04-29 07:57:29 -07:00
Jordan Ritter 22e72af6ab fix(showcase): subtle zebra striping on feature matrix rows 2026-04-29 07:57:03 -07:00
Jordan Ritter 605bfb497d fix(showcase): collapsible legend footer for mobile (#4426)
## Summary
- Makes the fixed legend footer collapsible via a toggle button. Default
is open. On mobile the legend was taking up most of the screen, making
the table unusable.

## Test plan
- Click the "Legend" toggle — content collapses to a thin bar. Click
again to expand.
- Verify on mobile viewport — collapsed state leaves room for the table.
2026-04-29 07:32:11 -07:00
Jordan Ritter f99fb17f0a fix(showcase): make legend footer collapsible for mobile usability 2026-04-29 07:31:39 -07:00
github-actions[bot] 1f355b6594 style: auto-fix formatting 2026-04-29 14:03:44 +00:00
Alem Tuzlak 5961c8569f fix(showcase-dashboard): use 🚫 emoji for unsupported (not N/A text)
Per user preference, restore the 🚫 emoji as the unsupported marker in
both DepthChip and feature-grid. Keeps a slate-colored pill (vs the
dashed-gray unshipped chip and the red ✗ no-demo marker) so the three
states remain visually distinct.
2026-04-29 16:01:46 +02:00
Alem Tuzlak a912a2ddb0 fix(showcase-dashboard): render unsupported cells as N/A in feature-grid (not danger ✗)
The matrix view's links/depth overlays are rendered by feature-grid.tsx,
which had its own no-demo branch that displayed a hard ✗ in danger color
when integration.demos didn't contain an entry for the feature.

That branch fired even when the feature was architecturally unsupported
(in not_supported_features), because unsupported integrations don't add
the feature to their demos[] list. Result: 29 unsupported cells rendered
as a red ✗ titled 'No demo' — visually identical to the unshipped marker
the user is trying to distinguish from.

Now feature-grid checks integration.not_supported_features first; if the
feature is listed there, the cell renders the same slate N/A pill we use
in DepthChip (consistent with the unsupported branch added there in the
prior commit). The hard ✗ remains for genuine no-demo cases.

Also adds not_supported_features to the Integration TypeScript interface
in registry.ts (the field was already present in registry.json data;
the type just didn't expose it).
2026-04-29 16:01:45 +02:00
Alem Tuzlak 428a9e44cc fix(showcase-dashboard): use 'N/A' text for unsupported chip instead of 🚫 emoji
The 🚫 emoji falls back to a tofu/X-shaped glyph on systems without
color emoji support (notably Windows Chrome with default fonts), which
viewers misread as the unshipped X marker — making 29 unsupported cells
look indistinguishable from unshipped.

Switched to a slate-colored N/A pill with a distinct border so the
unsupported state reads clearly across all platforms regardless of emoji
font availability.
2026-04-29 15:04:40 +02:00
github-actions[bot] 7d131608c0 style: auto-fix formatting 2026-04-29 11:03:09 +00:00
Alem Tuzlak b375349e6a fix(showcase): cr-loop fixes — manifest validation, types, env-var fallbacks
- generate-registry: cross-validate not_supported_features against features list
- catalog-types: widen manifestation union to include 'starter'
- claude-sdk-python: drop invalid 'declarative-schema' from generative_ui enum
- crewai-crews: remove duplicate animated_preview_url key in mcp-apps demo
- built-in-agent + pydantic-ai: REASONING_MODEL env-var fallback so deployers can swap if gpt-5.2/gpt-5 isn't available
2026-04-29 12:58:31 +02:00
Alem Tuzlak 879b18740a feat(showcase-dashboard): add unsupported cell status distinct from unshipped
Adds a fourth cell status, "unsupported", to the showcase dashboard for
features whose framework cannot architecturally support them (e.g.,
no graph-interrupt API, no MCP tool runtime). This is distinct from
"unshipped" (just unbuilt).

- Manifest schema gains optional `not_supported_features: string[]`.
- generate-registry.ts: determineCellStatus checks `not_supported_features`
  first; CatalogCell/CatalogMetadata gain `unsupported`; max_depth=0 for
  unsupported cells; parity tier is computed against the supportable subset
  of the reference (unsupported features no longer drag a framework's tier
  down for gaps it legitimately cannot fill).
- depth-utils.ts: deriveDepth returns D0 with no regression for
  unsupported cells.
- DepthChip: renders a dashed gray border + 🚫 glyph with
  "Not supported by this framework" tooltip; data-status attribute
  distinguishes unshipped vs unsupported.
- CoverageBar gains diagonal-stripe gray segment for unsupported.
- StatsBar / AdaptiveStatsBar / CellsView: separate "Unsupported" chip.
- CellMatrix gaps filter excludes unsupported cells (not work to do).
- Tests: cover unsupported in DepthChip, depth-utils, cell-matrix, and
  catalog generator metadata/max_depth assertions.
2026-04-29 10:59:38 +02:00
Jordan Ritter bd17bc11e3 fix(showcase): docs overlay should render independently of health overlay 2026-04-29 00:58:36 -07:00
Jordan Ritter 8029b372c0 fix(showcase): align ref-depth column sticky offset with reduced feature column width 2026-04-29 00:54:19 -07:00
Jordan Ritter 34aeab2ec8 fix(showcase): add bottom padding to scroll area for fixed legend bar 2026-04-29 00:48:53 -07:00
Jordan Ritter 1980dcc210 fix(showcase): suppress health badges on CLI command cells
Command demos (npx copilotkit init) have no E2E/D5/D6 probes, so
health badges were perpetual gray noise. Skip HealthLayer when the
demo declares a command instead of a route.
2026-04-29 00:42:18 -07:00
Jordan Ritter 0213dbdcfd fix(showcase): dashboard UI — sticky headers, tighter cells, centered badges
Restructure page to viewport-filling flex layout so table column
headers stick below the overlay toggle bar on scroll. Halve cell
padding, reduce column min-width, center UWCT/health badges and
links. Remove duplicate CellStatus from CommandCell (ComposedCell
HealthLayer handles it). Split stats bar out of sticky container
so it scrolls away naturally.
2026-04-29 00:42:17 -07:00
Jordan Ritter 616a45bb1d fix(showcase): extend depth ladder to D5/D6 with emerald chips
Depth system was capped at D4 — D5/D6 PocketBase rows existed but
the chip never advanced past D4. Extends deriveDepth() through D6
with proper short-circuit gating, adds isD5Green() for multi-key
CATALOG_TO_D5_KEY resolution, and colors D5/D6 chips emerald to
distinguish from D3/D4 blue.
2026-04-29 00:42:17 -07:00
Jordan Ritter ea1caa4837 fix(showcase): D5 dashboard chip lookup + CLI deep-input mapping
Dashboard: resolveCell() looked up D5 rows by catalog feature ID
(e.g. d5:slug/hitl-in-chat) but the harness writes them keyed by D5
feature type (e.g. d5:slug/hitl-text-input). Added CATALOG_TO_D5_KEY
mapping so the dashboard resolves the correct PB row for each cell.

CLI: buildDeepInputs() passed manifest registry IDs as `features` but
the D5 driver only maps them through demosToFeatureTypes() when they
arrive as `demos`. Changed to pass `demos` so the driver's mapping
from registry IDs to D5 feature types activates correctly.
2026-04-28 23:30:57 -07:00
github-actions[bot] 45a71343c7 style: auto-fix formatting 2026-04-29 02:56:56 +00:00
Jordan Ritter bd0b32525f fix: resolve merge conflict in aimock-wiring.ts (ops→harness rename + starter exclusions) 2026-04-28 19:55:29 -07:00
Jordan Ritter 2001a40862 Merge slot B3 into blitz/dash-fixes/integration 2026-04-28 19:32:54 -07:00
Jordan Ritter 0f15d507df Merge slot B2 into blitz/dash-fixes/integration 2026-04-28 19:32:46 -07:00
Jordan Ritter 1a05269d4f test: add overlay selector integration tests with real UI components
Renders ComposedCell with real CellStatus, DocsRow, DepthChip, and Badge
components (only data layer mocked) to verify that overlay toggles
actually control visible content. Covers all 5 overlays individually,
key combinations (Health+Docs, Health-without-Docs), all 3 presets
(Catalog, Assessment, Parity Review), testing-kind D5/D6 hiding, and
the critical regression test proving Health-only no longer leaks docs
indicators after the CellStatus DocsRow removal fix.
2026-04-28 19:31:50 -07:00
Jordan Ritter 0b28c07946 fix: convert raw UTC timestamps to browser-local timezone in dashboard
Add shared formatTs() utility that converts ISO 8601 UTC strings to
the user's local timezone via toLocaleString(). Apply it to all raw
timestamp interpolation sites in tooltip/badge/drilldown rendering:
- live-status.ts formatTooltip() (4 sites)
- cell-pieces.tsx formatTransitionLine() (3 sites)
- level-strip.tsx resolveBadge() (1 site)
- cell-drilldown.tsx refactored to use shared formatTs()

Update existing live-status tests to expect formatted timestamps.
Add unit tests for formatTs() covering valid/invalid inputs.
2026-04-28 19:26:50 -07:00
Jordan Ritter 9af3e727f5 fix: remove duplicate DocsRow rendering from CellStatus
CellStatus unconditionally rendered DocsRow for non-testing features,
causing docs indicators (docs-og, docs-shell) to appear in matrix cells
whenever the Health overlay was active — even when the Docs overlay was
toggled OFF. DocsLayer in ComposedCell already handles docs rendering
correctly, gated on overlays.has("docs"). Remove the redundant DocsRow
from CellStatus so docs indicators respect the overlay toggle.
2026-04-28 19:26:25 -07:00
Jordan Ritter 016f355cd3 fix: hydration-safe initialization for useOverlays and useCollapsible 2026-04-28 18:05:55 -07:00
Jordan Ritter b6e58e7429 fix: TallyTrigger hydration mismatch causing production crash
Remove conditional early return that rendered different DOM structures
on server vs client (bare fragment vs div>button wrapper). All hooks
now run unconditionally; interaction is disabled via guards when items
array is empty. Fixes React errors #418 and #310.
2026-04-28 17:53:27 -07:00
github-actions[bot] 6d664ce101 style: auto-fix formatting 2026-04-29 00:13:58 +00:00
Jordan Ritter 3d48abde15 feat(shell-dashboard): merge B2 — TallyBreakdownPopover + header wiring 2026-04-28 17:09:15 -07:00
Jordan Ritter 34681013b8 feat(shell-dashboard): add TallyBreakdownPopover and wire into column headers
TallyTrigger wraps each tally count (green/amber/red) in OverlayColumnHeader
with hover-open (200ms delay) and click-pin semantics. The popover lists
which features/signals fall in each bucket with colored dots and dimension tags.
2026-04-28 17:08:38 -07:00
Jordan Ritter 4bd57eb88f feat: add computeColumnTallyDetail() and wire tallyDetails memo into FeatureGrid
Add companion function to computeColumnTally() that returns per-bucket
TallyItem arrays instead of numeric counts. Wire a tallyDetails memo
into FeatureGrid and pass tallyDetail prop to OverlayColumnHeader.

Includes 6 unit tests covering connection error, health routing,
e2e tone bucketing, and demo-less feature filtering.
2026-04-28 17:08:20 -07:00
Jordan Ritter 8e17586418 feat(shell-dashboard): add TallyDetail/TallyItem types for tally breakdown 2026-04-28 17:03:36 -07:00
Jordan Ritter c62dd66dc4 Merge remote-tracking branch 'origin/main' into blitz/showcase-harness-rename/integration
# Conflicts:
#	pnpm-lock.yaml
#	showcase/harness/config/alerts/smoke-red-tick.yml
#	showcase/harness/scripts/test-notify-harness-jq.sh
#	showcase/harness/src/probes/drivers/e2e-chat-tools.test.ts
#	showcase/harness/src/probes/drivers/e2e-chat-tools.ts
#	showcase/harness/src/probes/drivers/e2e-demos.test.ts
#	showcase/harness/src/probes/drivers/e2e-demos.ts
#	showcase/harness/src/probes/drivers/e2e-readiness.test.ts
#	showcase/harness/src/probes/drivers/e2e-readiness.ts
#	showcase/harness/src/probes/drivers/e2e-smoke.test.ts
#	showcase/harness/src/probes/drivers/e2e-smoke.ts
#	showcase/harness/src/probes/drivers/liveness.test.ts
#	showcase/harness/src/probes/drivers/liveness.ts
#	showcase/harness/src/probes/drivers/smoke.test.ts
#	showcase/harness/src/probes/drivers/smoke.ts
#	showcase/harness/src/probes/liveness.test.ts
#	showcase/harness/src/probes/liveness.ts
#	showcase/harness/src/probes/smoke.test.ts
#	showcase/harness/src/probes/smoke.ts
#	showcase/harness/test/fixtures/rules/valid/smoke-red-tick.yml
#	showcase/ops/src/probes/drivers/e2e-demos.test.ts
#	showcase/ops/src/probes/drivers/e2e-demos.ts
#	showcase/ops/src/probes/drivers/e2e-smoke.test.ts
#	showcase/ops/src/probes/drivers/e2e-smoke.ts
#	showcase/ops/src/probes/drivers/smoke.test.ts
#	showcase/ops/src/probes/drivers/smoke.ts
#	showcase/ops/src/probes/smoke.test.ts
#	showcase/ops/src/probes/smoke.ts
#	showcase/scripts/verify-railway-image-refs.ts
2026-04-28 16:04:44 -07:00
Jordan Ritter d815831a60 fix(shell-dashboard): update composed-cell test for docs dedup behavior 2026-04-28 15:48:47 -07:00
Jordan Ritter 1c7bead053 fix(shell-dashboard): center-align cell content to match X marks
The "no demo" X marks are text-center while depth chips and overlay
content were text-left, causing visual misalignment across all overlay
views. Center both the td and the ComposedCell flex column.
2026-04-28 15:45:27 -07:00
Jordan Ritter a322656e3d Merge branch 'blitz/dashboard-ux-fixes/b6' into blitz/dashboard-ux-fixes/integration 2026-04-28 15:45:08 -07:00
Jordan Ritter 9583b0b62b Merge branch 'blitz/dashboard-ux-fixes/b3' into blitz/dashboard-ux-fixes/integration 2026-04-28 15:45:05 -07:00
Jordan Ritter 6caa4a6e95 Merge branch 'blitz/dashboard-ux-fixes/b7' into blitz/dashboard-ux-fixes/integration 2026-04-28 15:45:01 -07:00
Jordan Ritter 8352ebe83d Merge branch 'blitz/dashboard-ux-fixes/b5' into blitz/dashboard-ux-fixes/integration 2026-04-28 15:44:58 -07:00