@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
@@ -6,7 +6,7 @@
6
6
  "plugins": [
7
7
  {
8
8
  "name": "i3-composer-agent",
9
- "version": "2.3.2",
9
+ "version": "2.3.3",
10
10
  "description": "覆盖需求、计划、开发、测试、审查与发布的软件工程技能,默认使用简体中文。",
11
11
  "source": {
12
12
  "source": "local",
@@ -8,7 +8,7 @@
8
8
  "plugins": [
9
9
  {
10
10
  "name": "i3-composer-agent",
11
- "version": "2.3.2",
11
+ "version": "2.3.3",
12
12
  "source": "./",
13
13
  "description": "覆盖需求、计划、开发、测试、审查与发布的软件工程技能,默认使用简体中文。",
14
14
  "homepage": "https://github.com/49780522/i3-composer-agent",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "i3-composer-agent",
3
- "version": "2.3.2",
3
+ "version": "2.3.3",
4
4
  "description": "覆盖需求、计划、开发、测试、审查与发布的软件工程技能,默认使用简体中文。",
5
5
  "author": {
6
6
  "name": "Givolt"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "i3-composer-agent",
3
- "version": "2.3.2",
3
+ "version": "2.3.3",
4
4
  "description": "覆盖需求、计划、开发、测试、审查与发布的软件工程技能,默认使用简体中文。",
5
5
  "author": {
6
6
  "name": "Givolt"
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # i3 Composer Agent v2.3.2
1
+ # i3 Composer Agent v2.3.3
2
2
 
3
3
  **Intelligence. Integration. Innovation.**
4
4
 
@@ -25,6 +25,8 @@ WorkBuddy 在第 2 项。上下键移动,空格勾选/取消,回车确认;
25
25
  搜索、翻页和命令参数预选均保留选择。搜索外 `q`、Esc 或 Ctrl-C 取消。
26
26
  确认工具后选择项目/全局范围并确认安装。
27
27
 
28
+ 可直接输入工具编号,例如 `1` 选择 CodeBuddy,或 `1,2` 多选,再按回车。CodeBuddy 的安装范围、Hooks、启用组、IDE/CLI、路由、UIUX/antDv 及最终确认均支持数字选择。新范围推荐启用 Hooks,已有安装默认保留现状;升级时要启用 Hooks 请明确选“启用”。UIUX/antDv 可选择安装两项、单项或跳过,之后也可补装。
29
+
28
30
  全部目标均安装 26 个技能、共享参考资料,以及完整评测/Hook/脚本配套。
29
31
  全部目标同时提供 10 个命令和 4 个 Agent 角色提示。
30
32
  CodeBuddy、WorkBuddy、Claude Code 使用原生命令入口;其他工具通过 Skills 机制使用,
@@ -239,3 +241,5 @@ npx @givolt/i3-composer-agent --codebuddy --dir /path/to/plugin --force
239
241
  仓库维护用的 AGENTS.md、CLAUDE.md 不复制进业务项目。
240
242
  Codex 通过 `$i3-spec-driven-development` 等技能名调用;其原生 `/plan` 是宿主计划模式。
241
243
  中文语言策略、工程方法、审批要求与工具限制在各入口独立生效。
244
+
245
+ 原型共享资料统一在项目 prototypes/:新索引 prototypes/index.json,准备范围 prototypes/.preparation/<id>/scope.json。新原生 scope.moduleIds 自动生成 appliesTo;旧索引、输入和实例保持兼容,安装升级不自动迁移。工具及运行缓存使用所选宿主基址;全局浏览器缓存按业务项目身份隔离。详细规则和只读查询/显式迁移命令见 i3-ui-prototype/references/project-layout.md。
@@ -8,8 +8,10 @@
8
8
  "label": "CodeBuddy",
9
9
  "projectSkillsDir": ".codebuddy/skills",
10
10
  "globalSkillsDir": {
11
- "base": "home",
12
- "path": ".codebuddy/skills"
11
+ "base": "env",
12
+ "env": "CODEBUDDY_CONFIG_DIR",
13
+ "fallback": ".codebuddy",
14
+ "path": "skills"
13
15
  }
14
16
  },
15
17
  {
@@ -24,6 +24,7 @@ ${pkg.name}
24
24
  npx ${pkg.name} --codebuddy --scope project --yes --prototype-skills uiux,antdv
25
25
  npx ${pkg.name} prototype-deps check --host codex --scope project --project <project>
26
26
  npx ${pkg.name} prototype-deps install --host workbuddy --scope global --skills uiux,antdv
27
+ npx ${pkg.name} hooks list --host codebuddy --scope project --project <project>
27
28
  npx ${pkg.name} --prepare --claude --dir <directory>
28
29
  npx ${pkg.name} --extract --dir <directory>
29
30
 
@@ -35,8 +36,15 @@ ${pkg.name}
35
36
  --claude 预选 Claude Code
36
37
  --scope <scope> project 项目 / global 全局(也可 --global / --local)
37
38
  --project-dir <dir> 项目安装根目录,默认当前目录
38
- --prototype-skills <ids> 可选原型依赖:none(默认)、uiux、antdv、uiux,antdv;跟随所选宿主和范围
39
+ --prototype-skills <ids> 可选原型依赖:none、uiux、antdv、uiux,antdv;向导数字选择,--yes 未指定时跳过
39
40
  --migrate-tools 显式迁移有 i3 来源记录的旧独立 antDv 工具;仅项目范围且需选择 antdv
41
+ --hooks <action> CodeBuddy 统一 Hooks:keep(非交互默认)/ enable / list / check / disable
42
+ --hook-groups <ids> session-start,sdd-cache,simplify-ignore,prototype 或 all;启停默认 prototype
43
+ --codebuddy-skill-routing <mode> hook(明确需要会话注入)/ native(已有原生路由)
44
+ --prototype-hooks <action> 旧参数保留,仅管理 prototype 组
45
+ --codebuddy-product <form> 启用时明确 ide 或 cli;CLI 注册后需在 /hooks 审核
46
+ --codebuddy-transcript-root <dir|auto> 默认自动识别;可选手动原生日志限制,auto 切回自动
47
+ --codebuddy-version <version> 实际宿主版本,便于核验记录
40
48
  --yes 确认明确指定的非交互安装
41
49
  --list-agents 列出全部支持的工具目录
42
50
  --prepare 另行导出插件目录并显示宿主注册步骤
@@ -48,13 +56,14 @@ ${pkg.name}
48
56
  --help 显示帮助
49
57
 
50
58
  终端向导先显示常用工具,WorkBuddy 在第 2 项;选择“更多”可分页/搜索全部工具。
51
- 上下键移动/跨页,空格勾选/取消,回车确认;列表下实时显示已选,q/Esc 退出。
59
+ 输入工具编号(如 1,2)后回车,或上下键移动/跨页、空格勾选、回车确认;q/Esc 退出。
60
+ 范围、Hooks、IDE/CLI、可选原型依赖和最终确认使用数字选择,Hook 组支持逗号分隔数字多选。
52
61
  CodeBuddy、WorkBuddy、Claude Code 同时安装短命令和 Agent 角色。
53
62
  其他工具通过 Skills 调用,短命令支持取决于宿主。
54
63
  所有工具默认安装单份 skills、commands、agents;配套资料集中在 i3-composer-agent/。
55
64
  评测、脚本和 Hook 读取同一份已安装技能。--prepare 用于另行导出标准插件并按宿主方式注册。
56
65
  WorkBuddy 桌面版建议全局安装,便于技能列表和输入补全发现。
57
- 评测需主动运行;Hook 文件已提供,需按宿主事件协议单独启用。
66
+ 评测需主动运行;向导可注册 CodeBuddy Hooks,实际生效仍需宿主审核/重载和回调验证。
58
67
  --prepare 仅供插件管理器安装方式使用,不自动注册插件或启用 Hook。
59
68
  `;
60
69
 
@@ -164,6 +173,10 @@ async function main() {
164
173
  console.log(JSON.stringify(await dependencies.main(args.slice(1)), null, 2));
165
174
  return;
166
175
  }
176
+ if (['hooks','prototype-hooks'].includes(args[0])) {
177
+ const result=require('../hooks/manage.cjs').main([...args.slice(1),...(args[0]==='prototype-hooks'?['--groups','prototype']:[])]);
178
+ console.log(JSON.stringify(result,null,2));if(result.status==='failed')process.exitCode=1;return;
179
+ }
167
180
  if (args.some(arg => ['--extract', '--prepare', '--dir'].includes(arg))) { prepare(); return; }
168
181
  const installer = require('./install.cjs');
169
182
  if (args.length === 1 && args[0] === '--list-agents') {
@@ -174,7 +187,7 @@ async function main() {
174
187
  for (let i = 0; i < args.length; i++) {
175
188
  const arg = args[i];
176
189
  if (['--codebuddy', '--workbuddy', '--codex', '--claude'].includes(arg)) options.agents.push(arg.slice(2));
177
- else if (['--agents', '--scope', '--project-dir', '--prototype-skills'].includes(arg)) {
190
+ else if (['--agents', '--scope', '--project-dir', '--prototype-skills','--prototype-hooks','--hooks','--hook-groups','--codebuddy-skill-routing','--codebuddy-product','--codebuddy-transcript-root','--codebuddy-version'].includes(arg)) {
178
191
  if (!args[i + 1] || args[i + 1].startsWith('--')) throw new Error(`${arg} 需要指定值。`);
179
192
  const value = args[++i];
180
193
  if (arg === '--agents') options.agents.push(value);
@@ -183,6 +196,13 @@ async function main() {
183
196
  require('../skills/i3-ui-prototype/scripts/optional-skill-install.cjs').selection(value);
184
197
  options.prototypeSkills = value;
185
198
  }
199
+ else if (arg === '--prototype-hooks') {if(!['keep','enable','check','disable'].includes(value))throw new Error('原型 Hooks 请选择 keep / enable / check / disable');options.prototypeHooks=value;}
200
+ else if (arg === '--hooks') {if(!['keep','enable','disable','list','check'].includes(value))throw new Error('Hooks 请选择 keep / enable / disable / list / check');options.hooks=value;}
201
+ else if (arg === '--hook-groups') {require('../hooks/manage.cjs').selection(value);options.hookGroups=value;}
202
+ else if (arg === '--codebuddy-skill-routing') {if(!['native','hook'].includes(value))throw new Error('请选择 native 或 hook');options.codebuddySkillRouting=value;}
203
+ else if (arg === '--codebuddy-product') {if(!['ide','cli'].includes(value))throw new Error('CodeBuddy 形态请选择 ide 或 cli');options.codebuddyProduct=value;}
204
+ else if (arg === '--codebuddy-transcript-root') options.codebuddyTranscriptRoot=value==='auto'?'auto':path.resolve(value);
205
+ else if (arg === '--codebuddy-version') options.codebuddyVersion=value;
186
206
  else options.projectDir = path.resolve(value);
187
207
  } else if (arg === '--global' || arg === '--local') {
188
208
  const scope = arg === '--global' ? 'global' : 'project';
@@ -195,6 +215,14 @@ async function main() {
195
215
  else throw new Error(`未知选项: ${arg}`);
196
216
  }
197
217
  options.agents = installer.selectAgents(options.agents);
218
+ if(options.prototypeHooks!==undefined&&(options.hooks!==undefined||options.hookGroups!==undefined))throw new Error('--prototype-hooks 旧参数不可与 --hooks / --hook-groups 混用');
219
+ const hookOptions=()=>({action:options.hooks||options.prototypeHooks||'keep',groups:options.hookGroups||(options.prototypeHooks!==undefined?'prototype':undefined),skillRouting:options.codebuddySkillRouting,host:'codebuddy',scope:options.scope,project:options.projectDir,product:options.codebuddyProduct,transcriptRoot:options.codebuddyTranscriptRoot,productVersion:options.codebuddyVersion,agents:options.agents});
220
+ if(['list','check','disable'].includes(hookOptions().action)) {
221
+ if(options.agents.length!==1||options.agents[0]!=='codebuddy'||!options.scope)throw new Error('Hooks check / disable 需明确 --codebuddy --scope project|global,不执行安装');
222
+ const manager=require('../hooks/manage.cjs');
223
+ const result=['list','check'].includes(hookOptions().action)?manager.check(hookOptions()):manager.configure({...hookOptions(),preview:!!options.dryRun});
224
+ console.log(JSON.stringify(result,null,2));if(result.status==='failed')process.exitCode=1;return;
225
+ }
198
226
  if (process.stdin.isTTY && process.stdout.isTTY && !options.yes && !options.dryRun) {
199
227
  const selection = await require('./wizard.cjs').choose(options, identity);
200
228
  if (!selection) { console.log('安装已取消,未修改文件。'); return; }
@@ -203,18 +231,25 @@ async function main() {
203
231
  throw new Error('请在交互终端使用向导,或明确指定 --agents <ids> --scope project|global --yes。');
204
232
  }
205
233
  if (options.migrateTools && (options.scope !== 'project' || !options.prototypeSkills?.split(',').includes('antdv'))) throw new Error('--migrate-tools requires project scope and selected antdv');
234
+ if(hookOptions().action!=='keep'&&!options.agents.includes('codebuddy'))throw new Error('首期统一 Hooks 仅适配 CodeBuddy');
235
+ const hookManager=require('../hooks/manage.cjs');
236
+ const hookChange=options.agents.includes('codebuddy')?hookManager.prepare(hookOptions()):null;
206
237
  const plan = installer.planInstallation(options);
207
238
  if (options.dryRun) {
208
239
  console.log(JSON.stringify({ name, version: pkg.version, mode: plan.mode, scope: plan.scope, agents: plan.agents, targets: plan.targets, conflicts: plan.conflicts, reused: plan.reused,
209
- ...(options.prototypeSkills !== undefined ? { optionalPrototypeSkills: options.prototypeSkills, migrateTools: !!options.migrateTools } : {}) }, null, 2));
240
+ ...(options.prototypeSkills !== undefined ? { optionalPrototypeSkills: options.prototypeSkills, migrateTools: !!options.migrateTools } : {}),...(hookChange?{hooks:hookChange.summary}:{}) }, null, 2));
210
241
  return;
211
242
  }
212
243
  if (!options.yes) {
213
- const confirmed = await require('./wizard.cjs').confirm(plan);
244
+ const confirmed = await require('./wizard.cjs').confirm(plan, { prototypeSkills: options.prototypeSkills, hooks: hookChange?.summary });
214
245
  if (!confirmed) { console.log('安装已取消,未修改文件。'); return; }
215
246
  options.force = plan.conflicts.length > 0;
216
247
  }
217
248
  installer.executeInstallation(plan, { force: options.force });
249
+ if(hookChange?.summary.changed) {
250
+ try {console.log(JSON.stringify({hooks:hookManager.apply(hookChange)},null,2));}
251
+ catch(error){throw new Error(`核心文件已安装,Hooks 注册未完成;请保留当前配置并重试或提供错误。${error.message}`);}
252
+ }
218
253
  console.log(identity);
219
254
  if (plan.reused.length) console.log(`已复用同版本的 ${plan.reused.length} 个未修改内容。`);
220
255
  for (const target of plan.targets) {
@@ -224,12 +259,13 @@ async function main() {
224
259
  console.log(`评测资料:${target.evalsDirectory}`);
225
260
  console.log(`完整校验:进入 "${target.toolkitDirectory}" 后运行 npm test`);
226
261
  console.log(`中文评测:node "${path.join(target.scriptsDirectory, 'run-evals.js')}" --locale zh-CN --min-rank1 95`);
227
- console.log(`Hook:${target.hooksDirectory}(尚未启用)`);
262
+ console.log(`Hooks:${target.hooksDirectory}${target.agents.includes('codebuddy')?';统一检查:node "'+path.join(target.hooksDirectory,'manage.cjs')+'" check --host codebuddy --scope '+plan.scope+' --project "'+options.projectDir+'"':';按宿主协议手动配置'}`);
228
263
  }
229
264
  for (const file of plan.preserved || []) console.log(`保留了用户文件:${file}`);
230
265
  console.log('请重新加载 IDE 窗口或新建宿主会话以发现安装内容。');
231
266
  if (plan.agents.some(id => !['codebuddy', 'workbuddy', 'claude-code'].includes(id))) console.log('这些工具通过技能 ID 调用;生命周期短命令支持取决于宿主。');
232
- console.log('安装完成。评测说明见 i3-composer-agent/evals/README.md;Hook 需按宿主事件协议启用。');
267
+ console.log('核心安装完成。评测说明见 i3-composer-agent/evals/README.md。');
268
+ if (hookChange) console.log(hookChange.summary.action === 'enable' ? `Hooks 已注册:${hookChange.summary.enabledGroups.join('、')}。${hookChange.summary.product === 'cli' ? '请在 CodeBuddy Code /hooks 审核并开启新会话。' : '请重载 CodeBuddy 窗口。'}实际触发另行检查。` : 'Hooks 保留现状;文件已提供不代表启用,请使用 hooks check 检查当前状态。');
233
269
  if (options.prototypeSkills !== undefined && options.prototypeSkills !== 'none') {
234
270
  try {
235
271
  // Shared project targets (for example CodeBuddy + WorkBuddy) prepare once.
package/bin/install.cjs CHANGED
@@ -29,6 +29,7 @@ function globalSkillsDir(agent, home, env) {
29
29
  let base = home;
30
30
  if (config.base === 'config') base = env.XDG_CONFIG_HOME && path.isAbsolute(env.XDG_CONFIG_HOME) ? env.XDG_CONFIG_HOME : path.join(home, '.config');
31
31
  if (config.base === 'env') base = env[config.env]?.trim() || path.join(home, config.fallback);
32
+ if (config.env === 'CODEBUDDY_CONFIG_DIR' && (!path.isAbsolute(base) || /[\x00\r\n]/.test(base))) throw new Error('CODEBUDDY_CONFIG_DIR must be an absolute safe directory');
32
33
  if (config.alternatives && !fs.existsSync(path.join(home, path.dirname(config.path)))) {
33
34
  const alternative = config.alternatives.find(relative => fs.existsSync(path.join(home, path.dirname(relative))));
34
35
  if (alternative) return path.join(home, alternative);
@@ -51,7 +52,7 @@ function checkDestination(file) {
51
52
  function assetPath(base, file) { return path.relative(base, file).split(path.sep).join('/'); }
52
53
  function manifestContent(plan, asset) {
53
54
  return JSON.stringify({ name, version, layoutVersion: 3, entryPrefix: 'i3-', scope: plan.scope, agents: asset.target.agents,
54
- capabilities: { nativeCommands: !!asset.target.nativeCommands, nativeAgents: !!asset.target.nativeCommands, hooks: 'manual' },
55
+ capabilities: { nativeCommands: !!asset.target.nativeCommands, nativeAgents: !!asset.target.nativeCommands, hooks: asset.target.agents.includes('codebuddy')?'codebuddy-managed':'manual' },
55
56
  catalog: asset.target.catalog, resources: asset.target.resources,
56
57
  assets: plan.assets.filter(item => item.base === asset.base && !['legacy', 'result'].includes(item.kind)).map(item => assetPath(asset.base, item.destination)) }, null, 2) + '\n';
57
58
  }
@@ -78,7 +78,7 @@ function renderAsset(buffer, asset) {
78
78
  '本目录提供评测、校验、回归测试、Hook、共享参考资料和使用指南。技能、命令和 Agent 位于上一级的对应目录,只有一份;这里的评测读取宿主实际安装的内容。\n\n' +
79
79
  '进入本目录后运行:\n\n```bash\nnpm test\nnode scripts/run-evals.js --locale zh-CN --min-rank1 95\n```\n\n' +
80
80
  '`npm test` 执行内容校验、中英文确定性评测及全部脚本回归测试,不需要 npm install。模型行为评测需要另行配置执行宿主;详见 [evals/README.md](evals/README.md)。\n\n' +
81
- '`adapters/` 保留其他命令格式和插件清单,供原版一致性校验与回归测试使用,不自动注册或启用插件。Hook 需按宿主支持的事件单独启用;缓存与代码块保护分别详见 [hooks/SDD-CACHE.md](hooks/SDD-CACHE.md) 和 [hooks/SIMPLIFY-IGNORE.md](hooks/SIMPLIFY-IGNORE.md)。\n');
81
+ '`adapters/` 保留其他命令格式和插件清单,供原版一致性校验与回归测试使用,不自动注册或启用插件。CodeBuddy 通过 `hooks/manage.cjs` 统一管理原版三组和新增原型审计,默认不启用;其他宿主仍按各自协议配置。缓存与代码块保护分别详见 [hooks/SDD-CACHE.md](hooks/SDD-CACHE.md) 和 [hooks/SIMPLIFY-IGNORE.md](hooks/SIMPLIFY-IGNORE.md),CodeBuddy 管理见 [docs/codebuddy-setup.md](docs/codebuddy-setup.md)。\n');
82
82
  if (asset.kind === 'runtime') return Buffer.from(text.replace('__I3_INSTALL_VERSION__', asset.version));
83
83
  if (asset.kind === 'script') return Buffer.from(nativeScript(text, relative));
84
84
  if (relative === 'hooks/session-start.sh') {
@@ -42,7 +42,7 @@ function wrap(text, columns) {
42
42
  function selectTools(initialSelection, input = process.stdin, output = process.stdout) {
43
43
  const selected = new Set(initialSelection);
44
44
  let view = 'common', cursor = 0, commonCursor = 0, query = '', searching = false, message = '';
45
- let frame = [], pageSize = 10, finished = false;
45
+ let frame = [], pageSize = 10, finished = false, numberInput = '';
46
46
  const wasRaw = Boolean(input.isRaw), wasFlowing = input.readableFlowing;
47
47
  const choices = () => view === 'common' ? [...orderedAgents.slice(0, commonIds.length), null]
48
48
  : view === 'more' ? orderedAgents.slice(commonIds.length)
@@ -71,8 +71,8 @@ function selectTools(initialSelection, input = process.stdin, output = process.s
71
71
  }
72
72
  const hints = searching
73
73
  ? ['输入关键词实时搜索', 'Enter/↓ 浏览结果 · Esc返回 · Ctrl-C取消']
74
- : ['↑↓ 移动/跨页 · 空格勾选 · Enter确认', 'm 更多 · / 搜索 · b/← 返回 · q/Esc取消'];
75
- const footer = ['', ...summary, ...hints.flatMap(line => wrap(line, columns)), message];
74
+ : ['数字+Enter指定工具 · ↑↓/空格勾选', 'm 更多 · / 搜索 · b/← 返回 · q/Esc取消'];
75
+ const footer = ['', ...summary, ...hints.flatMap(line => wrap(line, columns)), numberInput ? `编号:${numberInput}(逗号多选,Enter确认)` : message];
76
76
  const searchLine = view === 'search' ? [`搜索:${query}${searching ? '|' : ''}`] : [];
77
77
  pageSize = Math.max(1, Math.min(10, rows - footer.length - searchLine.length - 2));
78
78
  const page = Math.floor(cursor / pageSize), pages = Math.max(1, Math.ceil(entries.length / pageSize));
@@ -130,19 +130,36 @@ function selectTools(initialSelection, input = process.stdin, output = process.s
130
130
  if (view === 'search') back(); else { cancel(); return; }
131
131
  } else if (text === 'q') { cancel(); return; }
132
132
  else if (['return', 'enter'].includes(key.name)) {
133
+ if (numberInput) {
134
+ if (numberInput === '0') { cancel(); return; }
135
+ const numbers = numberInput.split(/[,,]/).map(Number);
136
+ if (numbers.every(number => Number.isInteger(number) && number >= 1 && number <= orderedAgents.length)) {
137
+ selected.clear();
138
+ for (const number of numbers) selected.add(orderedAgents[number - 1].id);
139
+ finish([...selected]); return;
140
+ }
141
+ numberInput = ''; message = `请输入 1–${orderedAgents.length} 的编号(逗号多选),0 取消。`;
142
+ render(); return;
143
+ }
133
144
  if (selected.size) { finish([...selected]); return; }
134
- message = '请至少用空格选择一个工具。';
145
+ message = '请用数字编号或空格选择工具,再按 Enter。';
146
+ } else if (text && /^[0-9,,]$/.test(text)) {
147
+ if (numberInput.length < 255) numberInput += text;
148
+ } else if (key.name === 'backspace') {
149
+ numberInput = numberInput.slice(0, -1);
135
150
  } else if (key.name === 'space' || text === ' ') {
151
+ if (numberInput) { render(); return; }
136
152
  const entry = choices()[cursor];
137
153
  if (entry) { if (selected.has(entry.id)) selected.delete(entry.id); else selected.add(entry.id); }
138
154
  else if (view === 'common') openMore();
139
155
  } else if (['up', 'down', 'pageup', 'pagedown'].includes(key.name) || ['n', 'p'].includes(text)) {
156
+ numberInput = '';
140
157
  const direction = ['up', 'pageup'].includes(key.name) || text === 'p' ? -1 : 1;
141
158
  const step = ['pageup', 'pagedown'].includes(key.name) || ['n', 'p'].includes(text) ? pageSize : 1;
142
159
  cursor = Math.max(0, Math.min(choices().length - 1, cursor + direction * step));
143
- } else if (text === 'm' || (key.name === 'right' && view === 'common')) openMore();
144
- else if (text === 'b' || key.name === 'left') back();
145
- else if (text === '/') { if (view === 'common') commonCursor = cursor; view = 'search'; query = ''; cursor = 0; searching = true; }
160
+ } else if (text === 'm' || (key.name === 'right' && view === 'common')) { numberInput = ''; openMore(); }
161
+ else if (text === 'b' || key.name === 'left') { numberInput = ''; back(); }
162
+ else if (text === '/') { numberInput = ''; if (view === 'common') commonCursor = cursor; view = 'search'; query = ''; cursor = 0; searching = true; }
146
163
  render();
147
164
  } catch (error) { fail(error); }
148
165
  }
package/bin/wizard.cjs CHANGED
@@ -1,6 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  const readline = require('node:readline');
4
+ const fs = require('node:fs');
5
+ const path = require('node:path');
4
6
  const { selectAgents } = require('./install.cjs');
5
7
  const { selectTools } = require('./tool-selector.cjs');
6
8
 
@@ -21,25 +23,88 @@ async function session(action) {
21
23
  try { return await action(ask); }
22
24
  finally { terminal.close(); }
23
25
  }
24
- async function choose(options, identity) {
25
- console.log(identity);
26
- const agents = await selectTools(selectAgents(options.agents));
27
- if (!agents) return null;
28
- if (agents.includes('workbuddy')) console.log('WorkBuddy 桌面版建议全局安装,以便技能列表和输入补全发现 Skills;项目安装仍支持命令,技能列表可能不显示。');
29
- return session(async ask => {
30
- const cancelled = input => input === null || ['q', 'cancel', '取消'].includes(input.toLowerCase());
26
+ const cancelled = input => input === null || ['0', 'q', 'cancel', '取消'].includes(input.toLowerCase());
27
+ async function menu(ask, prompt, values, fallback) {
28
+ while (true) {
29
+ const answer = await ask(prompt);
30
+ if (cancelled(answer)) return null;
31
+ const key = answer || fallback;
32
+ if (Object.hasOwn(values, key)) return values[key];
33
+ console.log(`请选择数字 ${Object.keys(values).join('、')},或 0 取消。`);
34
+ }
35
+ }
36
+ function existingInstallation(options, scope) {
37
+ const { base } = require('../hooks/manage.cjs').location({ scope, project: options.projectDir });
38
+ return ['.i3-composer-agent.json', 'settings.json', 'settings.local.json', 'state/i3-prototype/installation.json', 'state/i3-composer-agent/hooks.json']
39
+ .some(file => fs.existsSync(path.join(base, file)));
40
+ }
41
+ async function chooseSettings(options, agents, ask, services = {}) {
31
42
  let scope = options.scope;
32
43
  while (!scope) {
33
- const input = await ask('安装范围:1. 项目(当前项目),2. 全局(所有项目)[1](q/取消退出): ');
44
+ const input = await ask('安装范围:1. 项目(当前项目),2. 全局(所有项目)[1](0/q/取消退出): ');
34
45
  if (cancelled(input)) return null;
35
46
  if (['', '1', 'project', '项目'].includes(input)) scope = 'project';
36
47
  else if (['2', 'global', '全局'].includes(input)) scope = 'global';
37
48
  else console.log('请选择 1(项目)或 2(全局)。');
38
49
  }
39
- return { agents, scope };
40
- });
50
+ let hooks=options.hooks||options.prototypeHooks||'keep',hookGroups=options.hookGroups||(options.prototypeHooks!==undefined?'prototype':undefined),codebuddyProduct=options.codebuddyProduct,codebuddyTranscriptRoot=options.codebuddyTranscriptRoot,codebuddySkillRouting=options.codebuddySkillRouting;
51
+ if (agents.includes('codebuddy') && agents.includes('workbuddy') && options.hooks === undefined && options.prototypeHooks === undefined) {
52
+ console.log('CodeBuddy 与 WorkBuddy 本次共享目录,保留现有 Hooks;需要启用时请在 CodeBuddy 独立范围配置。');
53
+ } else if (agents.includes('codebuddy')) {
54
+ if (options.hooks === undefined && options.prototypeHooks === undefined) {
55
+ const existing = (services.existingInstallation || existingInstallation)(options, scope);
56
+ const unsupported = process.platform === 'win32';
57
+ if (unsupported) console.log('Windows Hooks 引用尚未完成宿主验证,默认保留;核心技能仍可安装。');
58
+ const fallback = existing || unsupported ? '2' : '1';
59
+ hooks = await menu(ask, `CodeBuddy 统一 Hooks:1. 选择启用${existing || unsupported ? '' : '(首次安装推荐)'},2. 保留现状${existing ? '(已有配置,推荐)' : ''} [${fallback}](0 取消): `, { '1': 'enable', '2': 'keep' }, fallback);
60
+ if (hooks === null) return null;
61
+ }
62
+ if (hooks === 'enable' && !hookGroups) {
63
+ console.log('Hook 组:1. 原型执行审计;2. Skill 发现与路由;3. 官方文档请求缓存;4. 代码块简化保护;5. 全部。');
64
+ while (!hookGroups) {
65
+ const answer = await ask('启用组:输入数字,可多选(例如 1,3,4)[1](0 取消): ');
66
+ if (cancelled(answer)) return null;
67
+ const numbers = (answer || '1').split(/[,,]/).map(x => x.trim());
68
+ if (numbers.every(x => ['1', '2', '3', '4'].includes(x))) hookGroups = [...new Set(numbers)].map(x => ({ '1': 'prototype', '2': 'session-start', '3': 'sdd-cache', '4': 'simplify-ignore' })[x]).join(',');
69
+ else if (numbers.length === 1 && numbers[0] === '5') hookGroups = 'all';
70
+ else console.log('请选择 1、2、3、4(可逗号多选),或 5(全部)。');
71
+ }
72
+ }
73
+ const chosen=require('../hooks/manage.cjs').selection(hookGroups,hooks);
74
+ if (hooks === 'enable' && !codebuddyProduct) {
75
+ codebuddyProduct = await menu(ask, 'CodeBuddy 形态:1. 桌面 IDE,2. CodeBuddy Code CLI [1](0 取消): ', { '1': 'ide', '2': 'cli' }, '1');
76
+ if (codebuddyProduct === null) return null;
77
+ }
78
+ if (hooks === 'enable' && chosen.includes('session-start')) {
79
+ if (!codebuddySkillRouting) {
80
+ codebuddySkillRouting = await menu(ask, 'Skill 路由:1. 需要 Hook 会话提示,2. 已有原生路由(自动去除 Skill 发现组)[1](0 取消): ', { '1': 'hook', '2': 'native' }, '1');
81
+ if (codebuddySkillRouting === null) return null;
82
+ }
83
+ if (codebuddySkillRouting === 'native') {
84
+ const remaining = chosen.filter(id => id !== 'session-start');
85
+ hookGroups = remaining.length ? remaining.join(',') : undefined;
86
+ if (!remaining.length) hooks = 'keep';
87
+ console.log('已选择原生路由,本次不新增 session-start;其余所选组保留,已有配置不会被移除。');
88
+ }
89
+ }
90
+ if(hooks==='enable'&&chosen.includes('prototype')&&!codebuddyTranscriptRoot)console.log('新启用的原型审计默认从 Hook 自动识别会话日志;升级保留已有手动限制。特殊环境可使用 --codebuddy-transcript-root <目录|auto>。');
91
+ }
92
+ let prototypeSkills = options.prototypeSkills;
93
+ if (prototypeSkills === undefined) {
94
+ console.log('可选原型依赖:所选项将联网下载官方固定版本,安装到本次宿主范围;已有可用内容复用。');
95
+ prototypeSkills = await menu(ask, 'UIUX / antDv:1. 两项都安装(推荐),2. 仅 UIUX,3. 仅 antDv,4. 跳过 [1](0 取消): ', { '1': 'uiux,antdv', '2': 'uiux', '3': 'antdv', '4': 'none' }, '1');
96
+ if (prototypeSkills === null) return null;
97
+ }
98
+ return { agents, scope, hooks, hookGroups, codebuddyProduct, codebuddyTranscriptRoot, codebuddySkillRouting, prototypeSkills };
99
+ }
100
+ async function choose(options, identity) {
101
+ console.log(identity);
102
+ const agents = await selectTools(selectAgents(options.agents));
103
+ if (!agents) return null;
104
+ if (agents.includes('workbuddy')) console.log('WorkBuddy 桌面版建议全局安装,以便技能列表和输入补全发现 Skills;项目安装仍支持命令,技能列表可能不显示。');
105
+ return session(ask => chooseSettings(options, agents, ask));
41
106
  }
42
- async function confirm(plan) {
107
+ async function confirm(plan, selection = {}) {
43
108
  console.log(`\n安装范围:${plan.scope === 'project' ? '项目' : '全局'}`);
44
109
  for (const target of plan.targets) {
45
110
  console.log(` ${target.agents.join(', ')}: ${target.skillsDirectory}`);
@@ -50,10 +115,19 @@ async function confirm(plan) {
50
115
  }
51
116
  if (plan.conflicts.length) console.log(`将替换 ${plan.conflicts.length} 个已有内容;安装成功后清理旧文件,失败则恢复。`);
52
117
  if (plan.reused.length) console.log(`将复用同版本的 ${plan.reused.length} 个未修改内容。`);
53
- console.log('包含技能、共享资料和完整评测/Hook/脚本配套。安装不执行评测;Hook 需按宿主方式启用。');
118
+ if (selection.hooks) {
119
+ console.log(`CodeBuddy Hooks:${selection.hooks.action === 'enable' ? '启用 ' + selection.hooks.groups.join('、') : '保留现状'}${selection.hooks.product ? ';' + (selection.hooks.product === 'ide' ? '桌面 IDE' : 'CLI') : ''}。`);
120
+ if (selection.hooks.action === 'enable') console.log(selection.hooks.product === 'cli' ? '注册后仍需在 CodeBuddy Code /hooks 审核并开启新会话。' : '注册后请重载 CodeBuddy 窗口验证实际回调。');
121
+ }
122
+ if (selection.prototypeSkills !== undefined) console.log(`可选依赖:${selection.prototypeSkills === 'none' ? '跳过' : selection.prototypeSkills.split(',').map(id => id === 'uiux' ? 'UIUX Pro Max' : 'antDv 官方 Skill 与工具').join('、')}。`);
123
+ console.log('包含技能、共享资料和完整评测/Hook/脚本配套。安装不执行评测。');
54
124
  return session(async ask => {
55
- const answer = await ask('确认安装这些内容?[y/N]: ');
56
- return answer !== null && ['y', 'yes', '是', '确认'].includes(answer.toLowerCase());
125
+ while (true) {
126
+ const answer = await ask('确认安装这些内容:1. 开始安装,0. 取消 [0]: ');
127
+ if (answer === '' || cancelled(answer) || ['n', 'no', '否'].includes(answer.toLowerCase())) return false;
128
+ if (['1', 'y', 'yes', '是', '确认'].includes(answer.toLowerCase())) return true;
129
+ console.log('请选择 1 开始安装,或 0 取消。');
130
+ }
57
131
  });
58
132
  }
59
- module.exports = { choose, confirm };
133
+ module.exports = { choose, chooseSettings, confirm };
@@ -48,7 +48,7 @@ CodeBuddy 与 WorkBuddy 项目共用 `.codebuddy/`;同版本追加客户端会
48
48
  npx @givolt/i3-composer-agent --codebuddy --scope project --yes --prototype-skills uiux,antdv
49
49
  ```
50
50
 
51
- 值为 none、uiux、antdv 或 uiux,antdv;默认 none。可选工具跟随宿主和项目/全局范围,位于基址下 `tools/i3-prototype/`;旧项目 `.prototype-tools` 保持读取兼容。需要固定本次版本时使用 `npx @givolt/i3-composer-agent@2.3.2`。已安装后可随时单独检测/补装,无需重装 i3:
51
+ 值为 none、uiux、antdv 或 uiux,antdv;默认 none。可选工具跟随宿主和项目/全局范围,位于基址下 `tools/i3-prototype/`;旧项目 `.prototype-tools` 保持读取兼容。需要固定本次版本时使用 `npx @givolt/i3-composer-agent@2.3.3`。已安装后可随时单独检测/补装,无需重装 i3:
52
52
 
53
53
  ```bash
54
54
  node .codebuddy/skills/i3-ui-prototype/scripts/prototype-dependencies.cjs check --host codebuddy --scope project --project .
@@ -106,7 +106,30 @@ node .codebuddy/skills/i3-ui-prototype/scripts/native-pilot.cjs preview prototyp
106
106
 
107
107
  在业务项目运行 `node .codebuddy/i3-composer-agent/scripts/run-evals.js --min-rank1 95`,
108
108
  可检查中英文触发,不调用模型;进入 `.codebuddy/i3-composer-agent/` 可运行 `npm test` 和 `node scripts/run-evals.js --locale zh-CN --min-rank1 95`。全局安装使用脚本的全局绝对路径。五项校验、行为评测和样例用法见
109
- [评测说明](../evals/README.md)。Hook 文件已安装,需要按宿主协议单独启用。
109
+ [评测说明](../evals/README.md)。Hooks 默认只分发,统一管理如下。
110
+
111
+ ## CodeBuddy 统一 Hooks 管理
112
+
113
+ 原版 `session-start`、`sdd-cache`、`simplify-ignore` 与新增 `prototype` 四组统一由安装器及 `.codebuddy/i3-composer-agent/hooks/manage.cjs` 管理。`i3-prototype.cjs` 是新增审计注册入口,委托 Skill 内原有实现;旧 helper 和 `--prototype-hooks` 参数保留。原版脚本保持,包装只处理宿主路径与输入字段。测试/说明文件不注册。
114
+
115
+ ```sh
116
+ # 已安装后只读列举/检查,项目根运行
117
+ node .codebuddy/i3-composer-agent/hooks/manage.cjs list --host codebuddy --scope project --project .
118
+ node .codebuddy/i3-composer-agent/hooks/manage.cjs check --host codebuddy --scope project --project .
119
+ # 单独启用缓存;全部选择用 --groups all 并满足所有组条件
120
+ node .codebuddy/i3-composer-agent/hooks/manage.cjs enable --host codebuddy --scope project --project . --groups sdd-cache --product ide
121
+ node .codebuddy/i3-composer-agent/hooks/manage.cjs disable --host codebuddy --scope project --project . --groups sdd-cache
122
+ ```
123
+
124
+ 全局改用 `~/.codebuddy/i3-composer-agent/hooks/manage.cjs` 和 `--scope global`,继续指定测试项目来判断有效来源。发行 CLI 可用 `hooks list|check|enable|disable` 子命令;安装时使用 `--hooks enable --hook-groups <ids>`,默认 keep 保留既有开关。启停不指定组时兼容旧用法仅针对 prototype,list/check 默认全部。
125
+
126
+ `session-start` 需要明确 `--skill-routing hook`,已有原生路由时不选该组;安装器对应 `--codebuddy-skill-routing hook`。上游三组需要 Bash、jq 和相应 SHA 工具,缓存另需 curl,缺依赖会在启用前拒绝;不自动安装。prototype 需要真实 `--product ide|cli`;项目/全局新启用默认从 Hook 自动识别当前会话日志,可选 `--transcript-root <实际目录|auto>`。已有手动限制保留,首次尚无原生事件显示 awaiting-native-event,不能当成已验收。全局跟随绝对 CODEBUDDY_CONFIG_DIR,默认 ~/.codebuddy;不移动原生日志。原型严格证据规则见 Skill 的 execution-evidence 参考资料。
127
+
128
+ 配置合并到所选范围 `settings.json`,通用归属在 `state/i3-composer-agent/hooks.json`,原型归属保持 `state/i3-prototype/installation.json`。上游适配缓存在 `<host-base>/cache/i3-composer-agent/hooks/<projectKey>/`;全局按项目隔离。已识别的手动原版注册只报告,不自动接管或重复注册。代码块保护运行时会临时替换文件内容,存在未恢复备份时拒绝移除该组,先结束会话恢复。
129
+
130
+ IDE 项目设置覆盖全局;CLI 合并后按组选择有效来源避免同组重复执行。CLI 变更后在原生 `/hooks` 审核并新建会话,IDE 重载。文件存在、注册、回调观察与业务验收分别显示;原版 triggered 不表示已验证模型行为。首期仍待用户实际宿主验收,Windows Hooks 未验证,默认不启用的核心安装不受此限制。
131
+
132
+ 依据:[CodeBuddy IDE Hooks](https://www.codebuddy.cn/docs/ide/Features/Hooks)、[CodeBuddy CLI Hooks](https://www.codebuddy.cn/docs/cli/hooks)。
110
133
 
111
134
  ## 通过 CodeBuddy Code 插件管理器安装
112
135
 
@@ -133,3 +156,5 @@ npx @givolt/i3-composer-agent --prepare --codebuddy
133
156
  目录遵循 [配置目录参考](https://www.codebuddy.cn/docs/cli/codebuddy-dir),可参照
134
157
  [IDE Skills](https://www.codebuddy.cn/docs/ide/Features/Skills) 与
135
158
  [自定义命令](https://www.codebuddy.cn/docs/ide/User-guide/Slash-Commands) 检查发现与调用。
159
+
160
+ 原型共享资料统一在项目 prototypes/:新索引 prototypes/index.json,准备范围 prototypes/.preparation/<id>/scope.json。新原生 scope.moduleIds 自动生成 appliesTo;旧索引、输入和实例保持兼容,安装升级不自动迁移。工具及运行缓存使用所选宿主基址;全局浏览器缓存按业务项目身份隔离。详细规则和只读查询/显式迁移命令见 i3-ui-prototype/references/project-layout.md。
@@ -37,4 +37,6 @@ Codex 已有原生技能路由,勿把元技能全文预加载为常驻上下
37
37
 
38
38
  ## 可选原型工具
39
39
 
40
- 原型辅助工具位于本宿主基址的 `tools/i3-prototype/`,支持项目和全局范围;旧项目 `.prototype-tools` 继续读取兼容。项目安装可使用 `npx @givolt/i3-composer-agent@2.3.2 --codex --scope project --yes --prototype-skills uiux,antdv`;全局安装将 scope 改为 global。可选依赖默认 none,后续也可使用已安装 Skill 的 prototype-dependencies.cjs 单独检测/补装。完整用法见原型 Skill 的 references/optional-skills.md。
40
+ 原型辅助工具位于本宿主基址的 `tools/i3-prototype/`,支持项目和全局范围;旧项目 `.prototype-tools` 继续读取兼容。项目安装可使用 `npx @givolt/i3-composer-agent@2.3.3 --codex --scope project --yes --prototype-skills uiux,antdv`;全局安装将 scope 改为 global。可选依赖默认 none,后续也可使用已安装 Skill 的 prototype-dependencies.cjs 单独检测/补装。完整用法见原型 Skill 的 references/optional-skills.md。
41
+
42
+ 原型共享资料统一在项目 prototypes/:新索引 prototypes/index.json,准备范围 prototypes/.preparation/<id>/scope.json。新原生 scope.moduleIds 自动生成 appliesTo;旧索引、输入和实例保持兼容,安装升级不自动迁移。工具及运行缓存使用所选宿主基址;全局浏览器缓存按业务项目身份隔离。详细规则和只读查询/显式迁移命令见 i3-ui-prototype/references/project-layout.md。
@@ -6,7 +6,7 @@
6
6
 
7
7
  ## 使用本地分发目录
8
8
 
9
- 以下命令使用完整分发包解压目录里的 CLI,适用于本地测试和离线接入。`/absolute/path/to/package` 均替换为实际解压目录;已发布版本也可使用 `npx @givolt/i3-composer-agent@2.3.2` 的对应入口。
9
+ 以下命令使用完整分发包解压目录里的 CLI,适用于本地测试和离线接入。`/absolute/path/to/package` 均替换为实际解压目录;已发布版本也可使用 `npx @givolt/i3-composer-agent@2.3.3` 的对应入口。
10
10
 
11
11
  ### fx
12
12
 
@@ -49,12 +49,12 @@ node .codebuddy/skills/i3-ui-prototype/scripts/native-pilot.cjs template-page --
49
49
 
50
50
  ## 需求范围与创建
51
51
 
52
- 主会话根据实际 PRD 整理 .prototype-preparation/assets/scope.json:逐页声明业务标题、referencePage、区域类型、需求原文及来源。列表适用查询、复选、分页、批量与状态反馈;编辑区域适用校验、保存失败保留和重试。豁免须有明确需求依据。不能漏报实际区域来逃避能力。
52
+ 主会话根据实际 PRD 整理 schemaVersion=2 的 prototypes/.preparation/assets/scope.json,moduleIds 填实际模块 ID(未关联填 []),索引 appliesTo 自动去重生成:逐页声明业务标题、referencePage、区域类型、需求原文及来源。列表适用查询、复选、分页、批量与状态反馈;编辑区域适用校验、保存失败保留和重试。豁免须有明确需求依据。不能漏报实际区域来逃避能力。
53
53
 
54
54
  新原型默认提供明亮、暗黑、清新、科技,默认明亮,无编号。列表默认可调分页 10/20/50,默认 10;在 scope 的区域参数中明确覆盖真实需要。旧实例仍按原有固定输入,不追溯修改。
55
55
 
56
56
  ```sh
57
- node .codebuddy/skills/i3-ui-prototype/scripts/native-pilot.cjs create --project . --id assets --scope .prototype-preparation/assets/scope.json --host codebuddy
57
+ node .codebuddy/skills/i3-ui-prototype/scripts/native-pilot.cjs create --project . --id assets --scope prototypes/.preparation/assets/scope.json --host codebuddy
58
58
  # 仅在明确选择基础模板模式后,增加 --expert-mode template。
59
59
  ```
60
60
 
@@ -89,3 +89,5 @@ node .codebuddy/skills/i3-ui-prototype/scripts/native-pilot.cjs state prototypes
89
89
  新会话先 state 恢复身份、范围、模式、构建与证据,按 nextAction 继续,不重新生成覆盖。已有 v1 HTML 与旧 v2 原生实例按原合同检查,保留原摘要、手改和认可基线;小模板仅保留测试夹具,旧设备框架起点在 legacy-starter,不作为新生成入口。
90
90
 
91
91
  最终回复给出原型路径、范围、revision、实际模式、已执行检查、证据及未决项。完成本地技术验证仍为 pending-review,人工认可具体 revision/digest 后才能冻结基线;不把骨架、安装通过或自填报告当作业务完成。
92
+
93
+ 共享索引为 prototypes/index.json,旧根索引保持兼容。只安装不创建业务目录;全局 Skill 仍把原型留在业务项目,缓存按宿主与项目隔离。查询、同步、显式迁移和浏览器输出命令见 Skill 的 references/project-layout.md。
@@ -85,4 +85,6 @@ npx @givolt/i3-composer-agent --workbuddy --scope global --yes --force
85
85
 
86
86
  ## 可选原型工具
87
87
 
88
- 原型辅助工具位于本宿主基址的 `tools/i3-prototype/`,支持项目和全局范围;旧项目 `.prototype-tools` 继续读取兼容。推荐使用 `npx @givolt/i3-composer-agent@2.3.2 --workbuddy --scope global --yes --prototype-skills uiux,antdv`;项目安装将 scope 改为 project。可选依赖默认 none,后续也可使用已安装 Skill 的 prototype-dependencies.cjs 单独检测/补装。完整用法见原型 Skill 的 references/optional-skills.md。
88
+ 原型辅助工具位于本宿主基址的 `tools/i3-prototype/`,支持项目和全局范围;旧项目 `.prototype-tools` 继续读取兼容。推荐使用 `npx @givolt/i3-composer-agent@2.3.3 --workbuddy --scope global --yes --prototype-skills uiux,antdv`;项目安装将 scope 改为 project。可选依赖默认 none,后续也可使用已安装 Skill 的 prototype-dependencies.cjs 单独检测/补装。完整用法见原型 Skill 的 references/optional-skills.md。
89
+
90
+ 原型共享资料统一在项目 prototypes/:新索引 prototypes/index.json,准备范围 prototypes/.preparation/<id>/scope.json。新原生 scope.moduleIds 自动生成 appliesTo;旧索引、输入和实例保持兼容,安装升级不自动迁移。工具及运行缓存使用所选宿主基址;全局浏览器缓存按业务项目身份隔离。详细规则和只读查询/显式迁移命令见 i3-ui-prototype/references/project-layout.md。