@givolt/i3-composer-agent 2.2.3 → 2.3.1

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 (439) hide show
  1. package/.agents/plugins/marketplace.json +1 -1
  2. package/.claude/commands/i3-prototype.md +23 -0
  3. package/.claude/commands/i3-review.md +1 -1
  4. package/.claude/commands/i3-ship.md +1 -1
  5. package/.claude-plugin/marketplace.json +1 -1
  6. package/.claude-plugin/plugin.json +1 -1
  7. package/.codex-plugin/plugin.json +2 -2
  8. package/.gemini/commands/i3-prototype.toml +23 -0
  9. package/.gemini/commands/i3-review.toml +1 -1
  10. package/.gemini/commands/i3-ship.toml +1 -1
  11. package/README.md +15 -5
  12. package/agents/code-reviewer.md +1 -1
  13. package/agents/test-engineer.md +1 -1
  14. package/bin/native-layout.cjs +2 -0
  15. package/commands/i3-prototype.toml +23 -0
  16. package/commands/i3-review.toml +1 -1
  17. package/commands/i3-ship.toml +1 -1
  18. package/docs/agents.md +2 -2
  19. package/docs/codebuddy-setup.md +2 -2
  20. package/docs/codex-setup.md +1 -1
  21. package/docs/copilot-setup.md +4 -0
  22. package/docs/cursor-setup.md +3 -0
  23. package/docs/other-hosts.md +44 -9
  24. package/docs/workbuddy-setup.md +2 -2
  25. package/evals/README.md +2 -0
  26. package/evals/cases/i3-documentation-and-adrs.json +18 -0
  27. package/evals/cases/i3-test-driven-development.json +8 -0
  28. package/evals/cases/i3-ui-prototype.json +49 -0
  29. package/evals/fixtures/i3-documentation-and-adrs/prose-review/README.md +19 -0
  30. package/evals/fixtures/i3-documentation-and-adrs/prose-review/queue.js +32 -0
  31. package/evals/fixtures/i3-ui-prototype/business-brief.md +7 -0
  32. package/evals/plugin/tdd-fires-on-pasted-bug/graders/failing-test-first.md +7 -0
  33. package/evals/plugin/tdd-fires-on-pasted-bug/graders/skill-fired.md +5 -0
  34. package/evals/plugin/tdd-fires-on-pasted-bug/prompt.md +15 -0
  35. package/evals/plugin/tdd-stays-quiet-on-debug/graders/not-fired.md +8 -0
  36. package/evals/plugin/tdd-stays-quiet-on-debug/prompt.md +25 -0
  37. package/evals/zh-CN/cases/i3-documentation-and-adrs.json +19 -0
  38. package/evals/zh-CN/cases/i3-test-driven-development.json +4 -0
  39. package/evals/zh-CN/cases/i3-ui-prototype.json +50 -0
  40. package/hooks/SIMPLIFY-IGNORE.md +3 -2
  41. package/hooks/simplify-ignore-test.sh +93 -1
  42. package/hooks/simplify-ignore.sh +94 -11
  43. package/package.json +31 -1
  44. package/plugin.json +1 -1
  45. package/references/performance-checklist.md +4 -2
  46. package/scripts/design-provider-discovery-test.js +190 -0
  47. package/scripts/design-provider-test.js +68 -0
  48. package/scripts/enterprise-template-test.js +179 -0
  49. package/scripts/lib/skill-lint-test.js +113 -1
  50. package/scripts/lib/skill-lint.js +62 -8
  51. package/scripts/run-evals-test.js +207 -0
  52. package/scripts/run-evals.js +47 -9
  53. package/scripts/template-adapter-test.js +155 -0
  54. package/scripts/ui-prototype-test.js +114 -0
  55. package/scripts/validate-commands-test.js +30 -0
  56. package/scripts/validate-commands.js +6 -16
  57. package/scripts/validate-reference-links-test.js +18 -0
  58. package/scripts/validate-reference-links.js +4 -2
  59. package/scripts/validate-skills.js +26 -3
  60. package/skills/i3-documentation-and-adrs/SKILL.md +9 -0
  61. package/skills/i3-frontend-ui-engineering/SKILL.md +5 -1
  62. package/skills/i3-idea-refine/SKILL.md +20 -5
  63. package/skills/i3-incremental-implementation/SKILL.md +4 -0
  64. package/skills/i3-performance-optimization/SKILL.md +10 -10
  65. package/skills/i3-security-and-hardening/references/hardening-patterns.md +1 -1
  66. package/skills/i3-shipping-and-launch/SKILL.md +6 -0
  67. package/skills/i3-test-driven-development/SKILL.md +3 -3
  68. package/skills/i3-ui-prototype/SKILL.md +119 -0
  69. package/skills/i3-ui-prototype/assets/templates/catalog.json +148 -0
  70. package/skills/i3-ui-prototype/assets/templates/classic-admin/manifest.json +9 -0
  71. package/skills/i3-ui-prototype/assets/templates/classic-admin/preset.json +6 -0
  72. package/skills/i3-ui-prototype/assets/templates/common/app/app.mjs +89 -0
  73. package/skills/i3-ui-prototype/assets/templates/common/app/config.json +1 -0
  74. package/skills/i3-ui-prototype/assets/templates/common/app/domain.mjs +20 -0
  75. package/skills/i3-ui-prototype/assets/templates/common/app/index.html +17 -0
  76. package/skills/i3-ui-prototype/assets/templates/common/app/serve.cjs +16 -0
  77. package/skills/i3-ui-prototype/assets/templates/common/app/styles.css +670 -0
  78. package/skills/i3-ui-prototype/assets/templates/common/app/tokens.css +19 -0
  79. package/skills/i3-ui-prototype/assets/templates/common/design-system/master.md +20 -0
  80. package/skills/i3-ui-prototype/assets/templates/common/gallery.html +2 -0
  81. package/skills/i3-ui-prototype/assets/templates/common/mocks/applications.json +5 -0
  82. package/skills/i3-ui-prototype/assets/templates/common/requirements-map.json +8 -0
  83. package/skills/i3-ui-prototype/assets/templates/common/serve-gallery.cjs +16 -0
  84. package/skills/i3-ui-prototype/assets/templates/credits.md +17 -0
  85. package/skills/i3-ui-prototype/assets/templates/data-operations/manifest.json +9 -0
  86. package/skills/i3-ui-prototype/assets/templates/data-operations/preset.json +6 -0
  87. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/design-system.md +32 -0
  88. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/index.html +29 -0
  89. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/manifest.json +9 -0
  90. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/origin.json +344 -0
  91. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/preset.json +928 -0
  92. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/app.js +22 -0
  93. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets/empty.svg +1 -0
  94. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets/reference-styles.json +1 -0
  95. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets/result-403.svg +1 -0
  96. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets/result-404.svg +1 -0
  97. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets-manifest.json +334 -0
  98. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/baseline.json +173 -0
  99. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/conversion.md +30 -0
  100. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/credits.md +17 -0
  101. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/design-tokens.json +881 -0
  102. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/index.html +28 -0
  103. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/licenses/@qin-ui-antdv-next-pro.txt +9 -0
  104. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/licenses/ant-design-icons.txt +22 -0
  105. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/licenses/antdv-next.txt +21 -0
  106. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/package.json +12 -0
  107. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/browser-routes.json +298 -0
  108. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/coverage.json +180 -0
  109. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/integrity.json +13 -0
  110. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/keyboard.json +11 -0
  111. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/responsive.json +125 -0
  112. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/review.md +51 -0
  113. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/rules.log +150 -0
  114. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/flow-editor-html.png +0 -0
  115. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/flow-editor-original.png +0 -0
  116. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/intent-create-html.png +0 -0
  117. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/intent-create-original.png +0 -0
  118. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/models-html.png +0 -0
  119. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/models-original.png +0 -0
  120. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/workbench-html.png +0 -0
  121. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/workbench-original.png +0 -0
  122. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/selection.json +9 -0
  123. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/visual-comparison.json +342 -0
  124. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/readme.md +73 -0
  125. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/reference.md +59 -0
  126. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/routes.json +178 -0
  127. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/controls.js +99 -0
  128. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/dialogs.js +54 -0
  129. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/dom.js +264 -0
  130. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/forms.js +47 -0
  131. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/icons.js +41 -0
  132. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/layout.js +47 -0
  133. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/router.js +63 -0
  134. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/state.js +90 -0
  135. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/table.js +41 -0
  136. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/widgets.js +8 -0
  137. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentDetail.html +3 -0
  138. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentDetail.js +36 -0
  139. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentEditor.html +2 -0
  140. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentEditor.js +51 -0
  141. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentsPage.html +3 -0
  142. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentsPage.js +48 -0
  143. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/CheckResults.html +2 -0
  144. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/CheckResults.js +6 -0
  145. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/ResourcePicker.html +2 -0
  146. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/ResourcePicker.js +13 -0
  147. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/data.js +24 -0
  148. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/domain.js +32 -0
  149. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/registry.js +25 -0
  150. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/store.js +85 -0
  151. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentClose.html +2 -0
  152. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentClose.js +17 -0
  153. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentCreate.html +2 -0
  154. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentCreate.js +66 -0
  155. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDecisions.html +3 -0
  156. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDecisions.js +38 -0
  157. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDetail.html +2 -0
  158. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDetail.js +66 -0
  159. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDocument.html +2 -0
  160. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDocument.js +5 -0
  161. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentHeader.html +2 -0
  162. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentHeader.js +12 -0
  163. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentHistory.html +2 -0
  164. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentHistory.js +11 -0
  165. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentList.html +2 -0
  166. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentList.js +116 -0
  167. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentReplan.html +2 -0
  168. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentReplan.js +32 -0
  169. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentRevision.html +2 -0
  170. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentRevision.js +49 -0
  171. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentSummary.html +2 -0
  172. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentSummary.js +10 -0
  173. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentWorkspace.html +2 -0
  174. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentWorkspace.js +77 -0
  175. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/data.js +60 -0
  176. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/domain.js +105 -0
  177. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/store.js +212 -0
  178. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/AuditPanel.html +2 -0
  179. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/AuditPanel.js +18 -0
  180. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelDetail.html +2 -0
  181. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelDetail.js +23 -0
  182. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelEditor.html +2 -0
  183. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelEditor.js +78 -0
  184. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelGrant.html +2 -0
  185. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelGrant.js +55 -0
  186. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelReferences.html +2 -0
  187. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelReferences.js +26 -0
  188. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelRelease.html +2 -0
  189. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelRelease.js +38 -0
  190. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelStatus.html +2 -0
  191. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelStatus.js +7 -0
  192. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelTable.html +2 -0
  193. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelTable.js +72 -0
  194. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelTester.html +2 -0
  195. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelTester.js +46 -0
  196. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelsPage.html +2 -0
  197. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelsPage.js +52 -0
  198. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/RowActions.html +2 -0
  199. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/RowActions.js +19 -0
  200. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/UsagePanel.html +2 -0
  201. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/UsagePanel.js +30 -0
  202. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/data.js +48 -0
  203. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/domain.js +39 -0
  204. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/store.js +129 -0
  205. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/IncidentDetail.html +4 -0
  206. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/IncidentDetail.js +21 -0
  207. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/IntentSource.html +2 -0
  208. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/IntentSource.js +8 -0
  209. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationActionDialog.html +2 -0
  210. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationActionDialog.js +37 -0
  211. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationEntry.html +2 -0
  212. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationEntry.js +10 -0
  213. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationsPage.html +2 -0
  214. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationsPage.js +37 -0
  215. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/RepairTrack.html +2 -0
  216. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/RepairTrack.js +49 -0
  217. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/RunDetail.html +4 -0
  218. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/RunDetail.js +22 -0
  219. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/SourceSummary.html +2 -0
  220. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/SourceSummary.js +9 -0
  221. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/commands.js +82 -0
  222. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/examples.js +47 -0
  223. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/model.js +61 -0
  224. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/repair.js +68 -0
  225. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/store.js +55 -0
  226. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/types.js +1 -0
  227. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/workbench.js +18 -0
  228. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ManagementTable.html +3 -0
  229. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ManagementTable.js +28 -0
  230. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcCreateEntry.html +2 -0
  231. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcCreateEntry.js +18 -0
  232. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcDetail.html +2 -0
  233. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcDetail.js +31 -0
  234. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcEditor.html +2 -0
  235. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcEditor.js +27 -0
  236. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcLifecycle.html +2 -0
  237. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcLifecycle.js +16 -0
  238. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcPage.html +2 -0
  239. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcPage.js +43 -0
  240. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcPicker.html +4 -0
  241. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcPicker.js +34 -0
  242. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcProgress.html +2 -0
  243. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcProgress.js +30 -0
  244. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcWizard.html +3 -0
  245. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcWizard.js +67 -0
  246. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcWorkspace.html +2 -0
  247. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcWorkspace.js +41 -0
  248. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcsPage.html +2 -0
  249. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcsPage.js +31 -0
  250. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ServiceEditor.html +2 -0
  251. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ServiceEditor.js +26 -0
  252. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ServiceList.html +2 -0
  253. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ServiceList.js +70 -0
  254. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/data.js +8 -0
  255. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/domain.js +62 -0
  256. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/management.js +36 -0
  257. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/managementStore.js +49 -0
  258. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/store.js +132 -0
  259. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/AdminList.html +2 -0
  260. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/AdminList.js +38 -0
  261. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/EffectiveGrants.html +2 -0
  262. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/EffectiveGrants.js +11 -0
  263. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/GrantEditor.html +2 -0
  264. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/GrantEditor.js +45 -0
  265. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/MemberEditor.html +2 -0
  266. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/MemberEditor.js +54 -0
  267. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/MembersPage.html +3 -0
  268. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/MembersPage.js +27 -0
  269. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RecordsPage.html +2 -0
  270. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RecordsPage.js +12 -0
  271. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RoleEditor.html +2 -0
  272. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RoleEditor.js +45 -0
  273. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RolesPage.html +3 -0
  274. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RolesPage.js +38 -0
  275. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/domain.js +61 -0
  276. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/state.js +51 -0
  277. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/store.js +116 -0
  278. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseActionDialog.html +2 -0
  279. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseActionDialog.js +45 -0
  280. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseDetail.html +4 -0
  281. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseDetail.js +30 -0
  282. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseEditor.html +2 -0
  283. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseEditor.js +67 -0
  284. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseExecution.html +2 -0
  285. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseExecution.js +5 -0
  286. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleasesPage.html +4 -0
  287. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleasesPage.js +60 -0
  288. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/commands.js +157 -0
  289. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/model.js +136 -0
  290. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/store.js +76 -0
  291. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewDetail.html +3 -0
  292. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewDetail.js +26 -0
  293. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewEvidence.html +2 -0
  294. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewEvidence.js +14 -0
  295. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewProcess.html +2 -0
  296. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewProcess.js +113 -0
  297. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewsPage.html +3 -0
  298. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewsPage.js +62 -0
  299. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/commands.js +97 -0
  300. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/model.js +147 -0
  301. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/store.js +13 -0
  302. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ColumnSettings.html +2 -0
  303. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ColumnSettings.js +9 -0
  304. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListBatchBar.html +2 -0
  305. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListBatchBar.js +8 -0
  306. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListDeleteDialog.html +2 -0
  307. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListDeleteDialog.js +37 -0
  308. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListMore.html +2 -0
  309. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListMore.js +8 -0
  310. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/RecordMetadata.html +2 -0
  311. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/RecordMetadata.js +17 -0
  312. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/columns.js +32 -0
  313. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/deliveryGuide.js +49 -0
  314. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/deliveryView.js +12 -0
  315. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/listBatch.js +15 -0
  316. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/listSelection.js +37 -0
  317. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/policy.js +68 -0
  318. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/session.js +44 -0
  319. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ConfirmationDialog.html +2 -0
  320. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ConfirmationDialog.js +25 -0
  321. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ConsoleShell.html +2 -0
  322. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ConsoleShell.js +53 -0
  323. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/PrototypeGuide.html +10 -0
  324. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/PrototypeGuide.js +30 -0
  325. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ScopePage.html +2 -0
  326. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ScopePage.js +10 -0
  327. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/SessionDialog.html +2 -0
  328. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/SessionDialog.js +9 -0
  329. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/confirmation.js +3 -0
  330. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/navigation.js +19 -0
  331. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecDocument.html +2 -0
  332. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecDocument.js +8 -0
  333. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecEdit.html +2 -0
  334. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecEdit.js +32 -0
  335. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecHeader.html +2 -0
  336. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecHeader.js +15 -0
  337. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecHistory.html +2 -0
  338. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecHistory.js +11 -0
  339. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecReview.html +2 -0
  340. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecReview.js +57 -0
  341. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecWorkspace.html +2 -0
  342. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecWorkspace.js +37 -0
  343. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/data.js +20 -0
  344. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/domain.js +55 -0
  345. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/store.js +151 -0
  346. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/ArtifactDetail.html +3 -0
  347. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/ArtifactDetail.js +18 -0
  348. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskCreate.html +2 -0
  349. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskCreate.js +40 -0
  350. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskDetail.html +2 -0
  351. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskDetail.js +51 -0
  352. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskLaunch.html +2 -0
  353. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskLaunch.js +9 -0
  354. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TasksPage.html +5 -0
  355. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TasksPage.js +48 -0
  356. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/domain.js +204 -0
  357. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/exampleSource.js +22 -0
  358. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/registry.js +135 -0
  359. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/store.js +137 -0
  360. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workbench/WorkbenchPage.html +3 -0
  361. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workbench/WorkbenchPage.js +36 -0
  362. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workbench/model.js +56 -0
  363. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workbench/store.js +15 -0
  364. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowCanvas.html +2 -0
  365. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowCanvas.js +27 -0
  366. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowDetail.html +4 -0
  367. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowDetail.js +31 -0
  368. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowEditor.html +2 -0
  369. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowEditor.js +68 -0
  370. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/WorkflowsPage.html +5 -0
  371. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/WorkflowsPage.js +55 -0
  372. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/data.js +16 -0
  373. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/domain.js +83 -0
  374. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/registry.js +18 -0
  375. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/store.js +61 -0
  376. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/admin.css +60 -0
  377. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/agents.css +46 -0
  378. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/antdv.css +295 -0
  379. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/app.css +102 -0
  380. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/delivery.css +4 -0
  381. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/intents.css +37 -0
  382. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/native.css +22 -0
  383. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/operations.css +2 -0
  384. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/pbc.css +3 -0
  385. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/permissions.css +22 -0
  386. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/pro.css +1 -0
  387. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/releases.css +4 -0
  388. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/reset.css +246 -0
  389. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/reviews.css +8 -0
  390. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/tasks.css +6 -0
  391. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/tokens.css +15 -0
  392. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/workbench.css +61 -0
  393. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/workflows.css +1 -0
  394. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/admin-rules.test.js +96 -0
  395. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/agents.test.js +14 -0
  396. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/intent-state.test.js +37 -0
  397. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/list-batch.test.js +44 -0
  398. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/operation-fixtures.js +19 -0
  399. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/operation-repair.test.js +14 -0
  400. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/operations.test.js +25 -0
  401. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/pbc-management.test.js +17 -0
  402. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/pbc-state.test.js +24 -0
  403. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/permission-config.test.js +23 -0
  404. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/permissions.test.js +24 -0
  405. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/releases.test.js +50 -0
  406. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/reviews.test.js +36 -0
  407. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/runtime-forms-router.test.js +28 -0
  408. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/runtime-state.test.js +42 -0
  409. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/runtime-stores.test.js +16 -0
  410. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/spec-state.test.js +11 -0
  411. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/tasks.test.js +27 -0
  412. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/workbench.test.js +34 -0
  413. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/workflows.test.js +16 -0
  414. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tools/convert.mjs +168 -0
  415. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tools/serve.mjs +7 -0
  416. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tools/styles.mjs +11 -0
  417. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tools/verify.mjs +24 -0
  418. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/serve.cjs +16 -0
  419. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/usability.css +44 -0
  420. package/skills/i3-ui-prototype/assets/templates/gallery/index.html +40 -0
  421. package/skills/i3-ui-prototype/assets/templates/modern-workspace/manifest.json +9 -0
  422. package/skills/i3-ui-prototype/assets/templates/modern-workspace/preset.json +6 -0
  423. package/skills/i3-ui-prototype/assets/templates/serve-gallery.cjs +23 -0
  424. package/skills/i3-ui-prototype/references/artifact-contract.md +41 -0
  425. package/skills/i3-ui-prototype/references/enterprise-admin.md +38 -0
  426. package/skills/i3-ui-prototype/references/expert-adapter.md +48 -0
  427. package/skills/i3-ui-prototype/references/template-adapters.md +57 -0
  428. package/skills/i3-ui-prototype/references/workflow-contract.md +19 -0
  429. package/skills/i3-ui-prototype/scripts/adapters/easel-html.cjs +30 -0
  430. package/skills/i3-ui-prototype/scripts/adapters/legacy-html.cjs +28 -0
  431. package/skills/i3-ui-prototype/scripts/check-design-provider.cjs +9 -0
  432. package/skills/i3-ui-prototype/scripts/check-prototype.cjs +14 -0
  433. package/skills/i3-ui-prototype/scripts/design-provider-discovery.cjs +128 -0
  434. package/skills/i3-ui-prototype/scripts/enterprise-template.cjs +97 -0
  435. package/skills/i3-ui-prototype/scripts/init-prototype.cjs +8 -0
  436. package/skills/i3-ui-prototype/scripts/manage-baseline.cjs +11 -0
  437. package/skills/i3-ui-prototype/scripts/prototype-lib.cjs +259 -0
  438. package/skills/i3-ui-prototype/scripts/template-adapters.cjs +89 -0
  439. package/skills/i3-using-agent-skills/SKILL.md +5 -0
@@ -0,0 +1,190 @@
1
+ 'use strict';
2
+ const test = require('node:test');
3
+ const assert = require('node:assert/strict');
4
+ const fs = require('node:fs');
5
+ const os = require('node:os');
6
+ const path = require('node:path');
7
+ const childProcess = require('node:child_process');
8
+ const installationFile = path.join(__dirname, 'lib/installation.js');
9
+ const skillsDirectory = fs.existsSync(installationFile) ? require(installationFile).loadInstallation().skillsDirectory : path.resolve(__dirname, '../skills');
10
+ const moduleFile = path.join(skillsDirectory, 'i3-ui-prototype/scripts/design-provider-discovery.cjs');
11
+
12
+ function fixture(t) {
13
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), 'i3-provider-discovery-'));
14
+ t.after(() => fs.rmSync(root, { recursive: true, force: true }));
15
+ const home = path.join(root, 'home'), project = path.join(root, 'project');
16
+ fs.mkdirSync(home); fs.mkdirSync(project);
17
+ return { root, home, project, env: {} };
18
+ }
19
+ function write(file, value) { fs.mkdirSync(path.dirname(file), { recursive: true }); fs.writeFileSync(file, typeof value === 'string' ? value : JSON.stringify(value)); }
20
+ function skill(root) { write(path.join(root, 'SKILL.md'), '# Fixture UI/UX'); return root; }
21
+ function discover(options, run = () => { throw new Error('Unexpected host CLI call'); }) {
22
+ const original = childProcess.spawnSync;
23
+ childProcess.spawnSync = run;
24
+ delete require.cache[require.resolve(moduleFile)];
25
+ let api;
26
+ try { api = require(moduleFile); } finally { childProcess.spawnSync = original; }
27
+ return api.discoverProviderCandidates(options);
28
+ }
29
+ function codexPlugin(f, overrides = {}) {
30
+ const record = { pluginId: 'ui-ux-pro-max@ui-ux-pro-max-skill', name: 'ui-ux-pro-max', marketplaceName: 'ui-ux-pro-max-skill', version: '2.15.0', installed: true, enabled: true, ...overrides };
31
+ const cache = path.join(f.env.CODEX_HOME || path.join(f.home, '.codex'), 'plugins/cache/ui-ux-pro-max-skill/ui-ux-pro-max', record.version);
32
+ if (!record.version.includes('..')) {
33
+ write(path.join(cache, '.claude-plugin/plugin.json'), { name: 'ui-ux-pro-max', version: record.version, skills: './.claude/skills/' });
34
+ skill(path.join(cache, '.claude/skills/ui-ux-pro-max'));
35
+ }
36
+ return { record, cache, run: () => ({ status: 0, stdout: JSON.stringify({ installed: [record], available: [] }) }) };
37
+ }
38
+ function registryPlugin(f, host, records, enabled = true) {
39
+ const config = path.join(f.home, `.${host}`), id = 'ui-ux-pro-max@fixture-market';
40
+ write(path.join(config, 'settings.json'), { enabledPlugins: { [id]: enabled } });
41
+ write(path.join(config, 'plugins/installed_plugins.json'), { version: 2, plugins: { [id]: records } });
42
+ for (const record of records) {
43
+ write(path.join(record.installPath, host === 'claude' ? '.claude-plugin/plugin.json' : '.codebuddy-plugin/plugin.json'), { name: 'ui-ux-pro-max', version: record.version, ...(host === 'claude' ? { skills: './.claude/skills/' } : {}) });
44
+ skill(path.join(record.installPath, host === 'claude' ? '.claude/skills/ui-ux-pro-max' : 'skills/ui-ux-pro-max'));
45
+ }
46
+ return config;
47
+ }
48
+
49
+ test('explicit provider has precedence over host roots and does not invoke discovery', t => {
50
+ const f = fixture(t), root = path.join(f.root, 'explicit');
51
+ assert.deepEqual(discover({ ...f, provider: root, providerRoots: ['/ignored'], host: 'codex' }), { candidates: [{ root, source: 'explicit' }], diagnostics: [] });
52
+ });
53
+ test('host-exposed provider roots work without host context and preserve order', t => {
54
+ const f = fixture(t), roots = [path.join(f.root, 'first'), path.join(f.root, 'second')];
55
+ assert.deepEqual(discover({ ...f, providerRoots: roots }).candidates.map(c => c.root), roots);
56
+ assert.equal(discover({ ...f, providerRoots: [] }).contextRequired, undefined);
57
+ });
58
+ test('unknown host requires context and cannot read another host cache', t => {
59
+ const f = fixture(t); skill(path.join(f.home, '.claude/skills/ui-ux-pro-max'));
60
+ assert.equal(discover(f).contextRequired, true);
61
+ assert.equal(discover({ ...f, host: 'unknown' }).contextRequired, true);
62
+ assert.deepEqual(discover({ ...f, host: 'unknown' }).candidates, []);
63
+ });
64
+ test('discover false prevents automatic host access', t => {
65
+ const f = fixture(t); skill(path.join(f.home, '.agents/skills/ui-ux-pro-max'));
66
+ assert.deepEqual(discover({ ...f, host: 'codex', discover: false }), { candidates: [], diagnostics: [], contextRequired: true });
67
+ });
68
+ test('Codex returns project then global skill locations and the exact enabled plugin version', t => {
69
+ const f = fixture(t), plugin = codexPlugin(f);
70
+ const project = skill(path.join(f.project, '.agents/skills/ui-ux-pro-max'));
71
+ const global = skill(path.join(f.home, '.codex/skills/ui-ux-pro-max'));
72
+ const stale = path.join(f.home, '.codex/plugins/cache/ui-ux-pro-max-skill/ui-ux-pro-max/99.0.0/.claude/skills/ui-ux-pro-max'); skill(stale);
73
+ let command;
74
+ const result = discover({ ...f, host: 'codex' }, (...args) => { command = args; return plugin.run(); });
75
+ assert.deepEqual(result.candidates.map(c => c.root), [project, global, path.join(plugin.cache, '.claude/skills/ui-ux-pro-max')]);
76
+ assert.equal(command[0], 'codex');
77
+ assert.deepEqual(command[1], ['plugin', 'list', '--marketplace', 'ui-ux-pro-max-skill', '--json']);
78
+ assert.ok(command[2].timeout > 0 && command[2].timeout <= 15000);
79
+ assert.equal(command[2].shell, false);
80
+ });
81
+ test('Codex honors isolated CODEX_HOME and never scans the default cache', t => {
82
+ const f = fixture(t); f.env.CODEX_HOME = path.join(f.root, 'custom-codex');
83
+ const plugin = codexPlugin(f);
84
+ const result = discover({ ...f, host: 'codex' }, plugin.run);
85
+ assert.equal(result.candidates.at(-1).root, path.join(plugin.cache, '.claude/skills/ui-ux-pro-max'));
86
+ });
87
+ test('Codex disabled cached plugin is not a candidate', t => {
88
+ const f = fixture(t), plugin = codexPlugin(f, { enabled: false });
89
+ const result = discover({ ...f, host: 'codex' }, plugin.run);
90
+ assert.deepEqual(result.candidates, []);
91
+ assert.equal(result.diagnostics[0].availability, 'disabled');
92
+ });
93
+ test('Codex missing installation does not inspect cached versions', t => {
94
+ const f = fixture(t); codexPlugin(f);
95
+ const result = discover({ ...f, host: 'codex' }, () => ({ status: 0, stdout: '{"installed":[],"available":[]}' }));
96
+ assert.deepEqual(result.candidates, []);
97
+ assert.ok(result.diagnostics.every(d => d.availability === 'missing'));
98
+ });
99
+ for (const [name, run] of [
100
+ ['missing CLI', () => ({ status: null, error: { code: 'ENOENT' }, stdout: '' })],
101
+ ['failed CLI', () => ({ status: 1, stderr: 'failure', stdout: '' })],
102
+ ['invalid JSON', () => ({ status: 0, stdout: '{bad' })],
103
+ ['invalid schema', () => ({ status: 0, stdout: '{}' })],
104
+ ]) test(`Codex ${name} is a discovery error, not a missing installation`, t => {
105
+ const f = fixture(t), result = discover({ ...f, host: 'codex' }, run);
106
+ assert.equal(result.diagnostics[0].availability, 'discovery-error');
107
+ });
108
+ test('Codex rejects multiple active installed records instead of selecting a version', t => {
109
+ const f = fixture(t), { record } = codexPlugin(f);
110
+ const result = discover({ ...f, host: 'codex' }, () => ({ status: 0, stdout: JSON.stringify({ installed: [record, { ...record, version: '2.14.0' }] }) }));
111
+ assert.deepEqual(result.candidates, []);
112
+ assert.equal(result.diagnostics[0].availability, 'ambiguous');
113
+ });
114
+ for (const [name, change] of [
115
+ ['wrong manifest version', m => { m.version = '2.14.0'; }],
116
+ ['wrong manifest name', m => { m.name = 'different'; }],
117
+ ['escaping skills declaration', m => { m.skills = '../../../outside'; }],
118
+ ['missing skills declaration', m => { delete m.skills; }],
119
+ ]) test(`Codex rejects ${name}`, t => {
120
+ const f = fixture(t), plugin = codexPlugin(f), file = path.join(plugin.cache, '.claude-plugin/plugin.json');
121
+ const manifest = JSON.parse(fs.readFileSync(file)); change(manifest); write(file, manifest);
122
+ const result = discover({ ...f, host: 'codex' }, plugin.run);
123
+ assert.deepEqual(result.candidates, []);
124
+ assert.equal(result.diagnostics[0].availability, 'discovery-error');
125
+ });
126
+ test('Codex validates the active version as a single safe path segment', t => {
127
+ const f = fixture(t), plugin = codexPlugin(f, { version: '../../escape' });
128
+ assert.equal(discover({ ...f, host: 'codex' }, plugin.run).diagnostics[0].availability, 'discovery-error');
129
+ });
130
+ test('Codex rejects a child skill symlink escaping the registered plugin root', t => {
131
+ const f = fixture(t), plugin = codexPlugin(f), outside = skill(path.join(f.root, 'outside'));
132
+ const child = path.join(plugin.cache, '.claude/skills/ui-ux-pro-max');
133
+ fs.rmSync(child, { recursive: true }); fs.symlinkSync(outside, child, 'dir');
134
+ const result = discover({ ...f, host: 'codex' }, plugin.run);
135
+ assert.deepEqual(result.candidates, []);
136
+ assert.equal(result.diagnostics[0].availability, 'discovery-error');
137
+ });
138
+ for (const host of ['claude', 'workbuddy', 'codebuddy']) test(`${host} selects only enabled registered plugins`, t => {
139
+ const f = fixture(t), installPath = path.join(f.root, host, 'plugin');
140
+ registryPlugin(f, host, [{ scope: 'user', installPath, version: '2.0.0' }]);
141
+ const result = discover({ ...f, host });
142
+ assert.deepEqual(result.candidates.map(c => c.root), [path.join(installPath, host === 'claude' ? '.claude/skills/ui-ux-pro-max' : 'skills/ui-ux-pro-max')]);
143
+ registryPlugin(f, host, [{ scope: 'user', installPath, version: '2.0.0' }], false);
144
+ const disabled = discover({ ...f, host });
145
+ assert.deepEqual(disabled.candidates, []); assert.equal(disabled.diagnostics[0].availability, 'disabled');
146
+ });
147
+ test('missing optional registry is normal, while corrupt metadata is an error', t => {
148
+ const f = fixture(t);
149
+ assert.ok(discover({ ...f, host: 'workbuddy' }).diagnostics.every(d => d.availability === 'missing'));
150
+ write(path.join(f.home, '.workbuddy/plugins/installed_plugins.json'), '{invalid');
151
+ assert.equal(discover({ ...f, host: 'workbuddy' }).diagnostics[0].availability, 'discovery-error');
152
+ });
153
+ test('a registered plugin with missing enablement metadata needs diagnosis instead of installation', t => {
154
+ const f = fixture(t);
155
+ const config = registryPlugin(f, 'workbuddy', [{ scope: 'user', installPath: path.join(f.root, 'plugin'), version: '2.0.0' }]);
156
+ fs.unlinkSync(path.join(config, 'settings.json'));
157
+ const result = discover({ ...f, host: 'workbuddy' });
158
+ assert.deepEqual(result.candidates, []);
159
+ assert.equal(result.diagnostics[0].availability, 'discovery-error');
160
+ });
161
+ test('project plugin scope must match the current project path', t => {
162
+ const f = fixture(t), installPath = path.join(f.root, 'plugin');
163
+ registryPlugin(f, 'claude', [{ scope: 'project', projectPath: path.join(f.root, 'other-project'), installPath, version: '2.0.0' }]);
164
+ assert.deepEqual(discover({ ...f, host: 'claude-code' }).candidates, []);
165
+ registryPlugin(f, 'claude', [{ scope: 'project', projectPath: f.project, installPath, version: '2.0.0' }]);
166
+ assert.equal(discover({ ...f, host: 'claude-code' }).candidates.length, 1);
167
+ registryPlugin(f, 'claude', [{ scope: 'project', installPath, version: '2.0.0' }]);
168
+ assert.deepEqual(discover({ ...f, host: 'claude-code' }).candidates, []);
169
+ });
170
+ test('ambiguous matching registry entries do not pick one arbitrarily', t => {
171
+ const f = fixture(t);
172
+ registryPlugin(f, 'workbuddy', [
173
+ { scope: 'user', installPath: path.join(f.root, 'first'), version: '2.0.0' },
174
+ { scope: 'user', installPath: path.join(f.root, 'second'), version: '2.1.0' },
175
+ ]);
176
+ const result = discover({ ...f, host: 'workbuddy' });
177
+ assert.deepEqual(result.candidates, []); assert.equal(result.diagnostics[0].availability, 'ambiguous');
178
+ });
179
+ test('host selection never borrows another host global plugin', t => {
180
+ const f = fixture(t);
181
+ registryPlugin(f, 'claude', [{ scope: 'user', installPath: path.join(f.root, 'claude'), version: '2.0.0' }]);
182
+ registryPlugin(f, 'workbuddy', [{ scope: 'user', installPath: path.join(f.root, 'workbuddy'), version: '2.0.0' }]);
183
+ assert.deepEqual(discover({ ...f, host: 'codebuddy' }).candidates, []);
184
+ });
185
+ test('WorkBuddy uses its global config override and the project CodeBuddy skills directory', t => {
186
+ const f = fixture(t); f.env.WORKBUDDY_CONFIG_DIR = path.join(f.root, 'custom-workbuddy');
187
+ const projectRoot = skill(path.join(f.project, '.codebuddy/skills/ui-ux-pro-max'));
188
+ const globalRoot = skill(path.join(f.env.WORKBUDDY_CONFIG_DIR, 'skills/ui-ux-pro-max'));
189
+ assert.deepEqual(discover({ ...f, host: 'workbuddy' }).candidates.map(c => c.root), [projectRoot, globalRoot]);
190
+ });
@@ -0,0 +1,68 @@
1
+ 'use strict';
2
+ const { test, mock } = require('node:test');
3
+ const assert = require('node:assert/strict');
4
+ const fs = require('node:fs');
5
+ const os = require('node:os');
6
+ const path = require('node:path');
7
+ const cp = require('node:child_process');
8
+ mock.method(cp, 'spawnSync', (command, args) => {
9
+ if (!args.includes('--json') || args[0] !== '-B') return { status: 1, stdout: '', stderr: 'No plugin CLI in isolated test' };
10
+ if (args[1].includes('query-fails')) return { status: 1, stdout: '', stderr: 'Python module unavailable' };
11
+ return { status: 0, stdout: JSON.stringify({ domain: 'ux', results: [{ name: 'Error summary' }] }), stderr: '' };
12
+ });
13
+ const installationFile = path.join(__dirname, 'lib/installation.js');
14
+ const skillsDirectory = fs.existsSync(installationFile) ? require(installationFile).loadInstallation().skillsDirectory : path.resolve(__dirname, '../skills');
15
+ const lib = require(path.join(skillsDirectory, 'i3-ui-prototype/scripts/prototype-lib.cjs'));
16
+ function fixture(t) {
17
+ const home = fs.mkdtempSync(path.join(os.tmpdir(), 'i3-provider-'));
18
+ t.after(() => fs.rmSync(home, { recursive: true, force: true }));
19
+ return home;
20
+ }
21
+ function provider(home, name) {
22
+ const root = path.join(home, name);
23
+ for (const file of ['SKILL.md', 'scripts/search.py', 'scripts/core.py', 'scripts/design_system.py', ...['ux-guidelines', 'styles', 'colors', 'typography', 'products', 'landing', 'ui-reasoning'].map(name => `data/${name}.csv`)]) {
24
+ fs.mkdirSync(path.dirname(path.join(root, file)), { recursive: true });
25
+ fs.writeFileSync(path.join(root, file), 'fixture');
26
+ }
27
+ return root;
28
+ }
29
+ test('an incomplete project provider does not shadow a usable global provider', t => {
30
+ const home = fixture(t), local = path.join(home, 'project-provider'), global = provider(home, 'global-provider');
31
+ fs.mkdirSync(local);
32
+ const result = lib.checkDesignProvider({ providerRoots: [local, global] });
33
+ assert.equal(result.availability, 'available');
34
+ assert.equal(result.root, global);
35
+ assert.equal(result.attempts[0].availability, 'unusable');
36
+ assert.ok(result.attempts[0].missing.includes('scripts/search.py'));
37
+ });
38
+ test('a failed project query does not shadow a usable global provider', t => {
39
+ const home = fixture(t), local = provider(home, 'query-fails'), global = provider(home, 'global-provider');
40
+ const result = lib.checkDesignProvider({ providerRoots: [local, global] });
41
+ assert.equal(result.availability, 'available');
42
+ assert.equal(result.root, global);
43
+ assert.match(result.attempts[0].reason, /Python module unavailable/);
44
+ });
45
+ test('an explicit provider failure never silently selects a different provider', t => {
46
+ const home = fixture(t), selected = path.join(home, 'missing'), other = provider(home, 'other');
47
+ const result = lib.checkDesignProvider({ provider: selected, providerRoots: [other] });
48
+ assert.equal(result.availability, 'missing');
49
+ assert.deepEqual(result.searched, [selected]);
50
+ });
51
+ test('without host or provider the result requests context, not installation', t => {
52
+ const home = fixture(t);
53
+ const result = lib.initPrototype({ project: home, id: 'demo', home, env: {} });
54
+ assert.equal(result.provider.availability, 'needs-context');
55
+ assert.equal(result.choices[0].id, 'locate');
56
+ assert.ok(!result.choices.some(choice => choice.id === 'install'));
57
+ assert.equal(fs.existsSync(path.join(home, 'prototypes')), false);
58
+ });
59
+ test('all unusable providers preserve their individual failure reasons without asking to reinstall', t => {
60
+ const home = fixture(t), incomplete = path.join(home, 'incomplete'), failing = provider(home, 'query-fails');
61
+ fs.mkdirSync(incomplete);
62
+ const result = lib.initPrototype({ project: home, id: 'demo', providerRoots: [incomplete, failing] });
63
+ assert.equal(result.provider.availability, 'unusable');
64
+ assert.equal(result.provider.attempts.length, 2);
65
+ assert.equal(result.choices[0].id, 'repair');
66
+ assert.ok(!result.choices.some(choice => choice.id === 'install'));
67
+ assert.equal(fs.existsSync(path.join(home, 'prototypes')), false);
68
+ });
@@ -0,0 +1,179 @@
1
+ 'use strict';
2
+ const test = require('node:test');
3
+ const assert = require('node:assert/strict');
4
+ const fs = require('node:fs');
5
+ const path = require('node:path');
6
+ const os = require('node:os');
7
+ const crypto = require('node:crypto');
8
+ const { spawn, spawnSync } = require('node:child_process');
9
+ const install = path.join(__dirname, 'lib/installation.js');
10
+ const skills = fs.existsSync(install) ? require(install).loadInstallation().skillsDirectory : path.resolve(__dirname, '../skills');
11
+ const skill = path.join(skills, 'i3-ui-prototype');
12
+ const lib = require(path.join(skill, 'scripts/prototype-lib.cjs'));
13
+ const enterprise = require(path.join(skill, 'scripts/enterprise-template.cjs'));
14
+ const read = (root, file) => JSON.parse(fs.readFileSync(path.join(root, file), 'utf8'));
15
+ function project(t) {
16
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), 'enterprise-template-'));
17
+ t.after(() => fs.rmSync(root, { recursive: true, force: true }));
18
+ return root;
19
+ }
20
+ function initialize(t, options = {}) {
21
+ return lib.initPrototype({ project: project(t), id: 'enterprise-demo', expertMode: 'template', purpose: 'template-review', ...options }).directory;
22
+ }
23
+ test('runtime branding changes uppercase product text only in runtime HTML and JavaScript', () => {
24
+ const source = 'EASEL easel-html /easel EASEL 研发';
25
+ for (const file of ['index.html', 'src/shell/ConsoleShell.html', 'src/models/data.js']) {
26
+ assert.equal(enterprise.brandRuntimeResource(file, source), 'i3-Composer easel-html /easel i3-Composer 研发');
27
+ }
28
+ for (const file of ['origin.json', 'licenses/EASEL.txt', 'qa/REVIEW.md', 'src/styles.css', 'tests/behavior.js', 'app.js']) {
29
+ const bytes = Buffer.from(source);
30
+ assert.equal(enterprise.brandRuntimeResource(file, bytes), bytes, file);
31
+ }
32
+ assert.ok(Buffer.isBuffer(enterprise.brandRuntimeResource('src/models/data.js', Buffer.from(source))));
33
+ });
34
+ test('generated enterprise runtime uses i3-Composer branding with one final adaptation record per changed source', t => {
35
+ const dir = initialize(t, { title: 'i3-Composer 品牌验收' });
36
+ const shell = fs.readFileSync(path.join(dir, 'app/src/shell/ConsoleShell.html'), 'utf8');
37
+ assert.match(shell, /<strong>i3-Composer<\/strong>/);
38
+ assert.doesNotMatch(shell, /EASEL/);
39
+ assert.match(fs.readFileSync(path.join(dir, 'app/index.html'), 'utf8'), /<title>i3-Composer/);
40
+ const models = fs.readFileSync(path.join(dir, 'app/src/models/data.js'), 'utf8');
41
+ assert.match(models, /i3-Composer 研发/);
42
+ assert.doesNotMatch(models, /EASEL/);
43
+ assert.match(fs.readFileSync(path.join(dir, 'app/src/permissions/MemberEditor.html'), 'utf8'), /i3-Composer 业务角色/);
44
+ assert.doesNotMatch(read(dir, 'requirements-map.json').scope, /EASEL/);
45
+ assert.doesNotMatch(fs.readFileSync(path.join(dir, 'mocks/README.md'), 'utf8'), /EASEL/);
46
+ const origin = enterprise.verifyReference(), source = read(dir, 'design-system/source.json');
47
+ assert.equal(origin.fileCount, 326);
48
+ assert.equal(new Set(source.adaptations.map(record => record.file)).size, source.adaptations.length);
49
+ const adapted = new Map(source.adaptations.map(record => [record.file, record]));
50
+ for (const [file, expected] of Object.entries(origin.files)) {
51
+ const generated = crypto.createHash('sha256').update(fs.readFileSync(path.join(dir, 'app', file))).digest('hex');
52
+ if (generated === expected) continue;
53
+ const record = adapted.get(file);
54
+ assert.ok(record, `Unrecorded runtime adaptation: ${file}`);
55
+ assert.equal(record.source, expected, file);
56
+ assert.equal(record.generated, generated, file);
57
+ assert.ok(record.reason, file);
58
+ }
59
+ assert.match(adapted.get('index.html').reason, /i3-Composer/);
60
+ assert.match(adapted.get('src/models/data.js').reason, /i3-Composer/);
61
+ });
62
+ test('four prototype families expose the EASEL enterprise template and explicitly defer the other three', () => {
63
+ const entries = lib.listTemplates();
64
+ assert.deepEqual(entries.map(x => x.id), ['enterprise-admin', 'ai-workbench', 'digital-twin', 'mobile-app']);
65
+ assert.deepEqual(entries.filter(x => x.availability === 'available').map(x => x.id), ['enterprise-admin']);
66
+ for (const entry of entries.slice(1)) assert.equal(entry.availability, 'planned');
67
+ });
68
+ test('default enterprise initializer preserves the complete EASEL runtime and its review scope', t => {
69
+ const dir = initialize(t), metadata = read(dir, 'prototype.json');
70
+ assert.equal(metadata.template.id, 'enterprise-admin');
71
+ assert.equal(metadata.purpose, 'template-review');
72
+ assert.equal(metadata.review.status, 'pending-review');
73
+ const inspection = lib.checkPrototype(dir);
74
+ assert.equal(inspection.status, 'passed', JSON.stringify(inspection));
75
+ const routes = read(dir, 'app/routes.json').filter(x => x.component && !x.path.startsWith('/module/'));
76
+ assert.equal(routes.length, 37);
77
+ assert.equal(new Set(routes.map(x => x.component)).size, 34);
78
+ for (const file of ['app/runtime/dom.js', 'app/styles/antdv.css', 'app/src/shell/ConsoleShell.html', 'app/licenses/antdv-next.txt', 'design-system/source.json']) {
79
+ assert.ok(fs.existsSync(path.join(dir, file)), file);
80
+ }
81
+ });
82
+ test('planned template families refuse initialization without silently generating a desktop demo', t => {
83
+ const root = project(t);
84
+ for (const template of ['ai-workbench', 'digital-twin', 'mobile-app']) {
85
+ assert.throws(() => lib.initPrototype({ project: root, id: template, template, expertMode: 'template' }), /planned|尚未|待建设/);
86
+ }
87
+ assert.equal(fs.existsSync(path.join(root, 'prototypes')), false);
88
+ });
89
+ test('all imported reference files retain their declared source hashes', () => {
90
+ const origin = read(skill, 'assets/templates/enterprise-admin/origin.json');
91
+ assert.equal(Object.keys(origin.files).length, 326);
92
+ for (const [file, expected] of Object.entries(origin.files)) {
93
+ const contents = fs.readFileSync(path.join(skill, 'assets/templates/enterprise-admin/reference', origin.storagePaths?.[file] || file));
94
+ assert.equal(crypto.createHash('sha256').update(contents).digest('hex'), expected, file);
95
+ }
96
+ });
97
+ test('an unadapted EASEL example cannot pass new-business acceptance', t => {
98
+ const dir = initialize(t, { purpose: 'business-prototype' });
99
+ assert.equal(read(dir, 'prototype.json').business.status, 'needs-adaptation');
100
+ assert.match(lib.checkPrototype(dir, { acceptance: true }).errors.join(' '), /业务|adapt/);
101
+ });
102
+ test('generated enterprise instances isolate their local demo storage and retain the original route behavior', t => {
103
+ const dir = initialize(t);
104
+ const source = fs.readFileSync(path.join(dir, 'app/src/shared/session.js'), 'utf8');
105
+ assert.match(source, /i3-enterprise-enterprise-demo-/);
106
+ assert.doesNotMatch(source, /i3-prototype-antdv-/);
107
+ assert.match(fs.readFileSync(path.join(dir, 'app/index.html'), 'utf8'), /enterprise-bootstrap\.mjs/);
108
+ assert.match(fs.readFileSync(path.join(dir, 'app/index.html'), 'utf8'), /tokens\.css/);
109
+ const other = initialize(t);
110
+ assert.notEqual(read(dir, 'prototype.json').runtime.storagePrefix, read(other, 'prototype.json').runtime.storagePrefix);
111
+ });
112
+ test('missing enterprise runtime imports are rejected while declarative data-bind attributes remain valid', t => {
113
+ const dir = initialize(t);
114
+ assert.equal(lib.checkPrototype(dir).status, 'passed');
115
+ fs.unlinkSync(path.join(dir, 'app/runtime/controls.js'));
116
+ const result = lib.checkPrototype(dir);
117
+ assert.equal(result.status, 'failed');
118
+ assert.match(result.errors.join(' '), /controls\.js/);
119
+ });
120
+ test('tampered template source assets are rejected before a new instance can be trusted', t => {
121
+ const temp = project(t);
122
+ const copy = path.join(temp, 'enterprise-admin');
123
+ fs.cpSync(path.join(skill, 'assets/templates/enterprise-admin'), copy, { recursive: true });
124
+ fs.appendFileSync(path.join(copy, 'reference/styles/app.css'), '\n/* unexpected source edit */');
125
+ const { verifyReference } = require(path.join(skill, 'scripts/enterprise-template.cjs'));
126
+ assert.throws(() => verifyReference(copy), /integrity|来源完整性/);
127
+ });
128
+ test('enterprise preview serves JavaScript modules and SVG assets with browser-compatible MIME types', async t => {
129
+ const dir = initialize(t);
130
+ const child = spawn(process.execPath, ['app/serve.cjs'], { cwd: dir, stdio: ['ignore', 'pipe', 'pipe'] });
131
+ t.after(() => child.kill());
132
+ const url = await new Promise((resolve, reject) => {
133
+ const timer = setTimeout(() => reject(new Error('Preview start timed out')), 5000);
134
+ child.stdout.on('data', data => { const match = data.toString().match(/http:\/\/127\.0\.0\.1:\d+\//); if (match) { clearTimeout(timer); resolve(match[0]); } });
135
+ child.once('error', reject);
136
+ });
137
+ const js = await fetch(url + 'app/app.js');
138
+ assert.equal(js.status, 200);
139
+ assert.match(js.headers.get('content-type'), /javascript/);
140
+ const svg = await fetch(url + 'app/assets/empty.svg');
141
+ assert.equal(svg.status, 200);
142
+ assert.match(svg.headers.get('content-type'), /image\/svg\+xml/);
143
+ });
144
+ test('gallery and generated enterprise instances deliver the same scrolling adapter while retaining the complete reference', t => {
145
+ const dir = initialize(t);
146
+ const css = fs.readFileSync(path.join(dir, 'app/usability.css'));
147
+ assert.equal(css.compare(fs.readFileSync(path.join(skill, 'assets/templates/enterprise-admin/usability.css'))), 0);
148
+ assert.match(fs.readFileSync(path.join(dir, 'app/index.html'), 'utf8'), /href="usability\.css"/);
149
+ const preview = lib.listTemplates()[0].preview.split('#')[0];
150
+ const entry = path.join(skill, 'assets/templates', preview);
151
+ assert.notEqual(preview, 'enterprise-admin/reference/index.html');
152
+ const html = fs.readFileSync(entry, 'utf8');
153
+ assert.match(html, /href="usability\.css"/);
154
+ for (const match of html.matchAll(/(?:src|href)="([^"#]+)"/g)) {
155
+ if (match[1].startsWith('data:')) continue;
156
+ assert.ok(fs.existsSync(path.resolve(path.dirname(entry), match[1])), match[1]);
157
+ }
158
+ const { verifyReference } = require(path.join(skill, 'scripts/enterprise-template.cjs'));
159
+ assert.equal(verifyReference().fileCount, 326);
160
+ });
161
+ test('scrolling behavior remains protected after an enterprise baseline is confirmed', t => {
162
+ const dir = initialize(t);
163
+ // Unit fixture only: these records exercise the baseline guard and do not
164
+ // claim real browser execution or human acceptance of a delivered prototype.
165
+ fs.writeFileSync(path.join(dir, 'qa/unit-fixture.txt'), 'UNIT FIXTURE ONLY');
166
+ const manifest = lib.contentManifest(dir);
167
+ const scenarios = new Set(read(dir, 'requirements-map.json').requirements.flatMap(x => x.scenarios));
168
+ fs.writeFileSync(path.join(dir, 'qa/browser.json'), JSON.stringify({
169
+ ...manifest, status: 'passed', source: 'UNIT FIXTURE ONLY', consoleErrors: [],
170
+ screenshots: ['qa/unit-fixture.txt'], viewports: [390, 1440],
171
+ journeys: [...scenarios].map(id => ({ id, status: 'passed' })),
172
+ }));
173
+ lib.freezeBaseline(dir, { revision: manifest.revision, digest: manifest.digest, reviewer: 'unit fixture', statement: 'UNIT FIXTURE ONLY', source: 'test fixture' });
174
+ fs.appendFileSync(path.join(dir, 'app/usability.css'), '\n/* changed scrolling behavior */\n');
175
+ assert.ok(lib.compareBaseline(dir).protectedChanges.includes('app/usability.css'));
176
+ const guard = spawnSync(process.execPath, [path.join(skill, 'scripts/check-prototype.cjs'), dir, '--enforce-baseline'], { encoding: 'utf8' });
177
+ assert.equal(guard.status, 1);
178
+ assert.match(guard.stdout, /Design constraints changed/);
179
+ });
@@ -9,7 +9,7 @@ const fs = require('node:fs');
9
9
  const os = require('node:os');
10
10
  const path = require('node:path');
11
11
 
12
- const { lintSkillContent, lintSkillLayout, topLevelFrontmatterKeys } = require('./skill-lint.js');
12
+ const { lintSkillContent, lintSkillLayout, topLevelFrontmatterKeys, parseFrontmatter, frontmatterYamlErrors, lintPersonaContent } = require('./skill-lint.js');
13
13
 
14
14
  const KNOWN = new Set(['alpha', 'beta']);
15
15
 
@@ -648,3 +648,115 @@ test('the spec-key check tolerates CRLF frontmatter', () => {
648
648
  const { errors } = lintSkillContent('alpha', content, KNOWN);
649
649
  assert.equal(errors.filter(e => /key 'temperature'/.test(e)).length, 1);
650
650
  });
651
+
652
+ test('parseFrontmatter ignores comments and nested metadata keys', () => {
653
+ const content = [
654
+ '---',
655
+ 'name: alpha',
656
+ '# note: this is a comment',
657
+ 'description: Designs alphas. Use when building one.',
658
+ 'metadata:',
659
+ ' name: beta',
660
+ ' description: Nested details without trigger',
661
+ '---',
662
+ '',
663
+ ].join('\n');
664
+ assert.deepEqual(parseFrontmatter(content), {
665
+ name: 'alpha',
666
+ description: 'Designs alphas. Use when building one.',
667
+ metadata: '',
668
+ });
669
+ });
670
+
671
+ test('frontmatterYamlErrors ignores comment lines containing colons or quotes', () => {
672
+ const content = [
673
+ '---',
674
+ 'name: alpha',
675
+ '# note: a comment: with a colon and "unclosed quote',
676
+ 'description: "Designs alphas. Use when building one."',
677
+ '---',
678
+ '',
679
+ ].join('\n');
680
+ assert.deepEqual(frontmatterYamlErrors(content), []);
681
+ });
682
+
683
+ test('a skill with frontmatter comments and nested metadata passes validation', () => {
684
+ const content = withAllSections([
685
+ '---',
686
+ 'name: alpha',
687
+ '# Note: keep description up to date: check docs',
688
+ 'description: Designs alphas. Use when building one.',
689
+ 'metadata:',
690
+ ' name: beta',
691
+ ' description: Internal notes',
692
+ '---',
693
+ ].join('\n'));
694
+ const { errors } = lintSkillContent('alpha', content, KNOWN);
695
+ assert.deepEqual(errors, []);
696
+ });
697
+
698
+ // ─── Personas (agents/<name>.md) ─────────────────────────────────────────────
699
+ //
700
+ // docs/agents.md: same frontmatter format as a skill, name equal to the file
701
+ // stem, and the file ends with a Composition block. Nothing more is checked.
702
+
703
+ function personaFile({ name = 'code-reviewer', description = 'Reviews changes. Use before merging.', body } = {}) {
704
+ const fm = ['---', name === null ? null : `name: ${name}`, description === null ? null : `description: ${description}`, '---']
705
+ .filter(l => l !== null).join('\n');
706
+ return `${fm}\n\n${body ?? '# Persona\n\n## Rules\n\nBe precise.\n\n## Composition\n\n- **Invoke via:** `/ship`.\n'}`;
707
+ }
708
+
709
+ test('a conforming persona produces no errors', () => {
710
+ assert.deepEqual(lintPersonaContent('code-reviewer', personaFile()).errors, []);
711
+ });
712
+
713
+ test('persona: frontmatter name must match the file stem', () => {
714
+ const { errors } = lintPersonaContent('code-reviewer', personaFile({ name: 'reviewer' }));
715
+ assert.equal(errors.length, 1);
716
+ assert.match(errors[0], /name 'reviewer' does not match file name 'code-reviewer'/);
717
+ });
718
+
719
+ test('persona: description is required', () => {
720
+ const { errors } = lintPersonaContent('code-reviewer', personaFile({ description: null }));
721
+ assert.equal(errors.length, 1);
722
+ assert.match(errors[0], /missing required field: 'description'/);
723
+ });
724
+
725
+ test('persona: a missing frontmatter block is reported and nothing else is attempted', () => {
726
+ const { errors } = lintPersonaContent('code-reviewer', '# Persona\n\n## Composition\n');
727
+ assert.equal(errors.length, 1);
728
+ assert.match(errors[0], /Missing or malformed YAML frontmatter/);
729
+ });
730
+
731
+ test('persona: frontmatter a host would reject as YAML is reported', () => {
732
+ const { errors } = lintPersonaContent('code-reviewer', personaFile({ description: 'Reviews: everything. Use before merging.' }));
733
+ assert.equal(errors.length, 1);
734
+ assert.match(errors[0], /Frontmatter line/);
735
+ });
736
+
737
+ test('persona: the Composition section is required', () => {
738
+ const { errors } = lintPersonaContent('code-reviewer', personaFile({ body: '# Persona\n\n## Rules\n\nBe precise.\n' }));
739
+ assert.equal(errors.length, 1);
740
+ assert.match(errors[0], /Missing "## Composition" section/);
741
+ });
742
+
743
+ test('persona: Composition must be the last section', () => {
744
+ const { errors } = lintPersonaContent('code-reviewer', personaFile({
745
+ body: '# Persona\n\n## Composition\n\n- **Invoke via:** `/ship`.\n\n## Output Format\n\nA report.\n',
746
+ }));
747
+ assert.equal(errors.length, 1);
748
+ assert.match(errors[0], /must be the last section, but "## Output Format" follows it/);
749
+ });
750
+
751
+ test('persona: a heading inside a fenced example after Composition is not a later section', () => {
752
+ const body = [
753
+ '# Persona', '', '## Composition', '', '- **Invoke via:** `/ship`. Report in this shape:', '',
754
+ '```markdown', '## Review: [title]', 'Findings…', '```', '',
755
+ ].join('\n');
756
+ assert.deepEqual(lintPersonaContent('code-reviewer', personaFile({ body })).errors, []);
757
+ });
758
+
759
+ test('persona: the Composition heading match is case-insensitive and tolerates trailing spaces', () => {
760
+ const body = '# Persona\n\n## composition \n\n- **Invoke via:** `/ship`.\n';
761
+ assert.deepEqual(lintPersonaContent('code-reviewer', personaFile({ body })).errors, []);
762
+ });