diff --git a/.planning/phases/18-initiative-detail/18-01-PLAN.md b/.planning/phases/18-initiative-detail/18-01-PLAN.md new file mode 100644 index 0000000..184a85d --- /dev/null +++ b/.planning/phases/18-initiative-detail/18-01-PLAN.md @@ -0,0 +1,114 @@ +--- +phase: 18-initiative-detail +plan: 01 +type: execute +wave: 1 +depends_on: [] +files_modified: + - packages/web/src/components/InitiativeHeader.tsx + - packages/web/src/components/ProgressPanel.tsx +autonomous: true +--- + + +Create InitiativeHeader and ProgressPanel components for the initiative detail page. + +Purpose: The header provides navigation back to the dashboard, displays initiative metadata (name, status, dates), and the progress panel shows phase/task completion stats with a progress bar. +Output: Two reusable components ready for page assembly in Plan 04. + + + +@~/.claude/get-shit-done/workflows/execute-plan.md +@~/.claude/get-shit-done/templates/summary.md + + + +@.planning/PROJECT.md +@.planning/ROADMAP.md +@.planning/STATE.md + +# Wireframe spec +@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 +@packages/web/src/lib/trpc.ts + +# Existing route placeholder +@packages/web/src/routes/initiatives/$id.tsx + +# Shared types +@packages/shared/src/types.ts + + + + + + Task 1: Create InitiativeHeader component + packages/web/src/components/InitiativeHeader.tsx + +Create a header component for the initiative detail page. + +Props interface: +- `initiative`: object with `{ id: string; name: string; status: string; createdAt: string; updatedAt: string }` (serialized initiative from tRPC — dates are ISO strings) +- `onBack`: `() => void` callback for the back button + +Layout (matching wireframe): +- Top bar: left-aligned "← Back to Dashboard" button (use `ChevronLeft` from lucide-react), right-aligned "[Actions]" placeholder (just a disabled Button for now — actions come in Plan 04) +- Below: Card containing initiative name as h1, status badge (reuse existing StatusBadge component), and metadata line showing created/updated dates formatted as readable strings (use `new Date(iso).toLocaleDateString()`) + +Use Tailwind classes. Follow same component structure as InitiativeCard (functional component, named export). +Do NOT fetch data — this is a presentational component that receives props. + + npx tsc --noEmit -p packages/web/tsconfig.app.json passes with no errors + InitiativeHeader renders initiative name, status badge, dates, and back button. TypeScript compiles cleanly. + + + + Task 2: Create ProgressPanel component + packages/web/src/components/ProgressPanel.tsx + +Create a progress panel component matching the wireframe's PROGRESS section. + +Props interface: +- `phasesComplete`: number +- `phasesTotal`: number +- `tasksComplete`: number +- `tasksTotal`: number + +Layout: +- Card with "Progress" heading +- Reuse existing ProgressBar component for overall task percentage (`tasksComplete / tasksTotal * 100`, handle 0/0 as 0%) +- Below the bar: two lines of text: "Phases: {phasesComplete}/{phasesTotal} complete" and "Tasks: {tasksComplete}/{tasksTotal} complete" + +Use Tailwind. Follow Card component from shadcn (CardHeader, CardContent pattern). +This is a pure presentational component — no data fetching. + + npx tsc --noEmit -p packages/web/tsconfig.app.json passes with no errors + ProgressPanel displays progress bar with phase/task completion stats. TypeScript compiles cleanly. + + + + + +Before declaring plan complete: +- [ ] `npx tsc --noEmit -p packages/web/tsconfig.app.json` passes +- [ ] `npx vite build` in packages/web succeeds +- [ ] Both components export correctly and follow existing patterns + + + + +- InitiativeHeader component created with back button, name, status badge, dates +- ProgressPanel component created with progress bar and phase/task counts +- Both components are presentational (no data fetching) +- TypeScript and Vite build pass + + + +After completion, create `.planning/phases/18-initiative-detail/18-01-SUMMARY.md` + diff --git a/.planning/phases/18-initiative-detail/18-02-PLAN.md b/.planning/phases/18-initiative-detail/18-02-PLAN.md new file mode 100644 index 0000000..67de51d --- /dev/null +++ b/.planning/phases/18-initiative-detail/18-02-PLAN.md @@ -0,0 +1,148 @@ +--- +phase: 18-initiative-detail +plan: 02 +type: execute +wave: 1 +depends_on: [] +files_modified: + - packages/web/src/components/PhaseAccordion.tsx + - packages/web/src/components/TaskRow.tsx + - packages/web/src/components/DependencyIndicator.tsx +autonomous: 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. + + + +@~/.claude/get-shit-done/workflows/execute-plan.md +@~/.claude/get-shit-done/templates/summary.md + + + +@.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) + + + + +- 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 + + + +After completion, create `.planning/phases/18-initiative-detail/18-02-SUMMARY.md` + diff --git a/.planning/phases/18-initiative-detail/18-03-PLAN.md b/.planning/phases/18-initiative-detail/18-03-PLAN.md new file mode 100644 index 0000000..a30b51f --- /dev/null +++ b/.planning/phases/18-initiative-detail/18-03-PLAN.md @@ -0,0 +1,136 @@ +--- +phase: 18-initiative-detail +plan: 03 +type: execute +wave: 1 +depends_on: [] +files_modified: + - packages/web/src/components/DecisionList.tsx + - packages/web/src/components/TaskDetailModal.tsx +autonomous: true +--- + + +Create DecisionList and TaskDetailModal components for the initiative detail page. + +Purpose: DecisionList shows key decisions made during initiative planning (collapsible). TaskDetailModal opens when clicking a task row to show full task details, dependencies, agent assignment, and action buttons. +Output: Two components ready for page assembly in Plan 04. + + + +@~/.claude/get-shit-done/workflows/execute-plan.md +@~/.claude/get-shit-done/templates/summary.md + + + +@.planning/PROJECT.md +@.planning/ROADMAP.md +@.planning/STATE.md + +# Wireframe spec +@docs/wireframes/initiative-detail.md + +# Existing shadcn components +@packages/web/src/components/ui/dialog.tsx +@packages/web/src/components/ui/button.tsx +@packages/web/src/components/ui/badge.tsx +@packages/web/src/components/ui/card.tsx + +# Existing feature components for patterns +@packages/web/src/components/StatusBadge.tsx +@packages/web/src/components/InitiativeCard.tsx + +# tRPC client +@packages/web/src/lib/trpc.ts +@packages/shared/src/types.ts + + + + + + Task 1: Create DecisionList component + packages/web/src/components/DecisionList.tsx + +Create a collapsible list of key decisions matching the wireframe's KEY DECISIONS panel. + +Props interface: +- `decisions`: `Array<{ topic: string; decision: string; reason: string }>` — decisions to display +- `maxVisible`: `number` (default 3) — how many to show before "show more" + +Behavior (matching wireframe): +- Each decision is individually collapsible: topic as header, decision + reason expand on click +- Use `ChevronDown`/`ChevronRight` from lucide-react for expand indicators +- Internal state: `expandedIndices` as `Set` tracking which decisions are expanded +- "Show more" / "Show less" button if decisions exceed `maxVisible` — uses another state toggle + +Layout: +- Wrap in Card (CardHeader with "Key Decisions" title, CardContent with list) +- Each decision item: clickable topic row, expandable detail below with decision text and "Reason: {reason}" in muted text +- If `decisions` array is empty, render Card with "No decisions recorded" placeholder text + +NOTE: There is currently no `listDecisions` tRPC procedure. The parent page will pass an empty array for now. This component is built for the future when decisions are persisted. This is intentional — the component is ready, the data source comes later. + + npx tsc --noEmit -p packages/web/tsconfig.app.json passes + DecisionList renders collapsible decision items with show more/less. Compiles cleanly. + + + + Task 2: Create TaskDetailModal component + packages/web/src/components/TaskDetailModal.tsx + +Create a modal dialog that shows full task details when clicking a task row. + +Props interface: +- `task`: serialized Task object or `null` (null = modal closed) +- `phaseName`: `string` — name of the phase this task belongs to +- `agentName`: `string | null` — assigned agent +- `dependencies`: `Array<{ name: string; status: string }>` — tasks this one depends on +- `dependents`: `Array<{ name: string; status: string }>` — tasks blocked by this one +- `onClose`: `() => void` — close the modal +- `onQueueTask`: `(taskId: string) => void` — callback to queue this task for dispatch +- `onStopTask`: `(taskId: string) => void` — callback to stop this task (placeholder) + +Layout (matching wireframe TaskDetailModal): +- Use shadcn Dialog component (controlled: `open={task !== null}`, `onOpenChange` calls `onClose`) +- DialogHeader: Task name + close button (built into Dialog) +- Content grid: + - Status: StatusBadge + - Priority: text display + - Phase: phaseName + - Type: task.type + - Agent: agentName or "Unassigned" +- Description section: task.description or "No description" +- Dependencies section: list of dependency names with their status badges. If empty, "No dependencies" +- Blocks section: list of dependent names. If empty, "None" +- DialogFooter: action buttons + - "Queue Task" button (enabled only if task status is 'pending' and dependencies array has all 'completed' items) + - "Stop Task" button (enabled only if task status is 'in_progress') + - Both call their respective callbacks with task.id + +Use shadcn Dialog, Button, Badge components. Follow controlled dialog pattern from CreateInitiativeDialog. + + npx tsc --noEmit -p packages/web/tsconfig.app.json passes + TaskDetailModal renders full task details with dependencies, dependents, and action buttons. Compiles cleanly. + + + + + +Before declaring plan complete: +- [ ] `npx tsc --noEmit -p packages/web/tsconfig.app.json` passes +- [ ] `npx vite build` in packages/web succeeds +- [ ] Both components export correctly +- [ ] Dialog follows controlled pattern matching CreateInitiativeDialog + + + + +- DecisionList renders collapsible decisions with show more/less +- TaskDetailModal renders full task details in a dialog with action buttons +- Both components are presentational with callback props for actions +- TypeScript and Vite build pass + + + +After completion, create `.planning/phases/18-initiative-detail/18-03-SUMMARY.md` + diff --git a/.planning/phases/18-initiative-detail/18-04-PLAN.md b/.planning/phases/18-initiative-detail/18-04-PLAN.md new file mode 100644 index 0000000..d2e736b --- /dev/null +++ b/.planning/phases/18-initiative-detail/18-04-PLAN.md @@ -0,0 +1,170 @@ +--- +phase: 18-initiative-detail +plan: 04 +type: execute +wave: 2 +depends_on: ["18-01", "18-02", "18-03"] +files_modified: + - packages/web/src/routes/initiatives/$id.tsx +autonomous: true +--- + + +Assemble the Initiative Detail page by wiring all Phase 18 components into the $id.tsx route with tRPC data fetching, queue actions, and build verification. + +Purpose: Replace the placeholder detail page with a fully functional initiative detail view that fetches data from the backend, renders the phase/task hierarchy, and provides queue action buttons. +Output: Working Initiative Detail page matching the wireframe specification. + + + +@~/.claude/get-shit-done/workflows/execute-plan.md +@~/.claude/get-shit-done/templates/summary.md + + + +@.planning/PROJECT.md +@.planning/ROADMAP.md +@.planning/STATE.md + +# Prior plan summaries — need to know what components were created +@.planning/phases/18-initiative-detail/18-01-SUMMARY.md +@.planning/phases/18-initiative-detail/18-02-SUMMARY.md +@.planning/phases/18-initiative-detail/18-03-SUMMARY.md + +# Wireframe spec +@docs/wireframes/initiative-detail.md + +# Existing page pattern to follow +@packages/web/src/routes/initiatives/index.tsx + +# Components created in plans 01-03 +@packages/web/src/components/InitiativeHeader.tsx +@packages/web/src/components/ProgressPanel.tsx +@packages/web/src/components/PhaseAccordion.tsx +@packages/web/src/components/TaskRow.tsx +@packages/web/src/components/DependencyIndicator.tsx +@packages/web/src/components/DecisionList.tsx +@packages/web/src/components/TaskDetailModal.tsx + +# tRPC client and types +@packages/web/src/lib/trpc.ts +@packages/shared/src/types.ts + +# tRPC router — need exact procedure signatures +@src/trpc/router.ts + + + + + + Task 1: Wire Initiative Detail page with data fetching and all components + packages/web/src/routes/initiatives/$id.tsx + +Replace the placeholder content with the full initiative detail page. + +**Data fetching strategy:** +The page needs to assemble a nested data structure (initiative → phases → tasks) from multiple tRPC calls. Use React Query's `useQuery` hooks with proper `enabled` chaining. + +1. `trpc.getInitiative.useQuery({ id })` — fetch initiative by route param `$id` +2. `trpc.listPhases.useQuery({ initiativeId: id })` — fetch all phases +3. For each phase, fetch plans: `trpc.listPlans.useQuery({ phaseId })` — but since hooks can't be called conditionally, use a pattern where the page fetches all plans for all phases. Use `trpc.useQueries()` if available, or fetch plans in a child component. + +**Recommended approach for nested fetching:** +Create a helper component `PhaseWithTasks` that: +- Receives a phase +- Calls `trpc.listPlans.useQuery({ phaseId: phase.id })` to get plans +- For each plan, calls `trpc.listTasks.useQuery({ planId: plan.id })` to get tasks +- Flattens all tasks from all plans into a single array (hiding the Plan layer per decision 15-02) +- Calls `trpc.getPhaseDependencies.useQuery({ phaseId: phase.id })` for phase-level deps +- Renders PhaseAccordion with the assembled task data + +This avoids the conditional hooks problem — each `PhaseWithTasks` instance has a stable hook call count. + +**Page layout (matching wireframe):** +``` +InitiativeHeader (back button, name, status, dates) + ↓ +Two-column layout on desktop (grid-cols-1 lg:grid-cols-[1fr_340px]): + Left: PHASES section with PhaseWithTasks for each phase + Right: ProgressPanel + DecisionList (stacked) + ↓ +TaskDetailModal (controlled by selectedTask state) +``` + +**State management:** +- `selectedTask`: `string | null` — ID of task with open modal +- For the modal, when a task is selected, look it up from the fetched data + +**Back button:** +Use `useNavigate` from TanStack Router to navigate to `/initiatives`. + +**Queue actions:** +- "Queue All" button in the PHASES section header — calls `trpc.queuePhase.useMutation()` for each pending phase (disabled if no pending phases) +- In TaskDetailModal, "Queue Task" calls `trpc.queueTask.useMutation()` with task ID +- After successful queue mutation, invalidate relevant queries + +**Loading/error states:** +- Show skeleton/spinner while initiative loads (follow InitiativeList pattern) +- Show "Initiative not found" if getInitiative returns 404/error +- Individual PhaseWithTasks components show their own loading states + +**DecisionList:** +Pass empty array for decisions: `decisions={[]}` — no backend endpoint exists yet. + +**Progress calculation:** +Compute from phases data: +- `phasesComplete`: count phases with status 'completed' +- `phasesTotal`: phases.length +- `tasksComplete/tasksTotal`: sum across all PhaseWithTasks (or compute at page level by fetching all) + +Since task counts require fetching all tasks (which happens in PhaseWithTasks children), lift the counts up via a callback or compute from the phase-level data. Simplest approach: use the phase statuses for the progress panel and skip exact task counts initially. Or pass task count via a state aggregation pattern. + +Pragmatic approach: ProgressPanel shows phase-level progress only (`phasesComplete/phasesTotal`). Task counts show as "—" until the phase components have loaded their tasks. This avoids overcomplicating the initial implementation. If you find a clean way to aggregate task counts, do it, but don't over-engineer. + + npx tsc --noEmit -p packages/web/tsconfig.app.json passes AND npx vite build in packages/web succeeds + Initiative Detail page renders with header, progress, decisions placeholder, phase accordion with tasks, and task detail modal. Build passes. + + + + Task 2: Verify full build and integration + packages/web/src/routes/initiatives/$id.tsx + +Run full verification: +1. `npx tsc --noEmit -p packages/web/tsconfig.app.json` — TypeScript check +2. `npx vite build` in packages/web — production build +3. `npm run build` in root — backend build (ensure no regressions) +4. Verify the route is accessible by checking routeTree.gen.ts includes the $id route + +Fix any TypeScript errors or build failures discovered. + +No new code unless fixing build issues. + + All three build commands pass with zero errors + Full project builds cleanly. Initiative detail page compiles and bundles correctly. + + + + + +Before declaring plan complete: +- [ ] `npx tsc --noEmit -p packages/web/tsconfig.app.json` passes +- [ ] `npx vite build` in packages/web succeeds +- [ ] `npm run build` in root succeeds +- [ ] Navigating from dashboard card to /initiatives/$id renders the detail page +- [ ] Phase accordion expand/collapse works +- [ ] Task detail modal opens on task click + + + + +- Initiative Detail page replaces placeholder with full implementation +- Data fetched from backend via tRPC (getInitiative, listPhases, listPlans, listTasks) +- Phase hierarchy renders with expand/collapse +- Task detail modal functional +- Queue actions wired to tRPC mutations +- All builds pass + + + +After completion, create `.planning/phases/18-initiative-detail/18-04-SUMMARY.md` +