# 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 | `` 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 `` 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: `) 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 `` 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 `` 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: (Phase: )` -- 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: text-xs text-muted-foreground font-mono child: 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 `` 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 `` 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 `