Files
Codewalkers/docs/wireframes/v2/initiative-detail.md
Lukas May 1e374abcd6 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)
2026-03-02 19:36:26 +09:00

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.