Per-option notes in the ask dialog #236

Merged
lucas merged 1 commit from agent/issue-234-per-option-notes into main 2026-11-09 10:38:34 +01:00
Collaborator

Closes: #234

Every option row in the deck's ask dialog — including the "Other" row — now carries its own note control (a pencil revealed on hover/focus), and the note is attached to exactly one row with the omp CLI's lifecycle rules.

  • apps/web/src/lib/ask-note.ts (new, unit-tested) holds the row/lifecycle rules: noteRowForOption, clearNoteIfRow, clearNoteUnlessRow, CLEAR_NOTE and resolveNote, mirroring pi-tui's noteRowKey / clearNoteIfRow / clearNoteUnlessRow / noteForSubmittedAnswer.
  • AskDialog.tsx gains an OptionRow wrapper (the note button is a sibling of the <label>, since a nested button would toggle the row's input) and the question-level + Add note expander is gone. NoteField is now just the textarea; expansion state lives in answer.noteRowKey.
  • The collapsed card and the Summary tab render the note the submit rules actually keep, so a note that will be dropped is never shown as sent.
  • Editing the custom-answer textarea deliberately does not clear an other note (the text is live here, unlike the CLI's one-shot prompt); submit still drops an other note whose custom text ended up empty. Documented on SelectInput.
  • Protocol: ExtUiDialogResponse.noteOption; the server bridge carries it into DeckSelectAnswer (a blank note drops the label too) and the agent-facing text reads note on <option>: …, unnamed for the custom answer. QuestionResult/AskToolDetails already declared noteOption, so no SDK type divergence.
  • apps/web/src/components/tools/Ask.tsx (transcript card) is unchanged, as planned.

Verification

  • bun test apps/web/src/lib/ask-note.test.ts apps/server/src/bridge/deck-tools.test.ts apps/server/src/bridge/ext-ui-bridge.test.ts — 28 pass.
  • Full bun test — 1569 pass, 0 fail.
  • bun run typecheck — clean across @omp-deck/*.

The manual end-to-end pass from the plan (hover/pencil behaviour, agent-visible note on <label>: line, clearing on deselect) was not run: this session has no browser against bun run dev. The behaviour it checks is covered by the pure resolveNote / clear-rule tests and the bridge tests, except the hover/focus affordance itself.

Closes: #234 Every option row in the deck's ask dialog — including the "Other" row — now carries its own note control (a pencil revealed on hover/focus), and the note is attached to exactly one row with the omp CLI's lifecycle rules. - `apps/web/src/lib/ask-note.ts` (new, unit-tested) holds the row/lifecycle rules: `noteRowForOption`, `clearNoteIfRow`, `clearNoteUnlessRow`, `CLEAR_NOTE` and `resolveNote`, mirroring `pi-tui`'s `noteRowKey` / `clearNoteIfRow` / `clearNoteUnlessRow` / `noteForSubmittedAnswer`. - `AskDialog.tsx` gains an `OptionRow` wrapper (the note button is a sibling of the `<label>`, since a nested button would toggle the row's input) and the question-level `+ Add note` expander is gone. `NoteField` is now just the textarea; expansion state lives in `answer.noteRowKey`. - The collapsed card and the Summary tab render the note the submit rules actually keep, so a note that will be dropped is never shown as sent. - Editing the custom-answer textarea deliberately does **not** clear an `other` note (the text is live here, unlike the CLI's one-shot prompt); submit still drops an `other` note whose custom text ended up empty. Documented on `SelectInput`. - Protocol: `ExtUiDialogResponse.noteOption`; the server bridge carries it into `DeckSelectAnswer` (a blank note drops the label too) and the agent-facing text reads `note on <option>: …`, unnamed for the custom answer. `QuestionResult`/`AskToolDetails` already declared `noteOption`, so no SDK type divergence. - `apps/web/src/components/tools/Ask.tsx` (transcript card) is unchanged, as planned. ## Verification - `bun test apps/web/src/lib/ask-note.test.ts apps/server/src/bridge/deck-tools.test.ts apps/server/src/bridge/ext-ui-bridge.test.ts` — 28 pass. - Full `bun test` — 1569 pass, 0 fail. - `bun run typecheck` — clean across `@omp-deck/*`. The manual end-to-end pass from the plan (hover/pencil behaviour, agent-visible `note on <label>:` line, clearing on deselect) was not run: this session has no browser against `bun run dev`. The behaviour it checks is covered by the pure `resolveNote` / clear-rule tests and the bridge tests, except the hover/focus affordance itself.
The deck's ask dialog collected one note per question with no way to
tell which option it belonged to. Every option row, including the
custom-answer row, now has its own note control, and the note follows
the omp CLI's lifecycle: it lives on exactly one row, moves when
another row is noted, is dropped when that row is deselected or a
single-select pick lands elsewhere, and is silently dropped at submit
if its row is not part of the answer.

The option label travels to the agent as `noteOption`, so a note on an
option reads `note on <label>: …`; a note on the custom answer keeps
the unnamed form. The review surfaces show the note the submit rules
actually keep, so a dropped note is never displayed as sent.

Co-Authored-By: Claude Opus 5 via omp-deck
lucas approved these changes 2026-11-09 10:38:30 +01:00
lucas merged commit 050dd53073 into main 2026-11-09 10:38:34 +01:00
lucas deleted branch agent/issue-234-per-option-notes 2026-11-09 10:38:35 +01:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
lucas/omp-deck!236
No description provided.