Files
cameleer-server/docs/superpowers/specs/2026-04-16-runtime-compact-view-design.md
hsiegeln bf289aa1b1 docs: add runtime compact view design spec
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 13:27:53 +02:00

5.2 KiB

Runtime Dashboard — Compact View

Summary

Add a compact/collapsed view mode to the runtime dashboard (AgentHealth page). In compact mode, each application is rendered as a small status card showing app name, live agent count, and last heartbeat, with health-state coloring (tinted background + tinted border + thick left accent border). Individual cards can be expanded inline to reveal the full agent instance table. A global toggle switches between compact and expanded views.

Decisions

Question Decision
Default view Compact — all apps start collapsed
Expand behavior Inline — card expands in place, pushes others down
Grid layout Auto-fill responsive (repeat(auto-fill, minmax(220px, 1fr)))
Toggle location Inside stat strip area (icon toggle, no new toolbar row)
Health coloring Same logic as existing appHealth() — worst agent state wins
Card styling Tinted background (8% health color) + tinted border (25%) + 3px left accent border

View Mode State

  • viewMode: 'compact' | 'expanded' — persisted to localStorage key cameleer:runtime:viewMode, default 'compact'.
  • expandedApps: Set<string> — tracks individually expanded app IDs. Ephemeral (not persisted).
  • When viewMode === 'compact': apps in expandedApps show the full GroupCard table. All others show compact cards.
  • When viewMode === 'expanded': all apps show the full GroupCard table (current behavior). expandedApps is ignored.
  • Collapse all / expand all: sets viewMode and clears expandedApps.

View Toggle

  • Two-button icon toggle rendered in the .statStrip area after the last StatCard.
  • Uses Button from @cameleer/design-system with variant="ghost". Active button styled with var(--running) background.
  • Icons: LayoutGrid (compact) / List (expanded) from lucide-react.
  • .statStrip grid changes from repeat(5, 1fr) to repeat(5, 1fr) auto to accommodate the toggle.

Compact Card (CompactAppCard)

Inline component in AgentHealth.tsx (page-specific, not reusable).

Props: group: AppGroup, onExpand: () => void.

Layout:

  • Container: var(--bg-raised) with health-color tint via CSS custom property --card-accent.
    • background: color-mix(in srgb, var(--card-accent) 8%, var(--bg-raised))
    • border: 1px solid color-mix(in srgb, var(--card-accent) 25%, transparent)
    • border-left: 3px solid var(--card-accent)
    • border-radius: var(--radius-md)
    • Cursor pointer, entire card clickable.
  • Row 1: App name (font-weight 700, var(--text-primary)) left. ChevronRight icon (var(--text-muted)) right.
  • Row 2: "{liveCount}/{total} live" in health color (font-weight 600) left. Last heartbeat right — computed as timeAgo(max(instances.map(i => i.lastHeartbeat))) (most recent across all instances in the group). Color: var(--text-muted) when healthy, health color when stale/dead.
  • Hover: tint increases to 12%.

Health color mapping (reuses existing appHealth() function):

  • .compactCardSuccess--card-accent: var(--success)
  • .compactCardWarning--card-accent: var(--warning)
  • .compactCardError--card-accent: var(--error)

Expanded Card in Compact Mode

  • Renders existing GroupCard + DataTable unchanged.
  • GroupCard header gets a ChevronDown icon button to collapse back.
  • Expanded card gets grid-column: span 2 in the compact grid for adequate table width (roughly matches current half-page GroupCard width).
  • Animation (single card toggle): CSS transition on wrapper div with overflow: hidden. Expand: compact fades out (opacity 0, ~100ms), expanded fades in + grows (opacity 1, max-height transition, ~200ms ease-out). Collapse: reverse. Collapse-all / expand-all toggle is instant (no animation).

Grid Layout

  • viewMode === 'expanded': existing .groupGrid (2-column 1fr 1fr, unchanged).
  • viewMode === 'compact': new .compactGrid class:
    .compactGrid {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
      gap: 10px;
      margin-bottom: 20px;
    }
    

Files Changed

File Change
ui/src/pages/AgentHealth/AgentHealth.tsx viewMode/expandedApps state, localStorage init, CompactAppCard component, view toggle in stat strip, conditional grid rendering
ui/src/pages/AgentHealth/AgentHealth.module.css .compactGrid, .compactCard, .compactCardSuccess/Warning/Error, .compactCardHeader, .compactCardMeta, .viewToggle, .viewToggleActive, animation classes, .statStrip column adjustment
.claude/rules/ui.md Add compact view mention under Runtime section

No new files. No new design system components. No API changes. Feature is entirely contained in the AgentHealth page and its CSS module.

Style Guide Compliance

  • All colors via @cameleer/design-system CSS variables (var(--success), var(--warning), var(--error), var(--bg-raised), var(--text-primary), var(--text-muted), var(--running), var(--radius-md), var(--border-subtle)).
  • No hardcoded hex values.
  • Shared CSS modules imported where applicable.
  • Design system components (Button, GroupCard, DataTable, StatusDot, Badge, MonoText) used throughout.
  • lucide-react for icons (consistent with rest of UI).