Files
Codewalkers/.planning/phases/19-agent-inbox/19-02-PLAN.md
Lukas May d9b6ce4748 docs(19): create agent inbox phase plan
Phase 19: Agent Inbox
- 4 plans in 2 waves
- 3 parallel (Wave 1), 1 sequential (Wave 2)
- Ready for execution
2026-02-04 21:47:58 +01:00

4.6 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous
phase plan type wave depends_on files_modified autonomous
19-agent-inbox 02 execute 1
packages/web/src/components/InboxList.tsx
packages/web/src/components/MessageCard.tsx
true
Build the InboxList and MessageCard components for the agent inbox message list view.

Purpose: These are the entry-point components for the inbox — showing a filterable, sortable list of agent messages. Following the wireframe spec from docs/wireframes/agent-inbox.md.

Output: InboxList and MessageCard components with filter/sort controls and empty state.

<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

@docs/wireframes/agent-inbox.md @packages/web/src/components/InitiativeList.tsx @packages/web/src/components/InitiativeCard.tsx @packages/web/src/components/StatusBadge.tsx @packages/web/src/components/ui/card.tsx @packages/web/src/components/ui/badge.tsx @packages/web/src/components/ui/button.tsx

Task 1: Create MessageCard component packages/web/src/components/MessageCard.tsx Create MessageCard following the wireframe spec. Props: - `agentName: string` — agent human-readable name - `agentStatus: string` — 'waiting_for_input' | 'running' | 'stopped' | etc. - `preview: string` — message preview text (truncated) - `timestamp: string` — ISO date string for relative time display - `requiresResponse: boolean` — determines filled (●) vs empty (○) indicator - `isSelected: boolean` — highlighted state - `onClick: () => void`

Display:

  • Status indicator: ● (filled circle) when requiresResponse=true, ○ (empty) otherwise
  • Agent name with status text in parentheses (e.g., "gastown (waiting)")
  • Message preview truncated to ~80 chars with ellipsis
  • Relative timestamp using simple helper (e.g., "2 min ago", "1h ago"). Write an inline formatRelativeTime(isoDate: string): string helper at the top of the file — do NOT create a separate utils file.
  • Selected state: slightly different background via className toggle

Use shadcn Card as the base, Tailwind for styling. Match the visual density of InitiativeCard. npx tsc --noEmit -p packages/web/tsconfig.app.json MessageCard renders with indicator, name, preview, timestamp, and selected state

Task 2: Create InboxList component packages/web/src/components/InboxList.tsx Create InboxList following the wireframe spec. Props: - `agents: Array<{ id: string; name: string; status: string; taskId: string; updatedAt: string }>` — agent data - `messages: Array<{ id: string; senderId: string | null; content: string; requiresResponse: boolean; status: string; createdAt: string }>` — message data - `selectedAgentId: string | null` — currently selected agent - `onSelectAgent: (agentId: string) => void` — selection handler - `onRefresh: () => void` — refresh handler

Internal state:

  • filter: 'all' | 'waiting' | 'completed' — default 'all'
  • sort: 'newest' | 'oldest' — default 'newest'

Behavior:

  1. Join agents with their latest message (match message.senderId to agent.id)
  2. Filter: 'waiting' = requiresResponse messages, 'completed' = responded/non-requiring messages, 'all' = everything
  3. Sort by message timestamp (newest or oldest)
  4. Render MessageCard for each result
  5. Show header with count badge: "Agent Inbox (3)" and Refresh button
  6. Filter and sort as simple button groups or select elements (not dropdowns — keep it simple)
  7. Empty state when no messages match filter: "No pending messages" with subtitle text

Follow the pattern from InitiativeList for the list layout structure. npx tsc --noEmit -p packages/web/tsconfig.app.json - InboxList renders with filter/sort controls - MessageCard instances rendered for each agent+message pair - Empty state shown when no messages - Filter and sort work correctly

Before declaring plan complete: - [ ] `npx tsc --noEmit -p packages/web/tsconfig.app.json` passes - [ ] `npx vite build` in packages/web succeeds

<success_criteria>

  • MessageCard shows indicator, agent name, preview, relative time
  • InboxList filters by waiting/completed/all
  • InboxList sorts by newest/oldest
  • Empty state renders when no messages match
  • All builds pass </success_criteria>
After completion, create `.planning/phases/19-agent-inbox/19-02-SUMMARY.md`