# Plan Tab (v2)

### Route: `/initiatives/$id` (Plan tab)
### Source: `packages/web/src/components/ExecutionTab.tsx`, `packages/web/src/components/execution/`

---

## v1 -> v2 Changes

| Aspect | v1 | v2 |
|--------|----|----|
| Save indicator | None on phase description editor | `<SaveIndicator>` component (same as Content tab) |
| Empty state (no agent) | Single "No phases yet" with both spinner and buttons shown contextually | Split: dedicated "No phases yet" empty state with action buttons |
| Empty state (agent running) | Spinner + "Planning phases..." inline with buttons | Dedicated "Planning in progress..." state, NO action buttons |
| Empty state (agent failed) | None -- user had no signal | Dedicated "Planning failed" state with error message + retry button |
| Pending review | Banner only on individual phase detail | Additional top-level banner when proposals exist initiative-wide |
| Sidebar width | 260px (inconsistent with Content tab's 192px) | 240px (matches Content tab v2 -- consistent divider line across tabs) |
| Phase reordering | None | Drag-and-drop via `[≡]` toggle in sidebar header |
| Task tree | Flat list | Nested tree showing parent-child decomposition + dependency indicators |
| Task inline editing | None | Click task name to inline-edit; own `<SaveIndicator>` per row |
| Keyboard shortcuts | None | `N` to add task (when task list focused), `E` to edit selected task |
| Bulk task operations | None | `[...]` menu on Tasks header with bulk actions |

---

## Default State (phases exist, one selected)

```
+=============================================================================+
|  Phases    [Detailing] [≡] [+] |  Phase: OAuth Implementation                |
|  --------------------------+                                  [✓] Saved     |
|  +------------------------+|  ------------------------------------------------|
|  | 1. Auth Setup          ||  Description:                                  |
|  | [DONE]  3/3 tasks      ||  Implement OAuth 2.0 authorization code flow   |
|  +------------------------+|  with PKCE extension for public clients.       |
|  +------------------------+|                                                |
|  |*2. OAuth Flow         *||  Support Google, GitHub, and Microsoft as      |
|  | [READY]  0 tasks       ||  identity providers with configurable scopes.  |
|  | dep: 1                 ||                                                |
|  +------------------------+|  Dependencies                                  |
|  +------------------------+|  [+ Add dependency v]                          |
|  | 3. UI Components       ||  * Phase 1: Auth Setup [DONE]        [x]      |
|  | [PENDING]  2/5 tasks   ||                                                |
|  | dep: 1, 2              ||  Tasks (2/5)              [...] [N] [+ Add Task]|
|  +------------------------+|  ├── Set up OAuth routes       * [DONE]        |
|                             |  ├── Implement PKCE flow       * [RUNNING]     |
|                             |  │   └─ agent: blue-fox-7                      |
|                             |  │   └─ child: Validate scopes  [PENDING]      |
|                             |  ├── Google provider           [PENDING]  [x]  |
|                             |  │   ← blocked by: Implement PKCE flow         |
|                             |  ├── GitHub provider           [BLOCKED]  [x]  |
|                             |  │   ← blocked by: Google provider             |
|                             |  └── Microsoft provider        [PENDING]  [x]  |
|                             |                                                |
|        240px                |          detail panel (flex-1)                  |
|                             |                                                |
+=============================================================================+
```

- Phase sidebar: **240px**, `border-right` (see Design Review Notes on sidebar width rationale)
- Selected phase: left blue border + `bg-accent` background
- `[+]` in header triggers `handleStartAdd` (inline input at bottom of list)
- `[≡]` in header toggles drag-and-drop reorder mode (via `@dnd-kit/sortable`)
- `[✓] Saved` shows after phase description auto-save completes
- Task `[x]` delete buttons appear on hover; Shift+click bypasses confirm dialog
- Task tree shows parent-child nesting via indented `└─ child:` rows under parent tasks
- Dependency arrows (`← blocked by: <task-name>`) shown inline below blocked tasks
- `[N]` keyboard hint badge next to "Add Task" -- pressing `N` when task list is focused triggers inline task creation
- `[...]` on Tasks header row opens bulk actions menu (see Bulk Task Operations section)

---

## Phase Sidebar Cards

```
+------------------------+
| 1. Auth Setup          |    Phase number + name (truncated)
| [DONE]  3/3 tasks      |    StatusBadge (small) + "complete/total tasks"
+------------------------+
+------------------------+
|*2. OAuth Flow         *|    * = selected (border-l-2 border-primary bg-accent)
| [READY]  0 tasks       |    "0 tasks" when no tasks decomposed yet
| dep: 1                 |    dependency indicator
+------------------------+
+------------------------+
| 3. UI Components       |
| [PENDING]  2/5 tasks   |    progress fraction: completed/total
| dep: 1, 2              |    multiple dependency shorthand
+------------------------+
```

- Sidebar cards always show task progress as `N/M tasks` (not just total count)
- `N/M` uses `text-muted-foreground`; turns `text-status-success-fg` when N === M (all done)
- In reorder mode (`[≡]` active), each card gets a drag handle icon on the left
- Sidebar is `overflow-y-auto` with `scrollbar-thin` (webkit custom scrollbar, 4px wide)
- When > 8 phases, a subtle gradient fade at bottom edge signals scrollable content
- Selected phase auto-scrolls into view on selection change (`scrollIntoView({ block: 'nearest' })`)

---

## Phase Actions (sidebar header)

```
  Phases  [Detailing (2)]  [≡]  [+]  [Detail All]
           ^^^^^^^^^^^^^^   ^^^        ^^^^^^^^^^^
           spinner + count  drag       sparkles icon
           when detail      handle     disabled when no
           agents active    toggle     eligible phases
```

- `[Detailing (N)]` spinner badge shows when N detail agents are running
- `[Detail All]` spawns detail agents for all phases with 0 tasks
- `[+]` opens inline input for new phase name
- `[≡]` toggles reorder mode -- when active, cards become draggable, `bg-muted` highlight on sidebar

---

## Save Indicator on Phase Description

Same `<SaveIndicator>` component as Content tab, positioned top-right of phase detail header.

### Saving

```
  Phase: OAuth Implementation                         [spinner] Saving...
```

### Saved

```
  Phase: OAuth Implementation                              [✓] Saved
```

### Failed

```
  Phase: OAuth Implementation                         [!] Failed  [retry]
```

---

## Task Inline Editing

Tasks support inline name editing. Click a task name to toggle into an input field with its own save state.

### Viewing (default)

```
  ├── Set up OAuth routes       * [DONE]
```

### Editing (after click on name)

```
  ├── [Set up OAuth routes_______] [✓]  * [DONE]
```

- Input field replaces the text span; `Enter` or blur saves, `Escape` cancels
- `[✓]` micro-indicator shows save state (same `<SaveIndicator>` logic, icon-only, no text via `compact` prop)
- `E` keyboard shortcut opens edit mode on the currently focused/selected task row
- `Tab` while editing moves to the next task row in edit mode (rapid-fire renaming workflow)
- Changes call `trpc.updateTask.useMutation({ taskId, name })` with 300ms debounce (not on-blur-only; type-and-go feel)
- Only one task can be in edit mode at a time -- clicking another task's name exits the current edit (triggering save)
- Running tasks (`status === 'running'`) have their name input disabled with `cursor-not-allowed` -- you cannot rename a task while an agent is working on it

---

## Task Tree Structure (parent-child + dependencies)

The plan tab is the primary place users understand task structure. The task tree communicates two relationships:

### 1. Parent-child decomposition (vertical nesting)

```
  ├── Implement PKCE flow       * [RUNNING]
  │   └─ agent: blue-fox-7
  │   └─ child: Validate scopes    [PENDING]
  │   └─ child: Generate challenge [PENDING]
```

- Child tasks are indented one level under their parent (`parentTaskId`)
- `child:` prefix in `text-muted-foreground` distinguishes decomposition from agent info
- Children inherit phase context from parent; can be expanded/collapsed per parent
- Collapse state: parent rows show `[>]` / `[v]` chevron. Default: expanded if < 4 children, collapsed if >= 4
- Max nesting depth: 3 levels (parent > child > grandchild). Schema supports deeper, but UI truncates with "N deeper tasks..." link that opens Task Detail Modal
- Child count badge on collapsed parents: `Implement PKCE flow [3 subtasks] [RUNNING]`

### 2. Dependency blocking (inline annotation)

```
  ├── Google provider           [PENDING]  [x]
  │   ← blocked by: Implement PKCE flow
  ├── GitHub provider           [BLOCKED]  [x]
  │   ← blocked by: Google provider
```

- `←` arrow + `blocked by:` label in `text-muted-foreground text-xs`
- Blocked task name is a clickable link that scrolls to / highlights the blocking task (300ms `ring-2 ring-primary` pulse)
- Only shown when task has unresolved dependencies (hidden once dependency completes)
- Cross-phase dependencies: if the blocking task is in a different phase, show `← blocked by: <task-name> (Phase: <phase-name>)` -- clicking switches to that phase in the sidebar
- Circular dependency guard: if a task chain forms a cycle (should not happen, but can via manual edits), show `[!] Circular dependency` warning in `text-status-error-fg` instead of the blocked-by annotation

### Visual hierarchy

```
Task name             text-sm font-medium
  agent: <name>       text-xs text-muted-foreground font-mono
  child: <name>       text-sm (indented, normal weight)
  ← blocked by:       text-xs text-muted-foreground italic
```

---

## Bulk Task Operations

The `[...]` menu on the Tasks section header provides bulk operations for all tasks in the selected phase.

```
  Tasks (2/5)              [...] [N] [+ Add Task]
                             |
                      +------------------------+
                      | Select All    Ctrl+A   |
                      |------------------------|
                      | Delete All Tasks       |
                      | Reset All to Pending   |
                      | Re-categorize All  >   |
                      |   > execute            |
                      |   > verify             |
                      |   > research           |
                      |------------------------|
                      | Expand All Children    |
                      | Collapse All Children  |
                      +------------------------+
```

- `Select All` -- toggles checkbox selection on all task rows (for future multi-select operations); `Ctrl+A` shortcut when task list focused
- `Delete All Tasks` -- Shift+click bypasses confirm; normal click shows `window.confirm()`
- `Reset All to Pending` -- resets all non-running tasks in the phase back to `pending` status. Useful after a failed batch.
- `Re-categorize All` -- submenu with category options; updates all tasks in the phase
- `Expand All Children` / `Collapse All Children` -- bulk toggle for parent-child tree visibility
- Batch mutations: `trpc.deleteTasksByPhase`, `trpc.updateTaskCategory`, `trpc.resetTasksByPhase`
- Menu is a `<DropdownMenu>` from shadcn/ui
- Disabled when phase has 0 tasks

---

## Empty State -- No Phases (no agent running)

```
+=============================================================================+
|  Phases                     |                                               |
|  --------------------------+                                                |
|  (empty)                    |  +------------------------------------------+ |
|                             |  |                                          | |
|                             |  |            [layers icon]                 | |
|                             |  |          No phases yet                   | |
|                             |  |                                          | |
|                             |  |   Add a phase to start planning,         | |
|                             |  |   or let an agent plan for you.          | |
|                             |  |                                          | |
|                             |  |   [sparkles Plan with Agent]  [+ Add Phase] |
|                             |  |                                          | |
|                             |  +------------------------------------------+ |
|                             |                                               |
+=============================================================================+
```

- Centered `EmptyState` card in the detail panel area
- `[layers icon]` -- Lucide `Layers` icon, `text-muted-foreground`, 48px
- Two action buttons side by side:
  - **`[sparkles Plan with Agent]` -- `variant="default"` (primary/filled), calls `planSpawn.spawn()`** -- this is the recommended action
  - `[+ Add Phase]` -- `variant="outline"` (secondary/outline), calls `onAddPhase()` for inline input
- Visual hierarchy: "Plan with Agent" is indigo filled button (primary CTA), "Add Phase" is outline (secondary)
- Only shown when: `phasesLoaded && phases.length === 0 && !isPlanRunning && !planFailed`

---

## Empty State -- Planning in Progress (agent running)

```
+=============================================================================+
|  Phases                     |                                               |
|  --------------------------+                                                |
|  (empty)                    |  +------------------------------------------+ |
|                             |  |                                          | |
|                             |  |            [spinner]                     | |
|                             |  |       Planning in progress...            | |
|                             |  |                                          | |
|                             |  |   Agent is analyzing the initiative      | |
|                             |  |   and creating phases.                   | |
|                             |  |                                          | |
|                             |  +------------------------------------------+ |
|                             |                                               |
+=============================================================================+
```

- `[spinner]` -- `Loader2` with `animate-spin`, 32px, `text-primary`
- "Planning in progress..." -- `text-base font-medium`
- Subtext -- `text-sm text-muted-foreground`
- NO action buttons -- prevents user from adding phases while agent works
- Shown when: `phasesLoaded && phases.length === 0 && isPlanRunning`

---

## Empty State -- Planning Failed (agent crashed)

```
+=============================================================================+
|  Phases                     |                                               |
|  --------------------------+                                                |
|  (empty)                    |  +------------------------------------------+ |
|                             |  |                                          | |
|                             |  |         [AlertTriangle icon]             | |
|                             |  |         Planning failed                  | |
|                             |  |                                          | |
|                             |  |   The planning agent crashed before      | |
|                             |  |   creating any phases.                   | |
|                             |  |                                          | |
|                             |  |   [sparkles Retry Planning]  [View Log]  | |
|                             |  |                                          | |
|                             |  +------------------------------------------+ |
|                             |                                               |
+=============================================================================+
```

- `[AlertTriangle icon]` -- Lucide `AlertTriangle`, 48px, `text-status-error-fg`
- "Planning failed" -- `text-base font-medium text-status-error-fg`
- Subtext -- `text-sm text-muted-foreground`; shows truncated error reason if available from agent's last output (e.g., "API rate limit exceeded", "Account exhausted")
- Two action buttons:
  - `[sparkles Retry Planning]` -- `variant="default"` (primary), calls `planSpawn.spawn()` again
  - `[View Log]` -- `variant="outline"`, opens `AgentOutputViewer` for the crashed agent
- Shown when: `phasesLoaded && phases.length === 0 && !isPlanRunning && planAgent?.status === 'crashed'`
- Detection: query the most recent plan-category agent for this initiative; check `status === 'crashed'`
- Edge case -- partial failure: if the agent created *some* phases before crashing, this empty state does NOT show (phases exist). Instead, show a dismissible `AlertBanner` at the top of the detail panel: "Planning agent crashed after creating N phases. Some phases may be incomplete. [Retry] [Dismiss]"

---

## Pending Review Banner (top-level)

```
+=============================================================================+
|  +---------------------------------------------------------------------+   |
|  | [sparkles] 5 proposals ready for review       [Go to Review ->]     |   |
|  +---------------------------------------------------------------------+   |
|  Phases               [+]  |  Phase: OAuth Implementation                  |
|  --------------------------+                                  [✓] Saved     |
|  ...                        |  ...                                          |
+=============================================================================+
```

- Full-width banner above the sidebar+detail grid
- `[sparkles]` -- Lucide `Sparkles` icon, `text-amber-500`
- **Shows proposal count**: "N proposals ready for review" (not generic "Agent has proposals")
- Background: `bg-amber-50 dark:bg-amber-950/20 border border-amber-200 dark:border-amber-800`
- `[Go to Review ->]` -- text button that navigates to `?tab=review`
- Shown when: proposals with `status === 'pending'` exist for this initiative
- Query: `trpc.listProposals.useQuery({ initiativeId, status: 'pending' })`
- Count derived from `pendingProposals.data?.length`

---

## Phase Detail Header

```
+------------------------------------------------------------------------+
|  Phase 2: OAuth Implementation            [READY]  [git] branch  [...] |
|                                                         |          |    |
|                                                    branch badge    v    |
|                                                   +--------------------+
|                                                   | Detail with Agent  |
|                                                   | Duplicate Phase    |
|                                                   |--------------------|
|                                                   | Delete Phase       |
|                                                   +--------------------+
+------------------------------------------------------------------------+
```

- Phase name is inline-editable (click to toggle input); same `<SaveIndicator compact>` pattern as task names
- `[...]` dropdown:
  - `Detail with Agent` -- spawns a detail agent for this phase (disabled if detail agent already running or phase has tasks)
  - `Duplicate Phase` -- deep-copies phase + tasks with "(copy)" suffix; useful for templating similar phases
  - `Delete Phase` -- destructive, red text. Shift+click bypasses confirm. Normal click: `window.confirm()`
- `[git] branch` badge shows initiative branch when set; clicking copies branch name to clipboard (toast: "Copied to clipboard")

---

## Detailing In Progress (per-phase)

```
+------------------------------------------------------------------------+
|  Phase 2: OAuth Implementation            [READY]  [spinner] Detailing |
+------------------------------------------------------------------------+
```

- Shown in phase detail header when a detail agent is active for this phase
- `[spinner]` -- `Loader2` with `animate-spin`

---

## Empty State -- Phase Selected, No Tasks

```
+------------------------------------------------------------------------+
|  Phase 2: OAuth Implementation            [READY]              [...]   |
|------------------------------------------------------------------------|
|  Description:                                                          |
|  Implement OAuth 2.0 authorization code flow...                        |
|                                                                        |
|  Tasks (0)                                            [+ Add Task]     |
|  +------------------------------------------------------------------+  |
|  |                                                                  |  |
|  |                  [ListTodo icon]                                  |  |
|  |              No tasks in this phase                              |  |
|  |                                                                  |  |
|  |   Add tasks manually, or let an agent                            |  |
|  |   decompose this phase into tasks.                               |  |
|  |                                                                  |  |
|  |   [sparkles Detail with Agent]  [+ Add Task]                     |  |
|  |                                                                  |  |
|  +------------------------------------------------------------------+  |
+------------------------------------------------------------------------+
```

- Only appears inside the Tasks section of the detail panel (NOT a full-panel takeover like the no-phases empty state)
- `[sparkles Detail with Agent]` -- `variant="default"` (primary CTA), spawns a detail agent for this phase
- `[+ Add Task]` -- `variant="outline"` (secondary), opens inline task input
- `[ListTodo icon]` -- Lucide `ListTodo`, 36px, `text-muted-foreground`
- Distinct from the top-level "No phases yet" empty state -- this one is scoped to the Tasks area of an existing phase

---

## Per-Phase Pending Review Banner

```
+------------------------------------------------------------------------+
|  [!] 3 proposals pending review. Go to the Review tab to review.       |
+------------------------------------------------------------------------+
```

- Shown below phase header when phase-specific proposals are pending
- `[!]` -- `AlertCircle` icon, `text-amber-500`
- **Shows count**: "N proposals pending review" (not generic text)
- Distinct from top-level banner (this is phase-scoped)

---

## Task Row Hover & Focus States

```
Default:
  ├── Google provider           [PENDING]

Hover:
  ├── Google provider           [PENDING]  [play] [x]
       ^^^^^^^^^^^^^                        ^^^^^  ^^^
       bg-muted/50 row bg                   queue  delete
       cursor-pointer                       (on hover only)

Focused (keyboard nav):
  ├── Google provider           [PENDING]  [play] [x]
  ^^^^
  ring-1 ring-primary/50 outline on row

Selected (Space toggle):
  ├── [✓] Google provider       [PENDING]  [play] [x]
       ^^^
       checkbox visible when any task selected
```

- Hover reveals action buttons (`[play]` to queue, `[x]` to delete) at the right edge of the row
- `[play]` button: `variant="ghost" size="icon"` -- Lucide `Play` icon, calls `trpc.dispatchTask`
- `[x]` button: `variant="ghost" size="icon"` -- Lucide `X` icon, `text-destructive` on hover
- Running tasks replace `[play]` with `[square]` (stop button) and hide `[x]` (cannot delete running task)
- Focus ring uses `ring-1 ring-primary/50` (subtle, not aggressive -- this is keyboard nav, not a call to action)
- Hover and focus states stack: hovering a focused row shows both `bg-muted/50` and focus ring

---

## Task Detail Modal (overlay)

```
+----------------------------------------------------------+
|  Set up OAuth routes                              [x]    |
|                                                          |
|  Status      [PENDING]     |  Category     execute       |
|  Phase       2. OAuth Flow |  Priority     normal        |
|  Agent       (none)        |  Parent Task  (none)        |
|                                                          |
|  Description                                             |
|  Create Express routes for /auth/login, /auth/callback,  |
|  and /auth/logout with proper middleware chain.           |
|                                                          |
|  Child Tasks                                             |
|  (none -- will be created during decomposition)          |
|                                                          |
|  Dependencies                                            |
|  * DB Schema Migration  [DONE]                           |
|                                                          |
|  Blocks                                                  |
|  * GitHub provider adapter  [BLOCKED]                    |
|                                                          |
|                    [ Queue Task ]  [ Stop Task ]         |
+----------------------------------------------------------+
```

- Opened by clicking any task row (or pressing `Enter` on focused row)
- `[x]` close button top-right; `Escape` also closes
- **Parent Task** field shows the parent task name (clickable) if `parentTaskId` is set, otherwise "(none)"
- **Child Tasks** section lists decomposed children if any exist; each child is clickable to open its own modal
- **Dependencies** section shows blocking tasks with status; `[+ Add]` button to add a new dependency (dropdown of other tasks in same phase)
- **Blocks** section shows downstream tasks that depend on this one (read-only, informational)
- Description is a multi-line `<textarea>` with auto-resize; auto-saves with 500ms debounce + `<SaveIndicator>`
- `[ Queue Task ]` dispatches the task; `[ Stop Task ]` kills the running agent
- `[ Queue Task ]` is disabled with tooltip "Blocked by N tasks" when task has unresolved dependencies
- `[ Delete Task ]` -- `variant="ghost"` `text-destructive`, bottom-left of modal. Shift+click bypasses confirm.
- Shared component via `<TaskModal>` in `ExecutionContext`

---

## Keyboard Shortcuts (Plan Tab)

| Key | Context | Action |
|-----|---------|--------|
| `N` | Task list focused | Open inline "Add Task" input at bottom of list |
| `E` | Task row focused | Toggle inline name editing on focused task |
| `Tab` | Inline edit active | Save current edit, move to next task in edit mode |
| `Delete` / `Backspace` | Task row focused | Delete task (with confirm unless Shift held) |
| `Arrow Up` / `Arrow Down` | Task list | Navigate between task rows |
| `Arrow Right` | Collapsed parent focused | Expand children |
| `Arrow Left` | Expanded parent focused | Collapse children |
| `Arrow Left` | Child task focused | Jump focus to parent task |
| `Enter` | Task row focused | Open Task Detail Modal |
| `Space` | Task row focused | Toggle task selection (for future multi-select) |
| `Escape` | Inline edit active | Cancel edit, restore original value |
| `Ctrl+A` | Task list focused | Select all tasks |
| `?` | Plan tab focused, no input active | Show keyboard shortcut overlay |

- Shortcuts are scoped to the task list container (`onKeyDown` handler on the task list wrapper)
- Only active when no other input/textarea is focused (check `document.activeElement.tagName`)
- Discoverable via tooltip on `[+ Add Task]` button: "Add task (N)"
- `?` shortcut opens a shadcn `<Dialog>` listing all shortcuts -- same pattern as GitHub's `?` key

---

## Source

- `packages/web/src/components/ExecutionTab.tsx` (Plan tab = ExecutionTab with sidebar+detail layout)
- `packages/web/src/components/execution/PlanSection.tsx`
- `packages/web/src/components/execution/PhaseSidebarItem.tsx`
- `packages/web/src/components/execution/PhaseDetailPanel.tsx`
- `packages/web/src/components/execution/PhaseActions.tsx`
- `packages/web/src/components/execution/TaskModal.tsx`
- `packages/web/src/components/execution/BulkTaskMenu.tsx` (new)
- `packages/web/src/components/execution/TaskTree.tsx` (new -- replaces flat list)
- `packages/web/src/components/execution/TaskRowInlineEdit.tsx` (new -- extracted edit mode)
- `packages/web/src/components/execution/PhaseEmptyTasks.tsx` (new -- per-phase empty state)
- `packages/web/src/components/execution/PlanTabSkeleton.tsx` (new -- loading skeleton)
- `packages/web/src/components/KeyboardShortcutOverlay.tsx` (new -- `?` key dialog, reusable)
- `packages/web/src/components/TaskRow.tsx`
- `packages/web/src/hooks/useAutoSave.ts`

---

## Design Review Notes

Critique and rationale for all v2 Plan Tab design decisions. Each item maps to a review criterion.

### 1. Sidebar Width: 240px (consistent across tabs)

**Problem**: Content tab v1 used 192px for the page tree. Plan tab v1 was 260px. The 68px discrepancy means the divider line jumps when switching tabs -- jarring in a tabbed layout sharing the same viewport.

**Resolution**: Both Content tab and Plan tab now use **240px**. The divider line is stable across tab switches. Rationale:
- Phase cards carry status badges, task counts, and dependency indicators. 192px was too cramped.
- Content tab v2 independently moved to 240px to accommodate deep nesting + breadcrumb truncation.
- The convergence at 240px is incidental but correct -- both sidebars have similar information density now.
- **240px is the canonical sidebar width for all tabbed views within initiative detail.** Any future tabs with sidebars should use 240px unless there is a strong reason to deviate.

### 2. Three-Way Empty State Split (no phases / planning / planning failed)

**Problem**: v1 had no way to tell the user "planning failed." The agent could crash silently, leaving the user staring at a "No phases yet" screen with no signal.

**Resolution**: Added a third empty state -- "Planning failed" with `AlertTriangle` icon, error message, `[Retry Planning]` primary button, and `[View Log]` outline button. Detection: query the most recent plan-category agent for this initiative, check `status === 'crashed'`.

The three states form a clean state machine:
- `!isPlanRunning && !planFailed && phases.length === 0` -> "No phases yet" (with action buttons)
- `isPlanRunning && phases.length === 0` -> "Planning in progress..." (no action buttons)
- `!isPlanRunning && planFailed && phases.length === 0` -> "Planning failed" (retry + log buttons)

**Partial failure edge case**: If the agent crashes *after* creating some phases, the empty states do not apply (phases exist). Instead, a dismissible `AlertBanner` appears at the top of the detail panel: "Planning agent crashed after creating N phases. [Retry] [Dismiss]". This is critical -- without it, partial failures are invisible.

**Error context**: The failed empty state now shows a truncated error reason extracted from the agent's last output (e.g., "API rate limit exceeded"). This saves the user from having to click "View Log" just to understand *why* it failed.

### 3. Task Tree: Parent-Child + Dependency Visualization

**Problem**: The v1 flat task list gave no signal about task structure. Users managing 10+ agents need to understand the DAG at a glance -- which tasks decompose into subtasks, which tasks block other tasks.

**Resolution**: The task tree now communicates two distinct relationships:
- **Parent-child decomposition**: Indented rows under parent tasks (uses `parentTaskId` from the schema). Collapsible per parent. The `child:` prefix distinguishes these from agent assignment lines.
- **Dependency blocking**: `← blocked by: <task-name>` annotations below blocked tasks. The blocking task name is a clickable link that scrolls to and highlights the blocking task.
- **Cross-phase dependencies**: When a blocking task lives in a different phase, the annotation includes the phase name and clicking it switches the sidebar selection.
- **Collapse behavior**: Parents with >= 4 children default to collapsed, showing a child count badge. This prevents the tree from becoming unwieldy in heavily-decomposed phases.

**What this is NOT**: This is not a full DAG graph. The Plan tab shows a *tree* (hierarchical nesting + inline annotations), not a topological graph with SVG arrows. That is the Execution tab's job. The Plan tab's job is *editing* the structure, not *visualizing* execution order. The inline `← blocked by:` annotations are sufficient for understanding dependency relationships during planning; the full pipeline visualization belongs to the Execution tab.

**Known limitation**: The tree representation cannot fully express a DAG with convergent dependencies (task C depends on both A and B, which are not parent-child related). The inline annotations handle this for display, but visually it is not as clear as a graph. This is an acceptable tradeoff -- the Plan tab prioritizes editability over visualization fidelity.

### 4. Button Hierarchy: "Plan with Agent" (primary) vs "Add Phase" (outline)

**Problem**: Both buttons were visually ambiguous about which action is recommended.

**Resolution**: Explicit variant assignment:
- `Plan with Agent` -- `variant="default"` (indigo filled, primary CTA). This is the happy path. New users should click this first.
- `Add Phase` -- `variant="outline"` (secondary). This is for power users who want manual control.

The sparkles icon on "Plan with Agent" already signals "AI-powered," and making it the filled button reinforces it as the recommended action. The outline variant for "Add Phase" correctly communicates "alternative path."

### 5. Review Banner: Proposal Count

**Problem**: "Agent has proposals ready for review" is vague. Is it 1 proposal or 50? The user can't gauge urgency without switching tabs.

**Resolution**: Show the count: "5 proposals ready for review." Both the top-level banner and the per-phase banner now include counts. The count comes from `pendingProposals.data?.length` which is already fetched by the query.

### 6. Phase Reordering (drag-and-drop)

**Problem**: No way to reorder phases after creation. If the user adds phases manually or the agent creates them in the wrong order, there's no recourse.

**Resolution**: Added `[≡]` toggle button in the sidebar header. When active:
- Phase cards become draggable (via `@dnd-kit/sortable`)
- Sidebar gets a subtle `bg-muted` highlight to indicate mode change
- Drag handles appear on each card
- Drop triggers `trpc.updatePhaseSortOrder` mutation
- Toggle off returns to normal selection behavior

The toggle approach (vs. always-draggable) is intentional: drag-and-drop interferes with click-to-select in a sidebar this narrow. You don't want accidental drags when you're trying to navigate.

### 7. Phase Status Summary in Sidebar Cards

**Problem**: Sidebar cards showed task count but not progress. "5 tasks" tells you nothing about completion state.

**Resolution**: Changed to `N/M tasks` format (e.g., "2/5 tasks", "3/3 tasks"). When all tasks are complete (N === M), the text switches from `text-muted-foreground` to `text-status-success-fg` for a visual "done" signal without adding another badge.

### 8. Bulk Task Operations

**Problem**: No way to operate on all tasks in a phase at once. If the agent decomposes a phase poorly, the user has to delete tasks one by one.

**Resolution**: `[...]` dropdown menu on the Tasks section header, expanded to include:
- "Select All" (Ctrl+A) -- enables checkbox mode for future multi-select operations
- "Delete All Tasks" -- nukes all tasks in the phase. `window.confirm()` unless Shift held.
- "Reset All to Pending" -- resets all non-running tasks back to pending. Essential after a batch failure where some tasks are stuck in error states.
- "Re-categorize All" -- submenu to change the category of all tasks in the phase.
- "Expand All Children" / "Collapse All Children" -- tree visibility toggles for heavily decomposed phases.

The Select All + checkbox mode lays groundwork for future multi-select operations (bulk delete selected, bulk re-categorize selected) without building the full multi-select UI now.

### 9. Task Inline Editing + Save State

**Problem**: The `<SaveIndicator>` existed for phase descriptions but not for task names. If users can edit task names inline, they need feedback that the edit persisted.

**Resolution**: Each task row gets its own micro save indicator (icon-only `<SaveIndicator>` -- checkmark or spinner, no text label). The indicator appears inline next to the task name input during editing and disappears after save completes. This uses the same `<SaveIndicator>` component with a `compact` prop that renders icon-only.

### 10. Keyboard Shortcut for Add Task (and friends)

**Problem**: In a keyboard-first mission control UI, requiring a mouse click to add a task is a friction point. Power users managing dozens of tasks want to stay on the keyboard.

**Resolution**: Full keyboard shortcut table added (see "Keyboard Shortcuts" section). Key decisions:
- `N` for new task (mnemonic: **N**ew). Scoped to task list focus.
- `E` for edit (mnemonic: **E**dit). Opens inline editing on the focused row.
- `Tab` during inline edit advances to the next task in edit mode (rapid-fire renaming).
- `Delete`/`Backspace` for delete. With confirm unless Shift held (consistent with mouse Shift+click pattern).
- `Arrow Up`/`Down` for row navigation. `Arrow Left`/`Right` for tree expand/collapse (borrowed from VS Code tree behavior).
- `Space` toggles task selection (multi-select mode). `Ctrl+A` selects all.
- `Enter` to open modal.
- `?` opens a shortcut overlay dialog (GitHub-style discoverability).
- All shortcuts are scoped to the task list container and disabled when an input is focused.
- The `[N]` badge hint next to "Add Task" button makes the primary shortcut discoverable. The `?` overlay covers the rest.

---

### 11. Missing: Per-Phase Empty State (phase exists, no tasks)

**Problem caught in review**: The spec documented empty states for "no phases" and "planning in progress/failed," but NOT for the case where a phase exists with zero tasks. The user selects a phase, sees the description, and then... a blank Tasks section with just the "Add Task" button. No guidance.

**Resolution**: Added "Empty State -- Phase Selected, No Tasks" section. The Tasks area (not full panel) shows a small inline empty state with two CTAs: "Detail with Agent" (primary, spawns decomposition) and "Add Task" (outline, manual). This mirrors the plan-level empty state pattern: AI-first is primary, manual is secondary.

### 12. Missing: Task Row Hover & Focus States

**Problem caught in review**: The spec defined keyboard shortcuts and inline editing but never documented what happens on mouse hover or keyboard focus. In a dense list UI, hover states are not cosmetic -- they communicate interactivity and reveal action affordances.

**Resolution**: Added "Task Row Hover & Focus States" section. Key decisions:
- Hover reveals `[play]` (queue) and `[x]` (delete) action buttons at row's right edge. Hidden by default to keep the list clean.
- Running tasks swap `[play]` for `[square]` (stop) and hide `[x]` (cannot delete running tasks).
- Keyboard focus uses a subtle `ring-1 ring-primary/50` outline (not `ring-2` -- that's too aggressive for navigation).
- Hover and focus states stack visually (both can be active on the same row).

### 13. Missing: Phase Detail Header Actions

**Problem caught in review**: The original phase header dropdown only had "Delete Phase." That is one action in a dropdown -- just use a button. A dropdown implies a menu with multiple options.

**Resolution**: Expanded the `[...]` dropdown to three actions:
- "Detail with Agent" -- spawns task decomposition for the selected phase
- "Duplicate Phase" -- deep-copies phase + tasks, appends "(copy)" suffix. Useful for templating similar phases (e.g., duplicating "Google OAuth" to create "GitHub OAuth" with the same task structure).
- "Delete Phase" -- destructive, red text, bottom of menu with separator above.

Now the dropdown earns its existence.

### 14. Concern: Task Description Editing in Modal Only

The current spec puts task description editing exclusively in the Task Detail Modal. For quick edits, opening a modal is friction. Consider adding expandable inline description editing (click to expand a 2-line textarea below the task row) in a future iteration. Not adding it now because the tree is already vertically dense and expandable descriptions would make it harder to scan. But log this as a known future improvement.

### 15. Concern: No Loading / Skeleton States Documented

The spec documents empty states comprehensively but says nothing about what the user sees while phases are *loading*. On a slow connection or large initiative, there is a flash of empty state before data arrives. The plan tab should show:
- Sidebar: 3 skeleton cards (pulsing `bg-muted animate-pulse`, matching card dimensions)
- Detail panel: skeleton lines for title + description + task list

This prevents the "No phases yet" empty state from flashing before the actual phases load, which would be confusing.

### 16. Implementation Note: Component Boundary Map

New or modified components for v2 Plan Tab:

| Component | Path (proposed) | New? |
|-----------|----------------|------|
| `PhaseSidebarItem` | `packages/web/src/components/execution/PhaseSidebarItem.tsx` | Modified -- add task progress, dep indicator, drag handle |
| `PhaseActions` | `packages/web/src/components/execution/PhaseActions.tsx` | Modified -- add `[≡]` toggle, `[Detail All]`, detailing badge |
| `TaskTree` | `packages/web/src/components/execution/TaskTree.tsx` | **New** -- replaces flat task list with nested tree |
| `TaskRow` | `packages/web/src/components/TaskRow.tsx` | Modified -- add inline edit, hover actions, focus state, child indent |
| `TaskRowInlineEdit` | `packages/web/src/components/execution/TaskRowInlineEdit.tsx` | **New** -- extracted edit mode for TaskRow |
| `BulkTaskMenu` | `packages/web/src/components/execution/BulkTaskMenu.tsx` | **New** |
| `PhaseEmptyTasks` | `packages/web/src/components/execution/PhaseEmptyTasks.tsx` | **New** -- per-phase "no tasks" empty state |
| `PlanTabSkeleton` | `packages/web/src/components/execution/PlanTabSkeleton.tsx` | **New** -- loading skeleton |
| `KeyboardShortcutOverlay` | `packages/web/src/components/KeyboardShortcutOverlay.tsx` | **New** -- `?` key dialog, reusable across tabs |
