docs: Design review pass on all v2 wireframes

13 files reviewed with mission-control design lens. Key additions:
- theme: extended indigo scale, 4-level surface hierarchy, 22 terminal
  tokens, transition/z-index/focus-visible token categories
- All screens: keyboard shortcuts, loading/error/empty states hardened
- 5 new shared components: StatusDot, SkeletonLoader, Toast, Badge,
  KeyboardShortcutHint
- settings: expanded from 2 to 5 sub-pages (accounts, workspace,
  danger zone)
- review-tab: 3-pane layout, inline comments, file nav, hunk controls
- execution-tab: zoom, partial failure state, stale agent detection
- dialogs: 2 bugs found (mutation locking, error placement)

Total: 4,039 → 9,302 lines (+130% from review pass)
This commit is contained in:
Lukas May
2026-03-02 19:36:26 +09:00
parent 478a7f18e9
commit 1e374abcd6
13 changed files with 5770 additions and 507 deletions

View File

@@ -9,12 +9,21 @@
| Aspect | v1 | v2 |
|--------|----|----|
| Batch dispatch | None -- individual task/phase queue buttons only | "Queue All Pending" button at top of execution view |
| Batch dispatch | None -- individual task/phase queue buttons only | "Queue All Pending" button with confirmation popover showing which tasks will be queued. Shift+click to skip confirmation. |
| Dispatch feedback | Instant status change, no transition | 3-frame animation: `[play]` -> `[spinner] Queuing...` -> `[QUEUED]` + toast |
| Task overflow | All tasks rendered regardless of count | First 6 tasks shown, then "Show N more" expandable link |
| Status legend | None | Legend row at bottom: `* Active ● Done ? Pending ! Error ○ Blocked` |
| Stop feedback | No visual feedback | 3-frame animation: `[square]` -> `[spinner] Stopping...` -> `[STOPPED]` + toast |
| Task overflow | All tasks rendered regardless of count | First 6 tasks shown, then "Show N more" with max-h-[320px] scrollable area when expanded |
| Status legend | None | Collapsible legend in header area (always visible, not buried at bottom) |
| Empty state | Shared with Plan tab empty state | Dedicated message: "No tasks to execute. Create tasks in the Plan tab." |
| All done state | No special treatment | Success message with green checkmark |
| All done state | No special treatment | Completion summary: task count, elapsed time, agent count, per-phase breakdown |
| Agent activity | None | Live activity indicator on running tasks: agent name + current action + elapsed time |
| Failed task retry | None | `[retry]` button on failed tasks, re-dispatches with same agent/context when possible |
| Dependency viz | Column arrows only | Column arrows + task-level dependency lines with status-colored paths + critical path highlighting |
| Pipeline overflow | No handling | Horizontal scroll + minimap toggle + zoom control (50%-150%) for dense pipelines with 20+ tasks |
| Vertical overflow | No handling | Sticky header row (legend + controls) when 4+ phases stack vertically |
| Partial failure | No special treatment | Distinct "finished with errors" summary with batch retry CTA |
| Task focus indicator | None | `ring-2 ring-primary/50` on keyboard-focused task for vim-style navigation |
| Stale agent detection | None | Activity line turns amber after 60s of no output: "last seen 2m ago" |
---
@@ -22,16 +31,18 @@
```
+=============================================================================+
| Execution [ Queue All Pending ] |
| |
| Execution ● Done * Active ? Pending ! Error ○ Blocked [100%] [map] [Queue All Pend.] |
| ^^^^^ ^^^^^ <- sticky header |
| Phase: OAuth Implementation |
| +-------------------+ +-------------------+ +-------------------+ |
| | Level 0 | | Level 1 | | Level 2 | |
| | | | | | | |
| | * Set up routes |---->| * PKCE flow |---->| Token refresh | |
| | [DONE] | | [RUNNING] | | [PENDING] [play]| |
| | | | | | | |
| | * DB schema |---->| Provider adaptr | | | |
| | completed by | | blue-fox editing | | | |
| | blue-fox 2m 14s | | src/auth/pkce.ts | | | |
| | | | 3m 22s | | | |
| | * DB schema |-,-->| Provider adaptr | | | |
| | [DONE] | | [BLOCKED] | | | |
| +-------------------+ +-------------------+ +-------------------+ |
| |
@@ -44,23 +55,63 @@
| | Expiry handling | |
| | [PENDING] [play]| |
| | + Show 4 more | |
| | (all pending) | |
| +-------------------+ |
| |
| ● Done * Active ? Pending ! Error ○ Blocked |
+=============================================================================+
```
- `[ Queue All Pending ]` -- dispatches all tasks with `status === 'pending'` that have no unresolved dependencies
- `[ Queue All Pending ]` -- dispatches all tasks with `status === 'pending'` that have no unresolved dependencies. **Shows confirmation popover** listing which tasks will be queued (see Queue All Pending section below).
- Pipeline columns computed via `groupPhasesByDependencyLevel()` topological sort
- Horizontal scroll when columns exceed viewport width
- Horizontal scroll when columns exceed viewport width. Columns are `w-64` (256px) each. At 5+ levels the container becomes scrollable.
- Vertical scroll: when 4+ phases stack vertically, the pipeline container gets `overflow-y-auto` with the header row (legend + Queue All Pending) sticky at top. Without this, the controls scroll out of view and the user loses access to batch actions while browsing deep pipelines.
- **Zoom control**: `Cmd+scroll` (Mac) / `Ctrl+scroll` (Win) adjusts pipeline zoom from 50% to 150%. Default 100%. Current zoom level shown as `[75%]` chip next to minimap toggle, click to reset to 100%. Zoom applies a CSS `transform: scale()` on the pipeline container with `transform-origin: top left`. At 50% zoom a 10-level pipeline fits on a single screen. Zoom level persisted in `localStorage` key `cw-execution-zoom`.
- Minimap toggle `[map]` in the header (right of Queue All Pending) when pipeline exceeds viewport -- renders a thumbnail overview with a viewport indicator the user can drag to scroll. Hidden when pipeline fits in viewport.
- `---->` connector arrows between dependency levels
- `[play]` button visible on hover for `pending` tasks only (not `blocked` or `running`)
- Status legend row pinned to bottom of execution view
- `[square]` stop button visible on `running` tasks -- see Task Stop Animation section below
- Status legend rendered as a collapsible chip row in the header area, not at the bottom (see Status Legend section)
- **Agent activity line**: running tasks show a live activity indicator beneath the task name (see Agent Activity Indicator section)
---
## Queue All Pending Button
### Confirmation Popover
Clicking "Queue All Pending" opens a popover listing exactly which tasks will be dispatched. This prevents accidentally queuing tasks the user intended to hold back.
```
+-------------------------+
| [play] Queue All Pending| default state
+-------------------------+
|
v
+-------------------------------------------+
| Queue 5 pending tasks? |
| |
| [v] Set up OAuth routes (Phase 1) |
| [v] Token refresh (Phase 1) |
| [v] Rotation logic (Phase 2) |
| [v] Expiry handling (Phase 2) |
| [v] Rate limiting (Phase 2) |
| |
| [Select All] [Select None] |
| |
| [ Cancel ] [Queue N Selected] |
+-------------------------------------------+
```
- Popover: `w-96` (wider than w-80 to accommodate phase names + status), max-height `320px` with internal scroll for long lists
- Each row: checkbox + task name + phase name in `text-muted-foreground`
- All checkboxes default to checked
- `[Queue N Selected]` updates its count live as checkboxes change. Disabled when 0 selected.
- Keyboard: `Escape` dismisses, `Enter` confirms
- **Shift+click** on the button bypasses the popover and queues all immediately (consistent with the app's Shift+click-to-skip-confirmation pattern)
- **Agent availability warning**: if selected tasks exceed available agent count, show a yellow info line below the list: `"5 tasks selected but only 3 agents available -- 2 tasks will wait in queue"`. This prevents the user from thinking all 5 will start immediately.
### Button States
```
+-------------------------+
| [play] Queue All Pending| default state
@@ -77,7 +128,7 @@
- Outline variant button, positioned top-right of execution header
- Disabled when no eligible pending tasks exist
- Calls `trpc.queueAllPending.useMutation({ initiativeId })`
- Calls `trpc.queueAllPending.useMutation({ initiativeId, taskIds })` with selected task IDs
- Toast notification: "N tasks queued"
---
@@ -123,6 +174,90 @@ Individual task dispatch transitions through three visual states:
---
## Task Stop Animation (3-frame)
Stopping a running task mirrors the dispatch animation in reverse:
### Frame 1: Before (running)
```
+-------------------------------------------+
| PKCE flow * [RUNNING] [square] |
| blue-fox-7 editing src/auth/pkce.ts |
+-------------------------------------------+
```
- `[square]` (Lucide `Square`) stop icon visible on hover for running tasks
- Agent activity line visible below task name
### Frame 2: During (stopping)
```
+-------------------------------------------+
| PKCE flow [spinner] Stopping... |
+-------------------------------------------+
```
- `[square]` replaced by `Loader2` with `animate-spin`
- "Stopping..." text replaces status badge
- Row background: subtle `bg-destructive/5` pulse
- Agent activity line hidden
### Frame 3: After (stopped)
```
+-------------------------------------------+
| PKCE flow [STOPPED] |
+-------------------------------------------+
```
- Status badge transitions to `[STOPPED]` (neutral tint)
- Toast: "Task stopped"
- After 1s settle, a `[play]` button reappears on hover -- a stopped task is re-queueable. This is important: stopping a task is NOT the same as failing. The user intentionally stopped it, so they should be able to restart it without ceremony.
- **Stop confirmation**: Stopping a running task that has been active for >30 seconds shows a `window.confirm("Stop task? The agent has been working for 3m 22s.")` dialog. Shift+click bypasses. Tasks active for <30s stop immediately (likely a misclick recovery, no confirmation needed).
---
## Agent Activity Indicator
Running tasks display a live activity line beneath the task name, showing what the assigned agent is currently doing.
### Anatomy
```
+-------------------------------------------+
| PKCE flow * [RUNNING] [square] |
| blue-fox-7 editing src/auth/pkce.ts |
+-------------------------------------------+
```
- Activity line: `text-[11px] text-muted-foreground font-mono truncate`
- Format: `<agent-name> <verb> <target>` -- e.g., "blue-fox-7 editing src/auth/pkce.ts", "blue-fox-7 reading src/db/schema.ts"
- Sourced from `onAgentOutput` subscription -- latest tool_use event parsed for file path
- When no activity data yet: show `<agent-name> working...` with a subtle pulse
- Activity line is ONLY shown for tasks with `status === 'in_progress'` and an assigned agent
- Elapsed time badge on the right: `3m 22s` in `text-[11px] text-muted-foreground font-mono`, updates every second
### Activity line states
```
blue-fox-7 editing src/auth/pkce.ts 3m 22s <- active tool use
blue-fox-7 thinking... 0m 45s <- between tool uses (italic)
blue-fox-7 working... 0m 02s <- no output yet (pulse animation)
```
### Stale activity fallback
If the `onAgentOutput` subscription has not emitted for a task's agent in >60 seconds, the activity line switches to:
```
blue-fox-7 last seen 2m ago 5m 14s <- stale, text-status-warning-fg
```
This matters because a "stuck" agent looks identical to an actively working one without staleness detection. The `text-status-warning-fg` (amber) color is a soft signal that something might need attention, without being as aggressive as an error state.
---
## Task Overflow in Phase Cards
### Collapsed (default when > 6 tasks)
@@ -137,13 +272,14 @@ Individual task dispatch transitions through three visual states:
| Revocation logic [PENDING] |
| Audit logging [PENDING] |
| Rate limiting [PENDING] |
| + Show 4 more |
| + Show 4 more (all pending) |
+-----------------------------------------+
```
- First 6 tasks always visible
- First 6 tasks always visible, sorted by status priority: running > failed > pending > blocked > done. This ensures the most actionable tasks are always visible without expansion.
- `+ Show N more` is a text button at bottom of card, `text-primary text-xs`
- Count dynamically reflects hidden task count
- **Status summary in overflow indicator**: when hidden tasks include non-done statuses, the overflow button shows a summary: `+ Show 4 more (1 failed, 2 running)`. If all hidden tasks are done: `+ Show 4 more (all completed)`. This prevents a critical failure from hiding behind a collapsed card.
### Expanded (after clicking "Show N more")
@@ -157,6 +293,7 @@ Individual task dispatch transitions through three visual states:
| Revocation logic [PENDING] |
| Audit logging [PENDING] |
| Rate limiting [PENDING] |
| .........................................| <- scrollable area (max-h-[320px])
| Key rotation [PENDING] |
| Token introspection [PENDING] |
| Blacklist service [PENDING] |
@@ -165,8 +302,9 @@ Individual task dispatch transitions through three visual states:
+-----------------------------------------+
```
- All tasks rendered
- `- Show less` collapses back to 6
- Expanded task list has `max-h-[320px] overflow-y-auto` to prevent cards from growing unbounded
- Scroll indicator: subtle gradient fade at bottom edge when more content below (`bg-gradient-to-t from-card`)
- `- Show less` collapses back to 6 and scrolls back to top
- Expansion state is per-phase-card, resets on tab switch
---
@@ -178,9 +316,13 @@ Individual task dispatch transitions through three visual states:
| * Phase 2: OAuth Flow [READY] [play] | StatusDot + name + badge + queue btn
|-----------------------------------------|
| [play] Set up OAuth routes [DONE] | [play] on hover for pending only
| completed by blue-fox-7 2m 14s | completion attribution line
| [play] Implement PKCE flow [RUNNING] | running tasks: Loader2 icon, no play
| blue-fox-7 editing pkce.ts 3m 22s | live agent activity line
| [ .. ] Google provider [BLOCKED] | blocked tasks: Ban icon, no play
| [play] Microsoft provider [PENDING] |
| [retry] Token refresh [FAILED] | failed tasks: retry icon
| Error: timeout after 5m | error summary line
+-----------------------------------------+
```
@@ -189,10 +331,26 @@ Individual task dispatch transitions through three visual states:
- Clicking a task row opens `<TaskModal>` (via `ExecutionContext`)
- Task sort order: `sortByPriorityAndQueueTime()` from shared package
### Failed task retry
- Failed tasks show a `[retry]` button (Lucide `RotateCcw`, `h-3 w-3`) instead of `[play]`
- `[retry]` re-dispatches the task with the **same agent and context** (if the agent is still available), otherwise falls back to normal dispatch
- Error summary line beneath the task name: first line of the error message, `text-[11px] text-status-error-fg truncate`
- Retry calls `trpc.retryTask.useMutation({ taskId })` -- server decides whether to reuse the agent session (resume) or start fresh
### Completed task attribution
- Completed tasks show a subtle attribution line: `text-[11px] text-muted-foreground`
- Format: `completed by <agent-name>` + elapsed time
- Only visible when the phase card is not in overflow (hidden tasks omit attribution)
- **Right-click context menu** on any task row: `Open in TaskModal` / `View Agent Output` / `Copy Task ID`. The context menu is a lightweight escape hatch for power users who want to inspect without the full modal flow.
---
## Connector Arrows
### Phase-level arrows (between columns)
```
+--------+ +--------+
| Phase | ------[>]-----> | Phase |
@@ -205,6 +363,31 @@ Individual task dispatch transitions through three visual states:
- Arrow color: `text-border` (muted, follows theme)
- Multiple phases in same level stack vertically
### Task-level dependency lines (within and across phases)
```
+-------------------+ +-------------------+
| Level 0 | | Level 1 |
| | | |
| * Set up routes |---->| * PKCE flow |
| [DONE] | ,-->| [RUNNING] |
| | | | |
| * DB schema |-' | Provider adaptr |
| [DONE] | | [BLOCKED] |
+-------------------+ +-------------------+
```
- Thin SVG paths (`stroke-width: 1`) connect specific tasks that have dependency relationships
- Lines use the status color of the **upstream** (dependency) task:
- Upstream completed: `text-status-success-dot` (green) -- dependency satisfied
- Upstream in_progress: `text-status-active-dot` (blue) -- dependency in flight
- Upstream pending/blocked: `text-border` (muted) -- dependency not yet started
- On hover over a task, its dependency lines highlight to `text-primary` (indigo) and non-related lines dim to `opacity-20`
- **Default state at scale (>15 dependency lines)**: all lines render at `opacity-10` until a task is hovered. This prevents the spaghetti problem. Below 15 lines, render at `opacity-40` (readable but not overwhelming).
- Lines are drawn as bezier curves to avoid overlapping with cards. Use `d3-shape` or manual SVG path computation.
- **Critical path highlighting**: when at least one task is running, the critical path (longest chain of unsatisfied dependencies leading to the final task) is highlighted with a `stroke-dasharray: 4 2` dashed pattern in `text-primary/50`. This answers the question "what is blocking completion?" at a glance.
- When minimap is visible, dependency lines are also rendered in the minimap (thinner, 0.5px)
---
## Empty State (no tasks to execute)
@@ -238,45 +421,142 @@ Individual task dispatch transitions through three visual states:
```
+=============================================================================+
| Execution |
| Execution ● Done * Active ? Pending ! Error ○ Blocked |
| |
| +---------------------------------------------------------------------+ |
| | | |
| | [check-circle icon] | |
| | All tasks completed | |
| | | |
| | Every task across all phases has been executed. | |
| | 7/7 tasks completed across 3 phases | |
| | Total elapsed: 47 minutes . 4 agents used . 0 retries | |
| | | |
| | [ View in Review Tab ] | |
| | +-------------------------------------------+ | |
| | | Phase 1: Auth Setup 3/3 12m | | |
| | | Phase 2: OAuth Flow 2/2 28m | | |
| | | Phase 3: Token Mgmt 2/2 7m | | |
| | +-------------------------------------------+ | |
| | | |
| | [ View in Review Tab ] [ Re-run All ] | |
| | | |
| +---------------------------------------------------------------------+ |
| |
| ● Done * Active ? Pending ! Error ○ Blocked |
+=============================================================================+
```
- `[check-circle icon]` -- Lucide `CheckCircle2`, 48px, `text-green-500`
- `[check-circle icon]` -- Lucide `CheckCircle2`, 48px, `text-status-success-dot`
- "All tasks completed" -- `text-lg font-medium`
- Summary line: `text-sm text-muted-foreground` -- shows total task count, phase count, retry count
- Elapsed time: computed from first task dispatch to last task completion
- Agent count: distinct agents that worked on tasks in this initiative
- Retry count: total number of task retries across the run. Zero retries = clean run. High retry count signals flaky task definitions or unstable agents.
- Per-phase breakdown: compact table showing phase name, task completion fraction, elapsed time
- `text-xs font-mono`, `bg-muted/50 rounded-md px-3 py-2`
- `[ View in Review Tab ]` -- outline button, navigates to `?tab=review`
- `[ Re-run All ]` -- outline button, resets all tasks to `pending` and navigates to the same execution tab. `window.confirm("Re-run all 7 tasks? This will reset their status.")`. Shift+click bypasses. This is useful when the user has made upstream changes (e.g., updated prompts, changed code) and wants to verify everything still works.
- Shown when: all tasks across all phases have `status === 'completed'`
- Legend row still visible at bottom
### Partial completion (mixed done + failed)
When all tasks have resolved (none pending/running/queued) but some failed:
```
+=============================================================================+
| Execution ● Done * Active ? Pending ! Error ○ Blocked |
| |
| +---------------------------------------------------------------------+ |
| | | |
| | [alert-triangle icon] | |
| | Execution finished with errors | |
| | | |
| | 5/7 tasks completed . 2 failed . 47 minutes . 4 agents | |
| | | |
| | +-------------------------------------------+ | |
| | | Phase 1: Auth Setup 3/3 12m | | |
| | | Phase 2: OAuth Flow 1/2 28m !1 | | |
| | | Phase 3: Token Mgmt 1/2 7m !1 | | |
| | +-------------------------------------------+ | |
| | | |
| | [ Retry 2 Failed ] [ View in Review Tab ] | |
| | | |
| +---------------------------------------------------------------------+ |
| |
+=============================================================================+
```
- `[alert-triangle icon]` -- Lucide `AlertTriangle`, 48px, `text-status-error-dot`
- `!1` in the phase breakdown indicates failed task count per phase
- `[ Retry 2 Failed ]` -- primary button, retries all failed tasks. Confirmation popover lists which tasks will be retried (same pattern as Queue All Pending).
- This state is distinct from "all done" because the user needs to take action. The primary CTA is retry, not review.
---
## Status Legend Row
## Status Legend
Positioned in the header area (not at the bottom) so it is always visible without scrolling to the pipeline terminus.
### Default (expanded)
```
● Done * Active ? Pending ! Error ○ Blocked
+=============================================================================+
| Execution ● Done * Active ? Pending ! Error ○ Blocked [100%] [map] [Queue All..] |
| |
```
- Fixed at bottom of execution view (below pipeline graph)
- Each item: colored dot/symbol + label
- `●` -- `text-green-500` (CheckCircle2)
- `*` -- `text-blue-500` (Loader2, no spin in legend)
- `?` -- `text-muted-foreground` (Clock)
- `!` -- `text-red-500` (AlertTriangle)
- `○` -- `text-red-500/50` (Ban)
- `text-xs text-muted-foreground`, `flex gap-4 justify-center`
- Inline with the "Execution" heading, before the Queue All Pending button
- Each item: colored dot/icon + label, `text-xs text-muted-foreground`, `flex gap-3 items-center`
- `●` -- `text-status-success-dot` (CheckCircle2)
- `*` -- `text-status-active-dot` (Loader2, no spin in legend)
- `?` -- `text-status-neutral-dot` (Clock)
- `!` -- `text-status-error-dot` (AlertTriangle)
- `○` -- `text-status-urgent-dot` (Ban)
- Collapsible: small `[?]` toggle to hide/show the legend. Preference persisted in `localStorage` key `cw-execution-legend`.
- On narrow viewports (<768px), legend collapses to icon-only (no labels) to save horizontal space.
---
## Pipeline Minimap
When the pipeline exceeds the viewport width (typically 5+ dependency levels at `w-64` each), a minimap provides spatial orientation.
### Minimap Toggle
```
Execution ● Done * Active ... [75%] [map] [Queue All Pending]
^^^^^ ^^^^^
zoom toggle minimap visibility
(click to reset 100%)
```
- `[map]` button (Lucide `Map`): `h-4 w-4`, outline variant, toggles minimap panel
- Only rendered when pipeline width exceeds container width
- State persisted in `localStorage` key `cw-execution-minimap`
### Minimap Panel (when visible)
```
+=============================================================================+
| Execution ● Done * Active ? Pending ! Error ○ Blocked [75%] [map] [Queue All] |
| +-----------------------------------------------------------------------+ |
| | [====] [ ] [ ] [ ] [ ] [ ] [ ] | |
| | [====] [ ] [ ] | |
| +-----------------------------------------------------------------------+ |
| ^--- draggable viewport indicator |
| |
| Phase: OAuth Implementation |
| ... |
```
- Minimap: `h-16`, full-width, `bg-muted/30 border-b border-border rounded-sm`
- Phase cards rendered as tiny rectangles, color-coded by aggregate phase status
- All tasks done: `bg-status-success-dot`
- Any task running: `bg-status-active-dot`
- Any task failed: `bg-status-error-dot`
- Otherwise: `bg-border`
- Viewport indicator: semi-transparent `bg-primary/20 border border-primary` rectangle
- Drag the viewport indicator to scroll the pipeline horizontally
- Click anywhere in the minimap to jump to that position
- Minimap also renders task-level dependency lines (0.5px stroke)
---
@@ -297,6 +577,28 @@ Individual task dispatch transitions through three visual states:
---
## Keyboard Shortcuts
| Key | Action |
|-----|--------|
| `q` | Focus "Queue All Pending" button |
| `j` / `k` | Navigate between tasks (down/up) in the focused phase card |
| `h` / `l` | Navigate between dependency levels (left/right) |
| `Enter` | Open TaskModal for focused task |
| `Space` | Context-sensitive: queue (if pending), stop (if running), retry (if failed). The action matches what the visible button would do. |
| `r` | Retry focused failed task (same as `Space` on failed, explicit shortcut for muscle memory) |
| `m` | Toggle minimap |
| `?` | Toggle status legend |
| `+` / `-` | Zoom in / out (10% increments) |
| `0` | Reset zoom to 100% |
| `Escape` | Clear task focus (deselect current task, remove dependency line highlighting) |
- Shortcuts disabled when any input/textarea is focused or a modal is open
- Requires `tabIndex={0}` on the pipeline container to receive keyboard events
- **Focus indicator**: the currently focused task has a `ring-2 ring-primary/50 rounded-md` outline. Without a visible focus indicator, keyboard navigation is unusable -- the user cannot tell which task `Space` or `Enter` will act on.
---
## Source
- `packages/web/src/components/pipeline/PipelineTab.tsx`
@@ -307,3 +609,71 @@ Individual task dispatch transitions through three visual states:
- `packages/web/src/components/execution/ExecutionContext.tsx`
- `packages/web/src/components/execution/TaskModal.tsx`
- `packages/web/src/components/execution/PlanSection.tsx`
- `packages/web/src/components/pipeline/PipelineMinimap.tsx` (proposed)
- `packages/web/src/components/pipeline/TaskDependencyLines.tsx` (proposed)
- `packages/web/src/components/pipeline/AgentActivityLine.tsx` (proposed)
- `packages/web/src/components/pipeline/PipelineZoomControl.tsx` (proposed)
- `packages/web/src/components/pipeline/CompletionSummary.tsx` (proposed)
- `packages/web/src/hooks/usePipelineKeyboard.ts` (proposed — extracts keyboard handling from PipelineTab)
---
## Design Review Notes
Critique of the v2 spec, what works, what was added, and what is still weak.
### What the v2 spec already got right
The v1-to-v2 changelog is strong. The confirmation popover on Queue All Pending, the 3-frame dispatch/stop animations, the minimap, the agent activity indicator, the retry mechanism, the overflow scrolling, the header-positioned legend, the completion summary, and the task-level dependency lines -- these are all real problems that were identified and addressed. The keyboard shortcuts are well-chosen (vim-style hjkl + semantic keys). The spec is implementable as written; it gives concrete Tailwind classes, component names, tRPC mutations, and localStorage keys.
### 1. Pipeline scalability: zoom was missing
The minimap handles horizontal orientation, but a 20-task, 5-level pipeline is still physically too wide to comprehend at 100% zoom. You can scroll and you can see the minimap, but you cannot get a gestalt view of the whole pipeline. Added zoom control (50%-150%, Cmd+scroll or +/- keys) so the user can zoom out for the big picture and zoom in for task details. This is standard for any node-graph editor (Figma, Miro, n8n). Without zoom, the minimap is doing double duty as both orientation and overview, and it is too small (h-16) to serve as a real overview.
Also added: vertical overflow handling. The spec addressed horizontal overflow but said nothing about the vertical axis. With 4+ phases stacking vertically, the header (legend, Queue All Pending, minimap toggle) scrolls out of view. Fixed with a sticky header row.
### 2. Queue All Pending: agent availability blind spot
The confirmation popover is good, but it is missing a critical piece of information: how many agents are available to actually run the queued tasks. If you queue 8 tasks but only have 3 agents, 5 tasks sit in the queue doing nothing. The user might think something is broken. Added an agent availability warning line in the popover that shows the mismatch. This is not a blocking concern (tasks will wait in queue as expected) but it is a situational awareness gap.
### 3. Stop animation: what happens next?
The 3-frame stop animation was well-specified but the spec ended at `[STOPPED]` and said "No [play] or [square] buttons rendered until status resolves to a re-queueable state." That is vague. Re-queueable state is... what? When? Added explicit behavior: after 1s settle, `[play]` reappears on hover because a stopped task IS re-queueable immediately.
Also added stop confirmation for long-running tasks (>30s). Stopping a task that has been churning for 5 minutes is a significant action -- the agent has accumulated context and work product. A misclick here wastes real money. The Shift+click bypass keeps the power-user path fast.
### 4. Overflow "Show N more": hidden failures
The `+ Show 4 more` indicator tells you there are more tasks, but it does not tell you whether any of those hidden tasks are on fire. If 2 of the hidden tasks have failed, the user has no idea unless they expand. Added status summary in the overflow indicator: `+ Show 4 more (1 failed, 2 running)`. This is the difference between "collapsed for convenience" and "collapsed and hiding problems."
Also added sort-by-status-priority so that running and failed tasks bubble to the top of the visible 6. Without this, a freshly failed task could be task #8 and invisible.
### 5. Agent activity: stale detection missing
The activity indicator shows what the agent is doing RIGHT NOW. But what if the agent stopped emitting output 3 minutes ago? The activity line still shows the last action as if it is current. Added a staleness fallback: if no output in >60s, the line switches to `"blue-fox-7 last seen 2m ago"` with warning-colored text. This is the difference between "agent is editing a file" and "agent SAID it was editing a file 3 minutes ago and has gone silent."
### 6. Completion state: no partial failure handling
The spec had an "all done" state but no "mostly done with some failures" state. In practice, getting 7/7 clean completions on the first run is the exception, not the norm. Added a distinct partial-completion wireframe with `AlertTriangle`, failed task count per phase, and a `[ Retry 2 Failed ]` primary CTA. Without this, the user sees... what? The pipeline in its normal state with some green and some red cards, no summary, no batch retry. That is not a completion state, that is just the default state with different colors.
Also added retry count to the clean completion summary and a `[ Re-run All ]` button for re-executing after upstream changes.
### 7. Dependency lines: spaghetti at scale
The spec says "On hover, dependency lines highlight and non-related lines dim to opacity-20." Good for hover state. But what is the DEFAULT state when nobody is hovering? With 20+ tasks and 30+ dependency lines, the default is visual noise. Added a scale-aware default: >15 lines renders at opacity-10 (almost invisible until hover), <15 lines at opacity-40 (readable). Also added critical path highlighting -- a dashed indigo line showing the longest unsatisfied dependency chain. This is the single most important piece of information in the entire pipeline: "what is blocking completion?"
### 8. Keyboard navigation: invisible focus
The keyboard shortcuts assume the user can tell which task is focused. The spec never defined a focus indicator. Added `ring-2 ring-primary/50` on the focused task. Without this, pressing `Space` is a gamble -- the user does not know what they are about to queue or stop. Also added `Escape` to clear focus and zoom shortcuts (`+`/`-`/`0`).
### 9. Task context actions
The spec requires opening a TaskModal for any task inspection. Added a right-click context menu as a lightweight alternative: `Open in TaskModal` / `View Agent Output` / `Copy Task ID`. Power users managing 10+ tasks do not want to open a modal for every inspection.
### Still weak / deferred
- **Cost tracking**: The system burns real API credits. The completion summary shows elapsed time and agent count but NOT cost. This is because cost data is not currently available in the data model (no token/cost tracking per task). When cost tracking is added to the agent output system, the completion summary should show `$X.XX total cost` and per-phase cost breakdown. Flag this for the next iteration.
- **Multi-agent per task**: The spec assumes 1 agent per task. Decomposed parent tasks can have multiple child tasks each with their own agent, but the parent task card does not show aggregate child status. This is partially handled by the task hierarchy (children are separate rows), but a parent task with 8 children is going to blow out the phase card. Consider a collapsible sub-tree within the phase card for decomposed tasks.
- **Pipeline diff**: When the pipeline changes mid-execution (e.g., a plan agent adds new phases), the user has no notification. The pipeline just quietly grows. Consider a toast or activity feed event: "Pipeline updated: 2 new phases added by plan-fox-3."
- **Error categorization**: All failures look the same. A timeout failure, an API rate limit, and a code compilation error are fundamentally different problems with different remediation paths. The error summary line shows the first line of the error, but richer error categorization (with suggested actions) would make the retry decision easier.
- **Accessibility**: The dependency lines are pure SVG with color-coded status. Color-blind users cannot distinguish green (satisfied) from red (failed) lines. Add pattern differentiation (solid = satisfied, dashed = in-flight, dotted = waiting) in addition to color. The existing `stroke-dasharray` on critical path is a start; extend it to all dependency line states.