Files
Codewalkers/.planning/phases/19-agent-inbox/19-03-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

5.2 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous
phase plan type wave depends_on files_modified autonomous
19-agent-inbox 03 execute 1
packages/web/src/components/QuestionForm.tsx
packages/web/src/components/OptionGroup.tsx
packages/web/src/components/FreeTextInput.tsx
true
Build the question form components that render multi-question forms with mixed input types.

Purpose: Agents ask structured questions with options (radio/checkbox), multi-select, free-text, and "Other" fields. These components render the question forms inside the message detail view. Following the wireframe spec from docs/wireframes/agent-inbox.md.

Output: QuestionForm, OptionGroup, and FreeTextInput components.

<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 @src/agent/types.ts @packages/web/src/components/ui/input.tsx @packages/web/src/components/ui/label.tsx @packages/web/src/components/ui/textarea.tsx @packages/web/src/components/ui/button.tsx

Task 1: Create OptionGroup and FreeTextInput components packages/web/src/components/OptionGroup.tsx, packages/web/src/components/FreeTextInput.tsx **OptionGroup** — renders radio buttons OR checkboxes for a question's options. Props: - `questionId: string` — for form identification - `options: Array<{ label: string; description?: string }>` — available choices - `multiSelect: boolean` — checkboxes (true) or radio buttons (false) - `value: string` — current selection (for radio: single label, for checkbox: comma-separated labels) - `onChange: (value: string) => void` — change handler - `allowOther?: boolean` — show "Other" free-text option (default true)

Behavior:

  • Radio buttons for single-select (default). Use native HTML radio inputs with Tailwind styling.
  • Checkboxes for multi-select. Use native HTML checkbox inputs with Tailwind styling.
  • Each option shows label and optional description in lighter text
  • "Other" option: text input that auto-selects its radio/checkbox when user types. The "Other" value is whatever the user typed.
  • For multi-select, value is comma-joined selected labels. When "Other" is checked, append the typed text.

FreeTextInput — renders when question has NO options (pure free-text). Props:

  • questionId: string
  • value: string
  • onChange: (value: string) => void
  • multiline?: boolean — textarea vs single input (default false)
  • placeholder?: string

Use shadcn Input for single-line, shadcn Textarea for multiline. Keep it simple. npx tsc --noEmit -p packages/web/tsconfig.app.json - OptionGroup renders radio or checkbox based on multiSelect prop - "Other" field auto-selects when typed into - FreeTextInput renders Input or Textarea based on multiline prop

Task 2: Create QuestionForm component packages/web/src/components/QuestionForm.tsx QuestionForm orchestrates rendering multiple questions with mixed input types. Props: - `questions: Array<{ id: string; question: string; options?: Array<{ label: string; description?: string }>; multiSelect?: boolean }>` — structured question data from agent - `onSubmit: (answers: Record) => void` — submit handler with questionId→answer map - `onCancel: () => void` — cancel handler - `isSubmitting?: boolean` — disable form during submission

Internal state:

  • answers: Record<string, string> — maps question ID to answer string

Behavior:

  1. Render each question sequentially with "Q1:", "Q2:", etc. prefix and question text
  2. For each question, determine input type:
    • If options array exists → render OptionGroup (with multiSelect from question)
    • If no options → render FreeTextInput
  3. Track answers in local state via onAnswerChange callbacks
  4. "Send Answers" button: enabled only when ALL questions have non-empty answers
  5. "Cancel" button: always enabled
  6. On submit: call onSubmit(answers) with the complete answer map
  7. Button row at bottom: [Cancel] [Send Answers] — right-aligned, matching wireframe

Use shadcn Button for actions. npx tsc --noEmit -p packages/web/tsconfig.app.json - QuestionForm renders mixed question types from questions array - Submit disabled until all questions answered - onSubmit called with Record<string, string> mapping questionId to answer

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

<success_criteria>

  • OptionGroup handles radio (single-select) and checkbox (multi-select) with "Other" field
  • FreeTextInput handles single-line and multiline inputs
  • QuestionForm renders sequential questions with correct input type per question
  • Submit validates all questions answered
  • All builds pass </success_criteria>
After completion, create `.planning/phases/19-agent-inbox/19-03-SUMMARY.md`