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)
533 lines
22 KiB
Markdown
533 lines
22 KiB
Markdown
# Initiative Detail (v2)
|
|
|
|
### Route: `/initiatives/$id`
|
|
### Source: `packages/web/src/routes/initiatives/$id.tsx`
|
|
|
|
---
|
|
|
|
## v1 -> v2 Changes
|
|
|
|
| Aspect | v1 | v2 |
|
|
|--------|----|----|
|
|
| Header layout | Single row: back + name + all badges | Two rows: Row 1 = back + name + actions menu, Row 2 = badges |
|
|
| Initiative name | Static text | Editable on hover (pencil icon -> inline input) |
|
|
| Actions menu | Only on cards in list view (`[...]`) | `[...]` menu on Row 1: Discuss, Plan, Refine, Change Mode, Archive, Delete |
|
|
| Tab badges | None | Content `(5)`, Plan `(3)`, Execution `3/7`, Review `(2)` with yellow tint |
|
|
| Keyboard hints | None | Tooltip on tab hover + CommandPalette entries + first-visit hint |
|
|
| Activity feed | None | Collapsible ticker at bottom of tab content area |
|
|
| Tab transition | None specified | Explicitly instant (no animation) |
|
|
| Tab internal headers | Inconsistent | Consistent left=context, right=action pattern documented |
|
|
| Not found state | Same as generic error | Distinct 404 message: "Initiative not found" |
|
|
| Branch editing | Inline edit on click | Unchanged (still inline) |
|
|
| Project editing | Popover checklist | Unchanged (still popover) |
|
|
|
|
---
|
|
|
|
## Default State
|
|
|
|
```
|
|
+=============================================================================+
|
|
| [CW] [*Initiatives*] Agents *3 Inbox (2) Settings [cmd-k] [sun] * |
|
|
+=============================================================================+
|
|
| |
|
|
| [<] Auth System Overhaul [...] |
|
|
| [ACTIVE] [REVIEW] [git] cw/auth-overhaul [P] backend, frontend |
|
|
| |
|
|
| Content (5) Plan (3) Execution 3/7 Review (2) |
|
|
| ----------------------------------------------------------------------- |
|
|
| |
|
|
| |
|
|
| < tab content area > |
|
|
| |
|
|
| |
|
|
| |
|
|
+=============================================================================+
|
|
```
|
|
|
|
---
|
|
|
|
## Two-Row Header Anatomy
|
|
|
|
```
|
|
Row 1: [<] Initiative Name [pencil-on-hover] [...]
|
|
Row 2: [STATUS] [MODE] [git] branch [P] project1, project2
|
|
```
|
|
|
|
### Row 1
|
|
- `[<]` — Back chevron, navigates to `/initiatives`
|
|
- Initiative name — `text-2xl font-bold`. **Not** inline-editable by default.
|
|
On hover, a pencil icon (`Pencil`, 14px, `text-muted-foreground`) appears
|
|
to the right of the name. Clicking it replaces the `<h1>` with an `<Input>`
|
|
(same `text-2xl font-bold` styling). Enter saves, Escape cancels. Uses
|
|
`updateInitiative` mutation. This keeps the title line clean 99% of the time
|
|
while making rename discoverable.
|
|
- `[...]` — Actions menu, right-aligned on Row 1 (see **Initiative Actions Menu** below)
|
|
- Row 1 has no badges — clean title line + actions menu
|
|
|
|
### Row 2
|
|
- Indented to align under the initiative name (not under the back chevron)
|
|
- `[STATUS]` — StatusBadge: `[ACTIVE]` green, `[DONE]` grey, `[ARCHIVED]` dim
|
|
- `[MODE]` — ExecutionMode: `[YOLO]` amber (clickable toggle), `[REVIEW]` blue (clickable toggle)
|
|
- `[git] cw/<branch>` — GitBranch icon + branch name. Hidden if no branch yet.
|
|
- `[P] project1, project2` — Folder icon + project names. Hidden if none linked.
|
|
|
|
### No Branch Yet
|
|
|
|
```
|
|
[<] Mobile App Redesign
|
|
[ACTIVE] [REVIEW] [P] frontend
|
|
```
|
|
|
|
Branch badge simply absent. No placeholder or "add branch" button —
|
|
branch is auto-generated on first execution task dispatch.
|
|
|
|
### No Projects Yet
|
|
|
|
```
|
|
[<] Scratch Initiative
|
|
[ACTIVE] [YOLO] [git] cw/scratch [+ Add projects]
|
|
```
|
|
|
|
`[+ Add projects]` link opens project picker popover.
|
|
|
|
### Name Editing (click pencil on hover)
|
|
|
|
```
|
|
[<] [Auth System Overhaul___________________] [v] [x] [...]
|
|
[ACTIVE] [REVIEW] [git] cw/auth-overhaul [P] backend, frontend
|
|
```
|
|
|
|
Inline text input replaces the `<h1>`. Same `text-2xl font-bold` sizing.
|
|
`[v]` saves via `updateInitiative({ id, name })`, `[x]` cancels.
|
|
Enter also saves, Escape also cancels.
|
|
|
|
### Branch Editing (click branch badge)
|
|
|
|
```
|
|
[<] Auth System Overhaul
|
|
[ACTIVE] [REVIEW] [git] [cw/auth-overhaul______] [v] [x] [P] backend
|
|
```
|
|
|
|
Inline text input replaces branch badge. `[v]` saves, `[x]` cancels.
|
|
|
|
### Project Editing (click pencil icon on project badges)
|
|
|
|
```
|
|
[<] Auth System Overhaul
|
|
[ACTIVE] [REVIEW] [git] cw/auth-overhaul
|
|
+----------------------------------+
|
|
| [x] backend github.com/... |
|
|
| [ ] frontend github.com/... |
|
|
| [ ] shared github.com/... |
|
|
| + Register new project |
|
|
+----------------------------------+
|
|
[ Save ] [ Cancel ]
|
|
```
|
|
|
|
---
|
|
|
|
## Tab Bar
|
|
|
|
```
|
|
Content (5) Plan (3) Execution 3/7 Review (2)
|
|
-----------------------------------------------------------------------
|
|
^^^^^^^^^^^^^^^^^^
|
|
active tab (border-b-2 border-primary)
|
|
```
|
|
|
|
### Tab badge rendering
|
|
|
|
All non-progress badges use a consistent `(N)` format. Execution is
|
|
the exception because it communicates a ratio (done/total), not a count.
|
|
|
|
| Tab | Badge | Format | When |
|
|
|-----|-------|--------|------|
|
|
| Content | `(5)` | Page count | Hidden if 0 pages (only root page exists and is empty) |
|
|
| Plan | `(3)` | Phase count | Hidden if 0 phases |
|
|
| Execution | `3/7` | Completed/total tasks (fraction) | Hidden if 0 total tasks |
|
|
| Review | `(2)` | Pending proposal count, yellow tint | Hidden if 0 pending |
|
|
|
|
**Why the fraction for Execution?** It is a progress indicator, not a simple
|
|
count. `3/7` tells you "3 done out of 7" at a glance — a count `(7)` would
|
|
not convey progress. The other tabs show cardinality, not progress, so `(N)`
|
|
is the right format for them.
|
|
|
|
### Active tab indicator
|
|
- `border-b-2 border-primary` underline on active tab
|
|
- `font-medium text-foreground` for active tab text
|
|
- `text-muted-foreground` for inactive tab text
|
|
|
|
### Tab with zero badges
|
|
|
|
```
|
|
Content Plan Execution Review
|
|
-----------------------------------------------------------------------
|
|
```
|
|
|
|
When all counts are zero, all badges are hidden. No `(0)` or `0/0`.
|
|
Each badge appears independently as its count becomes non-zero.
|
|
|
|
### Hover state with keyboard hint (tooltip)
|
|
|
|
```
|
|
Content Plan Execution 3/7 Review (2)
|
|
-----------------------------------------------------------------------
|
|
^
|
|
+-------------+
|
|
| 3 Execution |
|
|
+-------------+
|
|
```
|
|
|
|
Tooltip shows the keyboard shortcut number + tab name.
|
|
Pressing `1`/`2`/`3`/`4` switches tabs when no input is focused.
|
|
|
|
Keyboard shortcuts:
|
|
- `1` — Content
|
|
- `2` — Plan
|
|
- `3` — Execution
|
|
- `4` — Review
|
|
|
|
### Keyboard shortcut discoverability
|
|
|
|
Tooltips are hover-only — users who never hover will never find them.
|
|
Two additional discoverability mechanisms:
|
|
|
|
1. **CommandPalette integration**: When the user opens Cmd+K and types
|
|
"content", "plan", "execution", or "review", results include entries
|
|
like `Go to Content tab [1]` with the shortcut shown as a right-aligned
|
|
`<kbd>` badge. These appear in a "Navigation" group.
|
|
|
|
2. **First-visit hint** (one-time): On the first render of the initiative
|
|
detail page (tracked via `localStorage` key `cw-tab-hints-shown`), a
|
|
subtle muted-foreground line below the tab bar reads:
|
|
`Tip: press 1-4 to switch tabs`. Auto-dismisses after 5s or on any
|
|
tab switch. Never shown again.
|
|
|
|
---
|
|
|
|
## Initiative Actions Menu
|
|
|
|
Row 1's `[...]` button opens a `<DropdownMenu>` anchored to the right.
|
|
This mirrors the `[...]` menu on initiative cards in the list view but
|
|
adds initiative-level actions relevant in the detail context.
|
|
|
|
```
|
|
[...]
|
|
+------------------+
|
|
| Discuss |
|
|
| Plan |
|
|
| Refine |
|
|
| ────────────── |
|
|
| Change Mode | → submenu: YOLO / Review
|
|
| ────────────── |
|
|
| Archive |
|
|
| Delete | ← destructive, red text
|
|
+------------------+
|
|
```
|
|
|
|
### Actions
|
|
|
|
| Action | Behavior |
|
|
|--------|----------|
|
|
| Discuss | Spawns a `discuss` agent for this initiative |
|
|
| Plan | Spawns a `plan` agent to generate phases |
|
|
| Refine | Spawns a `refine` agent on content pages |
|
|
| Change Mode | Submenu: `YOLO` / `Review`. Calls `updateInitiativeConfig`. Active mode has a checkmark. |
|
|
| Archive | Sets status to `archived`. `window.confirm()` dialog; Shift+click bypasses. |
|
|
| Delete | Calls `deleteInitiative`. `window.confirm("Delete permanently?")`; Shift+click bypasses. Navigates to `/initiatives` on success. |
|
|
|
|
The "Change Mode" action duplicates the `[MODE]` badge toggle in Row 2.
|
|
That is intentional — the badge is for quick toggle, the menu is for
|
|
discoverability and for users who do not realize the badge is clickable.
|
|
|
|
---
|
|
|
|
## Activity Feed
|
|
|
|
A collapsible activity ticker at the bottom of the tab content area,
|
|
showing the most recent cross-cutting events for this initiative. Think
|
|
"mission control status bar" — always visible, never overwhelming.
|
|
|
|
### Collapsed (default)
|
|
|
|
```
|
|
-----------------------------------------------------------------------
|
|
[^] blue-fox-7 completed "Implement PKCE flow" . 2m ago [View All]
|
|
```
|
|
|
|
Single-line ticker showing the most recent event. `[^]` expands the feed.
|
|
`[View All]` opens a full activity log (future page, not in v2 scope — link
|
|
is a no-op stub that shows a toast "Activity log coming soon").
|
|
|
|
### Expanded (click `[^]`)
|
|
|
|
```
|
|
-----------------------------------------------------------------------
|
|
[v] Activity [View All]
|
|
-----------------------------------------------------------------------
|
|
. 2m ago blue-fox-7 completed "Implement PKCE flow" [EXECUTION]
|
|
. 5m ago Proposal submitted: "Add rate limiting" [REVIEW]
|
|
. 8m ago green-fox-3 started "Google provider" [EXECUTION]
|
|
. 12m ago Phase "OAuth Flow" marked ready [PLAN]
|
|
. 15m ago Page "Architecture" updated [CONTENT]
|
|
-----------------------------------------------------------------------
|
|
```
|
|
|
|
- Max 10 items visible, scrollable if more
|
|
- Each item has: relative timestamp, description, tab context badge
|
|
- Tab context badge links to the relevant tab (clicking `[EXECUTION]` switches to Execution tab)
|
|
- `[v]` collapses back to single line
|
|
- Feed populated from EventBus events filtered by `initiativeId`
|
|
- Persists expanded/collapsed state in `localStorage` key `cw-activity-feed-${initiativeId}`
|
|
|
|
### Event Types Shown
|
|
|
|
| Event | Display |
|
|
|-------|---------|
|
|
| `task:completed` | `{agent} completed "{task}"` |
|
|
| `task:failed` | `{agent} failed on "{task}"` — error tint |
|
|
| `task:dispatched` | `"{task}" dispatched to {agent}` |
|
|
| `agent:spawned` | `{agent} started "{task}"` |
|
|
| `agent:completed` | `{agent} finished` |
|
|
| `agent:crashed` | `{agent} crashed` — error tint |
|
|
| `proposal:created` | `Proposal submitted: "{title}"` |
|
|
| `proposal:accepted` | `Proposal accepted: "{title}"` |
|
|
| `phase:status_changed` | `Phase "{phase}" marked {status}` |
|
|
| `page:updated` | `Page "{page}" updated` |
|
|
|
|
---
|
|
|
|
## Tab Transition Behavior
|
|
|
|
Tab switches are **instant with no transition animation**. Rationale:
|
|
|
|
- Mission control aesthetic prizes immediacy over polish
|
|
- Content in each tab can be tall and complex — crossfade or slide
|
|
animations on heterogeneous heights look janky
|
|
- The `border-b-2 border-primary` underline provides sufficient
|
|
visual feedback for which tab is active
|
|
- Keyboard shortcut `1-4` switching should feel instantaneous
|
|
|
|
The only animation is the tab underline itself, which uses
|
|
`transition-colors duration-150` (already specified in active tab styling).
|
|
No `opacity`, `transform`, or `height` transitions on tab content.
|
|
|
|
---
|
|
|
|
## Tab Content Internal Header Pattern
|
|
|
|
Each tab has its own internal header area, but they should follow a
|
|
consistent layout to avoid visual jarring when switching tabs.
|
|
|
|
```
|
|
Tab Name / Context [Primary Action]
|
|
-----------------------------------------------------------------------
|
|
< tab-specific content >
|
|
```
|
|
|
|
### Per-tab headers
|
|
|
|
| Tab | Left side | Right side |
|
|
|-----|-----------|------------|
|
|
| Content | `Pages [+]` (sidebar header) | `[breadcrumb] [SaveIndicator]` (editor header) |
|
|
| Plan | `Phases [+]` (sidebar header) | `[SaveIndicator]` (phase editor) |
|
|
| Execution | `Execution` (section title) | `[Queue All Pending]` |
|
|
| Review | `Diff: <filepath> N unresolved` | `Threads [v]` (sidebar header) |
|
|
|
|
The pattern is: **left = context/navigation, right = primary action**.
|
|
Tab-specific wireframes (content-tab.md, plan-tab.md, etc.) define the
|
|
full detail. This section documents the cross-tab consistency expectation.
|
|
|
|
---
|
|
|
|
## Not Found State (404)
|
|
|
|
When `getInitiative` returns a NOT_FOUND error (initiative was deleted
|
|
or ID is bogus), show a distinct 404-flavored error instead of the
|
|
generic error state.
|
|
|
|
```
|
|
+=============================================================================+
|
|
| |
|
|
| [<] |
|
|
| |
|
|
| [AlertCircle] |
|
|
| Initiative not found |
|
|
| This initiative may have been deleted. |
|
|
| |
|
|
| [ Back to Initiatives ] |
|
|
| |
|
|
+=============================================================================+
|
|
```
|
|
|
|
Detection: check if `error.message` includes "not found" (already done
|
|
in existing code). The heading changes from "Error loading initiative"
|
|
to "Initiative not found" and the description changes accordingly.
|
|
|
|
---
|
|
|
|
## Loading State
|
|
|
|
```
|
|
+=============================================================================+
|
|
| |
|
|
| [<] ░░░░░░░░░░░░░░░░░░░░░ |
|
|
| ░░░░░░░ ░░░░░░░ ░░░░░░░░░░░░░░░ ░░░░░░░░░░░░ |
|
|
| |
|
|
| ░░░░░░░ ░░░░░ ░░░░░░░░░░ ░░░░░░░ |
|
|
| ----------------------------------------------------------------------- |
|
|
| +-------------------------------------------------------------------+ |
|
|
| | ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ | |
|
|
| | ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ | |
|
|
| | ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ | |
|
|
| +-------------------------------------------------------------------+ |
|
|
| |
|
|
+=============================================================================+
|
|
```
|
|
|
|
Skeleton matches two-row header + tab bar + content area.
|
|
|
|
---
|
|
|
|
## Error State
|
|
|
|
```
|
|
+=============================================================================+
|
|
| |
|
|
| [<] |
|
|
| |
|
|
| [AlertCircle] |
|
|
| Error loading initiative |
|
|
| Could not fetch initiative data. |
|
|
| |
|
|
| [ Back to Initiatives ] |
|
|
| |
|
|
+=============================================================================+
|
|
```
|
|
|
|
Back chevron still functional. Error body uses `<ErrorState>` component
|
|
(see shared-components.md) but with navigation button instead of retry.
|
|
|
|
---
|
|
|
|
## Source
|
|
|
|
- `packages/web/src/routes/initiatives/$id.tsx`
|
|
- `packages/web/src/components/InitiativeHeader.tsx`
|
|
- `packages/web/src/components/InitiativeTabBar.tsx` (proposed)
|
|
- `packages/web/src/components/InitiativeActionsMenu.tsx` (proposed)
|
|
- `packages/web/src/components/ActivityFeed.tsx` (proposed)
|
|
|
|
---
|
|
|
|
## Design Review Notes
|
|
|
|
Findings from a design review of this wireframe against the mission control
|
|
aesthetic, implementation reality, and cross-wireframe consistency.
|
|
|
|
### 1. Inline-editable initiative name (ADDED)
|
|
|
|
The original spec showed the name as static `text-2xl font-bold` with no
|
|
edit affordance. This is a problem: the only way to rename an initiative was
|
|
via `updateInitiative` in the tRPC layer with no UI surface. Added a
|
|
hover-to-reveal pencil icon pattern. The pencil only appears on hover so
|
|
the title line stays clean. This matches the pattern used for branch editing
|
|
(click to activate inline input, Enter/Escape to save/cancel).
|
|
|
|
**Decision**: Not always-editable (clicking directly on text). That would
|
|
create accidental edit activations and conflicts with text selection. The
|
|
pencil-on-hover is the right middle ground.
|
|
|
|
### 2. Tab badge consistency (FIXED)
|
|
|
|
Original spec had `Execution 3/7` (fraction, no parens) and `Review (2)`
|
|
(count in parens). Content and Plan had no badges at all. This was
|
|
inconsistent in two ways: mixed formats, and missing information.
|
|
|
|
**Fix**: All count badges use `(N)` format. Execution keeps the fraction
|
|
format `3/7` because it communicates progress, not cardinality. Content
|
|
and Plan now show `(N)` for page count and phase count respectively.
|
|
Rationale documented inline.
|
|
|
|
### 3. Keyboard shortcut discoverability (ADDED)
|
|
|
|
The original spec relied entirely on tooltip-on-hover for `1-4` shortcuts.
|
|
Tooltips are invisible to keyboard-only users and to anyone who does not
|
|
happen to hover over a tab. Two mechanisms added:
|
|
|
|
- CommandPalette results surface tab shortcuts with `<kbd>` badges
|
|
- One-time first-visit hint below the tab bar
|
|
|
|
The first-visit hint is the more impactful one. It teaches the pattern
|
|
once without being permanently noisy.
|
|
|
|
### 4. Initiative actions menu (ADDED)
|
|
|
|
This was a genuine gap. The list view had `[...]` menus with Discuss, Plan,
|
|
Archive, Delete. The detail view had none of these. A user navigating into
|
|
an initiative had no way to archive, delete, or spawn agents without going
|
|
back to the list.
|
|
|
|
The `[...]` menu is right-aligned on Row 1. It duplicates the mode toggle
|
|
intentionally (badge = fast toggle, menu = discoverable).
|
|
|
|
**Concern raised and resolved**: "Change Mode" in the menu is redundant
|
|
with the clickable `[MODE]` badge. Kept both because badge clickability
|
|
is not obvious (it looks like a status indicator, not a button).
|
|
|
|
### 5. Activity feed (ADDED)
|
|
|
|
The original spec had no cross-tab awareness. If you were on the Content
|
|
tab, you had zero visibility into agent completions, task failures, or
|
|
proposal submissions happening on other tabs. For a mission control tool
|
|
managing 10+ agents, this is a critical gap.
|
|
|
|
The activity feed is a collapsible ticker at the bottom. Collapsed by
|
|
default (single line) so it does not steal vertical space. Each event
|
|
includes a tab context badge that doubles as a navigation shortcut.
|
|
|
|
**Scope note**: The `[View All]` link is a stub in v2. A full activity
|
|
log page is deferred. The ticker covers the 80% case.
|
|
|
|
### 6. Tab transition (DOCUMENTED)
|
|
|
|
Original spec was silent on this. Explicitly documented as instant (no
|
|
animation) with rationale. This is a deliberate choice, not an oversight
|
|
to be "fixed later" with a fade-in.
|
|
|
|
### 7. Tab content internal header pattern (DOCUMENTED)
|
|
|
|
Each tab wireframe defines its own layout, but there was no cross-tab
|
|
consistency expectation documented. Added a section specifying the
|
|
`left=context, right=action` pattern that all four tabs already follow
|
|
in practice. This is documentation of an emergent pattern, not a new
|
|
requirement.
|
|
|
|
### 8. Not Found vs generic Error state (SPLIT)
|
|
|
|
The original spec had one Error State wireframe for all errors. But the
|
|
existing code already differentiates "not found" from other errors (line 70
|
|
of `$id.tsx`). Added a distinct Not Found wireframe with a more specific
|
|
message. This is already partially implemented; the wireframe now matches.
|
|
|
|
### 9. Minor fix: Source path corrected
|
|
|
|
The header listed `$initiativeId.tsx` but the actual file is `$id.tsx`.
|
|
Fixed.
|
|
|
|
### Open questions for implementation
|
|
|
|
- **Activity feed event source**: The feed needs a tRPC subscription or
|
|
SSE stream filtered by `initiativeId`. The existing `useLiveUpdates`
|
|
hook invalidates queries but does not expose raw events. A new
|
|
`onInitiativeActivity` subscription may be needed.
|
|
|
|
- **Tab badge data loading**: Content `(N)` requires a `listPages` count,
|
|
Plan `(N)` requires a `listPhases` count. These queries already run on
|
|
their respective tabs but would need to be hoisted to the tab bar level
|
|
(or the tab bar reads from the query cache). Ensure no waterfall.
|
|
|
|
- **Activity feed performance**: Storing events in memory (not DB) is fine
|
|
for the ticker (last 50 events). But if `[View All]` eventually becomes
|
|
a real page, a persistent activity log table will be needed.
|