@givolt/i3-composer-agent 2.3.2 → 2.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/.agents/plugins/marketplace.json +1 -1
  2. package/.claude-plugin/marketplace.json +1 -1
  3. package/.claude-plugin/plugin.json +1 -1
  4. package/.codex-plugin/plugin.json +1 -1
  5. package/README.md +5 -1
  6. package/bin/agent-targets.json +4 -2
  7. package/bin/i3-composer-agent.cjs +44 -8
  8. package/bin/install.cjs +2 -1
  9. package/bin/native-layout.cjs +1 -1
  10. package/bin/tool-selector.cjs +24 -7
  11. package/bin/wizard.cjs +89 -15
  12. package/docs/codebuddy-setup.md +27 -2
  13. package/docs/codex-setup.md +3 -1
  14. package/docs/other-hosts.md +1 -1
  15. package/docs/ui-prototype-native/USAGE.md +4 -2
  16. package/docs/workbuddy-setup.md +3 -1
  17. package/hooks/codebuddy-upstream.cjs +93 -0
  18. package/hooks/i3-prototype.cjs +12 -0
  19. package/hooks/manage.cjs +162 -0
  20. package/package.json +31 -1
  21. package/plugin.json +1 -1
  22. package/scripts/prototype-cache-test.js +55 -0
  23. package/scripts/prototype-generation-entry-test.js +6 -0
  24. package/scripts/prototype-generation-evidence-test.js +10 -0
  25. package/scripts/prototype-generation-native-test.js +78 -0
  26. package/scripts/prototype-generation-test.js +99 -0
  27. package/scripts/prototype-inventory-test.js +43 -0
  28. package/scripts/prototype-locations-test.js +21 -0
  29. package/scripts/prototype-project-test.js +183 -0
  30. package/scripts/ui-prototype-codebuddy-hook-test.js +106 -0
  31. package/scripts/ui-prototype-execution-evidence-test.js +62 -0
  32. package/scripts/ui-prototype-execution-gates-test.js +66 -0
  33. package/scripts/ui-prototype-execution-policy-test.js +42 -0
  34. package/scripts/ui-prototype-execution-runtime-test.js +27 -0
  35. package/scripts/ui-prototype-ide-source-test.js +73 -0
  36. package/scripts/ui-prototype-registration-test.js +53 -0
  37. package/scripts/ui-prototype-transcript-auto-test.js +67 -0
  38. package/skills/i3-frontend-ui-engineering/SKILL.md +1 -1
  39. package/skills/i3-incremental-implementation/SKILL.md +1 -1
  40. package/skills/i3-ui-prototype/SKILL.md +27 -7
  41. package/skills/i3-ui-prototype/assets/capabilities/generation.json +833 -0
  42. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/generation-component-map.json +300 -0
  43. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/starter/src/App.vue +14 -3
  44. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/starter/src/PrototypeShell.vue +59 -0
  45. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/starter/src/config.ts +6 -1
  46. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/starter/src/domain/presentation.ts +29 -0
  47. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/starter/src/style.css +13 -0
  48. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/starter/tests/presentation.test.ts +23 -0
  49. package/skills/i3-ui-prototype/assets/hosts/codebuddy/profile.json +13 -0
  50. package/skills/i3-ui-prototype/assets/optional-skills/host-targets.json +4 -2
  51. package/skills/i3-ui-prototype/assets/templates/catalog.json +2 -1
  52. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/component-inventory.json +707 -0
  53. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/generation.json +49 -0
  54. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/template-inventory.json +28791 -0
  55. package/skills/i3-ui-prototype/assets/templates/gallery/index.html +1 -1
  56. package/skills/i3-ui-prototype/assets/templates/generation-options.js +42 -0
  57. package/skills/i3-ui-prototype/assets/templates/presentation.html +17 -0
  58. package/skills/i3-ui-prototype/references/artifact-contract.md +1 -1
  59. package/skills/i3-ui-prototype/references/content-template.md +9 -4
  60. package/skills/i3-ui-prototype/references/execution-evidence.md +66 -0
  61. package/skills/i3-ui-prototype/references/generation-contract.md +122 -0
  62. package/skills/i3-ui-prototype/references/interaction-acceptance.md +4 -0
  63. package/skills/i3-ui-prototype/references/optional-skills.md +4 -0
  64. package/skills/i3-ui-prototype/references/project-layout.md +92 -0
  65. package/skills/i3-ui-prototype/references/template-adapters.md +6 -0
  66. package/skills/i3-ui-prototype/references/workflow-contract.md +4 -0
  67. package/skills/i3-ui-prototype/scripts/browser-workspace.cjs +72 -0
  68. package/skills/i3-ui-prototype/scripts/codebuddy-context.cjs +75 -0
  69. package/skills/i3-ui-prototype/scripts/codebuddy-hook.cjs +157 -0
  70. package/skills/i3-ui-prototype/scripts/codebuddy-ide-source.cjs +69 -0
  71. package/skills/i3-ui-prototype/scripts/codebuddy-registration.cjs +123 -0
  72. package/skills/i3-ui-prototype/scripts/content-template.cjs +2 -2
  73. package/skills/i3-ui-prototype/scripts/execution-assertions.cjs +43 -0
  74. package/skills/i3-ui-prototype/scripts/execution-evidence.cjs +146 -0
  75. package/skills/i3-ui-prototype/scripts/execution-gates.cjs +147 -0
  76. package/skills/i3-ui-prototype/scripts/execution-policy.cjs +41 -0
  77. package/skills/i3-ui-prototype/scripts/execution-runtime.cjs +60 -0
  78. package/skills/i3-ui-prototype/scripts/generation-assets.cjs +18 -0
  79. package/skills/i3-ui-prototype/scripts/generation-contract.cjs +214 -0
  80. package/skills/i3-ui-prototype/scripts/generation-evidence.cjs +50 -0
  81. package/skills/i3-ui-prototype/scripts/generation-replan.cjs +34 -0
  82. package/skills/i3-ui-prototype/scripts/hosts/codebuddy.cjs +16 -0
  83. package/skills/i3-ui-prototype/scripts/native-delivery.cjs +17 -5
  84. package/skills/i3-ui-prototype/scripts/native-devtools.cjs +1 -0
  85. package/skills/i3-ui-prototype/scripts/native-pilot-lib.cjs +66 -18
  86. package/skills/i3-ui-prototype/scripts/native-pilot.cjs +18 -2
  87. package/skills/i3-ui-prototype/scripts/project-registry.cjs +126 -0
  88. package/skills/i3-ui-prototype/scripts/prototype-hooks.cjs +87 -0
  89. package/skills/i3-ui-prototype/scripts/prototype-lib.cjs +5 -7
  90. package/skills/i3-ui-prototype/scripts/prototype-locations.cjs +5 -1
  91. package/skills/i3-ui-prototype/scripts/template-contract.cjs +11 -2
  92. package/skills/i3-ui-prototype/scripts/template-inventory.cjs +78 -0
@@ -12,7 +12,7 @@
12
12
  <body>
13
13
  <header><h1>选择原型类型</h1><p>双击即可离线预览完整内容模板;修改后刷新。生成原型时再结合需求与目标框架实现。</p>
14
14
  <div class="options" aria-label="原型类型"></div>
15
- <div class="summary"><p id="summary" role="status">正在读取模板…</p><a id="open" target="_blank" rel="noopener">打开完整演示 ↗</a></div>
15
+ <div class="summary"><a href="../presentation.html" target="_blank" rel="noopener">选择风格、布局与密度 ↗</a><p id="summary" role="status">正在读取模板…</p><a id="open" target="_blank" rel="noopener">打开完整演示 ↗</a></div>
16
16
  </header>
17
17
  <iframe title="企业管理后台完整交互演示"></iframe>
18
18
  <script src="../catalog.js"></script>
@@ -0,0 +1,42 @@
1
+ // Generated from registered template metadata; refresh with sync-generation-assets.
2
+ globalThis.I3_GENERATION_OPTIONS = [
3
+ {
4
+ "id": "enterprise-admin",
5
+ "name": "企业管理后台",
6
+ "defaults": {
7
+ "layout": "sidebar",
8
+ "style": "business",
9
+ "density": "standard"
10
+ },
11
+ "choices": {
12
+ "layout": {
13
+ "sidebar": "侧栏导航",
14
+ "topbar": "顶部导航",
15
+ "mixed": "顶部+侧栏",
16
+ "focused": "独立工作区"
17
+ },
18
+ "style": {
19
+ "business": "商务稳重",
20
+ "minimal": "简约清晰",
21
+ "soft": "轻盈柔和"
22
+ },
23
+ "density": {
24
+ "compact": "紧凑",
25
+ "standard": "标准",
26
+ "comfortable": "宽松"
27
+ }
28
+ },
29
+ "patterns": [
30
+ "management-list",
31
+ "tree-list",
32
+ "tree-table",
33
+ "edit-form",
34
+ "form-page",
35
+ "detail",
36
+ "wizard",
37
+ "workflow",
38
+ "permissions",
39
+ "content"
40
+ ]
41
+ }
42
+ ];
@@ -0,0 +1,17 @@
1
+ <!doctype html>
2
+ <html lang="zh-CN"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>原型风格与布局选择</title><link rel="icon" href="data:,"><style>
3
+ *{box-sizing:border-box}body{margin:0;background:#f4f6fa;color:#23304a;font:15px/1.6 system-ui,sans-serif}main{max-width:1200px;margin:auto;padding:24px}h1{margin:0 0 8px}p{margin:8px 0 20px}.controls{display:flex;gap:16px;flex-wrap:wrap;margin:20px 0}label{display:grid;gap:6px}select,button,textarea{font:inherit;padding:8px;border:1px solid #b3bfd1;border-radius:6px}a{color:#1455bc}button{cursor:pointer;background:white;color:#1455bc}:focus-visible{outline:3px solid #1455bc;outline-offset:3px}.preview{--gap:20px;--radius:6px;display:grid;grid-template-columns:180px 1fr;grid-template-rows:auto auto 1fr;border:1px solid #cad2df;border-radius:var(--radius);overflow:hidden;min-height:320px;background:#edf1f7}.header{grid-column:1/-1;display:flex;justify-content:space-between;padding:16px;background:white;border-bottom:1px solid #dae1eb}.top{grid-column:1/-1;padding:10px 20px;background:white;border-bottom:1px solid #dae1eb}.side{padding:16px;background:white;border-right:1px solid #dae1eb}.side div{padding:8px;margin-bottom:8px}.active{background:#e6efff;color:#1455bc;border-radius:4px}.content{min-width:0;margin:var(--gap);padding:var(--gap);background:white;border:1px solid #dae1eb;border-radius:var(--radius)}.toolbar{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:12px}.mock-input{background:#f3f5f9;border:1px solid #c4cddb;border-radius:4px;padding:6px 12px}.row{display:grid;grid-template-columns:30px 1fr 1fr;gap:8px;padding:10px;border-top:1px solid #e1e6ee}.layout-topbar,.layout-focused{grid-template-columns:1fr}.layout-topbar .side,.layout-focused .side,.layout-sidebar .top,.layout-focused .top{display:none}.layout-focused .content{width:calc(100% - 2 * var(--gap));max-width:860px;justify-self:center}.style-minimal .content{border-color:transparent}.style-soft{--radius:10px}.style-soft .content{box-shadow:0 4px 20px #23304a10}.style-minimal{--radius:4px}.density-compact{--gap:12px}.density-compact .row{padding:6px}.density-comfortable{--gap:28px}.density-comfortable .row{padding:14px}textarea{width:100%;min-height:150px;background:white}.notice{border-left:4px solid #1455bc;padding-left:14px}@media(max-width:640px){main{padding:16px}.preview{grid-template-columns:1fr}.side{display:none}.content{margin:8px;padding:12px}.header{flex-wrap:wrap;gap:8px}}
4
+ </style></head><body><main>
5
+ <a href="gallery/index.html">返回完整内容模板</a><h1>原型风格与布局选择</h1><p>先预览结构和间距,再把下方配置交给原型 Skill。此页可离线打开,选择不会写入业务项目。</p>
6
+ <div class="controls"><label>模板<select id="template"></select></label><label>页面布局<select id="layout"></select></label><label>整体风格<select id="style"></select></label><label>信息密度<select id="density"></select></label></div>
7
+ <div id="preview" class="preview" aria-label="外壳与间距示意"><div class="header"><strong>业务原型</strong><span>主题:明亮</span></div><div class="top">工作台  ·  业务管理  ·  设置</div><aside class="side"><div>工作台</div><div class="active">业务管理</div><div>设置</div></aside><section class="content"><h2>业务列表</h2><div class="toolbar"><span class="mock-input">查询条件</span><span class="mock-input">查询</span><span class="mock-input">重置</span></div><div class="row"><span>□</span><b>名称</b><b>状态</b></div><div class="row"><span>□</span><span>示例条目</span><span>正常</span></div><div class="row"><span>□</span><span>示例条目</span><span>待处理</span></div><p>共 20 条  1 2 下一页</p></section></div>
8
+ <p class="notice">这里展示风格、布局与密度示意。生成后的原型使用真实组件,保留明亮、暗黑、清新、科技切换;抽屉、树、校验等交互在实际业务工程中实现并验收。</p>
9
+ <label for="configuration">交给原型 Skill 的选择配置</label><textarea id="configuration" readonly></textarea><button id="copy" type="button">复制配置</button><span id="status" role="status"></span>
10
+ <script src="generation-options.js"></script><script>
11
+ const byId=id=>document.getElementById(id),templates=globalThis.I3_GENERATION_OPTIONS;
12
+ function fill(select,values,selected){select.replaceChildren();for(const [value,label]of Object.entries(values)){const option=document.createElement('option');option.value=value;option.textContent=label;select.append(option)}select.value=selected}
13
+ function update(){const presentation=Object.fromEntries(['layout','style','density'].map(key=>[key,byId(key).value]));byId('preview').className=`preview layout-${presentation.layout} style-${presentation.style} density-${presentation.density}`;byId('configuration').value=JSON.stringify({template:byId('template').value,generation:{presentation}},null,2)}
14
+ function chooseTemplate(){const meta=templates.find(item=>item.id===byId('template').value);for(const key of ['layout','style','density'])fill(byId(key),meta.choices[key],meta.defaults[key]);update()}
15
+ try{fill(byId('template'),Object.fromEntries(templates.map(item=>[item.id,item.name])),templates[0].id);byId('template').addEventListener('change',chooseTemplate);for(const key of ['layout','style','density'])byId(key).addEventListener('change',update);chooseTemplate()}catch(error){byId('status').textContent='无法读取已登记选项:'+error.message}
16
+ byId('copy').addEventListener('click',async()=>{try{await navigator.clipboard.writeText(byId('configuration').value);byId('status').textContent=' 已复制'}catch{byId('configuration').select();byId('status').textContent=' 请复制选中的配置'}});
17
+ </script></main></body></html>
@@ -33,7 +33,7 @@ node_modules、缓存、执行状态、QA 证据不进入候选摘要。正式
33
33
 
34
34
  以下合同保留既有实例解释,不能补写 v2 字段、重新计算旧摘要或迁移已确认快照。新执行者需要先判运行层,再选择脚本。
35
35
 
36
- 项目 `.i3-ui-prototypes.json` 的 prototypes 列出 id、相对目录和 appliesTo。初始 appliesTo 为空,按实际业务补充模块范围;工程任务选择适用原型,不能把所有基线强加到无关模块。
36
+ 项目新索引为 `prototypes/index.json`;只有旧 `.i3-ui-prototypes.json` 时保持兼容并继续使用原索引,直到显式迁移。prototypes 条目列出 id、相对业务项目根目录的 directory 和 appliesTo;新原生实例从固定 scope.moduleIds 去重生成关联,空数组表示未关联。旧 scope 没有 moduleIds 时不自动补写或改动旧摘要。索引与输入不一致时查询报告失败;多个匹配保持歧义,不能自动套用任意基线。目录、同步与迁移命令见 [project-layout.md](project-layout.md)。
37
37
 
38
38
  原型目录含 prototype.json、requirements-map.json、design-system/MASTER.md 与 tokens.json、app、mocks、qa、reviews、baselines、baseline.json、HANDOFF.md。企业后台生成 EASEL 完整参考示例,兼容旧模板生成通用演示;用于新业务时代理必须适配实际业务。企业后台还保留 design-system/source.json、runtime 与 purpose,记录来源、实例数据隔离及用途。模板来源与许可在技能资源中保留。生成实例 app/qa 是来源历史记录;本轮验收证据必须写入根目录 qa,不能复用历史通过状态。
39
39
 
@@ -36,11 +36,14 @@ i3-ui-prototype/
36
36
 
37
37
  ## 需求与通用能力
38
38
 
39
- 完整参考含多种页面,不能默认把所有参考业务生成到新项目。先根据实际 PRD 声明页面与区域。新整理的 scope 放在本次允许写入的 `.prototype-preparation/<id>/scope.json`;已有范围文件只读引用,不改项目其他文件或提前创建原型目标目录。示例仅解释格式:
39
+ 新 scope 使用 schemaVersion=3,包含页面模式、客户选择、逐字段/操作、逐参考功能节点取舍和实施/证据绑定。完整当前格式见 [generation-contract.md](generation-contract.md)。下列 schemaVersion=2 示例仅解释旧输入兼容,不作为新任务起点。
40
+
41
+ 完整参考含多种页面,不能默认把所有参考业务生成到新项目。先根据实际 PRD 声明页面与区域。新整理的 scope 放在本次允许写入的 `prototypes/.preparation/<id>/scope.json`;已有范围文件只读引用,不改项目其他文件或提前创建原型目标目录。示例仅解释格式:
40
42
 
41
43
  ```json
42
44
  {
43
- "schemaVersion": 1,
45
+ "schemaVersion": 2,
46
+ "moduleIds": ["asset-management"],
44
47
  "title": "资产管理原型",
45
48
  "pages": [{
46
49
  "id": "assets", "title": "资产台账", "referencePage": "models-page",
@@ -57,16 +60,18 @@ i3-ui-prototype/
57
60
  }
58
61
  ```
59
62
 
63
+ moduleIds 只使用真实 PRD 或项目明确的稳定模块标识,未关联时填 [];多个 PRD 分别记录需求来源与版本,模块去重生成共享索引的 appliesTo。示例模块 ID 不能冒充真实 PRD 标识。旧 scope 不自动补字段。目录与关联查询见 [project-layout.md](project-layout.md)。
64
+
60
65
  `referencePage` 取本次选定模板索引的页面 ID;`template-page` 只读返回所选页面 HTML。显式引用旧副本时包含其已同步修改。业务 page/region ID 保持稳定;不能把示例 PRD 来源冒充实际需求。
61
66
 
62
- 区域类型为 `management-list`、`edit-form`、`content`;只声明本次真实页面。默认列表需要查询、复选、分页、批量和反馈;编辑需要表单与反馈。默认分页为 adjustable,默认 10、选项 10/20/50,至少三页默认容量测试数据;可在区域的 `parameters.pagination` 明确覆盖。固定分页须写 mode=fixed、fixedPageSize 和 minimumTestPages,不能混入可调参数。按真实需要在区域的 `parameters.<capabilityId>` 覆盖其他参数。
67
+ 旧 v2 区域类型为 `management-list`、`edit-form`、`content`;只声明本次真实页面。默认列表需要查询、复选、分页、批量和反馈;编辑需要表单与反馈。默认分页为 adjustable,默认 10、选项 10/20/50,至少三页默认容量测试数据;可在区域的 `parameters.pagination` 明确覆盖。固定分页须写 mode=fixed、fixedPageSize 和 minimumTestPages,不能混入可调参数。按真实需要在区域的 `parameters.<capabilityId>` 覆盖其他参数。
63
68
 
64
69
  新流程额外固定 `app-shell/appearance/theme`,包含明亮/暗黑/清新/科技且默认明亮。原型 Skill 检查区域声明是否对应实际需求;检查器重算各区域的必需能力、参数与验收。定义检查不自动证明页面实现。
65
70
 
66
71
  ## 创建与验收
67
72
 
68
73
  ```sh
69
- node <skill-root>/scripts/native-pilot.cjs create --project <project-root> --id assets --scope <project-root>/.prototype-preparation/assets/scope.json --expert-mode professional --provider <uiux-root>
74
+ node <skill-root>/scripts/native-pilot.cjs create --project <project-root> --id assets --scope <project-root>/prototypes/.preparation/assets/scope.json --expert-mode professional --provider <uiux-root>
70
75
  ```
71
76
 
72
77
  缺实际 scope 拒绝创建,不回退固定设备演示。初始化保存完整模板快照、scope、能力定义和绑定、框架版本、验收及需求映射,产生 Vue/antDv-next 骨架和四主题。主会话继续使用前端技能、官方框架知识和 UIUX 取舍实现业务。骨架是 `business.status=needs-adaptation`,state 下一步为 implement-business,不能作为已完成原型验收;完成实际页面后更新 adapted 并重新取得当前摘要。
@@ -0,0 +1,66 @@
1
+ # CodeBuddy A+B 执行合同
2
+
3
+ <!-- i3:zh-guide:start -->
4
+ ## 中文使用说明
5
+
6
+ 按下文完整工程步骤、检查项与验证条件执行。根据任务选择适用步骤,保留证据、风险和退出条件;正文示例中的英文标签在面向用户输出时译为中文。
7
+
8
+ 默认使用简体中文解释、追问及生成报告;用户明确要求其他语言时可切换。原方法正文、引用、阈值和审批条件完整保留。代码标识、路径、命令、工具参数、JSON 键/枚举与原文引用保持原样。
9
+ <!-- i3:zh-guide:end -->
10
+
11
+ 本合同首期支持 CodeBuddy 的 command Hooks;IDE、Code CLI 的原生安装与实际日志格式仍须用户手测。不是新增专责 Agent,不改 using 的发现/路由、上游前端/浏览器方法或上游 Hooks。A 是确定性门禁,B 采集与绑定原生来源;没有 C 提示词对照表方案。
12
+
13
+ ## 安装范围与原生生效
14
+
15
+ 安装器统一使用 `--hooks keep|enable|list|check|disable` 与 `--hook-groups session-start,sdd-cache,simplify-ignore,prototype|all`;默认 keep,启停不指定组时沿用旧用法仅针对 prototype。`--prototype-hooks keep|enable|check|disable` 作为原型组兼容参数保留,`--yes` 不隐含 enable。启用时选择 `--codebuddy-product ide|cli`;记录 `--codebuddy-version` 的实际版本。项目/全局 IDE/CLI 新启用默认 `transcriptMode=auto`,每次从原生 Hook 的 `transcript_path` 取得具体会话文件,不扫描目录或挑选最新日志。`--codebuddy-transcript-root <实际日志绝对目录>` 是可选手动限制;原有 transcriptRoots 注册继续按 manual 限制,不被升级放宽,显式传 `auto` 可切回自动。不能用业务 QA 或人为导出的会话文件;路径自动识别也不证明格式已支持。不把 IDE 示例后缀当成实际格式;协议不支持时来源未核验,不猜工具 ID。
16
+
17
+ 原型 Hook 的新注册入口是 `<host-base>/i3-composer-agent/hooks/i3-prototype.cjs`,委托本 Skill 的 `scripts/hosts/codebuddy.cjs`;旧入口继续兼容。统一管理入口为同目录 `manage.cjs`,原版三组由 `codebuddy-upstream.cjs` 包装,原脚本不改。设置在所选范围 `.codebuddy/settings.json`;原型归属记录继续在 `.codebuddy/state/i3-prototype/installation.json`,通用归属在 `.codebuddy/state/i3-composer-agent/hooks.json`。项目注册引用项目副本,全局注册引用全局副本。保留原设置、权限和其他 Hook;无效 JSON、被手改的自有注册、共享 WorkBuddy 目标或未知配置归属拒绝合并。Windows 命令引用尚未验证,此 B profile 不宣称支持。
18
+
19
+ 独立统一管理可调用 `node <host-base>/i3-composer-agent/hooks/manage.cjs list|check|enable|disable --host codebuddy --scope project|global --project <project-root> --groups prototype`。旧 `node <skill-root>/scripts/prototype-hooks.cjs check|enable|disable` 参数保持且只针对 prototype。启用增加 `--product ide|cli`、`--product-version <实际版本>`;可选 `--transcript-root <目录|auto>`。全局配置根遵循绝对 `CODEBUDDY_CONFIG_DIR`,未设置时为 `~/.codebuddy`,工具、注册、状态和运行时选择使用同一根。check 不执行安装、不写配置或缓存。首次没有实际日志时 `transcript.status=awaiting-native-event`,配置可注册但证据尚未核验;不是安装失败,也不算 active。CLI 注册后需用户在原生 `/hooks` 审核,然后新建会话;IDE 需重载。状态为 files-present/registered/pending-host-review/active/failed 等,active 只指展示的项目/会话和当前注册/脚本字节的近期事件。它不代表所有项目已激活或业务已通过。原版三组的 triggered 仅表示包装回调观察,仍是未核验等级。
20
+
21
+ IDE 对存在的项目设置保守按覆盖处理,不能穿透到全局冒称生效;CLI 在项目/全局合并来源中优先选自有项目绑定,否则全局。未选中的回调退出,选中状态用锁和原生来源游标去重。配置、脚本或 profile 改动使旧观察失效;重复启用不增加注册。disable 仅撤销自有配置,不删除原型与 QA。卸载核心前先 disable,避免悬空自有命令。
22
+
23
+ ## 新实例的固定预期
24
+
25
+ 先固定 scope,运行:
26
+
27
+ ```sh
28
+ node <skill-root>/scripts/native-pilot.cjs execution-assertions-template --scope <scope-file>
29
+ ```
30
+
31
+ 返回所有适用业务/框架场景及 `checks: []`。依据 PRD、绑定参数、框架场景填写每项检查,再传 `create --host codebuddy --execution-policy codebuddy-ab-v1 --execution-assertions <file>`。这个读取命令没有写入副作用。文件置于 `prototypes/.preparation/<id>/`;不更改随包 HTML 模板。每个场景至少一条,不能漏场景或用 `passed` 作实际事实;预期随其他 inputs 固定,不在验收后改到与结果一致。
32
+
33
+ ```json
34
+ {"scenarioId":"orders/list/form-validation","checks":[
35
+ {"method":"evaluate_script","pointer":"/form/invalidFields","operator":"equals","expected":1}
36
+ ]}
37
+ ```
38
+
39
+ 实际原生 evaluate_script 应读取真实 DOM/组件可观察状态并返回可解析 JSON(或唯一 JSON 代码块),例如 `{"form":{"invalidFields":1}}`。使用正常 click/fill 等完成业务操作,不在求值中直接修改业务状态制造通过。支持 equals、includes、gte、lte,JSON pointer 路径必须存在。视觉、语义、动效中间态、毛玻璃呈现仍按浏览器 Skill 方法复核,数值检查不代替人工质量判断。
40
+
41
+ ## 会话绑定与阶段
42
+
43
+ 通过自然语言/using 选到工作 Skill,或实际 `/i3-prototype` 快捷入口后,新实例执行 `execution-begin <prototype-root>`。B 回查原生用户请求和工作 Skill/快捷命令,绑定规范化 projectKey、sessionId、runId、实例、输入、模式、策略与注册。只读或停止请求不能启动写任务。新会话/新请求/压缩后的上下文在恢复实施前重新 begin 并加载适用 Skill;用户手改保留。初建骨架不等于实际实施。
44
+
45
+ `execution-template <prototype-root>` 只读返回当前证据骨架和已经成功返回的 Skill 引用;保存并填入 `qa/execution-evidence.json`。字段语义:
46
+
47
+ - 固定身份:schemaVersion=1、runId、sessionId、projectKey、policyDigest、inputDigest、candidateDigest、revision,须与当前绑定一致。
48
+ - frontend:真实 Skill 的 toolCallId/resultDigest;files 覆盖实际 app/src、mocks 和实现映射引用,每项 path/sha256;requirementIds 覆盖固定需求。首次业务 UI Write/Edit 在成功加载之后;实现后依据完整前端规范审查,而非只改 adapted。
49
+ - official:skill 真实 antDv 加载;version 是目标版本包/类型/源码查询的真实 toolCallId 和 quote;queries 每项 component、toolCallId、quote,覆盖当前实现映射的实际框架组件。CLI 数据 1.5.2 不得当成目标 1.5.3。固定 probe 不能替代业务 API 核实。合法 fallback 需 channel=official-source、unavailable.toolCallId 指向真实不可用返回,以及官方资料/目标类型结果。
50
+ - uiux(professional):真实 skill 引用;queries 每项 query、toolCallId、quote、decisions;decision 字段 identity、decision、rationale,采用/调整还要 implementation 和 scenarioId。原始条目身份必须在返回中,且与 qa/design-advice.json 的 resultIdentity、query、decision、rationale 一致。拒绝或 no-match 允许,不能假称采用。template 需 templateChoice.quote 指向真实用户的明确模式选择,功能场景照验。
51
+ - build:实际 native-pilot build 调用的 toolCallId,成功返回必须包含当前 buildId/buildDigest;类型检查、测试和构建按原构建合同。
52
+ - browser:真实浏览器 Skill 引用、report(尚未 record-run 的业务报告可位于 QA)、preview(当前构建 navigate_page/new_page 引用)、identity(实际页面返回的候选摘要 quote)、observations(六类对应原生方法的 toolCallId/quote)、facts。facts 每项 scenarioId、checkIndex、toolCallId、quote 连接固定预期和实际 JSON;每个场景/检查都有成功的真实工具返回。原 devtools 与业务报告的 ID、方法、场景、构建和文件摘要继续校验。
53
+
54
+ 所有引用回查实际 assistant/tool_use、user/tool_result 原文配对。读取 Skill 文件不当成原生加载;只有请求、失败返回、空结果、假 ID、旧会话、上下文失效、无关查询、错误版本、旧构建、被改写的源前缀均不能通过。来源字段来自 command Hook 的 transcript_path/session_id;若宿主日志不是支持的 JSONL 或缺实际会话字段,则 unverified。auto 只使用回调给定的具体文件,校验绝对路径、普通非链接文件、大小、业务目录排除与会话身份;不把任意父目录纳入信任。manual 还必须落在指定日志根。普通模型 JSON 不能替代原生来源,路径及摘要检查仍非防同用户篡改。
55
+
56
+ 本期按完整当前任务重新核验查询;未提供跨任务自动继承查询的捷径。同一会话与上下文内可复用真实 Skill 加载。修复 U01 时先加载、检查现有页面并作本次真实修订;不把旧写入倒填为已满足历史前置。
57
+
58
+ ## 门禁、回传与限制
59
+
60
+ `execution-check --stage design|implementation-entry|implementation|build|browser-entry|browser|delivery`、build、record-run、record-devtools-review、finalize 使用同一谓词。state 展示 execution 缺项及恢复命令,finalize 成功收据包含 runId/policyDigest、证据摘要和调用等级;HANDOFF 显示同一结果。修改源码/输入/设计/QA 会使相应检查失效,旧收据不能复用。
61
+
62
+ B 的 PreToolUse 只拒绝可识别的缺前置 UI 写入或明确阶段命令,不返回强制 allow,不替换原生结果。它不是通用 Shell 文件隔离器;未知 Shell 写法和所有自然语言完成方式不保证被拦截。Stop 对已纳管当前任务、可识别的完成声明且缺有效收据时反馈一次;进度、blocked、awaiting-input、用户停止正常结束,不能无限循环。崩溃/超时不生成成功记录,A 拒绝无有效来源的严格完成。
63
+
64
+ 本地原文、索引与配置同属用户权限域,`native-source-correlated` 表示受配置来源的逐项回查,不是防篡改签名。文件摘要、chmod、机器落盘或模型自述均不能单独证明可信。若日志本身缺独立可信来源,结果继续披露 unverified,需用户检查真实宿主调用。本测试包原生 profile 状态 pending-user;源码/合成/打包通过不改变它。
65
+
66
+ 旧 HTML/未采用 executionPolicy 的原生实例继续原摘要、输入、场景与基线,不自动迁移,新等级为 unverified。四主题、完整离线 HTML、业务共享索引和 moduleIds→appliesTo 不变;跨宿主可读共享原型,不继承 CodeBuddy 的调用证明。
@@ -0,0 +1,122 @@
1
+ # 模板、客户选择与逐项生成合同
2
+
3
+ <!-- i3:zh-guide:start -->
4
+ ## 中文使用说明
5
+
6
+ 按下文完整工程步骤、检查项与验证条件执行。根据任务选择适用步骤,保留证据、风险和退出条件;正文示例中的英文标签在面向用户输出时译为中文。
7
+
8
+ 默认使用简体中文解释、追问及生成报告;用户明确要求其他语言时可切换。原方法正文、引用、阈值和审批条件完整保留。代码标识、路径、命令、工具参数、JSON 键/枚举与原文引用保持原样。
9
+ <!-- i3:zh-guide:end -->
10
+
11
+ ## 分工和规则
12
+
13
+ HTML 提供完整内容和交互参考,可双击 index.html 离线修改。全量 template-inventory.json 登记所有资源摘要、路由、片段、节点属性、组件出现位置和事件;component-inventory.json 显式分类,不认识的新组件须先登记,不能静默忽略。清单验证能发现来源变化,不能替代对业务语义的人工判断。
14
+
15
+ assets/capabilities/generation.json 是独立的语义目录。核心必需:布局、导航、可访问性、四主题、视觉一致性、有效交互。页面选型后强制产生对应能力:
16
+
17
+ | 页面模式 | 必需能力(核心以外) |
18
+ | --- | --- |
19
+ | management-list | 列表身份、筛选、选择、分页、批量、反馈、列设置 |
20
+ | tree-list / tree-table | 管理列表全部能力,加筛选树/树表展开与勾选规则 |
21
+ | edit-form / form-page | 编辑、未保存保护、反馈;edit-form 另含弹层生命周期 |
22
+ | detail / content | 对象详情、反馈 |
23
+ | wizard | 分步、编辑、未保存保护、反馈 |
24
+ | workflow | 画布、编辑、未保存保护、反馈 |
25
+ | permissions | 权限、层级、编辑、未保存保护、反馈 |
26
+
27
+ 删除、菜单、状态转换、关系选择、持久化等从实际参考和需求中决定是否采用。列表工具不把“删除”强加给只读业务;选中的管理列表不能漏复选/分页/列设置。源模板里的导航树和权限树有明确记录,分类树列表/树表属于生成模式能力,仍需按业务实现,不能声称原 HTML 已有这两个示例。
28
+
29
+ 模板 generation.json 独立声明支持的框架、模式、默认值、客户选择和规则摘要。首期框架 Vue 3+antDv-next;4 布局、3 风格、3 密度进入真实原生外壳和候选摘要。支持的模板可替换;不同运行组织先明确适配,未知模板不回退。新增模板的维护步骤见 [template-adapters.md](template-adapters.md)。
30
+
31
+ 原型 Skill 在主会话确定范围并维护合同;前端 Skill 实现真实页面;框架官方 Skill/同版本资料确定组件 API;UIUX Pro Max 在客户已选方向内建议颜色、层次、排版、密度、反馈和可访问性,并记录采用/拒绝与实际验证。它不能替代缺失功能或覆盖客户选择。UIUX 和官方 Skill 独立可选,按已有接入合同后续检测。
32
+
33
+ ## 新 scope 格式
34
+
35
+ 下例仅演示结构,fixture 来源须替换为真实 PRD。新创建使用 schemaVersion=3;原型 prototype.json 仍为原生 schemaVersion=2,两者不是同一个版本字段。
36
+
37
+ ```json
38
+ {
39
+ "schemaVersion": 3,
40
+ "moduleIds": ["asset-management"],
41
+ "title": "资产原型",
42
+ "generation": {
43
+ "presentation": {"layout": "mixed", "style": "soft", "density": "standard"},
44
+ "navigation": [{"id":"business","title":"业务管理","children":[{"pageId":"assets"}]}],
45
+ "decisions": [],
46
+ "referenceDecisions": []
47
+ },
48
+ "pages": [{
49
+ "id": "assets", "title": "资产台账", "referencePage": "models-page",
50
+ "regions": [{
51
+ "id": "list", "pattern": "tree-list",
52
+ "parameters": {"hierarchy": {"kind":"filter-tree","selectionPolicy":"single"}},
53
+ "fields": [{"id":"name","label":"名称","kind":"text","required":true,"requirementId":"ASSET-01"}],
54
+ "actions": [{"id":"open","label":"查看","kind":"read","target":"row","outcome":"打开当前行对象的详情并可返回","requirementId":"ASSET-01"}]
55
+ }]
56
+ }],
57
+ "requirements": [{
58
+ "id":"ASSET-01", "text":"按资产层级查询台账并查看对象", "pages":["assets"],
59
+ "source":{"type":"prd","reference":"PRD.md#ASSET-01@v1","statement":"这里保留真实原文"}
60
+ }],
61
+ "exemptions": [], "openQuestions": []
62
+ }
63
+ ```
64
+
65
+ referencePage 从选定模板 template-page 的索引取得,不固定为某个示例。pages、regions、fields、actions 均用稳定且唯一的 ID;字段 kind 当前支持 text/textarea/select/number/checkbox/radio/date/time/tree-select/read-only。可补充必填、范围、长度和联动要求,实际实现与逐字段验收同时对应;未知控件类型先扩展合同,不偷偷改成文本。actions 明确 kind、target、outcome,kind 支持 create/read/update/delete/submit/state-change/other,target 支持 page/row/selected/node。无字段/操作的区域明确留空并在需求覆盖复核中解释,不能以不声明规避检查。导航省略时为全部页面的平面导航;分组时每页必须且只能出现一次,未知深链接显示不存在状态。
66
+
67
+ moduleIds 使用本原型真实稳定模块 ID,未明确填 []。多 PRD 需求逐条保留文件、版本与原文;scope.moduleIds 去重派生共享 prototypes/index.json 的 appliesTo。scope 及原型工程共享;宿主工具/缓存按原目录规则,不在业务根新增工具目录。
68
+
69
+ ## 参考逐项取舍
70
+
71
+ 先运行 generation-plan 只读计算草案,默认返回能力与片段级摘要;用 `--page <业务页面ID或app-shell> --fragment <片段路径>` 分批读取实际待处理节点,`--details` 才输出完整固定合同。不要反复把整份规则和参考闭包塞入上下文。新 v3 的 state 同样返回范围摘要、未决节点数/片段分组与精确命令,完整范围从 scopes.sourceFile 指向的固定文件按页读取;旧输入的 state 形态保持。每个选中页面及外壳的引用闭包保留 referenceCoverage,包括关联业务组件片段、节点和全部事件;不是只查看顶层页面。每个未覆盖的能力出现在 pendingDecisions;每个功能节点另出现在 pendingReferenceElements(装饰图标仍在全量源清单与视觉检查中),即使它属于已采用的 interaction/navigation,也不得被自动当成已处理。
72
+
73
+ 1. `generation.decisions` 对参考能力记录 `{pageId,capabilityId,decision,requirementId,reason}`。decision 为 adopted/not-applicable。采用额外能力时还须指定已声明 regionId,外壳使用 app-shell/shell,可用 parameters 固定规则;所选模式/核心必需项不能 N/A。模式内参数放区域的 parameters,不能混用多处参数或未采用能力的参数。
74
+ 2. `generation.referenceDecisions` 对功能节点记录 `{pageId,nodeIds,decision,requirementId,reason,bindingIds}`。nodeIds 取计算出的实际节点 ID;同类节点可显式列在一组。mapped 必须绑定本页或外壳中真实生成绑定且语义匹配;not-applicable 不填 bindingIds。未知节点、重复处置、错误页面或无来源拒绝。原示例业务的排除也要理由,不能把示例审批规则带入新业务。
75
+ 3. 字段、工具栏、行操作、菜单、展开、树、弹层内操作逐项与 PRD 对照。每个 mapped 功能节点独立产生 referenceNodeId 场景,即使它和其他按钮使用同一个交互能力,也不能靠检查另一个按钮代替。清单可保证已记录的节点没有消失,但从未写入 scope 的 PRD 需求仍需执行者逐条复核。不得声称工具自动理解全部业务。
76
+
77
+ create 可以保留未决项以便在原型 inputs 中继续整理;未决项未归零不能验收。初始未决数较多时,先按页面/片段/能力处理,只加载本页相关片段,不把整套 HTML 塞进上下文。客户选择本业务功能,执行者负责整理清单,不要求客户手填节点 JSON。
78
+
79
+ ## 固定输入和实施映射
80
+
81
+ 生成固定 `inputs/generation.json`、scope、模板快照、原能力、框架映射和 acceptance。generation.definition 固定本次规则,模板快照固定其摘要,检查重算后比对;不追随新安装版本。参考功能节点取舍、各区域/字段/操作和客户选择都有对应检查身份。旧 v1/旧原生 scope v1/v2 不追加此合同。
82
+
83
+ 原生外壳提供实际 Layout/Menu/Drawer、深链接、折叠、移动导航、404 与四主题。业务初始 needs-adaptation,由主会话继续实现。骨架不是完成的业务生成;实现每个绑定后在 `design-system/implementation.json` 中更新对应条目:
84
+
85
+ ```json
86
+ {
87
+ "bindingId": "assets/list/hierarchy",
88
+ "status": "implemented",
89
+ "components": ["Tree"],
90
+ "files": [{"path":"app/src/pages/Assets.vue","locator":"asset-tree"}],
91
+ "scenarioIds": ["generation/assets/list/hierarchy/expand", "generation/assets/list/hierarchy/selection-link"]
92
+ }
93
+ ```
94
+
95
+ files 必须是 app/src、app/public 或 mocks 中存在的实际源码,locator 必须在该文件出现;不能指向需求文档或缺失文件。components 取固定 framework.componentMap 的原语;自定义应用组合写 application:组件名,同时定位实际源码。Tree/Table 原语不自动实现业务联动,canvas 仍需真正实现节点、边和坐标逻辑。每个固定绑定和场景必须保留;初始全部 pending。改业务状态不能替代此映射,源码定位存在也不能证明交互正确。
96
+
97
+ 修订范围:在允许写入的 preparation 或现有指定 scope 文件内整理取舍/选择,运行 state 取得当前摘要,再使用明确写操作:
98
+
99
+ ```sh
100
+ node <skill-root>/scripts/native-pilot.cjs replan <prototype-root> --scope <updated-scope.json> --revision r002 --expected-revision r001 --expected-digest <actual-digest>
101
+ ```
102
+
103
+ replan 只服务已有 v3,沿用本实例模板/规则快照,统一重算 scope、generation、原能力、acceptance、需求映射和应用配置,在原修改权和关联索引事务下接受输入;非法来源/不一致或版本冲突时恢复原文件。实施定位保留供复核,但状态回到 pending,业务回到 needs-adaptation;更新源码并重新登记实际实现、构建和浏览器结果。它不改冻结基线,不升级/降级旧合同,也不把旧取舍自动带入新模板。仅源码修改不改 inputs,使用普通 revise;不得靠手删验收场景使输入通过。模板切换在新实例固定;已有实例更换模板须明确评估新的范围与交接,不隐式覆盖。
104
+
105
+
106
+ ## 交互验收
107
+
108
+ 仍按 [interaction-acceptance.md](interaction-acceptance.md) 对同一候选/构建执行真实浏览器流程并登记;新 v3 的业务报告增加 generationObservations,逐个使用 inputs/generation.json.scenarios 的 ID:
109
+
110
+ ```json
111
+ {
112
+ "scenarioId":"generation/assets/list/hierarchy/expand",
113
+ "bindingId":"assets/list/hierarchy", "status":"passed",
114
+ "steps":[{"action":"展开父节点","target":"实际节点的可访问名称","observed":"实际看到的子节点与数量,随后收起结果"}],
115
+ "toolCallIds":["真实宿主调用ID"],
116
+ "evidence":[{"path":"qa/actual-tree-observation.txt","sha256":"该实际文件的SHA256"}]
117
+ }
118
+ ```
119
+
120
+ 绑定、场景、实际动作/目标/结果、证据字节和当前身份都核对;缺项、变化、未决取舍、pending 实施均拒绝验收。证据可被多个实际相关场景引用,不伪造每场景独立 trace。逐项覆盖布局/风格/密度、四主题、列表/列/树/表单/流程等适用行为,并检查窄屏、键盘、焦点、减少动效、错误及恢复。动效看进出中间态和生命周期,毛玻璃看配置、计算样式及实际效果;不以静态截图代替。
121
+
122
+ 校验器只证明声明与字节一致,返回 invocationVerified=false;真正 Skill/MCP 调用和观测结论仍须核对原宿主记录。无真实执行不填 passed,用户认可仍单独 pending-review。换模板、改客户选择或源码变化后证据按候选身份失效,不能沿用旧通过记录。
@@ -163,3 +163,7 @@ previewBaseURL 是本次真实预览来源。observedResources 来自浏览器
163
163
  | 用户手改后重新初始化 | 不允许覆盖,必须走 revise |
164
164
 
165
165
  验收通过仍为 pending-review。用户只对明确 revision/digest 的认可可用于基线;未运行的项不能写 passed。
166
+
167
+ ## 新 scope v3 的逐项证据
168
+
169
+ 在既有业务报告与 DevTools 主链基础上,完整覆盖固定 generation.json.scenarios、逐参考节点取舍和 implementation.json。generationObservations 的动作/目标/实际结果、工具调用定位、证据摘要及缺项拒绝规则见 [generation-contract.md](generation-contract.md)。不以生成骨架、源码标记或报告字段替代真实交互。
@@ -57,3 +57,7 @@ skills 可选 none、uiux、antdv、uiux,antdv;none 不下载、不写入。gl
57
57
  迁移在同一项目中移动,目标存在则保留并停止;失败恢复旧位置。成功后重验实际入口,仅删除空的旧根;旧根其他内容保留。global 不迁移业务项目工具。查询和迁移不会修改已有原型、输入、基线或旧验收。安装后的模式变更仍须明确修订。
58
58
 
59
59
  官方来源:[UIUX](https://github.com/nextlevelbuilder/ui-ux-pro-max-skill#installation)、[antDv Skill](https://github.com/antdv-next/cli/blob/2b0dc514ee48bc130048724a5c5a0a76ec632aa1/skills/antdv/SKILL.md)。
60
+
61
+ ## 项目资料与运行缓存
62
+
63
+ 工具目录与项目原型分开管理:prototypes/index.json、准备范围、实例输入和正式 QA 跨宿主共享;工具及临时输出依赖所选宿主。项目/全局缓存解析、按项目隔离及索引旧路径兼容见 [project-layout.md](project-layout.md)。只读检测不为打印 cacheDirectory 而创建缓存。
@@ -0,0 +1,92 @@
1
+ # 项目共享目录、宿主缓存与模块关联
2
+
3
+ <!-- i3:zh-guide:start -->
4
+ ## 中文使用说明
5
+
6
+ 按下文完整工程步骤、检查项与验证条件执行。根据任务选择适用步骤,保留证据、风险和退出条件;正文示例中的英文标签在面向用户输出时译为中文。
7
+
8
+ 默认使用简体中文解释、追问及生成报告;用户明确要求其他语言时可切换。原方法正文、引用、阈值和审批条件完整保留。代码标识、路径、命令、工具参数、JSON 键/枚举与原文引用保持原样。
9
+ <!-- i3:zh-guide:end -->
10
+
11
+ ## 目录归属
12
+
13
+ 新项目的原型业务资料统一在 `prototypes/`:索引为 `prototypes/index.json`,准备资料为 `prototypes/.preparation/<id>/`,实例为 `prototypes/<id>/`。仅安装 Skill 不生成这些业务目录。业务修改落在实例 app,需求与模板快照在 inputs,正式设计、QA、交接和基线随项目保留。
14
+
15
+ Skill、命令和辅助工具沿用安装器所选宿主基址;工具仍在 `tools/i3-prototype/`。本地测试安装器的离线 npm 缓存在该基址 `cache/i3-prototype/install/`,预检使用系统临时目录并清理。浏览器工具只有实际执行时才创建自己的缓存,不在业务根默认创建 `.playwright-cli`。
16
+
17
+ | 范围 | 浏览器缓存 |
18
+ | --- | --- |
19
+ | 项目安装 | `<host-base>/cache/i3-prototype/playwright/<run-id>/` |
20
+ | 全局安装 | `<global-host-base>/cache/i3-prototype/<project-key>/playwright/<run-id>/` |
21
+
22
+ project-key 由规范化项目路径生成,包含摘要,同名项目不会共用一个缓存。CodeBuddy 项目/全局基址通常是项目 `.codebuddy`/`~/.codebuddy`;本包 Codex 适配使用项目 `.agents`/`~/.agents`。其他宿主、环境变量覆盖与共享物理目标按现有安装器目标表解析,不改变上游规则。
23
+
24
+ 同一项目换宿主时共用 prototypes;默认只发现当前宿主项目和全局工具。缓存不是需求或交接的唯一保存位置,正式证据归档到实例 QA。共享目录可读不等于某个 AD 流程已经自动接通索引或执行验收。
25
+
26
+ ## 先读取实际路径
27
+
28
+ ```sh
29
+ # 只读,不创建目录;host 与安装范围必须按实际填写。
30
+ node <skill-root>/scripts/native-pilot.cjs paths --project <project-root> --id assets --host codebuddy --scope project
31
+ # 全局 Skill 仍指定业务项目;返回该项目共享路径与全局宿主缓存。
32
+ node <skill-root>/scripts/native-pilot.cjs paths --project <project-root> --id assets --host codebuddy --scope global
33
+ ```
34
+
35
+ paths 返回的 scope 是安装范围,scopeFile 是准备区 scope.json 的完整路径。新 scope 按 scopeFile 保存;不要提前创建实例目录。初始化成功后已将需求固定到 `inputs/scope.json`,生成前的有效查询应归入本实例 QA。确认没有未归档资料后才清理本次工作副本;失败保留恢复所需资料,不删除用户原始需求。
36
+
37
+ ## scope.moduleIds 与 appliesTo
38
+
39
+ 新原生 scope 使用 schemaVersion=2,moduleIds 为数组,例如 `["asset-management", "work-order-management"]`。标识须来自实际 PRD 或已确定项目模块:小写字母开头,使用字母、数字和单个连字符分隔,总长不超过 128;不把文档名、需求全文、代码路径或通配符当模块标识。模块身份不清楚时填 [],不编造标识。
40
+
41
+ 需求的 source.reference 保留具体 PRD、版本与需求编号,statement 保留真实依据。多个 PRD 同模块去重;不同模块取本原型 scope 范围内并集。需求 ID 在本 scope 内唯一,文档冲突明确留作待确认项;模块关联不能代替需求覆盖或完成证明。
42
+
43
+ 创建会将 scope 固定到 inputs,并从 moduleIds 去重生成索引条目的 appliesTo。directory 始终相对业务项目根目录,不相对 index.json 所在目录。旧 scope 没有 moduleIds 时按原合同保留,既有中文模块标签仍可按原文查询;不将新标识格式追溯强加给旧数据。空 appliesTo 表示未关联,不适用于全项目。
44
+
45
+ ```sh
46
+ node <skill-root>/scripts/native-pilot.cjs index --project <project-root> --module asset-management
47
+ ```
48
+
49
+ 查询只读。返回 matches、unbound、selection:多匹配为 ambiguous,不自动挑选“最新”;关联与固定输入不一致时 status=failed,该条目不会进入 matches。随后仍须读取候选、有效 QA 与已认可基线,不能把 matched 当作已验收。
50
+
51
+ 已固定的 scope 改动需按现有 revise 合同明确接受输入、校验摘要并重新验证。`revise --accept-inputs` 接受新 scope 时同步索引,索引写入失败回退本次元数据更改;历史基线与用户编辑的输入不被覆盖。
52
+
53
+ 索引被误改、而固定输入仍有效时可显式修复:
54
+
55
+ ```sh
56
+ node <skill-root>/scripts/native-pilot.cjs sync-index --project <project-root> --id assets
57
+ ```
58
+
59
+ sync-index 只从该实例已接受的固定 scope 生成关联,不修改候选源码、输入或基线;输入尚未明确接受或另一负责人正在写入时拒绝。没有 moduleIds 的旧合同不自动补值。
60
+
61
+ ## 旧索引兼容与显式迁移
62
+
63
+ 只有旧根 `.i3-ui-prototypes.json` 的项目继续读取、更新同一旧索引,不在后台创建第二份;其已有实例保持原目录和摘要。双索引不一致时报告冲突,不能猜测、合并或覆盖。两份相同索引可读取,写入前仍需显式整理为一份。
64
+
65
+ ```sh
66
+ node <skill-root>/scripts/native-pilot.cjs migrate-index --project <project-root> --check
67
+ # 核对预览 sourceDigest,再明确执行:
68
+ node <skill-root>/scripts/native-pilot.cjs migrate-index --project <project-root> --expected-digest <sourceDigest>
69
+ ```
70
+
71
+ 迁移保留索引原文和 directory 的解析基准,将原根索引存档到 `prototypes/.migration/index-<id>/legacy-index.json`,新活动索引为 prototypes/index.json。失败保留原索引、移除本次未提交的新索引,备份可审查;不移原型或重写旧输入。安装/升级不触发该迁移。旧准备目录、模板副本、工具和 `.playwright-cli` 不自动搬动或清空。
72
+
73
+ ## 实际使用 Playwright CLI 时
74
+
75
+ 主验收继续按 i3-browser-testing-with-devtools 与框架合同执行。本节只收纳实际使用的 Playwright CLI 补充输出,不自动安装 CLI/浏览器,不替代 Skill/MCP 调用或业务验收。
76
+
77
+ ```sh
78
+ # 创建该宿主、项目与运行的输出配置,返回 configFile 和环境信息。
79
+ node <skill-root>/scripts/native-pilot.cjs browser-cache --project <project-root> --host codebuddy --scope global --run-id review-r001
80
+ # 也可用包装器运行已有 CLI 的 Node 入口;参数在 -- 后完整传给 CLI。
81
+ node <skill-root>/scripts/native-pilot.cjs browser-cli --project <project-root> --host codebuddy --scope global --run-id review-r001 --cli <absolute-playwright-cli.js> -- -s=i3-assets-review open <local-preview-url>
82
+ ```
83
+
84
+ 包装器设置输出配置、环境与工作目录到该缓存,保存调用输出。后续同一浏览器会话继续使用同样的 run-id、scope 和 session;资源路径使用绝对路径。命令返回 executed 仅说明进程成功退出,不说明界面或验收通过。只操作本次会话,不使用 close-all/kill-all,不自动安装。
85
+
86
+ 明确选择要保留的原始输出,归档后再清理缓存:
87
+
88
+ ```sh
89
+ node <skill-root>/scripts/native-pilot.cjs archive-browser-output --project <project-root> --host codebuddy --scope global --run-id review-r001 --id assets --files page.yml,cli-output.log
90
+ ```
91
+
92
+ 只拷贝指定缓存内的普通文件,不允许路径越界、符号链接或覆盖已有归档;实际文件名以本轮工具输出为准。目标为 `prototypes/assets/qa/runs/review-r001/tool-output/`,保存摘要及归档时的候选身份,verification 保持 not-assessed。它是可审查原始材料,不能替代实际浏览器报告与验收记录。缓存缺失不影响 AD 读取已经归档的项目资料。
@@ -55,3 +55,9 @@
55
55
  3. catalog 登记版本、manifest 和本地预览。planned 保持不可生成,原有实例不自动切换模板或升级摘要。
56
56
  4. 验证独立运行层无 common 也能生成,资源/实现变化改变指纹,非法清单写入前拒绝,运行检查与基线保护覆盖,旧实例摘要兼容;再做真实浏览器与业务场景验收。
57
57
  5. 在源码维护流程登记新增分发文件,完成品牌生成、打包/安装完整性检查。此登记不代表用户认可模板或授权发布。
58
+
59
+ ## 原生内容参考扩展(新 scope v3)
60
+
61
+ HTML 实例的 manifest/adapter 与原生内容参考各有合同。原生不靠 HTML adapter 选择框架:catalog 可用条目增加安全 `contentRoot`,该目录提供 template.json(kind=content-reference)、离线 index.html、完整源资产、component-inventory.json、generation.json 和派生 template-inventory.json;先列全组件分类,再生成清单。generation.json 固定本模板适用模式、框架、预设及通用规则摘要,不接受任意插件代码。新的同类模板不需要修改核心生成器的模板 ID 分支;不同文件组织/运行形态须先明确适配,不声称任意 HTML 可自动接入。
62
+
63
+ 维护者在 Skill 源码修改模板及分类后执行 `native-pilot.cjs sync-generation-assets`;以 `--check` 核对派生文件,随后执行 inventory、模式/反例、原生配置和真实业务验收。规则目录发生变化时先评审版本与能力,再更新各模板 generation.json 的 definitionDigest(generation.json 采用 Node JSON.stringify 后的 SHA256),重算清单,不靠更新摘要掩盖删功能。离线预设 JS 由注册元数据生成;品牌重放后重算派生清单,引用 HTML/历史来源内容保持原字节。业务生成、analyze 和旧实例 inspect 不写这些源资产;旧实例始终按 inputs 快照而非新安装目录验收。
@@ -71,3 +71,7 @@ verification 使用 not-run、partial、passed、failed、blocked;review 使
71
71
  各入口在工具之后用自然语言交付实际范围、身份、证据、缺项和下一步,不强制父子 JSON、标记或结构校验。validate-result.cjs 可作特定维护工具,不是普通原型入口前置。业务、当前 state/delivery、真实 QA 分别核对,不能由结构结果推断。analyze 留在会话、不写收据;参数冲突以部分覆盖和未决项说明,不把分析完成等同覆盖通过。
72
72
 
73
73
  企业后台默认 purpose=business-prototype,完整参考副本的 business.status=needs-adaptation;必须完成实际业务适配才能验收。用户明确评审 EASEL 模板本身时,使用 purpose=template-review,并将 reference-demo 范围写进交接。模板认可不等于任何新业务的需求或原型认可。
74
+
75
+ ## 项目共享与宿主缓存
76
+
77
+ 默认业务写入集中于 prototypes:准备区 .preparation/<id>、共享 index.json 和本次实例。安装与分析不提前生成这些资料;原型流程不在根目录散落准备目录、工具或浏览器 CLI 输出。工具与缓存使用实际宿主基址,global 缓存按规范化项目身份隔离;正式需求、交接与 QA 归实例。旧路径不因升级自动迁移。目录、scope.moduleIds 与 appliesTo 的唯一来源、冲突及迁移规则见 [project-layout.md](project-layout.md)。
@@ -0,0 +1,72 @@
1
+ 'use strict';
2
+ const { fs, path, crypto, hash, assert, json, id, inside, write } = require('./native-files.cjs');
3
+ const { spawnSync } = require('node:child_process');
4
+ const { resolveLocations } = require('./prototype-locations.cjs');
5
+ function location(options) {
6
+ id(options.runId);
7
+ const context = resolveLocations(options);
8
+ return { context, directory: inside(context.cacheDirectory, `playwright/${options.runId}`) };
9
+ }
10
+ function prepare(options = {}) {
11
+ const { context, directory } = location(options), configFile = inside(directory, 'cli.config.json');
12
+ const config = { outputDir: directory, outputMode: 'file' };
13
+ if (fs.existsSync(configFile)) assert.deepEqual(json(configFile), config, 'Existing browser output config differs; preserve it and use another run ID');
14
+ else write(directory, 'cli.config.json', config);
15
+ return { status: 'prepared', directory, configFile, host: context.host, scope: context.scope, projectKey: context.projectKey,
16
+ environment: { PLAYWRIGHT_MCP_OUTPUT_DIR: directory, PLAYWRIGHT_MCP_CONFIG: configFile } };
17
+ }
18
+ function runCli(options = {}) {
19
+ assert.ok(typeof options.cli === 'string' && path.isAbsolute(options.cli), '--cli requires an existing absolute Playwright CLI Node entry');
20
+ const entry = fs.realpathSync(options.cli); assert.ok(fs.statSync(entry).isFile(), 'CLI entry must be a file');
21
+ assert.ok(Array.isArray(options.command) && options.command.length && options.command.every(value => typeof value === 'string'), 'Provide CLI arguments after --');
22
+ assert.ok(!options.command.some(value => value === '--config' || value.startsWith('--config=')), 'Output config is managed by this wrapper');
23
+ const command = options.command.find(value => !value.startsWith('-'));
24
+ assert.ok(!['install', 'install-browser', 'close-all', 'kill-all'].includes(command), 'Installation and all-session commands are not prototype browser operations');
25
+ const output = prepare(options);
26
+ const result = spawnSync(process.execPath, [entry, '--config', output.configFile, ...options.command], {
27
+ cwd: output.directory, env: { ...process.env, ...(options.env || {}), ...output.environment }, encoding: 'utf8', timeout: 60000, maxBuffer: 16 * 1024 * 1024 });
28
+ const call = `cli-${crypto.randomUUID()}`;
29
+ write(output.directory, `${call}.stdout.log`, result.stdout || ''); write(output.directory, `${call}.stderr.log`, result.stderr || result.error?.message || '');
30
+ return { ...output, status: result.status === 0 && !result.error ? 'executed' : 'failed', exitCode: result.status,
31
+ stdout: result.stdout || '', stderr: result.stderr || result.error?.message || '', verification: 'not-assessed' };
32
+ }
33
+ function archive(options = {}) {
34
+ const { context, directory: source } = location(options);
35
+ assert.ok(fs.existsSync(source), 'Browser cache does not exist');
36
+ const files = Array.isArray(options.files) ? options.files : typeof options.files === 'string' ? options.files.split(',') : [];
37
+ assert.ok(files.length && new Set(files).size === files.length, 'Explicit unique output files are required');
38
+ const selected = files.map(file => {
39
+ assert.ok(!['archive.json', 'cli.config.json'].includes(file), 'Reserved browser output filename');
40
+ const from = inside(source, file); assert.ok(fs.statSync(from).isFile(), 'Only regular output files can be archived');
41
+ return { file, from, digest: hash(fs.readFileSync(from)) };
42
+ });
43
+ const prototype = require('./project-registry.cjs').paths(context.project, options.id).directory;
44
+ assert.ok(prototype && fs.existsSync(prototype), 'Prototype must already exist');
45
+ const ownerFile = inside(prototype, '.prototype-write.lock');
46
+ if (fs.existsSync(ownerFile)) assert.equal(json(ownerFile).owner, options.owner, 'Prototype has another active writer');
47
+ const native = require('./native-pilot-lib.cjs'), candidate = native.manifest(prototype);
48
+ const parent = inside(prototype, `qa/runs/${options.runId}`), destination = inside(parent, 'tool-output');
49
+ assert.ok(!fs.existsSync(destination), 'Archived output already exists; preserve it');
50
+ fs.mkdirSync(parent, { recursive: true });
51
+ const lockFile = inside(parent, '.tool-output.lock'), lock = fs.openSync(lockFile, 'wx');
52
+ let stage;
53
+ try {
54
+ stage = fs.mkdtempSync(path.join(parent, '.archive-'));
55
+ for (const item of selected) {
56
+ const target = inside(stage, item.file); fs.mkdirSync(path.dirname(target), { recursive: true });
57
+ fs.copyFileSync(item.from, target, fs.constants.COPYFILE_EXCL);
58
+ assert.equal(hash(fs.readFileSync(target)), item.digest, 'Output changed while archiving');
59
+ assert.equal(hash(fs.readFileSync(item.from)), item.digest, 'Source output changed while archiving');
60
+ }
61
+ write(stage, 'archive.json', { schemaVersion: 1, host: context.host, scope: context.scope, projectKey: context.projectKey, runId: options.runId,
62
+ candidateDigest: candidate.digest, revision: candidate.revision, files: Object.fromEntries(selected.map(item => [item.file, item.digest])), verification: 'not-assessed' });
63
+ assert.equal(native.manifest(prototype).digest, candidate.digest, 'Candidate changed while archiving');
64
+ assert.ok(!fs.existsSync(destination), 'Archived output appeared while copying');
65
+ fs.renameSync(stage, destination);
66
+ return { status: 'archived', directory: destination, files, verification: 'not-assessed' };
67
+ } finally {
68
+ if (stage && fs.existsSync(stage)) fs.rmSync(stage, { recursive: true, force: true });
69
+ fs.closeSync(lock); fs.unlinkSync(lockFile);
70
+ }
71
+ }
72
+ module.exports = { prepare, runCli, archive };