diff --git a/.agents/notes/implemented/feature/2026-07-29-ask-question-web-presentation.i18n.yaml b/.agents/notes/implemented/feature/2026-07-29-ask-question-web-presentation.i18n.yaml index 5d1e095629..b8b98a6ecb 100644 --- a/.agents/notes/implemented/feature/2026-07-29-ask-question-web-presentation.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-29-ask-question-web-presentation.i18n.yaml @@ -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 .agents/notes/implemented/feature/2026-07-29-ask-question-web-presentation.md -2026-07-29-ask-question-web-presentation.md: c51c6458fc01d4d99ec9784566439cfca31c43ad -2026-07-29-ask-question-web-presentation.zh.md: ab027b33ba2874547b986251665d611f5b984762 +2026-07-29-ask-question-web-presentation.md: 280671570ca015457ab3c17241cea3e973b88fd2 +2026-07-29-ask-question-web-presentation.zh.md: 9ad687d655de19ea913ddc5255fb6426ef0fbb77 diff --git a/.agents/notes/implemented/feature/2026-07-29-ask-question-web-presentation.md b/.agents/notes/implemented/feature/2026-07-29-ask-question-web-presentation.md index c51c6458fc..280671570c 100644 --- a/.agents/notes/implemented/feature/2026-07-29-ask-question-web-presentation.md +++ b/.agents/notes/implemented/feature/2026-07-29-ask-question-web-presentation.md @@ -42,7 +42,7 @@ Two adjacent fixes ride along. All generic toolview leading icons (and the hover `ask_user_question` and `todo_write` now demonstrate the intended toolview pattern: compose `ToolRow`, summarize from call args or result JSON with shape-checked fallbacks, and register through the keyed slot. The bespoke `todo-row.module.css` is gone. -The expanded transcript adds a structured-body path to the shared `ToolRow`; other tool views retain their existing generic or specialized cards. The question row reads only persisted call and result fields and does not add a Host presentation field. The approval composer takeover shipped ([web permission and approval](2026-07-23-web-permission-and-approval.md), height-capped per the [approval-panel note](../bug-fix/2026-07-30-approval-panel-command-cap.md)), and `PendingCard` no longer exists. +The expanded transcript adds a typed, plain-data question-card model to the shared `ToolRow`; other tool views retain their existing generic or specialized cards. The question row reads only persisted call and result fields and does not add a Host presentation field. The approval composer takeover shipped ([web permission and approval](2026-07-23-web-permission-and-approval.md), height-capped per the [approval-panel note](../bug-fix/2026-07-30-approval-panel-command-cap.md)), and `PendingCard` no longer exists. `ui-user-questions` gains a `dsh-client-locale` dependency and an inject face where it previously had none; its contract (`QuestionComposerInjected`) lives with the consumer in `contract/slots.ts`. diff --git a/.agents/notes/implemented/feature/2026-07-29-ask-question-web-presentation.zh.md b/.agents/notes/implemented/feature/2026-07-29-ask-question-web-presentation.zh.md index ab027b33ba..9ad687d655 100644 --- a/.agents/notes/implemented/feature/2026-07-29-ask-question-web-presentation.zh.md +++ b/.agents/notes/implemented/feature/2026-07-29-ask-question-web-presentation.zh.md @@ -42,7 +42,7 @@ Web GUI 已经可以通过 `QuestionComposer` 的输入区接管收集回答, `ask_user_question` 与 `todo_write` 现在共同示范预期的 toolview 模式:复用 `ToolRow`、从调用参数或结果 JSON 做带形状校验回退的摘要、通过带 key 的 slot 注册。专用的 `todo-row.module.css` 已删除。 -展开问答记录为共享 `ToolRow` 增加一条结构化内容路径;其他工具视图保留原有的通用或专用卡片。问题行只读取已持久化的调用与结果字段,不增加 Host 呈现字段。审批输入区接管已交付([Web 权限与审批](2026-07-23-web-permission-and-approval.zh.md),并按[审批面板 Agent Note](../bug-fix/2026-07-30-approval-panel-command-cap.zh.md)施加高度上限),`PendingCard` 已不复存在。 +展开问答记录为共享 `ToolRow` 增加类型化的纯数据问题卡片模型;其他工具视图保留原有的通用或专用卡片。问题行只读取已持久化的调用与结果字段,不增加 Host 呈现字段。审批输入区接管已交付([Web 权限与审批](2026-07-23-web-permission-and-approval.zh.md),并按[审批面板 Agent Note](../bug-fix/2026-07-30-approval-panel-command-cap.zh.md)施加高度上限),`PendingCard` 已不复存在。 `ui-user-questions` 新增 `dsh-client-locale` 依赖和此前没有的 inject face;其约定(`QuestionComposerInjected`)与消费方一起放在 `contract/slots.ts`。 diff --git a/apps/web/tests/question-composer.e2e.ts b/apps/web/tests/question-composer.e2e.ts index 36aadf2f20..d0956666b0 100644 --- a/apps/web/tests/question-composer.e2e.ts +++ b/apps/web/tests/question-composer.e2e.ts @@ -75,6 +75,8 @@ function cancelledFixture(fixture: string): string { const event: unknown = JSON.parse(line) if (!isRecord(event)) throw new Error('question fixture event is invalid') if (event.type === 'session') { + // Keep the derived session's relative-time header stable as the source + // fixture ages. event.createdAt = Date.now() lines.push(JSON.stringify(event)) continue @@ -100,7 +102,11 @@ function cancelledFixture(fixture: string): string { text: 'Error: the user cancelled ask_user_question', }] message.content[0].isError = true - data.error = { name: 'UserQuestionError', code: 'ASK_CANCELLED' } + data.error = { + name: 'UserQuestionError', + message: 'the user cancelled ask_user_question', + code: 'ASK_CANCELLED', + } replaced = true lines.push(JSON.stringify(event)) } diff --git a/packages/client/ui-tool/src/client/tool/toolviews/ask-question-row.module.css b/packages/client/ui-tool/src/client/tool/components/AskQuestionCard.module.css similarity index 100% rename from packages/client/ui-tool/src/client/tool/toolviews/ask-question-row.module.css rename to packages/client/ui-tool/src/client/tool/components/AskQuestionCard.module.css diff --git a/packages/client/ui-tool/src/client/tool/components/AskQuestionCard.tsx b/packages/client/ui-tool/src/client/tool/components/AskQuestionCard.tsx new file mode 100644 index 0000000000..d704aea501 --- /dev/null +++ b/packages/client/ui-tool/src/client/tool/components/AskQuestionCard.tsx @@ -0,0 +1,40 @@ +/** Ask-user transcript rendering from validated plain card data. @module */ + +import type { AskQuestionCardModel } from '../models/ask-question-card-model.ts' +import css from './AskQuestionCard.module.css' + +/** + * Render a validated ask-user transcript from plain card data. + * @param props - Localized transcript card data. + * @returns the readable answered or unanswered question list. + */ +export function AskQuestionCard({ card }: { card: AskQuestionCardModel }) { + if (card.kind === 'unanswered') { + return ( +
{card.verdict}
+{transcript.verdict}
-