Decomposed "Foundation Setup - Install Dependencies & Configure Tailwind" phase into 6 executable tasks: 1. Install Tailwind CSS, PostCSS & Autoprefixer 2. Map MUI theme to Tailwind design tokens 3. Setup CSS variables for dynamic theming 4. Install Radix UI primitives 5. Initialize shadcn/ui and setup component directory 6. Move MUI to devDependencies and verify setup Tasks follow logical dependency chain with final human verification checkpoint before proceeding with component migration. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
17 KiB
17 KiB
Agent Inbox Wireframe
Message queue UI where users see questions from agents and respond to them.
Screen Layout
Inbox List View
┌─────────────────────────────────────────────────────────────┐
│ Agent Inbox (3) [Refresh] │
├─────────────────────────────────────────────────────────────┤
│ Filter: [All ▾] Sort: [Newest ▾] │
├─────────────────────────────────────────────────────────────┤
│ ● gastown (waiting) 2 min ago │
│ "Which auth provider should we use? I need to decide..." │
├─────────────────────────────────────────────────────────────┤
│ ● chinatown (waiting) 5 min ago │
│ "I found 3 potential issues with the migration..." │
├─────────────────────────────────────────────────────────────┤
│ ○ yaletown (done) 15 min ago │
│ "Task completed: Created user schema" │
└─────────────────────────────────────────────────────────────┘
Legend:
- ● = Requires response (agent waiting)
- ○ = Informational (no response needed)
Empty State
┌─────────────────────────────────────────────────────────────┐
│ Agent Inbox (0) [Refresh] │
├─────────────────────────────────────────────────────────────┤
│ │
│ No pending messages │
│ │
│ Agents will appear here when they have │
│ questions or status updates │
│ │
└─────────────────────────────────────────────────────────────┘
Message Detail View
Single Question (Radio Buttons)
┌─────────────────────────────────────────────────────────────┐
│ gastown → You 2 minutes ago │
│ Task: Implement auth middleware │
│ Worktree: .cw-worktrees/gastown │
├─────────────────────────────────────────────────────────────┤
│ Q1: Which authentication provider should we use? │
│ │
│ ○ Supabase Auth - Built-in with our DB │
│ ○ Clerk - Beautiful pre-built UI │
│ ○ NextAuth.js - Self-hosted, maximum control │
│ ○ Other: [________________] │
│ │
│ [Cancel] [Send Answers] │
└─────────────────────────────────────────────────────────────┘
Multi-Question Format
┌─────────────────────────────────────────────────────────────┐
│ gastown → You 2 minutes ago │
│ Task: Implement auth middleware │
│ Worktree: .cw-worktrees/gastown │
├─────────────────────────────────────────────────────────────┤
│ Q1: Which authentication provider should we use? │
│ │
│ ○ Supabase Auth - Built-in with our DB │
│ ○ Clerk - Beautiful pre-built UI │
│ ○ NextAuth.js - Self-hosted, maximum control │
│ ○ Other: [________________] │
│ │
│ Q2: Should we implement refresh token rotation? │
│ │
│ ○ Yes - More secure │
│ ○ No - Simpler implementation │
│ │
│ Q3: Session storage preference? │
│ │
│ ○ Database - Full control, revocation │
│ ○ JWT only - Stateless, simpler │
│ │
│ [Cancel] [Send Answers] │
└─────────────────────────────────────────────────────────────┘
Multi-Select Question (Checkboxes)
┌─────────────────────────────────────────────────────────────┐
│ chinatown → You 5 minutes ago │
│ Task: Configure database schema │
│ Worktree: .cw-worktrees/chinatown │
├─────────────────────────────────────────────────────────────┤
│ Q1: Which optional features should we include? │
│ (Select all that apply) │
│ │
│ ☐ Soft deletes - Mark deleted instead of removing │
│ ☐ Audit logging - Track all changes │
│ ☐ Full-text search - PostgreSQL tsvector │
│ ☐ Row-level security - Fine-grained access │
│ │
│ Q2: Primary key strategy? │
│ │
│ ○ UUID - Globally unique, no collisions │
│ ○ Serial - Simple, human-readable │
│ ○ ULID - Sortable UUIDs │
│ │
│ [Cancel] [Send Answers] │
└─────────────────────────────────────────────────────────────┘
Free-Text Answer
┌─────────────────────────────────────────────────────────────┐
│ yaletown → You 10 minutes ago │
│ Task: Set up deployment │
│ Worktree: .cw-worktrees/yaletown │
├─────────────────────────────────────────────────────────────┤
│ Q1: What should the production domain be? │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ app.example.com │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ Q2: Any custom environment variables needed? │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ FEATURE_FLAGS=beta │ │
│ │ API_RATE_LIMIT=1000 │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
│ [Cancel] [Send Answers] │
└─────────────────────────────────────────────────────────────┘
Notification Message (No Response)
┌─────────────────────────────────────────────────────────────┐
│ yaletown → You 15 minutes ago │
│ Task: Create user schema │
│ Worktree: .cw-worktrees/yaletown │
├─────────────────────────────────────────────────────────────┤
│ │
│ ✓ Task completed successfully │
│ │
│ Created: │
│ - src/db/schema/user.ts │
│ - src/db/schema/session.ts │
│ - migrations/001_create_users.sql │
│ │
│ Ready for merge into main branch. │
│ │
│ [Dismiss] [View Changes] │
└─────────────────────────────────────────────────────────────┘
Component Specifications
InboxList
Props:
messages: Message[]- List of messages to displayfilter: 'all' | 'waiting' | 'completed'- Current filter statesort: 'newest' | 'oldest'- Sort orderonFilterChange: (filter) => void- Filter change handleronSortChange: (sort) => void- Sort change handleronRefresh: () => void- Refresh handleronSelectMessage: (messageId: string) => void- Message selection handler
Behavior:
- Displays message cards in a scrollable list
- Shows unread count badge in header
- Filterable by status (All, Waiting, Completed)
- Sortable by timestamp (Newest first, Oldest first)
- Clicking a message expands the detail view
MessageCard
Props:
message: Message- Message dataisSelected: boolean- Whether this card is currently selectedonClick: () => void- Click handler
Display:
- Sender agent name with status indicator (● waiting, ○ done)
- Message preview (first line, truncated)
- Relative timestamp (e.g., "2 min ago", "1 hour ago")
States:
- Default - normal styling
- Selected - highlighted/expanded
- Unread - bold text, filled indicator
MessageDetail
Props:
message: Message- Full message dataonSubmit: (answers: Record<string, string>) => void- Submit handleronCancel: () => void- Cancel/close handler
Display:
- Header: Sender name, timestamp, task info, worktree path
- Content: All questions with their input components
- Footer: Action buttons (Cancel, Send Answers / Dismiss)
Behavior:
- Validates all required questions are answered before enabling submit
- Calls agent resume with formatted answers on submit
- Closes detail view on cancel or successful submit
QuestionForm
Props:
questions: Question[]- Array of questions to renderanswers: Record<string, string>- Current answer stateonAnswerChange: (questionId: string, answer: string) => void- Answer change handler
Renders:
- Sequential question components based on question type
- Each question has unique ID for answer correlation
- Supports mixed question types in same form
OptionGroup
Props:
questionId: string- Question identifieroptions: Option[]- Available optionsmultiSelect: boolean- Whether to use checkboxes (true) or radio buttons (false)value: string | string[]- Current selectiononChange: (value: string | string[]) => void- Change handlerallowOther: boolean- Whether to show "Other" free-text option
Behavior:
- Radio buttons for single-select (default)
- Checkboxes for multi-select
- "Other" field appears when
allowOtheris true - Typing in "Other" selects it automatically
FreeTextInput
Props:
questionId: string- Question identifierplaceholder: string- Placeholder textmultiline: boolean- Single line or textareavalue: string- Current valueonChange: (value: string) => void- Change handler
Behavior:
- Single line input for short answers
- Textarea for longer content (auto-resize optional)
- Character limit indicator if applicable
Interaction Notes
Message Selection Flow
- User clicks message in InboxList
- MessageCard enters selected state
- MessageDetail panel appears (expands below or in side panel)
- Previous selection collapses
Answer Submission Flow
- User selects/enters answers for all questions
- "Send Answers" button becomes enabled when all required answered
- User clicks "Send Answers"
- System calls
agent.resumewith formatted answers:{ [questionId: string]: answer: string } - Detail panel closes
- Message moves to "Completed" status
- Agent continues execution
Notification Handling
- Completed task notifications don't require response
- User can dismiss to archive
- "View Changes" opens diff/preview (future feature)
Real-Time Updates
- New messages appear at top with subtle animation
- Unread count updates automatically
- Message status updates when agent state changes
- Optional desktop notification for new messages
Filter & Sort Options
Filter Options
| Filter | Shows |
|---|---|
| All | All messages |
| Waiting | Messages requiring response (agent status = waiting_for_input) |
| Completed | Notifications and answered messages |
Sort Options
| Sort | Behavior |
|---|---|
| Newest first | Most recent at top (default) |
| Oldest first | Oldest at top |
Data Schema Reference
Message
interface Message {
id: string
sender: { type: 'agent' | 'user', id?: string }
recipient: { type: 'agent' | 'user', id?: string }
content: string
requiresResponse: boolean
parentMessageId?: string // For response threading
createdAt: Date
}
Question
interface Question {
id: string // Unique ID for answer correlation
question: string // The question text
options?: Option[] // Available choices
multiSelect?: boolean // Checkboxes vs radio buttons
}
interface Option {
value: string
label: string
}
Agent Context
interface AgentContext {
name: string // Human-readable name (gastown, chinatown)
status: AgentStatus // 'waiting_for_input' | 'running' | 'completed'
taskId?: string // Associated task
worktreeId?: string // Associated worktree
}
Wireframe: Agent Inbox Created: 2026-02-02