Skip to content

feat(canvas): phase 5 — run history, debug panel, error UX#15

Open
prosdev wants to merge 12 commits intomainfrom
plan/canvas-phase-5
Open

feat(canvas): phase 5 — run history, debug panel, error UX#15
prosdev wants to merge 12 commits intomainfrom
plan/canvas-phase-5

Conversation

@prosdev
Copy link
Contributor

@prosdev prosdev commented Mar 21, 2026

Summary

Canvas Phase 5 adds a VS Code-style panel layout and four new features:

  • Panel layout system: Activity bar (left) with resizable side panel (right) and bottom panel. Keyboard shortcuts (⌘1-4, ⌘J). Replaces stacked Sheet overlays with a persistent flex layout.
  • Run history: Browse past runs filtered by status, auto-refresh on completion, delete completed/errored runs. New historySlice store + listRunsForGraph/deleteRun API client.
  • Debug panel (State Inspector): Click any node during/after a run to see its state snapshot with diff highlighting (new/modified/removed/unchanged). Falls back to final_state for historical runs.
  • Validation error UX: Pre-run flow now does client validate → save → server validate → dialog with "Go to node" links. Hard errors block run; warnings allow "Run anyway".
  • Schema viewer: View current GraphSchema as formatted JSON with validation badge, copy to clipboard, and download as .json.

New components

ActivityBar · SidePanel · BottomPanel · PanelControlToolbar · ResizeHandle · RunHistoryPanel · StateInspector · JsonTree · ValidationErrorDialog · SchemaPanel

New stores / API

historySlice.ts · listRunsForGraph() · deleteRun() · validateGraphServer() · graphSlice.validateServer()

Test plan

  • tsc --noEmit passes across all packages
  • 463 tests pass (38 test files), 0 failures
  • Code review: 3 CRITICAL findings fixed (layer rule violations), 4 WARNINGs addressed
  • Manual: verify activity bar toggles side panel content correctly
  • Manual: verify resize handles persist sizes to localStorage
  • Manual: verify run history loads and auto-refreshes after run completes
  • Manual: verify debug panel shows state diff when clicking nodes during/after run
  • Manual: verify validation dialog appears with "Go to node" on invalid graph
  • Manual: verify schema panel shows valid JSON with copy/download

🤖 Generated with Claude Code

prosdev and others added 12 commits March 20, 2026 18:22
Mark phase 4 as complete. Add phase 4 implementation log. Add phase 5
overview with VS Code-style layout, run history, debug panel, error UX,
and schema viewer.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add Phase 3-4 patterns (graph traversal, auto-mapping, output key
cascading, state panel, settings store, Radix Select, input map editor)
to the gw-frontend skill. Add orchestration workflow memory entry for
autonomous plan→review→implement→code-review→commit→PR lifecycle.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace stacked Sheet overlays with a flex-based panel system:
- ActivityBar (left): toggles side panel content (config/state/history/schema)
- SidePanel (right): resizable 240-480px, hosts NodeConfigPanel + StatePanel
- BottomPanel: resizable, tab bar (Timeline/Debug), auto-opens on run start
- PanelControlToolbar: floating top-right toggles for panel visibility
- ResizeHandle: draggable dividers with localStorage persistence
- Keyboard shortcuts: Cmd+1-4 for side panels, Cmd+J for bottom panel
- Mode-aware node clicks: idle→config panel, running→debug panel
- Strip Sheet wrappers from NodeConfigPanel, StatePanel, RunPanel

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- API: listRunsForGraph() and deleteRun() in runs.ts
- historySlice: Zustand store for run list, status filter, pagination
- RunHistoryPanel: status filter chips, run rows with icons/timestamps,
  delete button, auto-refresh on terminal run status
- Wire into SidePanel history slot via ActivityBar

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- JsonTree: recursive JSON renderer with expand/collapse and diff badges
- StateInspector: shows per-node state snapshots from SSE events with
  diff highlighting (new/modified/removed/unchanged between nodes)
- Falls back to final_state for completed runs without per-node data
- Wire into BottomPanel Debug tab, mode-aware node click opens it

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- validateGraphServer() API client in graphs.ts (handles 200 + 422)
- ValidationErrorDialog: shows errors (run disabled) and warnings
  (run anyway enabled), with "Go to node" links
- Updated run flow: save → client validate → server validate → dialog
  if issues → proceed to run. Status toasts during each step.
- fromClientErrors/fromServerErrors converters for validation items

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- SchemaPanel: displays current GraphSchema as formatted JSON
- Validation badge showing valid/invalid with error count
- Copy to clipboard and download as .json buttons
- Wire into SidePanel schema slot via ActivityBar braces icon

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Move validateGraphServer call from CanvasHeader into graphSlice store
  action (CRITICAL: component must not import from @api)
- Remove @api/graphs import from ValidationErrorDialog, use inline type
- Re-export RunStatus from historySlice, fix RunHistoryPanel import
- Fix validateGraphServer to use shared request() client with ApiError
- Fix double loadPanelSizes() parse — extract once into useState
- Add clipboard writeText error handling in SchemaPanel

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- CRITICAL: validateGraphServer no longer fires a duplicate fetch() to
  recover the 422 body. ApiError now carries the parsed response body,
  so the 422 validation payload is extracted from the first request.
- Wrap computeDiff in useMemo keyed on [snapshot, prevSnapshot] to avoid
  re-stringify on every StateInspector render
- Cap bottomHeight on localStorage load (MAX_BOTTOM_HEIGHT = 600) to
  prevent oversized panels on smaller screens

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- [HIGH] History row click now loads historical run via inspectRun(),
  shows final_state in debug tab. Live runs open timeline tab.
- [MEDIUM] Server validation failure shows warning toast instead of
  being silently swallowed
- [LOW] In-progress nodes show "still executing" message instead of
  generic "no snapshot" when node matches activeNodeId
- [LOW] Clipboard failure in SchemaPanel shows error toast
- [LOW] Add toggleBottomPanel() to context, eliminating stale closure
  and listener churn in Cmd+J keyboard shortcut handler
- Clear inspectedRun when new live run starts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move all panel state (activeSidePanel, sidePanelVisible, bottomPanel*,
activeBottomTab) and actions (toggle/open/close) from CanvasContext
into a dedicated Zustand panelSlice. This gives components surgical
re-renders via selectors instead of re-rendering all 21 context
consumers on every panel toggle.

CanvasContext is now slim: selectedNodeId, stampNodeType, reactFlowInstance.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Reset historyStore when navigating between graphs to prevent showing
  stale runs from the previous graph
- Add window.confirm before deleting a run (destructive, irreversible)
- Remove unused Clock import from RunHistoryPanel

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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