P1.A14.F4-module-library-from-registry · ModuleLibrary 改 hardcode → /api/plugins/list 数据源
Worker: ClaudeA · 部门: 前端 · 预计: 1.0d · 优先级: P2 · 状态: dispatched
🔍 触发与解锁链
- 触发:ADR-AIOS-14 §4.2 fork 4 · 用户 2026-06-02 11:22
start P1.A14.F4-module-library-from-registry(v1.9 新命名) - 前置就位:fork 1(
3c83f25✅ zombie · framework loader API 落地)+ ADR §2.5 ① 输入输出契约已锁 - 依赖:fork 3 P5.UB14-plugin-management-api(C# IPluginRegistry + REST · ClaudeB 1.5d 还在跑)· 联调依赖:fork 3 zombie 后才能拉真
/api/plugins/list· 本期实装 + mock 数据 + 接口契约对齐 - 解锁:配合 fork 5 xivst-sdk hello-effect-v1.dll 端到端验证(用户拖第三方 module 到 stage)
任务定义(基于 ADR-AIOS-14 §2.5 + §4.2 fork 4)
将 xilink ModuleLibrary 面板从 hardcode module 列表改造为动态 /api/plugins/list 数据源 · builtin / thirdparty 分类显示 + vendor 名标记 · 支持 v7 typeNumId 4 段位 vendorTag 解析(builtin / xistudio_ext / thirdparty / reserved)· 拖拽创建 instance 流程不变(走 ParseLinkFrame typeNumId 路径)。
业务行为契约 5 必填段:完整继承 ADR-AIOS-14 §2.5 ① 输入输出 + ② 收敛判据 + ③ 失败回退 5 类 + ④ 用户操作流 5 步 + ⑤ e2e 真值(本 prompt 不重复 · worker 必读 ADR §2.5)。本 fork e2e 真值落点 = §⑤ 测试用例 Step 3-4(前端 ModuleLibrary 暴露 + 拖入 stage)+ vitest 集成测试(mock /api/plugins/list 返回 builtin + thirdparty 各 ≥ 1 条 · 断言 UI 分类显示)。
完整 prompt(直接复制粘贴 worker 终端)
[U-thread] P1.A14.F4-module-library-from-registry(ADR-14 fork 4 · v1.9 新命名)
[部门] 前端 Vue + TS · ClaudeA · 1.0d · P2
[Worker CWD] d:/work/25_claude/workspace/AlgoDepartment/04_development/
[Occupies] P1.K-module-library(新建 · src/p1-xilink/components/ModuleLibrary/* + composables/usePluginRegistry.ts + types/plugin.ts)
[优先级] P2 · feature · 🧵 file 隔离
[ADR] docs/08-implementation/40-aios/ADR/ADR-AIOS-14-pc-dynamic-plugin-loading.md(必读 §2.3 LoadDynamicPluginsStats schema + §2.5 5 必填段 + §4.2 fork 4 描述)
[参考文档]
- dsp-algo v7 §4.3 module_type_id.h vendor 段位:docs/03-platform/40-dsp-algo/10-architecture-v7.md(0x0000 builtin / 0xAAAA0000+ thirdparty)
- 标本仿写:prompts/done/ADR-AIOS-12/(前端 widget 注册架构 · 若有)or src/p1-xilink/components/ModuleLibrary/ 现有 hardcode 实现
- fork 3 prompt(后端契约对齐):prompts/active/P5.UB14-plugin-management-api.md(C# IPluginRegistry + REST · LoadedPluginInfo schema 含 typeNumId/typeName/vendorTag/source/dllPath)
- fork 1 prompt(framework loader · 已 zombie):prompts/done/ADR-AIOS-14/F1-load-dynamic-plugins-api--3c83f25.md(LoadDynamicPluginsStats 物理意义)
【背景】
ADR-14 §4.2 fork 4:前端 ModuleLibrary 从 hardcode → 动态拉 /api/plugins/list · 支持 builtin + 第三方 module 统一展示。
worker 必读 ADR §2.5 业务行为契约 5 段(input/output + 收敛 + 失败回退 5 类 + 操作流 + e2e 真值)。
注意:fork 3(C# 端)1.5d ClaudeB 在跑 · 本任务可基于 ADR §2.3 schema 先实装 + mock · zombie 时若 fork 3 未 zombie · commit trailer 加 [need: P5.UB14-plugin-management-api] 标识。
【执行步骤 7 步】
Step 1 · 上游真值核查(0.1d)
- read ADR-14 §2.3 LoadedPluginInfo + LoadDynamicPluginsStats schema · §2.5 5 必填段
- read v7 §4.3 module_type_id.h vendor 段位定义(0x0000=builtin / 0xAAAA0000+=thirdparty)
- 检查 fork 3 状态:read prompts/active/P5.UB14-plugin-management-api.md 是否已 mv 到 done/
若否 → 本任务用 mock 数据(typeNumId=0x0001 builtin gain × 2 + typeNumId=0xAAAA0001 thirdparty hello-reverb)
若是 → 本任务直拉真 /api/plugins/list 联调
- npm run typecheck + test:unit 跑当前主仓基线(356/3 应保持)
Step 2 · 新建 types/plugin.ts(0.1d)
- LoadedPluginInfo:typeNumId(number)+ typeName(string)+ vendorTag('builtin'|'xistudio_ext'|'thirdparty'|'reserved')+ source('builtin'|'thirdparty')+ dllPath(string?)
- PluginLoadStats:scanned/loaded/failed/skipped(number)+ lastScanAt(string ISO)
- vendorTag 解析函数 parseVendorTag(typeNumId): VendorTag(高 16 位段位映射)
- 字段对齐 ADR-14 §2.3 + fork 3 后端 LoadedPluginInfo schema
Step 3 · 新建 composables/usePluginRegistry.ts(0.2d)
- useFetchPlugins():Promise<LoadedPluginInfo[]>(GET /api/plugins/list · vue-query 或 fetch + ref)
- usePluginStats():Promise<PluginLoadStats>(GET /api/plugins/load-stats)
- 失败回退 5 类对齐 ADR-14 §2.5 ③(网络错 / 后端崩溃 / DllNotFoundException 503 / vendor 段位 reserved 警告 / 空 list)· UI 表现:加载态 / 错误态 / 空态
- mock 模式开关(若 fork 3 未 zombie):import.meta.env.VITE_MOCK_PLUGINS === 'true' 时返 fixtures
Step 4 · 改造 ModuleLibrary.vue(0.3d)
- 移除 hardcode module 列表 · 改用 usePluginRegistry().fetchPlugins
- 分类展示:Builtin 段(vendorTag === 'builtin') + Third-Party 段(vendorTag === 'thirdparty') + Reserved 段(灰色 disabled)
- 每个 module 卡片显示:typeName + vendorTag badge + (thirdparty 时显示 dllPath 来源)
- 拖拽创建 instance 流程不变(emit drag-start 携带 typeNumId · stage 通过 ParseLinkFrame typeNumId 路径创建)
- 加载态 spinner + 错误态 toast + 空态 placeholder
Step 5 · 新建测试 ModuleLibrary.spec.ts + usePluginRegistry.spec.ts(0.2d · ≥ 5 case)
- case 1 happy:mock /api/plugins/list 返 3 builtin + 2 thirdparty → UI 渲染 5 卡片 + 2 段分类正确
- case 2 vendorTag 解析:typeNumId=0x0001 → builtin · 0xAAAA0001 → thirdparty · 0xFFFF???? → reserved
- case 3 网络错:fetch 503 → UI 显示错误 toast + 不渲染 list
- case 4 空 list:[] → UI 显示空态 placeholder
- case 5 拖拽:drag-start 携带 typeNumId · 不直接创建(交给 stage)
- vitest + @vue/test-utils + msw mock fetch
Step 6 · 端到端真值(0.1d)
- npm run typecheck → 0 error
- npm run test:unit → 356+5 = 361/3(基线保持)
- 启动 dev server(若 fork 3 zombie):curl /api/plugins/list 返 builtin module · 浏览器访问 xilink 面板看到 ModuleLibrary 真数据
- 若 fork 3 未 zombie:VITE_MOCK_PLUGINS=true npm run dev → mock 模式正常 · log "fork 3 联调 pending"
Step 7 · commit(0.1d)
- git add src/p1-xilink/components/ModuleLibrary/ src/p1-xilink/composables/usePluginRegistry.ts src/p1-xilink/types/plugin.ts src/p1-xilink/__tests__/
- subject:feat(P1.A14.F4/module-library-from-registry): ModuleLibrary 改 hardcode → /api/plugins/list 动态数据源
- 三元组 trailer:[step=7/7] [pid=P1] [uid=A14.F4-module-library-from-registry] [occupies=P1.K-module-library] [files=ModuleLibrary/* usePluginRegistry.ts types/plugin.ts __tests__/*]
- 若 fork 3 未 zombie:加 [need: P5.UB14-plugin-management-api] 联调标识
【验收】
☐ 文件清单:types/plugin.ts + composables/usePluginRegistry.ts + ModuleLibrary.vue 改造 + 2 spec.ts(≥ 5 case)
☐ npm run typecheck 0 error · test:unit 361/3(基线 356 + 新增 5)
☐ ModuleLibrary UI:Builtin / Third-Party / Reserved 三段分类显示 · vendor badge · 加载/错误/空态全
☐ vendorTag 4 段位解析正确(builtin / ext / thirdparty / reserved)
☐ 拖拽创建 instance 流程不变(typeNumId 透传 · 不动 stage 端 ParseLinkFrame)
☐ 业务行为契约 5 段引用 ADR-14 §2.5(input/output + 收敛 + 失败回退 5 类 + 操作流 + e2e 真值)
☐ 端到端真值:fork 3 zombie 后联调 builtin gain module 真显示(若 fork 3 未 zombie 留 TODO + commit trailer 标 need)
【禁止】
❌ 不修改 stage 端 ParseLinkFrame / typeNumId 路由(本 fork 仅改 ModuleLibrary 数据源)
❌ 不修改 backend_csharp/* 任何文件(fork 3 处理)
❌ 不修改 framework/* 或 dll/*(fork 1+2 已落地)
❌ 不重新发明 module ABI(强制复用 v7 ModuleFuncTable typeNumId)
❌ 不嵌入完整 Vue SFC > 30 行到 prompt(本 prompt 已严守)· worker 自行仿写现有 ModuleLibrary.vue
❌ commit 不带三元组(7 天宽限期 warning · 6/2 起 strict mode hook 硬拒)
解锁链(本任务 zombie 后)
- ✅ ADR-14 fork 5
xivst-sdk.A14.F5-pc-only-bootstrap(2.0d ClaudeB+Cline-AIOS · 等 fork 2 zombie + 本 fork zombie · 端到端 hello-effect-v1.dll 加载验证) - ✅ ADR-14 §5.3 e2e 真值脚本可起(用户拖第三方 module 到 stage · 注入 1kHz 信号 · 验证 -14dBFS ± 1dB)
风险评估
| 风险 | 缓解 |
|---|---|
| fork 3 未 zombie 时 schema 漂移 | Step 1 必读 fork 3 prompt + ADR §2.3 锁定 schema · 不齐则 commit trailer 留 need 标识 |
| ClaudeA 排队累计(P0.UH12 0.8d + P0.UA13-toolbar 0.5d + 本 fork 1.0d = 2.3d) | 1.0d 工作量 · 文件正交全新建 · 不阻塞前序任务 |
| ModuleLibrary 现有 hardcode 实现差异(可能有自定义 widget 类型已和 typeNumId 不对齐) | Step 1 read 现有 ModuleLibrary.vue · 若有不兼容 → 留 LEGACY_MAP 7 天宽限(对标 ADR-08-R1 normalizeSubgraphDef) |
| 4 段位 vendorTag 在前端类型推断不严 | types/plugin.ts 用 union literal type · 解析函数 + 单测覆盖 4 段位 |
历史
| 时间 | 事件 | hash |
|---|---|---|
| 2026-06-02 11:22 | dispatched · ClaudeA · 1.0d · v1.9 新命名格式首例(P1.A14.F4)· 本期前端框架 + mock + vitest · fork 3 zombie 后联调 | - |