From a6a938d5ccc985f3b5c39abff7baad66aea97a0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=BE=B7=E5=AE=87?= Date: Tue, 22 Sep 2026 16:07:06 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=87=E6=A1=A3=EF=BC=9A=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E5=BC=95=E7=94=A8=E8=BE=93=E5=85=A5=E5=8C=BA=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E4=B8=8E=E5=AE=BF=E4=B8=BB=E6=B3=A8=E5=85=A5=E7=9A=84=E5=AE=9E?= =?UTF-8?q?=E6=96=BD=E8=AE=A1=E5=88=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 记录一句话交付、五条验收判据、六个提交切分与验证方式 - 追加执行状态:六项已落地内容、顺带清理、验证结果(全绿门禁与定向用例)与未完成项(CSS 类名重命名、真机手感、粘贴解析) --- ...计划】引用输入区重构与宿主注入-2026-09-22.md | 63 +++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 docs/project-memory/plans/【实施计划】引用输入区重构与宿主注入-2026-09-22.md diff --git a/docs/project-memory/plans/【实施计划】引用输入区重构与宿主注入-2026-09-22.md b/docs/project-memory/plans/【实施计划】引用输入区重构与宿主注入-2026-09-22.md new file mode 100644 index 000000000..e2f957c43 --- /dev/null +++ b/docs/project-memory/plans/【实施计划】引用输入区重构与宿主注入-2026-09-22.md @@ -0,0 +1,63 @@ +# 引用输入区重构与宿主注入实施计划 + +对应:[引用候选由宿主注入](../../adr/【ADR】引用候选由宿主注入-2026-09-22.md);决策记录见 `docs/project-memory/shared-memory/decision-log.md` 的 2026-09-22 条目。本计划不含粘贴解析。 + +## 一句话交付与验收判据 + +把 `ResourceReferenceInput` 拆成「纯输入区 + 宿主注入的引用 provider + 独立的选择器面板」,并让附件芯片成为本轮附件的唯一事实源。 + +验收判据: + +1. 输入区不 import 任何具体引用种类,也不判断 `part.type` / `reference.type`:候选、身份解析、正文文本形态都经注入的 provider。 +2. 宿主按需选择性注入:只注入资源 → 只有 `@`;资源 + Skill → `@` 与 `$`;未注入的宿主连触发符都不存在,不需要额外的可见性开关。 +3. 素材选择器面板独立成组件、自己拿数据、由宿主渲染;输入区不再有 `versions` / `activeVersionId` / `showTriggerButton` / `onReferencePickerOpen` / `skills`。 +4. 附件导入成功后以芯片进入正文,失败或异常不插入;控制器不再持有附件数组,「待发送附件列表」删除;上限 8 按草稿中的附件芯片数计算;导入进行中禁止发送。 +5. 行为零变化:改名后芯片显示名自动刷新、打开面板前重读清单、`@`/`$` 候选与键盘交互、上限与失败提示文案逐条一致;唯一例外是已裁决的 Skill 可见性缺陷修复(非 DirectProject 宿主不再出现 `$`)。 + +## 流程判定 + +本次是无行为变化重构加两条已裁决缺陷修复(Skill 可见性、附件单一事实源),按轻量流程只建本实施计划,不新建主规范与里程碑规范;若评审要求补 SDD 里程碑,再单独补。 + +## 提交切分 + +1. **接口与 provider 工厂**:新增 `features/project-workspace/reference-source/types.ts`(`ReferenceProvider`)与四个工厂(资源 / Skill / 附件 / 运行画面区域),配规则矩阵单测:触发符有无、`match` 过滤、`toReference`、`refresh`(改名 / 删除 / 恒等)、`mentionToken`。 +2. **输入区接入注入**:输入区改为按 `providers` 派生候选菜单(不再写死两个触发符)、按数组顺序取第一个非空回答做草稿回填与改名刷新,删除 `skills` prop;测试夹具(22 处 `assets={assets}`)同批迁移为注入 provider。 +3. **面板外移**:素材选择器面板与缩略图预览搬进独立组件,宿主渲染并接线(`onConfirm → insertReferences`),输入区删除相关 props 与其死 CSS 规则(`styles.css` 里 `resource-reference-*` 共 78 条,逐条核对哪些随面板离开而失效)。 +4. **附件并入联合**:附件成为 `ChatReference` 成员,节点层收敛为单一节点类型,附件 chip 的 DOM 契约逐字保留(`data-attachment-reference`、`data-attachment-status`、`title`、移除按钮 `aria-label`)。 +5. **附件单一事实源**:`uploadFiles` 改为返回导入结果,composer 在导入成功后插入芯片、失败不插入;删除控制器附件状态、`ComposerPendingAttachments` 与提交时的附件 parts 拼接;上限改为按草稿芯片数计算,导入进行中禁止发送。 +6. **显示口径与文档**:`directCodexContentToPromptText` 的 token 前后补空白(不重复)并加 `// TODO we will rewrite this with ref as component later.`,显示名反查改由调用方注入;同步更新 `docs/【功能说明】AGC聊天素材引用-2026-09-08.md`(`ResourceReferenceInput` 共用口径、`@`/`$` 可见性、附件入口与上限口径都会变)。 + +`resource-reference-*` 的 CSS 类名重命名(78 条规则 / 15 个文件 / 22 处测试断言)留作最后一个独立机械提交,必须与 `RESOURCE_REFERENCE_OVERLAY_SELECTOR` 常量同批修改。 + +## 验证 + +每个提交后跑定向用例:`npx vitest run apps/ai-game-creator-shell/tests/resourceReferenceInput.test.tsx`,加上该提交触达的宿主用例(聊天 composer / 策划输入盒 / 画布生成面板 / 资源卡快速编辑)。全部完成后跑 `npm run typecheck`、`npm run check:encoding`、`npm run check:doc-index`、`git diff --check`,再按验收判据第 5 条逐条对照行为。真实客户端手感(候选菜单位置、面板内滚轮、附件插入位置)留待真机验收,未执行前按未验证项记录。 + +## 风险与回滚 + +- 漏注入某个宿主会让该宿主静默失去候选;fail-closed 语义正确,但必须在用例里逐宿主覆盖。 +- `LexicalTypeaheadMenuPlugin` 由两个写死实例改为按 provider 派生后,Enter 让位与 Escape 关闭口径要重新覆盖(`mentionMenuOpenRef` 需聚合成「任一菜单开着」)。 +- 附件插入位置在异步导入期间可能漂移:导入失败一律不插入;文档或选区已改动时退到草稿末尾。 +- 删除 `ComposerPendingAttachments` 会连带影响样式与既有断言,属于预期内的行为收敛,需在提交说明里写清。 +- 回滚按提交粒度 revert;无数据迁移,canonical content 形状不变。 + +## 执行状态(2026-09-22) + +已落地的提交内容: + +1. 接口与 provider 工厂:`features/project-workspace/reference-source/types.ts` + 四个工厂(资源 / Skill / 附件 / 运行画面区域),规则矩阵单测落在 `apps/ai-game-creator-shell/tests/referenceSourceProviders.test.ts`(触发符有无、`match` 过滤 / 去重 / 截断、`toReference`、`refresh`(改名 / 删除 / 恒等)、`mentionToken`、`isReady`、Skill 目录「首次 `match` 才读、失败可重试」)。 +2. 输入区接入注入:`providers` / `inputActions` / `submitSuppressed` 三个通用接缝;`skills`、`assets`、`versions`、`activeVersionId`、`showTriggerButton`、`openPicker` 全部删除;`ProviderMentionMenu` 按带触发符的 provider 派生(Enter 让位按 `mentionMenuOpenRef` 聚合)。 +3. 面板外移:`ResourceReferencePicker` + `ResourceReferencePickerAction` 由宿主渲染并接线(`onInsert → insertReferences`、`onOpenChange → submitSuppressed`),三个宿主的 `@` 触发钮位置逐处保持原样。 +4. 附件并入联合:附件成为 `ChatReference` 成员,编辑器只剩 `ResourceReferenceNode` 一种节点,附件 chip 的 DOM 契约逐字保留。 +5. 附件单一事实源:`uploadFiles(files, draftAttachmentCount)` 只返回导入成功的附件、失败不插入;控制器附件状态、`ComposerPendingAttachments`、提交时的附件 parts 拼接都删除;上限按草稿芯片数计算;导入进行中禁止发送。 +6. 显示口径与文档:`directCodexContentToPromptText(content, resolver)` 的 token 前后各补一个空白(不重复)并加 `// TODO we will rewrite this with ref as component later.`;显示名反查改由 `resourceLabelResolver(assets)` 注入;同步更新功能说明、ADR 与决策记录。 + +顺带清理:`ProjectChatComponentProps.activeVersionId` 在策划输入盒不再有 `@` 触发钮之后已无消费方,随本次删除(工作台壳自己的那份仍归 `ProjectDevelopmentView`)。 + +验证结果:`npx tsc -p tsconfig.json --noEmit`、`npm run typecheck`、`npm run check:encoding`、`npm run check:doc-index`、`git diff --check` 全通过;定向用例(`referenceSourceProviders`、`resourceReferenceInput`、`chatPromptPolish`、`resourceReferences`、画布生成面板、快速编辑、资源卡实时集成、`appSurface` 215 项、工作台壳清单合并 / 窗口同步、资源标签统计刷新、版本切换 / 替换)全绿。整仓 `npx vitest run` 仍有与本改动无关的既有环境失败(jsdom 缺 `localStorage`:`clientApi` / `clientAuthStorage` / `clientHttp` / `projectCreationDirectory` / `recentProjectsHook` 与 `src/components/image-editor/*` 若干),失败集合与本改动触及的模块不相交。 + +未完成项: + +- `resource-reference-*` CSS 类名重命名(78 条规则 / 15 个文件 / 22 处断言)仍是独立机械提交,须与 `RESOURCE_REFERENCE_OVERLAY_SELECTOR` 同批修改;本次未动,输入区与面板的既有类名逐字保留。 +- 真实客户端手感(候选菜单位置、面板内滚轮、附件插入位置、`@` 触发钮落点)未做真机验收,按未验证项记录。 +- 粘贴解析仍不在本次范围(未来接入点是 provider 的 `mentionToken` 与既有 `buildContentFromTextTokens`)。