feat(web): render a plan review as a decision card, not a quiz

The Web composer now renders a request that declares the `plan-review` intent
as its own surface: the waiting-approval card language — amber "Plan review"
strip, the plan as the scrolling markdown body, the question as the card's
accessible name — over one decision row of Chat about it / Refuse / Approve.
Gone from that surface are the 1/1 pager, the numbered radio rows, the custom
answer row, and Skip/Submit, which made approving a plan read as sitting an
exam.

Approve and Refuse answer with the asker's own option labels and keep its
descriptions as tooltips; Chat about it cancels the request so the composer
returns and the user can simply say what they want. Copy is bilingual under the
existing `question` namespace.

The shape choice lives inside the single composer entry rather than a second
chain registration, so the two surfaces cannot race the same carrier, and
`planReviewOf` falls back to the generic flow for any request it cannot render
as a card — the client sits downstream of a wire boundary and every request
must stay answerable.
This commit is contained in:
creatixchu
2026-07-30 19:09:35 +08:00
parent 89d30b0ef7
commit 2363ef01eb
17 changed files with 894 additions and 7 deletions

View File

@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write packages/client/ui-question/README.md
README.md: 0700375758774610fcd897b9a3e16484206a871d
README.zh.md: d9e5eb22cef13e16ab1ce2cebba9e563bd9d08d9
README.md: 6b40c503be61c2458cefceabbb35e16a3befbe66
README.zh.md: 7c0c4ee67d1ef8b4507f3899bdb1ae2f76408032