@givolt/i3-composer-agent 2.3.1 → 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 (173) hide show
  1. package/.agents/plugins/marketplace.json +1 -1
  2. package/.claude/commands/i3-prototype.md +5 -7
  3. package/.claude-plugin/marketplace.json +1 -1
  4. package/.claude-plugin/plugin.json +1 -1
  5. package/.codex-plugin/plugin.json +1 -1
  6. package/.gemini/commands/i3-prototype.toml +5 -7
  7. package/README.md +16 -7
  8. package/bin/agent-targets.json +4 -2
  9. package/bin/i3-composer-agent.cjs +74 -7
  10. package/bin/install.cjs +16 -1
  11. package/bin/native-layout.cjs +1 -1
  12. package/bin/native-migration.cjs +27 -3
  13. package/bin/tool-selector.cjs +24 -7
  14. package/bin/wizard.cjs +89 -15
  15. package/commands/i3-prototype.toml +5 -7
  16. package/docs/codebuddy-setup.md +91 -3
  17. package/docs/codex-setup.md +6 -0
  18. package/docs/other-hosts.md +1 -1
  19. package/docs/ui-prototype-native/MAIN-SESSION-REPORT.md +66 -0
  20. package/docs/ui-prototype-native/USAGE.md +93 -0
  21. package/docs/workbuddy-setup.md +6 -0
  22. package/evals/cases/i3-frontend-ui-engineering.json +16 -0
  23. package/evals/cases/i3-ui-prototype.json +109 -0
  24. package/evals/cases/i3-using-agent-skills.json +28 -0
  25. package/evals/fixtures/i3-ui-prototype/admin-list/assets/reference.css +3 -0
  26. package/evals/fixtures/i3-ui-prototype/admin-list/assets/reference.js +8 -0
  27. package/evals/fixtures/i3-ui-prototype/admin-list/capability-definition.json +67 -0
  28. package/evals/fixtures/i3-ui-prototype/admin-list/index.html +89 -0
  29. package/evals/fixtures/i3-ui-prototype/admin-list/readme.md +52 -0
  30. package/evals/fixtures/i3-ui-prototype/admin-list/template.json +8 -0
  31. package/evals/zh-CN/cases/i3-frontend-ui-engineering.json +17 -0
  32. package/evals/zh-CN/cases/i3-ui-prototype.json +115 -0
  33. package/evals/zh-CN/cases/i3-using-agent-skills.json +30 -0
  34. package/hooks/codebuddy-upstream.cjs +93 -0
  35. package/hooks/i3-prototype.cjs +12 -0
  36. package/hooks/manage.cjs +162 -0
  37. package/package.json +61 -1
  38. package/plugin.json +1 -1
  39. package/scripts/design-provider-test.js +7 -0
  40. package/scripts/enterprise-template-test.js +27 -1
  41. package/scripts/lib/prototype-fixture.cjs +17 -0
  42. package/scripts/prototype-cache-test.js +55 -0
  43. package/scripts/prototype-generation-entry-test.js +6 -0
  44. package/scripts/prototype-generation-evidence-test.js +10 -0
  45. package/scripts/prototype-generation-native-test.js +78 -0
  46. package/scripts/prototype-generation-test.js +99 -0
  47. package/scripts/prototype-inventory-test.js +43 -0
  48. package/scripts/prototype-locations-test.js +79 -0
  49. package/scripts/prototype-project-test.js +183 -0
  50. package/scripts/ui-prototype-codebuddy-hook-test.js +106 -0
  51. package/scripts/ui-prototype-content-test.js +123 -0
  52. package/scripts/ui-prototype-dependencies-test.js +213 -0
  53. package/scripts/ui-prototype-devtools-test.js +53 -0
  54. package/scripts/ui-prototype-execution-evidence-test.js +62 -0
  55. package/scripts/ui-prototype-execution-gates-test.js +66 -0
  56. package/scripts/ui-prototype-execution-policy-test.js +42 -0
  57. package/scripts/ui-prototype-execution-runtime-test.js +27 -0
  58. package/scripts/ui-prototype-ide-source-test.js +73 -0
  59. package/scripts/ui-prototype-native-test.js +504 -0
  60. package/scripts/ui-prototype-registration-test.js +53 -0
  61. package/scripts/ui-prototype-template-test.js +261 -0
  62. package/scripts/ui-prototype-test.js +10 -0
  63. package/scripts/ui-prototype-transcript-auto-test.js +67 -0
  64. package/skills/i3-frontend-ui-engineering/SKILL.md +1 -1
  65. package/skills/i3-incremental-implementation/SKILL.md +1 -1
  66. package/skills/i3-ui-prototype/SKILL.md +158 -19
  67. package/skills/i3-ui-prototype/assets/capabilities/generation.json +833 -0
  68. package/skills/i3-ui-prototype/assets/capabilities/management.json +294 -0
  69. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/acceptance.json +51 -0
  70. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/component-map.json +13 -0
  71. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/generation-component-map.json +300 -0
  72. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/legacy-starter/index.html +11 -0
  73. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/legacy-starter/package-lock.json +2298 -0
  74. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/legacy-starter/package.json +22 -0
  75. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/legacy-starter/public/prototype-config.json +6 -0
  76. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/legacy-starter/src/App.vue +136 -0
  77. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/legacy-starter/src/components/DeviceEditor.vue +111 -0
  78. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/legacy-starter/src/config.ts +19 -0
  79. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/legacy-starter/src/content.ts +28 -0
  80. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/legacy-starter/src/domain/devices.ts +50 -0
  81. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/legacy-starter/src/domain/theme.ts +25 -0
  82. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/legacy-starter/src/main.ts +18 -0
  83. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/legacy-starter/src/style.css +50 -0
  84. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/legacy-starter/src/useDevices.ts +66 -0
  85. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/legacy-starter/tests/devices.test.ts +44 -0
  86. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/legacy-starter/tests/theme.test.ts +26 -0
  87. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/legacy-starter/tsconfig.json +15 -0
  88. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/legacy-starter/vite.config.ts +4 -0
  89. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/profile.json +174 -0
  90. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/readme.md +61 -0
  91. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/starter/index.html +11 -0
  92. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/starter/package-lock.json +2298 -0
  93. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/starter/package.json +22 -0
  94. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/starter/public/prototype-config.json +21 -0
  95. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/starter/src/App.vue +62 -0
  96. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/starter/src/PrototypeShell.vue +59 -0
  97. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/starter/src/config.ts +23 -0
  98. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/starter/src/domain/presentation.ts +29 -0
  99. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/starter/src/domain/theme.ts +25 -0
  100. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/starter/src/main.ts +18 -0
  101. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/starter/src/style.css +26 -0
  102. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/starter/tests/presentation.test.ts +23 -0
  103. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/starter/tests/theme.test.ts +26 -0
  104. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/starter/tsconfig.json +15 -0
  105. package/skills/i3-ui-prototype/assets/frameworks/vue-antdv-next/starter/vite.config.ts +4 -0
  106. package/skills/i3-ui-prototype/assets/hosts/codebuddy/profile.json +13 -0
  107. package/skills/i3-ui-prototype/assets/optional-skills/host-targets.json +739 -0
  108. package/skills/i3-ui-prototype/assets/optional-skills/sources.json +27 -0
  109. package/skills/i3-ui-prototype/assets/templates/catalog.js +149 -0
  110. package/skills/i3-ui-prototype/assets/templates/catalog.json +2 -1
  111. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/capability-definition.json +294 -0
  112. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/component-inventory.json +707 -0
  113. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/generation.json +49 -0
  114. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/index.html +507 -2
  115. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/offline-build.json +265 -0
  116. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/offline.js +8888 -0
  117. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/template-inventory.json +28791 -0
  118. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/template.json +9 -0
  119. package/skills/i3-ui-prototype/assets/templates/gallery/index.html +5 -5
  120. package/skills/i3-ui-prototype/assets/templates/generation-options.js +42 -0
  121. package/skills/i3-ui-prototype/assets/templates/index.html +3 -0
  122. package/skills/i3-ui-prototype/assets/templates/presentation.html +17 -0
  123. package/skills/i3-ui-prototype/references/artifact-contract.md +26 -1
  124. package/skills/i3-ui-prototype/references/content-template.md +81 -0
  125. package/skills/i3-ui-prototype/references/enterprise-admin.md +6 -0
  126. package/skills/i3-ui-prototype/references/entry-contract.md +71 -0
  127. package/skills/i3-ui-prototype/references/execution-evidence.md +66 -0
  128. package/skills/i3-ui-prototype/references/expert-adapter.md +33 -5
  129. package/skills/i3-ui-prototype/references/framework-contract.md +76 -0
  130. package/skills/i3-ui-prototype/references/generation-contract.md +122 -0
  131. package/skills/i3-ui-prototype/references/interaction-acceptance.md +169 -0
  132. package/skills/i3-ui-prototype/references/legacy-native.md +58 -0
  133. package/skills/i3-ui-prototype/references/optional-skills.md +63 -0
  134. package/skills/i3-ui-prototype/references/project-layout.md +92 -0
  135. package/skills/i3-ui-prototype/references/template-adapters.md +7 -1
  136. package/skills/i3-ui-prototype/references/workflow-contract.md +62 -4
  137. package/skills/i3-ui-prototype/scripts/adapters/easel-html.cjs +1 -1
  138. package/skills/i3-ui-prototype/scripts/browser-workspace.cjs +72 -0
  139. package/skills/i3-ui-prototype/scripts/codebuddy-context.cjs +75 -0
  140. package/skills/i3-ui-prototype/scripts/codebuddy-hook.cjs +157 -0
  141. package/skills/i3-ui-prototype/scripts/codebuddy-ide-source.cjs +69 -0
  142. package/skills/i3-ui-prototype/scripts/codebuddy-registration.cjs +123 -0
  143. package/skills/i3-ui-prototype/scripts/content-template.cjs +98 -0
  144. package/skills/i3-ui-prototype/scripts/enterprise-template.cjs +13 -6
  145. package/skills/i3-ui-prototype/scripts/execution-assertions.cjs +43 -0
  146. package/skills/i3-ui-prototype/scripts/execution-evidence.cjs +146 -0
  147. package/skills/i3-ui-prototype/scripts/execution-gates.cjs +147 -0
  148. package/skills/i3-ui-prototype/scripts/execution-policy.cjs +41 -0
  149. package/skills/i3-ui-prototype/scripts/execution-runtime.cjs +60 -0
  150. package/skills/i3-ui-prototype/scripts/generation-assets.cjs +18 -0
  151. package/skills/i3-ui-prototype/scripts/generation-contract.cjs +214 -0
  152. package/skills/i3-ui-prototype/scripts/generation-evidence.cjs +50 -0
  153. package/skills/i3-ui-prototype/scripts/generation-replan.cjs +34 -0
  154. package/skills/i3-ui-prototype/scripts/hosts/codebuddy.cjs +16 -0
  155. package/skills/i3-ui-prototype/scripts/manage-baseline.cjs +1 -1
  156. package/skills/i3-ui-prototype/scripts/native-browser.cjs +785 -0
  157. package/skills/i3-ui-prototype/scripts/native-build.cjs +91 -0
  158. package/skills/i3-ui-prototype/scripts/native-delivery.cjs +103 -0
  159. package/skills/i3-ui-prototype/scripts/native-devtools.cjs +92 -0
  160. package/skills/i3-ui-prototype/scripts/native-files.cjs +35 -0
  161. package/skills/i3-ui-prototype/scripts/native-pilot-lib.cjs +292 -0
  162. package/skills/i3-ui-prototype/scripts/native-pilot.cjs +50 -0
  163. package/skills/i3-ui-prototype/scripts/optional-skill-install.cjs +203 -0
  164. package/skills/i3-ui-prototype/scripts/project-registry.cjs +126 -0
  165. package/skills/i3-ui-prototype/scripts/prototype-dependencies.cjs +81 -0
  166. package/skills/i3-ui-prototype/scripts/prototype-hooks.cjs +87 -0
  167. package/skills/i3-ui-prototype/scripts/prototype-lib.cjs +31 -13
  168. package/skills/i3-ui-prototype/scripts/prototype-locations.cjs +69 -0
  169. package/skills/i3-ui-prototype/scripts/sync-template.cjs +19 -0
  170. package/skills/i3-ui-prototype/scripts/template-contract.cjs +407 -0
  171. package/skills/i3-ui-prototype/scripts/template-inventory.cjs +78 -0
  172. package/skills/i3-ui-prototype/scripts/validate-result.cjs +117 -0
  173. package/skills/i3-using-agent-skills/SKILL.md +2 -5
@@ -6,7 +6,7 @@
6
6
  "plugins": [
7
7
  {
8
8
  "name": "i3-composer-agent",
9
- "version": "2.3.1",
9
+ "version": "2.3.3",
10
10
  "description": "覆盖需求、计划、开发、测试、审查与发布的软件工程技能,默认使用简体中文。",
11
11
  "source": {
12
12
  "source": "local",
@@ -1,6 +1,6 @@
1
1
  ---
2
- description: "选择模板并生成、评审和迭代交互原型,维护已确认的 UI 基线。"
3
- # i3-description-source: "description: Create, review and iterate interactive UI prototypes with template selection and approved baselines"
2
+ description: "在主会话中分析、创建、检查与迭代 UI 交互原型。"
3
+ # i3-description-source: "description: Create, analyze, inspect and iterate UI prototypes in the main session"
4
4
  ---
5
5
 
6
6
  <!-- i3:zh-CN:start -->
@@ -11,13 +11,11 @@ description: "选择模板并生成、评审和迭代交互原型,维护已确
11
11
  Skill/Command/Agent 标识、文件路径、命令参数、代码/API 名称、工具调用参数、JSON 键/类型/枚举、机器状态、测试期望字面量及引用原文保持原样。生成文档正文用中文,SPEC.md、tasks/plan.md、tasks/todo.md、CONSTRAINTS.md 等约定路径不改名。
12
12
  严重程度按原规则判断,面向用户可写“严重(Critical)”“必须修复(Required)”“小问题(Nit)”“可选(Optional)”“建议考虑(Consider)”“仅供参考(FYI)”;High/Medium/Low、APPROVE/REQUEST CHANGES 和 GO/NO-GO 保留其原始语义与机器值。不得因翻译降低门槛,角色不能互相委派。
13
13
 
14
- 适用说明:选择模板并生成、评审和迭代交互原型,维护已确认的 UI 基线。
14
+ 适用说明:在主会话中分析、创建、检查与迭代 UI 交互原型。
15
15
  <!-- i3:zh-CN:end -->
16
16
 
17
- Invoke the i3-ui-prototype skill.
17
+ Use the i3-ui-prototype skill in the main session for the user's request below. Follow its shared preflight, operation boundaries and applicable runtime workflow.
18
18
 
19
19
  $ARGUMENTS
20
20
 
21
- With no arguments, use create. Supported operations: create, revise, inspect, confirm-baseline.
22
- Default to professional enhancement mode. Detect UI/UX Pro Max in the current host; if unavailable, offer installation or explicit template mode. Never silently downgrade.
23
- Use the skill workflow for template selection, business mapping, professional advice, real browser verification and version-specific human confirmation. Preserve approved snapshots during iteration.
21
+ With no arguments use create; explicit analysis or read-only limits take precedence. Preserve the user's scope, manual edits, fixed inputs and approved baselines. Use supporting engineering, framework, design and browser skills as the working skill requires; keep its workflow and evidence requirements there.
@@ -8,7 +8,7 @@
8
8
  "plugins": [
9
9
  {
10
10
  "name": "i3-composer-agent",
11
- "version": "2.3.1",
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.1",
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.1",
3
+ "version": "2.3.3",
4
4
  "description": "覆盖需求、计划、开发、测试、审查与发布的软件工程技能,默认使用简体中文。",
5
5
  "author": {
6
6
  "name": "Givolt"
@@ -1,5 +1,5 @@
1
- description = "选择模板并生成、评审和迭代交互原型,维护已确认的 UI 基线。"
2
- # i3-description-source: "description = \"Create, review and iterate interactive UI prototypes with template selection and approved baselines\""
1
+ description = "在主会话中分析、创建、检查与迭代 UI 交互原型。"
2
+ # i3-description-source: "description = \"Create, analyze, inspect and iterate UI prototypes in the main session\""
3
3
 
4
4
  prompt = """
5
5
  <!-- i3:zh-CN:start -->
@@ -10,14 +10,12 @@ prompt = """
10
10
  Skill/Command/Agent 标识、文件路径、命令参数、代码/API 名称、工具调用参数、JSON 键/类型/枚举、机器状态、测试期望字面量及引用原文保持原样。生成文档正文用中文,SPEC.md、tasks/plan.md、tasks/todo.md、CONSTRAINTS.md 等约定路径不改名。
11
11
  严重程度按原规则判断,面向用户可写“严重(Critical)”“必须修复(Required)”“小问题(Nit)”“可选(Optional)”“建议考虑(Consider)”“仅供参考(FYI)”;High/Medium/Low、APPROVE/REQUEST CHANGES 和 GO/NO-GO 保留其原始语义与机器值。不得因翻译降低门槛,角色不能互相委派。
12
12
 
13
- 适用说明:选择模板并生成、评审和迭代交互原型,维护已确认的 UI 基线。
13
+ 适用说明:在主会话中分析、创建、检查与迭代 UI 交互原型。
14
14
  <!-- i3:zh-CN:end -->
15
15
 
16
- Invoke the i3-ui-prototype skill.
16
+ Use the i3-ui-prototype skill in the main session for the user's request below. Follow its shared preflight, operation boundaries and applicable runtime workflow.
17
17
 
18
18
  $ARGUMENTS
19
19
 
20
- With no arguments, use create. Supported operations: create, revise, inspect, confirm-baseline.
21
- Default to professional enhancement mode. Detect UI/UX Pro Max in the current host; if unavailable, offer installation or explicit template mode. Never silently downgrade.
22
- Use the skill workflow for template selection, business mapping, professional advice, real browser verification and version-specific human confirmation. Preserve approved snapshots during iteration.
20
+ With no arguments use create; explicit analysis or read-only limits take precedence. Preserve the user's scope, manual edits, fixed inputs and approved baselines. Use supporting engineering, framework, design and browser skills as the working skill requires; keep its workflow and evidence requirements there.
23
21
  """
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # i3 Composer Agent v2.3.1
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 机制使用,
@@ -161,7 +163,7 @@ CodeBuddy、WorkBuddy、Claude Code 原生安装使用 `/i3-spec`、`/i3-plan`
161
163
  | /i3-composer-agent:i3-code-simplify | 简化代码,降低复杂度,提高可读性与维护性,并保持既有行为不变。 |
162
164
  | /i3-composer-agent:i3-constraints | 访谈并定义项目质量门槛,提供合理默认值,写入 CONSTRAINTS.md 并落实约束。 |
163
165
  | /i3-composer-agent:i3-plan | 把工作拆成带验收标准、验证步骤和依赖顺序的小任务。 |
164
- | /i3-composer-agent:i3-prototype | 选择模板并生成、评审和迭代交互原型,维护已确认的 UI 基线。 |
166
+ | /i3-composer-agent:i3-prototype | 在主会话中分析、创建、检查与迭代 UI 交互原型。 |
165
167
  | /i3-composer-agent:i3-review | 从正确性、可读性、架构、安全和性能五个维度审查代码。 |
166
168
  | /i3-composer-agent:i3-ship | 并行调用三个专业角色执行发布前检查,主会话汇总 GO/NO-GO 决策与回滚计划。 |
167
169
  | /i3-composer-agent:i3-spec | 先编写结构化规格、目标、范围与验收标准,再进入实现。 |
@@ -176,10 +178,15 @@ CodeBuddy、WorkBuddy、Claude Code 原生安装使用 `/i3-spec`、`/i3-plan`
176
178
  由主会话汇总 GO/NO-GO 决策,回滚计划必需。代码审查使用 Critical、Required、Optional、Nit
177
179
  四级;Critical 和 Required 问题默认阻止发布,各专业角色仍保留自己的报告字段和判断规则。
178
180
 
179
- `/i3-prototype` 调用 `i3-ui-prototype` 技能,支持先选模板,再按业务需求生成原型。默认采用专业增强模式,
180
- UI/UX Pro Max 是需要单独安装的外部设计能力,不计入本包的技能数量;未安装时提示安装,
181
- 用户也可明确选择模板模式继续。企业后台模板可用于人工测试,AI 工作台、数字孪生大屏和
182
- 移动端模板仍在规划中。原型验收、后续迭代约束与项目需求需要单独确认;本包尚未实现企业 SOP 自动编排。
181
+ `/i3-prototype` 在主会话调用 `i3-ui-prototype` 技能,按需求使用前端与浏览器技能完成原型。
182
+ 完整企业后台 HTML 内容模板可双击 index.html 离线查看与修改;生成的 Vue 3+antDv-next 工程
183
+ 使用真实组件,支持明亮、暗黑、清新、科技四主题,默认明亮。已有原型按原合同继续使用。
184
+ 模板在 Skill 源码中维护并随版本发布,生成时只读引用;业务直接修改原型工程,不默认创建项目 ui-templates。
185
+ UI/UX Pro Max 与 antDv 官方 Skill 可通过 `--prototype-skills uiux,antdv` 明确选择安装,
186
+ 也可稍后检测/补装;工具随所选宿主和范围存入 `tools/i3-prototype/`,旧路径继续兼容。
187
+ 默认采用专业增强模式,UIUX 不可用时提示修复或由用户明确选择模板模式继续。
188
+ 两项外部能力不计入本包技能数量。AI 工作台、数字孪生大屏和移动端模板仍在规划中。
189
+ 每个生成原型仍需独立的交互验收和用户评审;本包尚未实现企业 SOP 自动编排。
183
190
 
184
191
  ## Skills
185
192
 
@@ -209,7 +216,7 @@ UI/UX Pro Max 是需要单独安装的外部设计能力,不计入本包的技
209
216
  | [i3-source-driven-development](skills/i3-source-driven-development/SKILL.md) | 以官方文档和权威来源支撑实现决策。适用于核对框架/库用法、验证方案、查证 API 和避免过时实现,并保留来源证据。 |
210
217
  | [i3-spec-driven-development](skills/i3-spec-driven-development/SKILL.md) | 在实现前形成结构化规格。适用于新项目、功能或重大改动、PRD、需求澄清、目标与范围、场景和验收标准,以及将需求拆为独立可测试能力。 |
211
218
  | [i3-test-driven-development](skills/i3-test-driven-development/SKILL.md) | 执行测试先行的红绿重构循环。适用于实现逻辑、修复缺陷、修改行为、复现报错及证明改动有效;也用于为函数补测试、修复或修改直接粘贴的代码,即使请求未提到测试;缺陷修复使用先证明失败的 Prove-It 模式。 |
212
- | [i3-ui-prototype](skills/i3-ui-prototype/SKILL.md) | 根据业务需求选择 UI 模板,生成、评审并迭代交互原型。适用于选择原型模板、制作可操作审查原型、检查原型一致性及维护已确认的原型基线。 |
219
+ | [i3-ui-prototype](skills/i3-ui-prototype/SKILL.md) | 将 HTML 内容模板、业务需求与目标组件框架组合为可操作 UI 原型。适用于原型分析、原型候选生成、原型交互验证和已确认原型基线维护;生产页面实现使用工程流程。 |
213
220
  | [i3-using-agent-skills](skills/i3-using-agent-skills/SKILL.md) | 发现并调用合适的工程技能。适用于开始会话、判断任务意图、选择技能或工作流;作为元技能协调其他技能的发现和调用。 |
214
221
 
215
222
  ## Agent 角色
@@ -234,3 +241,5 @@ npx @givolt/i3-composer-agent --codebuddy --dir /path/to/plugin --force
234
241
  仓库维护用的 AGENTS.md、CLAUDE.md 不复制进业务项目。
235
242
  Codex 通过 `$i3-spec-driven-development` 等技能名调用;其原生 `/plan` 是宿主计划模式。
236
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
  {
@@ -21,6 +21,10 @@ ${pkg.name}
21
21
  npx ${pkg.name} --workbuddy --scope global
22
22
  npx ${pkg.name} --agents codebuddy,workbuddy --scope global --yes
23
23
  npx ${pkg.name} --agents codebuddy,codex --scope project --yes
24
+ npx ${pkg.name} --codebuddy --scope project --yes --prototype-skills uiux,antdv
25
+ npx ${pkg.name} prototype-deps check --host codex --scope project --project <project>
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>
24
28
  npx ${pkg.name} --prepare --claude --dir <directory>
25
29
  npx ${pkg.name} --extract --dir <directory>
26
30
 
@@ -32,6 +36,15 @@ ${pkg.name}
32
36
  --claude 预选 Claude Code
33
37
  --scope <scope> project 项目 / global 全局(也可 --global / --local)
34
38
  --project-dir <dir> 项目安装根目录,默认当前目录
39
+ --prototype-skills <ids> 可选原型依赖:none、uiux、antdv、uiux,antdv;向导数字选择,--yes 未指定时跳过
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> 实际宿主版本,便于核验记录
35
48
  --yes 确认明确指定的非交互安装
36
49
  --list-agents 列出全部支持的工具目录
37
50
  --prepare 另行导出插件目录并显示宿主注册步骤
@@ -43,13 +56,14 @@ ${pkg.name}
43
56
  --help 显示帮助
44
57
 
45
58
  终端向导先显示常用工具,WorkBuddy 在第 2 项;选择“更多”可分页/搜索全部工具。
46
- 上下键移动/跨页,空格勾选/取消,回车确认;列表下实时显示已选,q/Esc 退出。
59
+ 输入工具编号(如 1,2)后回车,或上下键移动/跨页、空格勾选、回车确认;q/Esc 退出。
60
+ 范围、Hooks、IDE/CLI、可选原型依赖和最终确认使用数字选择,Hook 组支持逗号分隔数字多选。
47
61
  CodeBuddy、WorkBuddy、Claude Code 同时安装短命令和 Agent 角色。
48
62
  其他工具通过 Skills 调用,短命令支持取决于宿主。
49
63
  所有工具默认安装单份 skills、commands、agents;配套资料集中在 i3-composer-agent/。
50
64
  评测、脚本和 Hook 读取同一份已安装技能。--prepare 用于另行导出标准插件并按宿主方式注册。
51
65
  WorkBuddy 桌面版建议全局安装,便于技能列表和输入补全发现。
52
- 评测需主动运行;Hook 文件已提供,需按宿主事件协议单独启用。
66
+ 评测需主动运行;向导可注册 CodeBuddy Hooks,实际生效仍需宿主审核/重载和回调验证。
53
67
  --prepare 仅供插件管理器安装方式使用,不自动注册插件或启用 Hook。
54
68
  `;
55
69
 
@@ -154,6 +168,15 @@ function prepare() {
154
168
  async function main() {
155
169
  if (args.includes('--help') || (!args.length && !process.stdin.isTTY)) { console.log(help); return; }
156
170
  if (args.length === 1 && args[0] === '--version') { console.log(pkg.version); return; }
171
+ if (args[0] === 'prototype-deps') {
172
+ const dependencies = require('../skills/i3-ui-prototype/scripts/prototype-dependencies.cjs');
173
+ console.log(JSON.stringify(await dependencies.main(args.slice(1)), null, 2));
174
+ return;
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
+ }
157
180
  if (args.some(arg => ['--extract', '--prepare', '--dir'].includes(arg))) { prepare(); return; }
158
181
  const installer = require('./install.cjs');
159
182
  if (args.length === 1 && args[0] === '--list-agents') {
@@ -164,11 +187,22 @@ async function main() {
164
187
  for (let i = 0; i < args.length; i++) {
165
188
  const arg = args[i];
166
189
  if (['--codebuddy', '--workbuddy', '--codex', '--claude'].includes(arg)) options.agents.push(arg.slice(2));
167
- else if (['--agents', '--scope', '--project-dir'].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)) {
168
191
  if (!args[i + 1] || args[i + 1].startsWith('--')) throw new Error(`${arg} 需要指定值。`);
169
192
  const value = args[++i];
170
193
  if (arg === '--agents') options.agents.push(value);
171
194
  else if (arg === '--scope') { if (options.scope && options.scope !== value) throw new Error('请选择一个安装范围。'); options.scope = value; }
195
+ else if (arg === '--prototype-skills') {
196
+ require('../skills/i3-ui-prototype/scripts/optional-skill-install.cjs').selection(value);
197
+ options.prototypeSkills = value;
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;
172
206
  else options.projectDir = path.resolve(value);
173
207
  } else if (arg === '--global' || arg === '--local') {
174
208
  const scope = arg === '--global' ? 'global' : 'project';
@@ -177,9 +211,18 @@ async function main() {
177
211
  } else if (arg === '--yes') options.yes = true;
178
212
  else if (arg === '--force') options.force = true;
179
213
  else if (arg === '--dry-run') options.dryRun = true;
214
+ else if (arg === '--migrate-tools') options.migrateTools = true;
180
215
  else throw new Error(`未知选项: ${arg}`);
181
216
  }
182
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
+ }
183
226
  if (process.stdin.isTTY && process.stdout.isTTY && !options.yes && !options.dryRun) {
184
227
  const selection = await require('./wizard.cjs').choose(options, identity);
185
228
  if (!selection) { console.log('安装已取消,未修改文件。'); return; }
@@ -187,17 +230,26 @@ async function main() {
187
230
  } else if (!options.agents.length || !options.scope || (!options.yes && !options.dryRun)) {
188
231
  throw new Error('请在交互终端使用向导,或明确指定 --agents <ids> --scope project|global --yes。');
189
232
  }
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;
190
237
  const plan = installer.planInstallation(options);
191
238
  if (options.dryRun) {
192
- 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 }, null, 2));
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,
240
+ ...(options.prototypeSkills !== undefined ? { optionalPrototypeSkills: options.prototypeSkills, migrateTools: !!options.migrateTools } : {}),...(hookChange?{hooks:hookChange.summary}:{}) }, null, 2));
193
241
  return;
194
242
  }
195
243
  if (!options.yes) {
196
- const confirmed = await require('./wizard.cjs').confirm(plan);
244
+ const confirmed = await require('./wizard.cjs').confirm(plan, { prototypeSkills: options.prototypeSkills, hooks: hookChange?.summary });
197
245
  if (!confirmed) { console.log('安装已取消,未修改文件。'); return; }
198
246
  options.force = plan.conflicts.length > 0;
199
247
  }
200
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
+ }
201
253
  console.log(identity);
202
254
  if (plan.reused.length) console.log(`已复用同版本的 ${plan.reused.length} 个未修改内容。`);
203
255
  for (const target of plan.targets) {
@@ -207,11 +259,26 @@ async function main() {
207
259
  console.log(`评测资料:${target.evalsDirectory}`);
208
260
  console.log(`完整校验:进入 "${target.toolkitDirectory}" 后运行 npm test`);
209
261
  console.log(`中文评测:node "${path.join(target.scriptsDirectory, 'run-evals.js')}" --locale zh-CN --min-rank1 95`);
210
- 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+'"':';按宿主协议手动配置'}`);
211
263
  }
212
264
  for (const file of plan.preserved || []) console.log(`保留了用户文件:${file}`);
213
265
  console.log('请重新加载 IDE 窗口或新建宿主会话以发现安装内容。');
214
266
  if (plan.agents.some(id => !['codebuddy', 'workbuddy', 'claude-code'].includes(id))) console.log('这些工具通过技能 ID 调用;生命周期短命令支持取决于宿主。');
215
- 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 检查当前状态。');
269
+ if (options.prototypeSkills !== undefined && options.prototypeSkills !== 'none') {
270
+ try {
271
+ // Shared project targets (for example CodeBuddy + WorkBuddy) prepare once.
272
+ for (const target of plan.targets) {
273
+ const result = await require('../skills/i3-ui-prototype/scripts/optional-skill-install.cjs').install({ project: options.projectDir,
274
+ host: target.agents[0], scope: plan.scope, skills: options.prototypeSkills, migrateTools: !!options.migrateTools });
275
+ console.log(JSON.stringify({ optionalPrototypeDependencies: result }, null, 2));
276
+ }
277
+ } catch (error) {
278
+ throw new Error(`i3 核心已安装成功;可选原型依赖未完成,可稍后用 prototype-deps install 重试。${error.message}`);
279
+ }
280
+ } else {
281
+ console.log('UIUX / antDv 独立依赖未自动安装。可随时用 prototype-deps check 检测,或 prototype-deps install --skills uiux,antdv 按需准备。');
282
+ }
216
283
  }
217
284
  main().catch(error => { console.error(`${name}: ${error.message}`); process.exitCode = 1; });
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
  }
@@ -98,6 +99,7 @@ function planInstallation({ agents, scope, projectDir = process.cwd(), home = os
98
99
  const additions = nativeAssets(root, target, pluginFiles, version);
99
100
  const current = new Set(additions.map(asset => asset.relative));
100
101
  assets.push(...additions, ...migrationAssets(target, owned ? previous : undefined, current));
102
+ target.retiredEntryRuleAbsent = target.agents.includes('codebuddy') && !exists(path.join(target.base, 'rules/i3-prototype-entry.md'));
101
103
  for (const asset of additions) {
102
104
  // A new grouped resource must not take ownership of an unrelated file,
103
105
  // even when --force confirms replacement of a previous installation.
@@ -147,7 +149,14 @@ function executeInstallation(plan, { force = false } = {}) {
147
149
  fs.mkdirSync(directory);
148
150
  createdDirectories.push(directory);
149
151
  }
152
+ function checkRetiredEntryRules() {
153
+ for (const target of plan.targets) {
154
+ const file = path.join(target.base, 'rules/i3-prototype-entry.md');
155
+ if (target.retiredEntryRuleAbsent && exists(file)) throw new Error(`安装期间出现未归属的旧原型入口,保留文件并停止安装:${file}`);
156
+ }
157
+ }
150
158
  try {
159
+ checkRetiredEntryRules();
151
160
  // Stage every target before replacing the first installed asset.
152
161
  for (const [index, asset] of plan.assets.entries()) {
153
162
  if (!contexts.has(asset.base)) {
@@ -176,6 +185,9 @@ function executeInstallation(plan, { force = false } = {}) {
176
185
  }
177
186
  if (asset.kind === 'result' && fingerprint(asset.source) !== asset.expectedFingerprint) throw new Error(`安装期间评测结果已改变:${asset.source}`);
178
187
  if (asset.kind === 'result' && asset.existing && fingerprint(asset.destination) !== asset.expectedFingerprint) throw new Error(`安装期间目标评测结果已改变:${asset.destination}`);
188
+ if (asset.retiredFingerprint && fingerprint(asset.destination) !== asset.retiredFingerprint) {
189
+ throw new Error(`安装期间旧原型入口已改变,保留文件并停止自动退出:${asset.destination}`);
190
+ }
179
191
  if (asset.reusable) {
180
192
  const unchanged = fingerprint(asset.destination) === asset.expectedFingerprint
181
193
  && fingerprint(asset.staged) === asset.expectedFingerprint;
@@ -198,6 +210,7 @@ function executeInstallation(plan, { force = false } = {}) {
198
210
  change.written = true;
199
211
  }
200
212
  }
213
+ checkRetiredEntryRules();
201
214
  pruneRetiredDirectories(plan.assets);
202
215
  completed = true;
203
216
  const ownedPaths = new Set(plan.assets.filter(asset => asset.kind !== 'legacy').map(asset => asset.destination));
@@ -213,6 +226,8 @@ function executeInstallation(plan, { force = false } = {}) {
213
226
  for (const target of plan.targets) {
214
227
  findUserFiles(path.join(target.base, name));
215
228
  for (const category of ['references', 'evals', 'hooks', 'scripts', 'docs']) findUserFiles(path.join(target.base, category, name));
229
+ const userPrototypeAgent = path.join(target.base, 'agents', 'prototype-specialist.md');
230
+ if (exists(userPrototypeAgent) && !ownedPaths.has(userPrototypeAgent)) plan.preserved.push(userPrototypeAgent);
216
231
  }
217
232
  return [];
218
233
  } catch (error) {
@@ -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') {
@@ -6,6 +6,13 @@ const { fingerprint } = require('./asset-fingerprint.cjs');
6
6
  const inventory = require('./legacy-native-files.json').files;
7
7
  const name = 'i3-composer-agent';
8
8
  const publishedFiles = new Set(inventory);
9
+ // Reviewed native bytes from the 99b5eae / 521c958 pilot package. Earlier or
10
+ // edited variants have no reliable content record in layout-3 manifests, so
11
+ // they require manual handling rather than trusting a path-only ownership claim.
12
+ const retiredPrototypeAssets = {
13
+ 'rules/i3-prototype-entry.md': '1c89ad58619968e1826cab31b9f6de29ac04d5fc5b8b1c2a2e1a1b64ec9449af',
14
+ 'agents/prototype-specialist.md': '4d1aa1c6c913694e8a1c7d3373245377899f9cf3f08ec410b40814fa7cda541f',
15
+ };
9
16
 
10
17
  function ownsAsset(previous, relative) {
11
18
  return previous.assets.some(file => file === relative
@@ -15,7 +22,8 @@ function ownsAsset(previous, relative) {
15
22
  function allowed(relative) {
16
23
  return typeof relative === 'string' && !relative.includes('\0') && !relative.includes(':') && !relative.includes('\\')
17
24
  && !relative.split('/').some(part => ['', '.', '..'].includes(part))
18
- && (/^(skills|commands|agents|references|evals|hooks|scripts|docs)\//.test(relative)
25
+ && (relative === 'rules/i3-prototype-entry.md'
26
+ || /^(skills|commands|agents|references|evals|hooks|scripts|docs)\//.test(relative)
19
27
  || relative.startsWith(`${name}/`) || [`${name}-LICENSE`, `${name}-NOTICE.md`].includes(relative));
20
28
  }
21
29
 
@@ -31,17 +39,33 @@ function fileAt(base, relative) {
31
39
  }
32
40
 
33
41
  function migrationAssets(target, previous, current) {
34
- if (!previous) return [];
35
42
  const assets = [];
36
43
  const oldFiles = new Set();
37
44
  const retired = new Set();
38
45
  const base = target.base;
46
+ for (const [relative, expectedFingerprint] of Object.entries(retiredPrototypeAssets)) {
47
+ if (current.has(relative)) continue;
48
+ const file = fileAt(base, relative);
49
+ let present;
50
+ try { present = fs.lstatSync(path.join(base, relative)); }
51
+ catch (error) { if (error.code === 'ENOENT') continue; throw error; }
52
+ const owned = previous?.assets.includes(relative);
53
+ // Keep the existing protection for unowned CodeBuddy rules. A user-created
54
+ // Agent with this name is outside our catalog and must not be claimed.
55
+ if (!owned && relative.startsWith('agents/')) continue;
56
+ if (!owned && !target.agents?.includes('codebuddy')) continue;
57
+ if (!owned || !file || !present.isFile() || fingerprint(file) !== expectedFingerprint) {
58
+ throw new Error(`保留了已修改、未知或未归属本包的旧原型入口,不能自动退出;请先检查并手动处理后重试:${path.join(base, relative)}`);
59
+ }
60
+ }
61
+ if (!previous) return [];
39
62
  function retire(relative) {
40
63
  if (retired.has(relative) || current.has(relative)) return;
41
64
  const file = fileAt(base, relative);
42
65
  if (!file || !fs.statSync(file).isFile()) return;
43
66
  retired.add(relative);
44
- assets.push({ base, destination: file, relative, kind: 'legacy' });
67
+ assets.push({ base, destination: file, relative, kind: 'legacy',
68
+ ...(retiredPrototypeAssets[relative] ? { retiredFingerprint: retiredPrototypeAssets[relative] } : {}) });
45
69
  }
46
70
  for (const relative of previous.assets) {
47
71
  const file = fileAt(base, relative);
@@ -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
  }