Files
Codewalkers/.planning/phases/18-initiative-detail/18-02-PLAN.md
Lukas May 305809f0b2 docs(18): create initiative detail phase plan
Phase 18: Initiative Detail
- 4 plans in 2 waves
- 3 parallel (wave 1), 1 sequential (wave 2)
- Ready for execution
2026-02-04 21:28:33 +01:00

6.2 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous
phase plan type wave depends_on files_modified autonomous
18-initiative-detail 02 execute 1
packages/web/src/components/PhaseAccordion.tsx
packages/web/src/components/TaskRow.tsx
packages/web/src/components/DependencyIndicator.tsx
true
Create PhaseAccordion, TaskRow, and DependencyIndicator components for the initiative detail hierarchy view.

Purpose: The core of the detail page — renders the phase → task tree with expand/collapse, status indicators, agent assignments, and dependency annotations. The UI flattens the Phase → Plan → Task hierarchy by hiding the Plan layer (per decision 15-02). Output: Three interconnected components ready for page assembly in Plan 04.

<execution_context> @/.claude/get-shit-done/workflows/execute-plan.md @/.claude/get-shit-done/templates/summary.md </execution_context>

@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md

Wireframe spec — the primary reference for this plan

@docs/wireframes/initiative-detail.md

Prior phase components to follow patterns

@packages/web/src/components/StatusBadge.tsx @packages/web/src/components/ProgressBar.tsx @packages/web/src/components/InitiativeCard.tsx

tRPC client and existing types

@packages/web/src/lib/trpc.ts @packages/shared/src/types.ts

tRPC router — need to understand listPlans, listTasks, getPhaseDependencies signatures

@src/trpc/router.ts

Task 1: Create DependencyIndicator component packages/web/src/components/DependencyIndicator.tsx Create a component that renders dependency annotations for blocked tasks/phases.

Props interface:

  • blockedBy: Array<{ name: string; status: string }> — the items blocking this one
  • type: 'task' | 'phase' — for display text

Layout (matching wireframe):

  • Renders a line with ^ prefix and text: "blocked by: {name1}, {name2}"
  • Text is muted/orange color (text-orange-500 or text-amber-600)
  • Indented to align with parent tree structure (use pl-8 or similar)
  • If blockedBy is empty, render nothing (return null)

This is a pure presentational component. npx tsc --noEmit -p packages/web/tsconfig.app.json passes DependencyIndicator renders blocked-by annotations with ^ prefix. Compiles cleanly.

Task 2: Create TaskRow component packages/web/src/components/TaskRow.tsx Create a component for a single task row in the phase tree.

Props interface:

  • task: serialized Task object from tRPC ({ id, name, status, type, priority, order } — dates are strings)
  • agentName: string | null — agent assigned to this task (if any)
  • blockedBy: Array<{ name: string; status: string }> — blocking dependencies
  • isLast: boolean — whether this is the last sibling (affects tree connector)
  • onClick: () => void — opens task detail modal

Layout (matching wireframe):

  • Row with tree connector: |-- for siblings, +-- for last item (use ├── and └── Unicode)
  • Task name as main text
  • StatusBadge showing task status (reuse existing component)
  • If agentName is set, show [agentName] inline in blue/muted text
  • If blockedBy has items, render DependencyIndicator below the row (indented)
  • Entire row is clickable (calls onClick)
  • Use hover state: hover:bg-accent for clickability feedback

Tree connectors: Use a left-side border or pseudo-element pattern. Keep it simple — a border-l-2 on a wrapper div with connector characters as inline text.

Do NOT add "Spawn Agent" button yet — that comes in Plan 04 with queue actions. npx tsc --noEmit -p packages/web/tsconfig.app.json passes TaskRow renders task with tree connectors, status badge, agent name, and dependency indicator. Compiles cleanly.

Task 3: Create PhaseAccordion component packages/web/src/components/PhaseAccordion.tsx Create an expandable/collapsible phase container that holds TaskRow components.

Props interface:

  • phase: serialized Phase object ({ id, number, name, status, description })
  • tasks: Array<{ task: SerializedTask; agentName: string | null; blockedBy: Array<{ name: string; status: string }> }> — tasks with their metadata, already fetched and assembled by parent
  • defaultExpanded: boolean — whether to start expanded
  • onTaskClick: (taskId: string) => void — callback when a task row is clicked

Behavior (matching wireframe):

  • Header row: v/> expand indicator (use ChevronDown/ChevronRight from lucide-react), phase number + name, task count (completed/total), and StatusBadge for phase status
  • Click header to toggle expand/collapse (internal state with useState, initialized from defaultExpanded)
  • When expanded, render all tasks as TaskRow components
  • Phase with status 'blocked' shows DependencyIndicator below header (needs additional prop phaseDependencies: Array<{ name: string; status: string }>)

Add phaseDependencies prop: Array<{ name: string; status: string }> — for phase-level blocked-by display.

Use Tailwind for styling. Border-bottom between phases for visual separation. npx tsc --noEmit -p packages/web/tsconfig.app.json passes PhaseAccordion renders expandable phase with task list, status, and dependency indicators. Compiles cleanly.

Before declaring plan complete: - [ ] `npx tsc --noEmit -p packages/web/tsconfig.app.json` passes - [ ] `npx vite build` in packages/web succeeds - [ ] All three components export correctly - [ ] Components follow existing codebase patterns (functional components, named exports, Tailwind)

<success_criteria>

  • PhaseAccordion renders expandable phases with task counts and status
  • TaskRow renders tasks with tree connectors, status, agent names
  • DependencyIndicator renders blocked-by annotations
  • All components are presentational (data assembled by parent)
  • TypeScript and Vite build pass </success_criteria>
After completion, create `.planning/phases/18-initiative-detail/18-02-SUMMARY.md`