@givolt/i3-composer-agent 2.2.3 → 2.3.0

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 (436) 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 +27 -1
  44. package/plugin.json +1 -1
  45. package/references/performance-checklist.md +4 -2
  46. package/scripts/enterprise-template-test.js +139 -0
  47. package/scripts/lib/skill-lint-test.js +113 -1
  48. package/scripts/lib/skill-lint.js +62 -8
  49. package/scripts/run-evals-test.js +207 -0
  50. package/scripts/run-evals.js +47 -9
  51. package/scripts/template-adapter-test.js +155 -0
  52. package/scripts/ui-prototype-test.js +114 -0
  53. package/scripts/validate-commands-test.js +30 -0
  54. package/scripts/validate-commands.js +6 -16
  55. package/scripts/validate-reference-links-test.js +18 -0
  56. package/scripts/validate-reference-links.js +4 -2
  57. package/scripts/validate-skills.js +26 -3
  58. package/skills/i3-documentation-and-adrs/SKILL.md +9 -0
  59. package/skills/i3-frontend-ui-engineering/SKILL.md +5 -1
  60. package/skills/i3-idea-refine/SKILL.md +20 -5
  61. package/skills/i3-incremental-implementation/SKILL.md +4 -0
  62. package/skills/i3-performance-optimization/SKILL.md +10 -10
  63. package/skills/i3-security-and-hardening/references/hardening-patterns.md +1 -1
  64. package/skills/i3-shipping-and-launch/SKILL.md +6 -0
  65. package/skills/i3-test-driven-development/SKILL.md +3 -3
  66. package/skills/i3-ui-prototype/SKILL.md +119 -0
  67. package/skills/i3-ui-prototype/assets/templates/catalog.json +147 -0
  68. package/skills/i3-ui-prototype/assets/templates/classic-admin/manifest.json +9 -0
  69. package/skills/i3-ui-prototype/assets/templates/classic-admin/preset.json +6 -0
  70. package/skills/i3-ui-prototype/assets/templates/common/app/app.mjs +89 -0
  71. package/skills/i3-ui-prototype/assets/templates/common/app/config.json +1 -0
  72. package/skills/i3-ui-prototype/assets/templates/common/app/domain.mjs +20 -0
  73. package/skills/i3-ui-prototype/assets/templates/common/app/index.html +17 -0
  74. package/skills/i3-ui-prototype/assets/templates/common/app/serve.cjs +16 -0
  75. package/skills/i3-ui-prototype/assets/templates/common/app/styles.css +670 -0
  76. package/skills/i3-ui-prototype/assets/templates/common/app/tokens.css +19 -0
  77. package/skills/i3-ui-prototype/assets/templates/common/design-system/master.md +20 -0
  78. package/skills/i3-ui-prototype/assets/templates/common/gallery.html +2 -0
  79. package/skills/i3-ui-prototype/assets/templates/common/mocks/applications.json +5 -0
  80. package/skills/i3-ui-prototype/assets/templates/common/requirements-map.json +8 -0
  81. package/skills/i3-ui-prototype/assets/templates/common/serve-gallery.cjs +16 -0
  82. package/skills/i3-ui-prototype/assets/templates/credits.md +17 -0
  83. package/skills/i3-ui-prototype/assets/templates/data-operations/manifest.json +9 -0
  84. package/skills/i3-ui-prototype/assets/templates/data-operations/preset.json +6 -0
  85. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/design-system.md +32 -0
  86. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/index.html +29 -0
  87. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/manifest.json +9 -0
  88. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/origin.json +344 -0
  89. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/preset.json +928 -0
  90. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/app.js +22 -0
  91. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets/empty.svg +1 -0
  92. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets/reference-styles.json +1 -0
  93. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets/result-403.svg +1 -0
  94. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets/result-404.svg +1 -0
  95. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets-manifest.json +334 -0
  96. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/baseline.json +173 -0
  97. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/conversion.md +30 -0
  98. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/credits.md +17 -0
  99. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/design-tokens.json +881 -0
  100. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/index.html +28 -0
  101. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/licenses/@qin-ui-antdv-next-pro.txt +9 -0
  102. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/licenses/ant-design-icons.txt +22 -0
  103. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/licenses/antdv-next.txt +21 -0
  104. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/package.json +12 -0
  105. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/browser-routes.json +298 -0
  106. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/coverage.json +180 -0
  107. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/integrity.json +13 -0
  108. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/keyboard.json +11 -0
  109. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/responsive.json +125 -0
  110. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/review.md +51 -0
  111. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/rules.log +150 -0
  112. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/flow-editor-html.png +0 -0
  113. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/flow-editor-original.png +0 -0
  114. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/intent-create-html.png +0 -0
  115. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/intent-create-original.png +0 -0
  116. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/models-html.png +0 -0
  117. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/models-original.png +0 -0
  118. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/workbench-html.png +0 -0
  119. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/workbench-original.png +0 -0
  120. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/selection.json +9 -0
  121. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/visual-comparison.json +342 -0
  122. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/readme.md +73 -0
  123. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/reference.md +59 -0
  124. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/routes.json +178 -0
  125. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/controls.js +99 -0
  126. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/dialogs.js +54 -0
  127. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/dom.js +264 -0
  128. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/forms.js +47 -0
  129. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/icons.js +41 -0
  130. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/layout.js +47 -0
  131. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/router.js +63 -0
  132. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/state.js +90 -0
  133. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/table.js +41 -0
  134. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/widgets.js +8 -0
  135. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentDetail.html +3 -0
  136. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentDetail.js +36 -0
  137. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentEditor.html +2 -0
  138. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentEditor.js +51 -0
  139. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentsPage.html +3 -0
  140. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentsPage.js +48 -0
  141. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/CheckResults.html +2 -0
  142. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/CheckResults.js +6 -0
  143. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/ResourcePicker.html +2 -0
  144. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/ResourcePicker.js +13 -0
  145. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/data.js +24 -0
  146. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/domain.js +32 -0
  147. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/registry.js +25 -0
  148. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/store.js +85 -0
  149. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentClose.html +2 -0
  150. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentClose.js +17 -0
  151. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentCreate.html +2 -0
  152. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentCreate.js +66 -0
  153. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDecisions.html +3 -0
  154. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDecisions.js +38 -0
  155. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDetail.html +2 -0
  156. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDetail.js +66 -0
  157. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDocument.html +2 -0
  158. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDocument.js +5 -0
  159. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentHeader.html +2 -0
  160. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentHeader.js +12 -0
  161. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentHistory.html +2 -0
  162. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentHistory.js +11 -0
  163. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentList.html +2 -0
  164. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentList.js +116 -0
  165. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentReplan.html +2 -0
  166. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentReplan.js +32 -0
  167. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentRevision.html +2 -0
  168. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentRevision.js +49 -0
  169. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentSummary.html +2 -0
  170. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentSummary.js +10 -0
  171. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentWorkspace.html +2 -0
  172. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentWorkspace.js +77 -0
  173. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/data.js +60 -0
  174. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/domain.js +105 -0
  175. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/store.js +212 -0
  176. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/AuditPanel.html +2 -0
  177. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/AuditPanel.js +18 -0
  178. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelDetail.html +2 -0
  179. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelDetail.js +23 -0
  180. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelEditor.html +2 -0
  181. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelEditor.js +78 -0
  182. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelGrant.html +2 -0
  183. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelGrant.js +55 -0
  184. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelReferences.html +2 -0
  185. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelReferences.js +26 -0
  186. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelRelease.html +2 -0
  187. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelRelease.js +38 -0
  188. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelStatus.html +2 -0
  189. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelStatus.js +7 -0
  190. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelTable.html +2 -0
  191. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelTable.js +72 -0
  192. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelTester.html +2 -0
  193. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelTester.js +46 -0
  194. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelsPage.html +2 -0
  195. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelsPage.js +52 -0
  196. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/RowActions.html +2 -0
  197. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/RowActions.js +19 -0
  198. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/UsagePanel.html +2 -0
  199. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/UsagePanel.js +30 -0
  200. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/data.js +48 -0
  201. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/domain.js +39 -0
  202. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/store.js +129 -0
  203. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/IncidentDetail.html +4 -0
  204. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/IncidentDetail.js +21 -0
  205. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/IntentSource.html +2 -0
  206. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/IntentSource.js +8 -0
  207. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationActionDialog.html +2 -0
  208. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationActionDialog.js +37 -0
  209. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationEntry.html +2 -0
  210. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationEntry.js +10 -0
  211. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationsPage.html +2 -0
  212. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationsPage.js +37 -0
  213. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/RepairTrack.html +2 -0
  214. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/RepairTrack.js +49 -0
  215. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/RunDetail.html +4 -0
  216. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/RunDetail.js +22 -0
  217. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/SourceSummary.html +2 -0
  218. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/SourceSummary.js +9 -0
  219. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/commands.js +82 -0
  220. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/examples.js +47 -0
  221. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/model.js +61 -0
  222. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/repair.js +68 -0
  223. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/store.js +55 -0
  224. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/types.js +1 -0
  225. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/workbench.js +18 -0
  226. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ManagementTable.html +3 -0
  227. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ManagementTable.js +28 -0
  228. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcCreateEntry.html +2 -0
  229. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcCreateEntry.js +18 -0
  230. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcDetail.html +2 -0
  231. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcDetail.js +31 -0
  232. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcEditor.html +2 -0
  233. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcEditor.js +27 -0
  234. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcLifecycle.html +2 -0
  235. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcLifecycle.js +16 -0
  236. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcPage.html +2 -0
  237. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcPage.js +43 -0
  238. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcPicker.html +4 -0
  239. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcPicker.js +34 -0
  240. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcProgress.html +2 -0
  241. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcProgress.js +30 -0
  242. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcWizard.html +3 -0
  243. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcWizard.js +67 -0
  244. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcWorkspace.html +2 -0
  245. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcWorkspace.js +41 -0
  246. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcsPage.html +2 -0
  247. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcsPage.js +31 -0
  248. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ServiceEditor.html +2 -0
  249. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ServiceEditor.js +26 -0
  250. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ServiceList.html +2 -0
  251. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ServiceList.js +70 -0
  252. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/data.js +8 -0
  253. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/domain.js +62 -0
  254. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/management.js +36 -0
  255. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/managementStore.js +49 -0
  256. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/store.js +132 -0
  257. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/AdminList.html +2 -0
  258. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/AdminList.js +38 -0
  259. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/EffectiveGrants.html +2 -0
  260. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/EffectiveGrants.js +11 -0
  261. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/GrantEditor.html +2 -0
  262. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/GrantEditor.js +45 -0
  263. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/MemberEditor.html +2 -0
  264. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/MemberEditor.js +54 -0
  265. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/MembersPage.html +3 -0
  266. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/MembersPage.js +27 -0
  267. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RecordsPage.html +2 -0
  268. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RecordsPage.js +12 -0
  269. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RoleEditor.html +2 -0
  270. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RoleEditor.js +45 -0
  271. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RolesPage.html +3 -0
  272. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RolesPage.js +38 -0
  273. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/domain.js +61 -0
  274. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/state.js +51 -0
  275. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/store.js +116 -0
  276. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseActionDialog.html +2 -0
  277. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseActionDialog.js +45 -0
  278. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseDetail.html +4 -0
  279. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseDetail.js +30 -0
  280. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseEditor.html +2 -0
  281. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseEditor.js +67 -0
  282. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseExecution.html +2 -0
  283. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseExecution.js +5 -0
  284. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleasesPage.html +4 -0
  285. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleasesPage.js +60 -0
  286. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/commands.js +157 -0
  287. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/model.js +136 -0
  288. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/store.js +76 -0
  289. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewDetail.html +3 -0
  290. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewDetail.js +26 -0
  291. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewEvidence.html +2 -0
  292. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewEvidence.js +14 -0
  293. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewProcess.html +2 -0
  294. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewProcess.js +113 -0
  295. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewsPage.html +3 -0
  296. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewsPage.js +62 -0
  297. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/commands.js +97 -0
  298. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/model.js +147 -0
  299. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/store.js +13 -0
  300. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ColumnSettings.html +2 -0
  301. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ColumnSettings.js +9 -0
  302. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListBatchBar.html +2 -0
  303. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListBatchBar.js +8 -0
  304. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListDeleteDialog.html +2 -0
  305. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListDeleteDialog.js +37 -0
  306. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListMore.html +2 -0
  307. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListMore.js +8 -0
  308. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/RecordMetadata.html +2 -0
  309. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/RecordMetadata.js +17 -0
  310. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/columns.js +32 -0
  311. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/deliveryGuide.js +49 -0
  312. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/deliveryView.js +12 -0
  313. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/listBatch.js +15 -0
  314. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/listSelection.js +37 -0
  315. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/policy.js +68 -0
  316. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/session.js +44 -0
  317. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ConfirmationDialog.html +2 -0
  318. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ConfirmationDialog.js +25 -0
  319. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ConsoleShell.html +2 -0
  320. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ConsoleShell.js +53 -0
  321. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/PrototypeGuide.html +10 -0
  322. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/PrototypeGuide.js +30 -0
  323. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ScopePage.html +2 -0
  324. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ScopePage.js +10 -0
  325. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/SessionDialog.html +2 -0
  326. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/SessionDialog.js +9 -0
  327. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/confirmation.js +3 -0
  328. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/navigation.js +19 -0
  329. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecDocument.html +2 -0
  330. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecDocument.js +8 -0
  331. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecEdit.html +2 -0
  332. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecEdit.js +32 -0
  333. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecHeader.html +2 -0
  334. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecHeader.js +15 -0
  335. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecHistory.html +2 -0
  336. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecHistory.js +11 -0
  337. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecReview.html +2 -0
  338. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecReview.js +57 -0
  339. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecWorkspace.html +2 -0
  340. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecWorkspace.js +37 -0
  341. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/data.js +20 -0
  342. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/domain.js +55 -0
  343. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/store.js +151 -0
  344. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/ArtifactDetail.html +3 -0
  345. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/ArtifactDetail.js +18 -0
  346. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskCreate.html +2 -0
  347. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskCreate.js +40 -0
  348. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskDetail.html +2 -0
  349. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskDetail.js +51 -0
  350. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskLaunch.html +2 -0
  351. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskLaunch.js +9 -0
  352. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TasksPage.html +5 -0
  353. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TasksPage.js +48 -0
  354. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/domain.js +204 -0
  355. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/exampleSource.js +22 -0
  356. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/registry.js +135 -0
  357. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/store.js +137 -0
  358. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workbench/WorkbenchPage.html +3 -0
  359. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workbench/WorkbenchPage.js +36 -0
  360. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workbench/model.js +56 -0
  361. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workbench/store.js +15 -0
  362. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowCanvas.html +2 -0
  363. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowCanvas.js +27 -0
  364. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowDetail.html +4 -0
  365. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowDetail.js +31 -0
  366. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowEditor.html +2 -0
  367. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowEditor.js +68 -0
  368. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/WorkflowsPage.html +5 -0
  369. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/WorkflowsPage.js +55 -0
  370. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/data.js +16 -0
  371. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/domain.js +83 -0
  372. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/registry.js +18 -0
  373. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/store.js +61 -0
  374. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/admin.css +60 -0
  375. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/agents.css +46 -0
  376. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/antdv.css +295 -0
  377. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/app.css +102 -0
  378. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/delivery.css +4 -0
  379. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/intents.css +37 -0
  380. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/native.css +22 -0
  381. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/operations.css +2 -0
  382. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/pbc.css +3 -0
  383. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/permissions.css +22 -0
  384. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/pro.css +1 -0
  385. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/releases.css +4 -0
  386. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/reset.css +246 -0
  387. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/reviews.css +8 -0
  388. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/tasks.css +6 -0
  389. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/tokens.css +15 -0
  390. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/workbench.css +61 -0
  391. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/workflows.css +1 -0
  392. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/admin-rules.test.js +96 -0
  393. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/agents.test.js +14 -0
  394. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/intent-state.test.js +37 -0
  395. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/list-batch.test.js +44 -0
  396. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/operation-fixtures.js +19 -0
  397. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/operation-repair.test.js +14 -0
  398. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/operations.test.js +25 -0
  399. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/pbc-management.test.js +17 -0
  400. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/pbc-state.test.js +24 -0
  401. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/permission-config.test.js +23 -0
  402. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/permissions.test.js +24 -0
  403. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/releases.test.js +50 -0
  404. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/reviews.test.js +36 -0
  405. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/runtime-forms-router.test.js +28 -0
  406. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/runtime-state.test.js +42 -0
  407. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/runtime-stores.test.js +16 -0
  408. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/spec-state.test.js +11 -0
  409. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/tasks.test.js +27 -0
  410. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/workbench.test.js +34 -0
  411. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/workflows.test.js +16 -0
  412. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tools/convert.mjs +168 -0
  413. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tools/serve.mjs +7 -0
  414. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tools/styles.mjs +11 -0
  415. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tools/verify.mjs +24 -0
  416. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/serve.cjs +16 -0
  417. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/usability.css +44 -0
  418. package/skills/i3-ui-prototype/assets/templates/gallery/index.html +40 -0
  419. package/skills/i3-ui-prototype/assets/templates/modern-workspace/manifest.json +9 -0
  420. package/skills/i3-ui-prototype/assets/templates/modern-workspace/preset.json +6 -0
  421. package/skills/i3-ui-prototype/assets/templates/serve-gallery.cjs +16 -0
  422. package/skills/i3-ui-prototype/references/artifact-contract.md +41 -0
  423. package/skills/i3-ui-prototype/references/enterprise-admin.md +38 -0
  424. package/skills/i3-ui-prototype/references/expert-adapter.md +42 -0
  425. package/skills/i3-ui-prototype/references/template-adapters.md +57 -0
  426. package/skills/i3-ui-prototype/references/workflow-contract.md +19 -0
  427. package/skills/i3-ui-prototype/scripts/adapters/easel-html.cjs +30 -0
  428. package/skills/i3-ui-prototype/scripts/adapters/legacy-html.cjs +28 -0
  429. package/skills/i3-ui-prototype/scripts/check-design-provider.cjs +9 -0
  430. package/skills/i3-ui-prototype/scripts/check-prototype.cjs +14 -0
  431. package/skills/i3-ui-prototype/scripts/enterprise-template.cjs +88 -0
  432. package/skills/i3-ui-prototype/scripts/init-prototype.cjs +8 -0
  433. package/skills/i3-ui-prototype/scripts/manage-baseline.cjs +11 -0
  434. package/skills/i3-ui-prototype/scripts/prototype-lib.cjs +255 -0
  435. package/skills/i3-ui-prototype/scripts/template-adapters.cjs +89 -0
  436. package/skills/i3-using-agent-skills/SKILL.md +5 -0
@@ -0,0 +1,42 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { ref, computed, reactive, watch, defineStore, nextTick } from '../runtime/state.js';
4
+
5
+ test('deep edits and computed permissions remain observable', async () => {
6
+ const role = ref({ actions: ['view', 'edit'] });
7
+ const canEdit = computed(() => role.value.actions.includes('edit'));
8
+ const seen = [];
9
+ const stop = watch(canEdit, value => seen.push(value), { immediate: true });
10
+ role.value.actions.splice(1, 1);
11
+ await nextTick();
12
+ assert.equal(canEdit.value, false);
13
+ assert.deepEqual(seen, [true, false]);
14
+ stop();
15
+ role.value.actions.push('edit');
16
+ await nextTick();
17
+ assert.deepEqual(seen, [true, false]);
18
+ });
19
+
20
+ test('store fields unwrap state and retain one shared instance', async () => {
21
+ const useDemo = defineStore('native-state-test', () => {
22
+ const scope = ref('heating');
23
+ const rows = reactive({ count: 1 });
24
+ return { scope, rows, allowed: computed(() => scope.value === 'heating') };
25
+ });
26
+ const a = useDemo(), b = useDemo();
27
+ assert.equal(a, b);
28
+ assert.equal(a.allowed, true);
29
+ a.scope = 'north';
30
+ a.rows.count = 2;
31
+ await nextTick();
32
+ assert.equal(b.scope, 'north');
33
+ assert.equal(b.allowed, false);
34
+ assert.equal(b.rows.count, 2);
35
+ });
36
+
37
+ test('derived form fields support explicit setters', () => {
38
+ const value = ref('old');
39
+ const field = computed({ get: () => value.value, set: v => { value.value = v.trim(); } });
40
+ field.value = ' new ';
41
+ assert.equal(value.value, 'new');
42
+ });
@@ -0,0 +1,16 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ const storage=new Map();
4
+ globalThis.localStorage={getItem:key=>storage.get(key)??null,setItem:(key,value)=>storage.set(key,String(value)),removeItem:key=>storage.delete(key)};
5
+
6
+ test('committed observations update both the runtime store and the persisted task',async()=>{
7
+ const {useOperations}=await import('../src/operations/store.js');
8
+ const store=useOperations();store.addExamples();
9
+ const id='run-ops-release-2',before=store.find(id);
10
+ assert.equal(before.run.observations.length,0);
11
+ store.apply(id,{id:'html-observation-test',action:'observe',expected:before.run.recordVersion,note:'HTML 原生状态层观测提交测试',checked:true,outcome:'pass'});
12
+ assert.equal(store.find(id).run.observations.length,1);
13
+ assert.equal(store.find(id).run.recordVersion,2);
14
+ const saved=JSON.parse(storage.get('i3-prototype-antdv-tasks-v010'));
15
+ assert.equal(saved.find(t=>t.id==='operation-example-2').operations[0].observations.length,1);
16
+ });
@@ -0,0 +1,11 @@
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { actors, can } from "../src/shared/policy.js";
4
+ import { newIntent, publishVersion, confirmVersion } from "../src/intents/domain.js";
5
+ import { newSpec, appendVersion, sourceOf, beginSpecConfirmation, completeSpecConfirmation, sections, assertSpec } from "../src/specs/domain.js";
6
+ const actor = actors.at(-1), at = '2026-09-10T10:00:00Z';
7
+ function fixture() { let i = newIntent({ title: '供热报修', request: '分诊建议', outcome: '确认后派单', context: '意图池' }, 'i1', 'INT-001', at, actor); i.answers = { audience: '居民', process: '确认后派单', boundary: '不控制设备', acceptance: '不重复派单' }; i = confirmVersion(publishVersion(i, at), 1, at, actor); const content = Object.fromEntries(sections.map(s => [s.key, s.label])); return { i, s: appendVersion(newSpec(i, actor, at), sourceOf(i), content, [], '示例', actor, at) }; }
8
+ test('spec confirmation binds source, version and authorized human', () => { const { i, s } = fixture(); const pending = beginSpecConfirmation(s, i, actor, 1, 1, 'q1', at); const confirmed = completeSpecConfirmation({ ...pending, pending: { ...pending.pending, acceptedAt: at } }); assert.equal(confirmed.versions[0]?.confirmedBy, actor.name); assert.equal(s.versions[0]?.confirmedAt, undefined); assert.throws(() => beginSpecConfirmation(s, i, actor, 2, 1, 'q2', at), /版本/); assert.throws(() => beginSpecConfirmation(s, { ...i, status: 'clarifying' }, actor, 1, 1, 'q3', at), /意图/); });
9
+ test('spec unresolved decisions and missing reasons block confirmation', () => { const { i, s } = fixture(); s.versions[0].decisions = [{ id: 'd', question: '选哪种', options: ['A'], answer: 'A', reason: '', owner: '有权用户' }]; assert.throws(() => beginSpecConfirmation(s, i, actor, 1, 1, 'q', at), /决策/); });
10
+ test('pending or unknown operations cannot be resubmitted and need a receipt', () => { const { i, s } = fixture(); const pending = beginSpecConfirmation(s, i, actor, 1, 1, 'q', at); assert.throws(() => beginSpecConfirmation(pending, i, actor, 1, 1, 'r', at), /处理中/); assert.throws(() => completeSpecConfirmation(pending), /核实/); assert.throws(() => assertSpec({ ...pending, confirmation: 'unknown' }, actor, 'spec:edit'), /核实/); });
11
+ test('grant revocation and cross-scope assignment deny the exact action', () => { const { i, s } = fixture(); const limited = { ...actor, grants: [{ id: 'north', name: '确认', actions: ['spec:confirm'], tenantIds: ['north'] }] }; assert.equal(can(limited, 'spec:confirm'), true); assert.throws(() => beginSpecConfirmation(s, i, limited, 1, 1, 'q', at), /权限/); });
@@ -0,0 +1,27 @@
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { actors } from "../src/shared/policy.js";
4
+ import { standardBody } from "../src/workflows/data.js";
5
+ import { newTask, startTask, advanceTask, approveTask, retryTask, controlTask, assertTaskRemovable, latestArtifact, clone } from "../src/tasks/domain.js";
6
+ const actor = actors[0];
7
+ function binding() { return { intentId: 'intent', spec: { number: 1, source: { intentId: 'intent', code: 'INT-1', title: '测试需求', version: 1, confirmedAt: '2026-09-11' }, content: { overview: '需求', stories: '故事', requirements: '需求条款', acceptance: 'AC', success: '标准', entities: '实体', pages: '页面', assumptions: '假设' }, decisions: [], reason: '确认样例', createdBy: '演示', createdAt: '2026-09-11', confirmedBy: '演示', confirmedAt: '2026-09-11' }, specRecordVersion: 1, pbcId: 'pbc-0', project: '供热工单', tenantId: 'heating', flowId: 'flow-0', flowRecordVersion: 1, flow: { number: 1, body: standardBody(), note: '标准', by: '演示', at: '2026-09-11', submittedBy: '演示' }, agents: [] }; }
8
+ function task() { return newTask(binding(), actor, '交付测试'); }
9
+ function build() { const t = task(); startTask(t, '陈敏'); advanceTask(t); approveTask(t, '核对人', 1, '已核对原型与规格'); return t; }
10
+ function verify() { const t = build(); advanceTask(t); advanceTask(t); return t; }
11
+ test('草稿要求有效名称;基础字段与独立快照完整', () => { const b = binding(), t = newTask(b, actor, '交付'); b.flow.body.nodes[0].name = '后续改变'; assert.equal(t.binding.flow.body.nodes[0].name, '交付开始'); assert.equal(t.tenantId, 'heating'); assert.equal(t.recordVersion, 1); assert.ok(t.createdBy && t.createdAt && t.createdDept); assert.throws(() => newTask(b, actor, ' '), /名称/); assert.throws(() => newTask(b, actor, 'a', 'x'.repeat(1001)), /1000/); assert.doesNotThrow(() => assertTaskRemovable(t)); });
12
+ test('启动固定输入;重复启动与已启动删除被拒绝', () => { const t = task(); startTask(t, '陈敏'); assert.equal(t.artifacts.length, 2); assert.equal(t.artifacts[0].versions[0].taskId, t.id); assert.throws(() => startTask(t, '陈敏'), /已经启动/); assert.throws(() => assertTaskRemovable(t), /仅草稿/); assert.equal(t.currentId, 'start'); });
13
+ test('原型确认阻断推进;缺少说明和过期产物版本不接受', () => { const t = task(); startTask(t, '陈敏'); advanceTask(t); assert.equal(t.status, 'waiting'); assert.throws(() => advanceTask(t), /可推进/); assert.throws(() => approveTask(t, '确认人', 1, ''), /核对说明/); assert.throws(() => approveTask(t, '确认人', 2, '已核对'), /已变化/); approveTask(t, '确认人', 1, '已核对'); assert.equal(t.currentId, 'build'); assert.ok(t.prototypeApproved); });
14
+ test('标准流程至待后续确认,没有实际发布或归档', () => { const t = verify(); advanceTask(t); assert.equal(t.status, 'ready'); assert.equal(t.currentId, 'approval'); assert.equal(t.stages.find(s => s.nodeId === 'release').state, 'pending'); assert.equal(t.stages.find(s => s.nodeId === 'archive').state, 'pending'); assert.throws(() => advanceTask(t), /可推进/); assert.throws(() => approveTask(t, '确认人', 1, '发布'), /不接受/); assert.ok(latestArtifact(t, 'verify').inputs.some(x => x.id === 'code' && x.version === 1)); });
15
+ test('独立验证不接受同一实现 Agent,也不接受未通过的质量检查', () => { const t = verify(); t.checksPassed = false; assert.throws(() => advanceTask(t), /质量检查/); const x = verify(); x.binding.flow.body.nodes.find(n => n.id === 'verify').agentId = 'agent-1'; assert.throws(() => advanceTask(x), /不能同时实现/); assert.equal(x.status, 'running'); });
16
+ test('验证失败返工重跑实现与质量检查,旧版本和失败证据不覆盖', () => { const t = verify(); advanceTask(t, 'fail'); const old = clone(t.artifacts); retryTask(t, '处理人', '修复幂等性'); assert.equal(t.currentId, 'build'); assert.equal(t.reworks, 1); assert.equal(t.checksPassed, false); advanceTask(t); assert.equal(t.stages.find(s => s.nodeId === 'verify').state, 'pending'); advanceTask(t); advanceTask(t); assert.equal(t.status, 'ready'); assert.equal(latestArtifact(t, 'code').number, 2); for (const a of old)
17
+ assert.deepEqual(t.artifacts.find(x => x.id === a.id).versions[0], a.versions[0]); assert.equal(t.artifacts.find(a => a.kind === 'verify').versions[0].result, 'fail'); });
18
+ test('阶段失败重试仅继续当前阶段,不重复已完成实现', () => { const t = build(); advanceTask(t); advanceTask(t, 'fail'); assert.equal(t.status, 'failed'); assert.equal(t.currentId, 'ci'); retryTask(t, '处理人', '检查服务已恢复'); advanceTask(t); assert.equal(latestArtifact(t, 'code').number, 1); assert.equal(t.stages.find(s => s.nodeId === 'build').attempts, 1); assert.equal(t.stages.find(s => s.nodeId === 'ci').attempts, 2); });
19
+ test('处理次数有界;接管不会清零预算、判定通过或修改产物', () => { const t = build(); for (let i = 0; i < 3; i++) {
20
+ advanceTask(t, 'fail');
21
+ if (i < 2)
22
+ retryTask(t, '处理人', '重试');
23
+ } assert.equal(t.reworks, 2); assert.throws(() => retryTask(t, '处理人', '继续'), /达到/); const versions = clone(t.artifacts); controlTask(t, 'takeover', '接管人', '人工检查'); assert.equal(t.status, 'manual'); assert.equal(t.owner, '接管人'); controlTask(t, 'resume', '接管人', '继续原任务'); assert.equal(t.status, 'failed'); assert.equal(t.reworks, 2); assert.deepEqual(t.artifacts, versions); });
24
+ test('暂停和刷新后恢复保留当前阶段;等待确认也能恢复到等待', () => { const t = build(); advanceTask(t); controlTask(t, 'pause', '陈敏', '等待窗口'); const restored = JSON.parse(JSON.stringify(t)); controlTask(restored, 'resume', '陈敏', '窗口已到'); assert.equal(restored.status, 'running'); assert.equal(restored.currentId, 'ci'); assert.deepEqual(restored.artifacts, t.artifacts); const w = task(); startTask(w, '陈敏'); advanceTask(w); controlTask(w, 'pause', '陈敏', '稍后核对'); controlTask(w, 'resume', '陈敏', '继续核对'); assert.equal(w.status, 'waiting'); assert.throws(() => advanceTask(w), /可推进/); });
25
+ test('不允许伪造跳到发布确认:缺少本轮验证结论会被拦住', () => { const t = build(); t.binding.flow.body.edges.find(e => e.from === 'build').to = 'approval'; assert.throws(() => advanceTask(t), /有效独立验证/); assert.notEqual(t.status, 'ready'); });
26
+ test('真实采用绑定流程的分支,未选路径标记跳过', () => { const t = build(), b = t.binding.flow.body; b.nodes.push({ id: 'decision', kind: 'branch', name: '质量判断', condition: 'checks.passed', x: 0, y: 0 }, { id: 'fix', kind: 'loop', name: '有限修复', agentId: 'agent-1', limit: 2, x: 0, y: 0 }); b.edges.find(e => e.from === 'ci').to = 'decision'; b.edges.push({ id: 'yes', from: 'decision', to: 'verify', label: '满足' }, { id: 'no', from: 'decision', to: 'fix', label: '不满足' }, { id: 'fixed', from: 'fix', to: 'verify', label: '' }); t.stages.push({ nodeId: 'decision', state: 'pending', attempts: 0, detail: '' }, { nodeId: 'fix', state: 'pending', attempts: 0, detail: '' }); advanceTask(t); advanceTask(t); assert.equal(t.currentId, 'decision'); advanceTask(t); assert.equal(t.currentId, 'verify'); assert.equal(t.stages.find(s => s.nodeId === 'fix').state, 'skipped'); advanceTask(t); assert.equal(t.status, 'ready'); });
27
+ test('检查不通过时走已定义的有限修复分支,再独立验证', () => { const t = build(), b = t.binding.flow.body; b.nodes.push({ id: 'decision', kind: 'branch', name: '质量判断', condition: 'checks.passed', x: 0, y: 0 }, { id: 'fix', kind: 'loop', name: '有限修复', agentId: 'agent-1', limit: 1, x: 0, y: 0 }); b.edges.find(e => e.from === 'ci').to = 'decision'; b.edges.push({ id: 'yes', from: 'decision', to: 'verify', label: '满足' }, { id: 'no', from: 'decision', to: 'fix', label: '不满足' }, { id: 'fixed', from: 'fix', to: 'verify', label: '' }); t.stages.push({ nodeId: 'decision', state: 'pending', attempts: 0, detail: '' }, { nodeId: 'fix', state: 'pending', attempts: 0, detail: '' }); advanceTask(t); advanceTask(t, 'fail'); assert.equal(t.currentId, 'decision'); advanceTask(t); assert.equal(t.currentId, 'fix'); advanceTask(t, 'fail'); retryTask(t, '处理人', '修复'); advanceTask(t); assert.equal(t.currentId, 'verify'); advanceTask(t); assert.equal(t.status, 'ready'); assert.equal(latestArtifact(t, 'code').number, 3); });
@@ -0,0 +1,34 @@
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { actors, metadata } from "../src/shared/policy.js";
4
+ import { newIntent, publishVersion, confirmVersion } from "../src/intents/domain.js";
5
+ import { newSpec, appendVersion, sourceOf, sections } from "../src/specs/domain.js";
6
+ import { makeJob } from "../src/pbc/domain.js";
7
+ import { affiliation, deliveryGuide, actorAccess } from "../src/shared/deliveryGuide.js";
8
+ import { buildWorkbench, relatedTo } from "../src/workbench/model.js";
9
+ const actor = actors.find(a => a.id === 'complete'), at = '2026-09-11T00:00:00Z';
10
+ function fixture() {
11
+ let i = newIntent({ title: '测试归属', request: '报修分诊', outcome: '人工确认', context: '集团意图池 · 尚未立项' }, 'i1', 'INT-001', at, actor);
12
+ i.answers = { audience: '居民', process: '确认', boundary: '演示', acceptance: '可追溯' };
13
+ i = confirmVersion(publishVersion(i, at), 1, at, actor);
14
+ const content = Object.fromEntries(sections.map(s => [s.key, s.label])), s = appendVersion(newSpec(i, actor, at), sourceOf(i), content, [], '示例', actor, at);
15
+ s.versions[0].confirmedAt = at;
16
+ const p = { ...metadata(actor, at), id: 'p1', name: '供热智能分诊01', slug: 'heating', ebc: '服务', domain: 'example.test', owner: actor.name, services: [] }, j = makeJob(i, s, actor, p);
17
+ j.status = 'done';
18
+ return { i, s, p, j };
19
+ }
20
+ test('实际归属读取当前目录名称,保留原始意图与请求快照', () => { const { i, j, p } = fixture(); const result = affiliation(i, [j], [{ ...p, name: '改名后的系统' }], actorAccess(actor)); assert.equal(result.label, '已归属:改名后的系统'); assert.equal(result.key, 'pbc:p1'); assert.equal(i.context, '集团意图池 · 尚未立项'); assert.equal(j.pbc.name, '供热智能分诊01'); });
21
+ test('已有归属目标不可见时不暴露名称或导航,也不退回未归属', () => { const { i, j, p } = fixture(); const r = affiliation(i, [j], [p], () => false); assert.equal(r.state, 'restricted'); assert.equal(r.path, ''); assert.ok(!r.label.includes(p.name)); });
22
+ test('未知、失败与进行中归属均指向原请求,禁止创建重复请求', () => { const { i, j, s } = fixture(); for (const status of ['unknown', 'failed', 'running', 'paused']) {
23
+ const r = deliveryGuide(i, s, [{ ...j, status }], actorAccess(actor));
24
+ assert.equal(r.create, false);
25
+ assert.equal(r.path, '/intents/i1/pbc');
26
+ assert.notEqual(r.stage, 'done');
27
+ } });
28
+ test('来源重新澄清时安全解释,不能因sourceOf抛错导致来源列表消失', () => { const { i, s } = fixture(); const r = deliveryGuide({ ...i, status: 'clarifying' }, s, [], actorAccess(actor)); assert.equal(r.stage, 'intent'); assert.equal(r.create, false); assert.equal(r.path, '/intents/i1/workspace'); });
29
+ test('未生成、未确认和旧版规格分别解释;最新已确认才允许创建', () => { const { i, s } = fixture(), access = actorAccess(actor); assert.equal(deliveryGuide(i, undefined, [], access).label, '尚未生成规格'); assert.equal(deliveryGuide(i, { ...s, versions: [{ ...s.versions[0], confirmedAt: undefined }] }, [], access).label, '规格待确认'); assert.equal(deliveryGuide(i, { ...s, versions: [{ ...s.versions[0], source: { ...s.versions[0].source, version: 0 } }] }, [], access).label, '规格来源已变化'); assert.equal(deliveryGuide(i, s, [], access).create, true); });
30
+ test('零未决项不等于拥有规格确认或创建权限', () => { const { i, s } = fixture(); const limited = { ...actor, grants: [{ id: 'r', name: 'read', actions: ['intent:view', 'spec:view', 'pbc:view'], tenantIds: ['heating'] }] }; const r = deliveryGuide(i, { ...s, versions: [{ ...s.versions[0], confirmedAt: undefined }] }, [], actorAccess(limited)); assert.equal(r.allowed, false); assert.match(r.reason, /确认权限/); assert.equal(deliveryGuide(i, s, [], actorAccess(limited)).create, false); });
31
+ test('我的范围先按授权过滤;他人的可见记录不能冒充我的', () => { const { i, s, p } = fixture(); const other = { ...i, id: 'other', createdById: 'zhou', owner: '周晨' }, input = { actor, active: true, intents: [i, other], specs: [s], jobs: [], pbcs: [p], tasks: [] }; assert.equal(buildWorkbench(input, 'mine').todos.length, 1); assert.equal(buildWorkbench(input, 'all').todos.length, 2); assert.equal(buildWorkbench({ ...input, actor: { ...actor, grants: [] } }, 'all').todos.length, 0); assert.equal(buildWorkbench({ ...input, active: false }, 'all').pbcs.length, 0); });
32
+ test('归属完成后从待办移除,相关PBC进入首页且重新命名同步', () => { const { i, s, p, j } = fixture(); const input = { actor, active: true, intents: [i], specs: [s], jobs: [], pbcs: [{ ...p, createdById: 'zhou', owner: '周晨' }], tasks: [] }; assert.equal(buildWorkbench(input, 'mine').todos.length, 1); assert.equal(buildWorkbench(input, 'mine').pbcs.length, 0); const done = buildWorkbench({ ...input, jobs: [j] }, 'mine'); assert.equal(done.todos.length, 0); assert.equal(done.pbcs.length, 1); });
33
+ test('个人身份适配不合并权限,不按岗位或任意重名判定关系', () => { assert.equal(relatedTo(actor, { createdById: 'lin' }), true); assert.equal(relatedTo({ ...actor, id: 'zhou' }, { createdById: 'lin', owner: '林晓' }), false); assert.equal(relatedTo(actor, { createdById: 'unknown', owner: '同名用户' }), false); assert.equal(actorAccess({ ...actor, grants: [] })('intent:view'), false); });
34
+ test('隐藏租户与删除记录不影响可见计数或关系', () => { const { i, s, p, j } = fixture(); const out = buildWorkbench({ actor, active: true, intents: [{ ...i, tenantId: 'north' }], specs: [s], jobs: [j], pbcs: [{ ...p, tenantId: 'north' }], tasks: [] }, 'all'); assert.equal(out.todos.length, 0); assert.equal(out.pbcs.length, 0); assert.equal(buildWorkbench({ actor, active: true, intents: [{ ...i, isDeleted: true }], specs: [s], jobs: [], pbcs: [{ ...p, isDeleted: true }], tasks: [] }, 'mine').todos.length, 0); });
@@ -0,0 +1,16 @@
1
+ import test from "node:test";
2
+ import assert from "node:assert/strict";
3
+ import { validateFlow, clone, diffBodies, assertRemovable, protectedNode } from "../src/workflows/domain.js";
4
+ import { standardBody, seedFlows } from "../src/workflows/data.js";
5
+ const agents = ['agent-1', 'agent-2'].map(id => ({ id, name: id, available: true, reason: '', recordVersion: 1 }));
6
+ const failed = (b = standardBody()) => validateFlow(b, agents).filter(c => !c.ok);
7
+ test('标准交付路径通过;必要治理节点受保护', () => { assert.deepEqual(failed(), []); for (const id of ['prototype', 'verify', 'approval'])
8
+ assert.equal(protectedNode(standardBody().nodes.find(n => n.id === id)), true); });
9
+ test('删除治理节点和直接连线绕过批准都被检查拒绝', () => { const b = standardBody(); b.edges.push({ id: 'bypass', from: 'build', to: 'release', label: '' }); assert.ok(failed(b).some(c => c.id === 'release')); const d = standardBody(); d.nodes = d.nodes.filter(n => n.id !== 'prototype'); assert.ok(failed(d).some(c => c.id === 'gates')); });
10
+ test('无法借条件分支让一条发布路径绕过独立验证', () => { const b = standardBody(); b.nodes.find(n => n.id === 'ci').kind = 'branch'; b.nodes.find(n => n.id === 'ci').condition = 'checks.passed'; b.edges.find(e => e.from === 'ci').label = '满足'; b.edges.push({ id: 'branch-bypass', from: 'ci', to: 'approval', label: '不满足' }); assert.ok(failed(b).some(c => c.id === 'release')); });
11
+ test('同一 Agent 自验证、验证后修改及未登记人工权限均阻断', () => { const b = standardBody(); b.nodes.find(n => n.id === 'verify').agentId = 'agent-1'; assert.ok(failed(b).some(c => c.id === 'independent')); const d = standardBody(); d.edges.push({ id: 'rewrite', from: 'verify', to: 'build', label: '' }); assert.ok(failed(d).some(c => c.id === 'after-verify')); const e = standardBody(); e.nodes.find(n => n.id === 'approval').permission = 'unknown'; assert.ok(failed(e).some(c => c.id === 'human-approval')); });
12
+ test('有限修复必须有上限;普通循环与断开的节点被拒绝', () => { const b = standardBody(); Object.assign(b.nodes.find(n => n.id === 'build'), { kind: 'loop', limit: 0 }); assert.ok(failed(b).some(c => c.id === 'limit-build')); b.nodes.find(n => n.id === 'build').limit = 2; assert.deepEqual(failed(b), []); b.edges.push({ id: 'loop', from: 'ci', to: 'build', label: '' }); assert.ok(failed(b).some(c => c.id === 'cycle')); const d = standardBody(); d.edges = d.edges.filter(e => e.to !== 'ci'); assert.ok(failed(d).some(c => c.id === 'connectivity')); });
13
+ test('缺失或停用的 Agent 及无输入输出不能发布', () => { const b = standardBody(); assert.ok(validateFlow(b, agents.map(a => ({ ...a, available: false, reason: '已停用' }))).some(c => c.id === 'agent-build' && !c.ok)); b.nodes.find(n => n.id === 'build').input = ''; assert.ok(failed(b).some(c => c.id === 'io-build')); });
14
+ test('差异覆盖节点属性/连线和元数据,旧版本快照不变', () => { const before = standardBody(), after = clone(before); after.description = '新描述'; after.nodes.find(n => n.id === 'build').name = '实现工单助手'; after.edges.pop(); const diff = diffBodies(before, after); assert.ok(diff.some(x => x.includes('更新用途'))); assert.ok(diff.some(x => x.includes('实现工单助手'))); assert.ok(diff.some(x => x.includes('移除连线'))); assert.equal(before.nodes.find(n => n.id === 'build').name, '实现应用'); });
15
+ test('模板启用、待审核及已有选择引用均保护删除', () => { const r = seedFlows()[0]; assert.throws(() => assertRemovable(r, false), /停用/); assert.throws(() => assertRemovable({ ...r, enabled: false, state: 'review' }, false), /撤回/); assert.throws(() => assertRemovable({ ...r, enabled: false }, true), /引用/); assert.doesNotThrow(() => assertRemovable({ ...r, enabled: false }, false)); });
16
+ test('合规双分支与有限修复均汇入独立验证;移除属性计入差异', () => { const b = standardBody(); b.nodes.push({ id: 'judge', kind: 'branch', name: '质量结果', condition: 'checks.passed', x: 1100, y: 60 }, { id: 'fix', kind: 'loop', name: '修复产物', agentId: 'agent-1', input: '检查报告', output: '修订产物', limit: 2, x: 1100, y: 260 }); b.edges.find(e => e.from === 'ci').to = 'judge'; b.edges.push({ id: 'ok', from: 'judge', to: 'verify', label: '满足' }, { id: 'bad', from: 'judge', to: 'fix', label: '不满足' }, { id: 'fixed', from: 'fix', to: 'verify', label: '' }); assert.deepEqual(failed(b), []); const c = clone(b); delete c.nodes.find(n => n.id === 'fix').agentId; assert.ok(diffBodies(b, c).some(x => x.includes('Agent:agent-1 → 未设置'))); });
@@ -0,0 +1,168 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import crypto from 'node:crypto';
4
+ import { createRequire } from 'node:module';
5
+ import { fileURLToPath } from 'node:url';
6
+
7
+ const output = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
8
+ const source = path.resolve(output, '../../交互原型/console-operations-v0.14');
9
+ const require = createRequire(path.join(source, 'package.json'));
10
+ const ts = require('typescript');
11
+ const { parse: parseSfc } = require('@vue/compiler-sfc');
12
+ const { parse: parseTemplate } = require('@vue/compiler-dom');
13
+ const hashes = {};
14
+ const iconNames = new Set(['DownOutlined', 'UpOutlined', 'LeftOutlined', 'RightOutlined', 'CloseOutlined', 'CloseCircleOutlined', 'SearchOutlined', 'LoadingOutlined', 'CheckOutlined', 'CheckCircleOutlined', 'InfoCircleOutlined', 'ExclamationCircleOutlined','CheckCircleFilled','InfoCircleFilled','CloseCircleFilled','ExclamationCircleFilled']);
15
+ const esc = value => String(value).replaceAll('&', '&amp;').replaceAll('"', '&quot;').replaceAll('<', '&lt;').replaceAll('>', '&gt;');
16
+ const transpile = input => ts.transpileModule(input, { compilerOptions: { target: ts.ScriptTarget.ES2022, module: ts.ModuleKind.ESNext, verbatimModuleSyntax: false } }).outputText;
17
+
18
+ function expression(input) {
19
+ if (!input) return '';
20
+ const js = transpile(`const __expression = (${input});`);
21
+ return js.replace(/^const __expression =\s*/, '').replace(/;\s*$/, '').trim();
22
+ }
23
+ function eventExpression(input) {
24
+ const parsed = ts.createSourceFile('event.ts', `const __event = (${input});`, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
25
+ return parsed.parseDiagnostics.length ? transpile(input).trim() : expression(input);
26
+ }
27
+ function relativeRuntime(file, module) {
28
+ return path.relative(path.dirname(file), 'runtime/' + module + '.js').replaceAll(path.sep, '/').replace(/^(?!\.)/, './');
29
+ }
30
+ function rewriteImports(input, file) {
31
+ const sf = ts.createSourceFile(file, input, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
32
+ const changes = [];
33
+ for (const node of sf.statements) {
34
+ if (!ts.isImportDeclaration(node)) continue;
35
+ const from = node.moduleSpecifier.text;
36
+ if (from === 'vue') {
37
+ const specs = node.importClause?.namedBindings?.elements || [];
38
+ const state = specs.filter(s => !s.isTypeOnly && !['h', 'defineComponent'].includes(s.propertyName?.text || s.name.text)).map(s => s.getText(sf));
39
+ const dom = specs.filter(s => !s.isTypeOnly && ['h', 'defineComponent'].includes(s.propertyName?.text || s.name.text)).map(s => s.getText(sf));
40
+ changes.push([node.getStart(sf), node.end, [state.length ? `import { ${state.join(', ')} } from '${relativeRuntime(file, 'state')}';` : '', dom.length ? `import { ${dom.join(', ')} } from '${relativeRuntime(file, 'dom')}';` : ''].filter(Boolean).join('\n')]);
41
+ } else {
42
+ let target = from;
43
+ if (from === 'pinia') target = relativeRuntime(file, 'state');
44
+ else if (from === 'vue-router') target = relativeRuntime(file, 'router');
45
+ else if (from === 'antdv-next' || from === '@qin-ui/antdv-next-pro') target = relativeRuntime(file, 'widgets');
46
+ else if (from === '@ant-design/icons-vue') target = relativeRuntime(file, 'icons');
47
+ else if (from.startsWith('.')) target = from.replace(/\.(vue|ts)$/, '.js') + (/\.[a-z]+$/.test(from) ? '' : '.js');
48
+ changes.push([node.moduleSpecifier.getStart(sf), node.moduleSpecifier.end, JSON.stringify(target)]);
49
+ }
50
+ }
51
+ for (const [start, end, replacement] of changes.sort((a, b) => b[0] - a[0])) input = input.slice(0, start) + replacement + input.slice(end);
52
+ return input.replace(/(['"`])easel(?=[-:])/g, '$1i3-prototype-antdv').replace(/(['"`])(ops-(?:draft|link):)/g,'$1i3-prototype-antdv-$2').replaceAll('当前 4187 地址','当前 HTML 原型地址');
53
+ }
54
+ function bindings(sf) {
55
+ const names = [];
56
+ const add = node => { if (ts.isIdentifier(node)) names.push(node.text); else if (ts.isObjectBindingPattern(node) || ts.isArrayBindingPattern(node)) for (const element of node.elements) if (ts.isBindingElement(element)) add(element.name); };
57
+ for (const s of sf.statements) {
58
+ if (ts.isVariableStatement(s)) for (const d of s.declarationList.declarations) add(d.name);
59
+ else if ((ts.isFunctionDeclaration(s) || ts.isClassDeclaration(s)) && s.name) names.push(s.name.text);
60
+ else if (ts.isImportDeclaration(s) && s.importClause && !s.importClause.isTypeOnly) {
61
+ if (s.importClause.name) names.push(s.importClause.name.text);
62
+ const n = s.importClause.namedBindings;
63
+ if (n && ts.isNamedImports(n)) for (const e of n.elements) if (!e.isTypeOnly) names.push(e.name.text);
64
+ }
65
+ }
66
+ return [...new Set(names)];
67
+ }
68
+ function templateNode(node) {
69
+ if (node.type === 2) return esc(node.content);
70
+ if (node.type === 5) return '{{ ' + esc(expression(node.content.content)) + ' }}';
71
+ if (node.type === 3) return '';
72
+ if (node.type === 0) return node.children.map(templateNode).join('');
73
+ if (node.type !== 1) throw Error('Unsupported template node ' + node.type);
74
+ const attrs = [];
75
+ const original = node.tag;
76
+ const component = node.tagType === 1 || original === 'component';
77
+ let tag = component ? 'template' : original;
78
+ if (component) attrs.push(['data-component', original === 'component' ? '$dynamic' : original]);
79
+ for (const p of node.props) {
80
+ if (p.type === 6) attrs.push([p.name, p.value?.content ?? '']);
81
+ else if (p.type === 7) {
82
+ const value = p.exp?.content || '';
83
+ const arg = p.arg?.content || '';
84
+ if (p.name === 'bind') attrs.push([arg ? 'data-bind-' + arg : 'data-bind', expression(value || arg)]);
85
+ else if (p.name === 'on') attrs.push(['data-on-' + arg + (p.modifiers.length ? '.' + p.modifiers.map(m => m.content || m).join('.') : ''), eventExpression(value)]);
86
+ else if (p.name === 'model') attrs.push(['data-model-' + (arg || 'model-value'), expression(value)]);
87
+ else if (p.name === 'slot') { attrs.push(['data-slot', arg || 'default']); if (value) attrs.push(['data-slot-args', value]); }
88
+ else if (p.name === 'for') {
89
+ const loop=value.match(/^(.*?)\s+(in|of)\s+([\s\S]+)$/);
90
+ if(!loop)throw Error('Invalid source iteration: '+value);
91
+ attrs.push(['data-each',loop[1]+' '+loop[2]+' '+expression(loop[3])]);
92
+ }
93
+ else if (['if', 'else-if', 'else', 'show'].includes(p.name)) attrs.push(['data-' + p.name,expression(value)]);
94
+ else if (p.name === 'html' || p.name === 'text') attrs.push(['data-' + p.name, expression(value)]);
95
+ else throw Error('Unsupported directive ' + p.name);
96
+ }
97
+ }
98
+ const attributes = attrs.map(([key, value]) => ` ${key}="${esc(value)}"`).join('');
99
+ const children = node.children.map(templateNode).join('');
100
+ if (['input', 'img', 'br', 'hr', 'meta', 'link', 'source'].includes(tag)) return `<${tag}${attributes}>`;
101
+ return `<${tag}${attributes}>${children}</${tag}>`;
102
+ }
103
+ async function write(file, body) { await fs.mkdir(path.dirname(path.join(output, file)), { recursive: true }); await fs.writeFile(path.join(output, file), body); }
104
+ async function walk(base) { const out = []; for (const e of await fs.readdir(base, { withFileTypes: true })) { const f = path.join(base, e.name); if (e.isDirectory()) out.push(...await walk(f)); else if (e.isFile()) out.push(f); } return out; }
105
+
106
+ for (const full of await walk(path.join(source, 'src'))) {
107
+ const file = path.relative(source, full).replaceAll(path.sep, '/');
108
+ const input = await fs.readFile(full, 'utf8');
109
+ for (const match of input.matchAll(/import\s*\{([^}]+)\}\s*from\s*['"]@ant-design\/icons-vue['"]/g)) for (const name of match[1].split(',').map(s => s.trim())) iconNames.add(name);
110
+ hashes[file] = crypto.createHash('sha256').update(input).digest('hex');
111
+ if (file === 'src/main.ts' || file === 'src/App.vue' || file === 'src/styles/theme.ts') continue;
112
+ if (file.endsWith('.css')) { await write(file.replace('src/styles/', 'styles/'), input); continue; }
113
+ if (file.endsWith('.ts')) { await write(file.replace(/\.ts$/, '.js'), transpile(rewriteImports(input, file))); continue; }
114
+ if (!file.endsWith('.vue')) continue;
115
+ const { descriptor, errors } = parseSfc(input);
116
+ if (errors.length) throw errors[0];
117
+ let code = rewriteImports(descriptor.scriptSetup?.content || '', file);
118
+ const sf = ts.createSourceFile(file, code, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
119
+ const exposed = bindings(sf);
120
+ const propKeys = [];
121
+ const visitProps = node => {
122
+ if (ts.isCallExpression(node) && node.expression.getText(sf) === 'defineProps' && ts.isTypeLiteralNode(node.typeArguments?.[0])) {
123
+ for (const member of node.typeArguments[0].members) if (member.name) propKeys.push(member.name.getText(sf).replace(/^['"]|['"]$/g, ''));
124
+ }
125
+ ts.forEachChild(node, visitProps);
126
+ };
127
+ visitProps(sf);
128
+ const imports = sf.statements.filter(ts.isImportDeclaration).map(s => s.getText(sf)).join('\n');
129
+ let body = sf.statements.filter(s => !ts.isImportDeclaration(s)).map(s => s.getText(sf)).join('\n');
130
+ body = body.replace(/defineProps\s*<[^]*?>\s*\(\s*\)/g, '__props').replace(/defineEmits\s*<[^]*?>\s*\(\s*\)/g, '__emit');
131
+ const compiled = transpile(`${imports}\nimport { createComponent } from '${relativeRuntime(file, 'dom')}';\nimport { withDefaults } from '${relativeRuntime(file, 'state')}';\nexport default createComponent({ name: '${path.basename(file, '.vue')}', propKeys: ${JSON.stringify(propKeys)}, template: new URL('./${path.basename(file, '.vue')}.html', import.meta.url).href, setup(__props, __emit) { ${body}\n return { ${exposed.join(', ')} }; } });`);
132
+ await write(file.replace(/\.vue$/, '.js'), compiled);
133
+ const html = templateNode(parseTemplate(descriptor.template?.content || '', { expressionPlugins: ['typescript'], whitespace: 'condense' }));
134
+ await write(file.replace(/\.vue$/, '.html'), `<!-- 来源:${file};HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->\n${html}\n`);
135
+ }
136
+ for (const full of await walk(path.join(source, 'tests'))) {
137
+ if (!full.endsWith('.ts')) continue;
138
+ const file = path.relative(source, full).replaceAll(path.sep, '/');
139
+ await write(file.replace(/\.ts$/, '.js'), transpile(rewriteImports(await fs.readFile(full, 'utf8'), file)));
140
+ }
141
+ const main = await fs.readFile(path.join(source, 'src/main.ts'), 'utf8');
142
+ const routes = main.split('\n').flatMap(line => {
143
+ const route = line.match(/path:\s*['"]([^'"]+)['"]/); if (!route) return [];
144
+ let component = line.match(/import\(['"]\.\/([^'"]+)\.vue['"]\)/)?.[1];
145
+ if (line.includes('component: ModelsPage')) component = 'models/ModelsPage';
146
+ if (line.includes('component: ScopePage')) component = 'shell/ScopePage';
147
+ return [{ path: route[1], ...(component ? { component: './src/' + component + '.js' } : {}), ...(line.match(/redirect:\s*['"]([^'"]+)['"]/) ? { redirect: line.match(/redirect:\s*['"]([^'"]+)['"]/)[1] } : {}) }];
148
+ });
149
+ await write('routes.json', JSON.stringify(routes, null, 2) + '\n');
150
+ await write('baseline.json', JSON.stringify({ source: path.relative(path.resolve(output, '../..'), source), version: 'v0.14', package: 'PT-06b', convertedAt: '2026-10-13', files: hashes, businessRouteCount: 37, userApproval: 'pending-review' }, null, 2) + '\n');
151
+ const iconCode = ["import { h, defineWidget } from './dom.js';", "const svg = node => h(node.tag, node.attrs || {}, (node.children || []).map(svg));", "const icon = (name, data) => defineWidget(name, props => h('span', { class: ['anticon', 'anticon-' + data.name, props.class], role: 'img', 'aria-label': data.name, style: props.style }, svg({ ...data.icon, attrs: { ...data.icon.attrs, width: '1em', height: '1em', fill: 'currentColor', 'aria-hidden': 'true' } })));" ];
152
+ for (const name of iconNames) {
153
+ const loaded = require('@ant-design/icons-svg/lib/asn/' + name + '.js');
154
+ iconCode.push(`export const ${name} = icon('${name}', ${JSON.stringify(loaded.default || loaded)});`);
155
+ }
156
+ await write('runtime/icons.js', iconCode.join('\n') + '\n');
157
+ await fs.copyFile(require.resolve('antdv-next/dist/reset.css'), path.join(output, 'styles/reset.css'));
158
+ for(const name of await fs.readdir(path.join(source,'dist/assets')))if(name.endsWith('.css')){
159
+ const css=await fs.readFile(path.join(source,'dist/assets',name),'utf8'),split=css.indexOf(':root{--easel-primary');
160
+ if(split>=0)await write('styles/pro.css',css.slice(0,split).replace(/\[data-v-[a-f0-9]+\]/g,'')+'\n');
161
+ }
162
+ for (const packageName of ['antdv-next', '@ant-design/icons-svg','@ant-design/icons-vue', '@qin-ui/antdv-next-pro']) {
163
+ const packageDirectory = await fs.realpath(path.join(source, 'node_modules', packageName));
164
+ for (const name of (await fs.readdir(packageDirectory)).filter(name=>/^licen[cs]e(?:\..*)?$/i.test(name))) {
165
+ try { const text = await fs.readFile(path.join(packageDirectory, name), 'utf8'); await write('licenses/' + packageName.replaceAll('/', '-') + '.txt', text); break; } catch {}
166
+ }
167
+ }
168
+ console.log(`Converted ${Object.keys(hashes).length} source files; ${routes.length} route rules.`);
@@ -0,0 +1,7 @@
1
+ import http from 'node:http';
2
+ import fs from 'node:fs/promises';
3
+ import path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ const root=path.resolve(path.dirname(fileURLToPath(import.meta.url)),'..'),port=Number(process.env.PROTOTYPE_PORT||process.argv[2]||4194);
6
+ const types={'.html':'text/html; charset=utf-8','.js':'text/javascript; charset=utf-8','.json':'application/json; charset=utf-8','.css':'text/css; charset=utf-8','.svg':'image/svg+xml','.png':'image/png','.md':'text/plain; charset=utf-8'};
7
+ http.createServer(async(req,res)=>{try{let pathname=decodeURIComponent(new URL(req.url,'http://localhost').pathname),file=path.resolve(root,'.'+pathname);if(file!==root&&!file.startsWith(root+path.sep)){res.writeHead(403);res.end();return;}if(pathname.endsWith('/'))file=path.join(file,'index.html');const body=await fs.readFile(file);res.writeHead(200,{'Content-Type':types[path.extname(file)]||'application/octet-stream','Cache-Control':'no-store'});res.end(body);}catch(error){res.writeHead(error.code==='ENOENT'?404:500,{'Content-Type':'text/plain; charset=utf-8'});res.end('文件不可用');}}).listen(port,'127.0.0.1',()=>console.log(`HTML 原型:http://127.0.0.1:${port}/#/workbench`));
@@ -0,0 +1,11 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
+ const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
5
+ const sheets = JSON.parse(await fs.readFile(path.join(root, 'assets/reference-styles.json'), 'utf8'));
6
+ const variables = {};
7
+ for (const sheet of sheets) for (const match of sheet.matchAll(/(--[\w-]+)\s*:\s*([^;{}]+);/g)) variables[match[1]] = match[2].trim();
8
+ const css = sheets.map(sheet => sheet.replace(/:where\(\.css-(?!var-)[^)]*\)/g, '').replace(/\.css-var-[a-zA-Z0-9_-]+/g, '.native-theme')).join('\n');
9
+ await fs.writeFile(path.join(root, 'styles/antdv.css'), css + '\n:root{' + Object.entries(variables).map(([key, value]) => key + ':' + value).join(';') + '}\n');
10
+ await fs.writeFile(path.join(root, 'design-tokens.json'), JSON.stringify({ origin: 'v0.14 rendered Antdv Next theme', cssVariables: variables }, null, 2) + '\n');
11
+ console.log(`${sheets.length} rendered style blocks; ${Object.keys(variables).length} CSS variables.`);
@@ -0,0 +1,24 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import crypto from 'node:crypto';
4
+ import { execFileSync } from 'node:child_process';
5
+ import { fileURLToPath } from 'node:url';
6
+ const root=path.resolve(path.dirname(fileURLToPath(import.meta.url)),'..'),source=path.resolve(root,'../../交互原型/console-operations-v0.14');
7
+ const hash=bytes=>crypto.createHash('sha256').update(bytes).digest('hex');
8
+ async function walk(directory){const result=[];for(const entry of await fs.readdir(directory,{withFileTypes:true})){const file=path.join(directory,entry.name);if(entry.isDirectory())result.push(...await walk(file));else if(entry.isFile())result.push(file);}return result;}
9
+ const files=await walk(root),errors=[];let externalImports=0;
10
+ for(const file of files.filter(file=>file.endsWith('.js')||file.endsWith('.mjs')))try{execFileSync(process.execPath,['--check',file],{stdio:'pipe'});}catch(error){errors.push(path.relative(root,file)+': '+error.stderr?.toString());}
11
+ const runtimeFiles=files.filter(file=>file===path.join(root,'app.js')||file.startsWith(path.join(root,'runtime')+path.sep)||file.startsWith(path.join(root,'src')+path.sep));
12
+ for(const file of runtimeFiles.filter(file=>file.endsWith('.js'))){const code=await fs.readFile(file,'utf8');for(const match of code.matchAll(/\bfrom\s*['"]([^'"]+)['"]/g)){const spec=match[1];if(!spec.startsWith('.')){externalImports++;errors.push('外部运行时导入:'+spec);}else try{await fs.access(path.resolve(path.dirname(file),spec));}catch{errors.push('导入缺失:'+spec+' in '+file);}}}
13
+ if(files.some(file=>file.endsWith('.vue')))errors.push('HTML 交付中出现 .vue 文件');
14
+ const routes=JSON.parse(await fs.readFile(path.join(root,'routes.json'),'utf8')),business=routes.filter(route=>route.component&&!route.path.startsWith('/module/'));
15
+ if(business.length!==37)errors.push('业务路由数量应为 37');
16
+ for(const route of routes.filter(route=>route.component))try{await fs.access(path.join(root,route.component));await fs.access(path.join(root,route.component.replace(/\.js$/,'.html')));}catch{errors.push('路由文件缺失:'+route.path);}
17
+ const baseline=JSON.parse(await fs.readFile(path.join(root,'baseline.json'),'utf8'));
18
+ let sourceFilesChecked=0,sourceManifestFilesChecked=0,sourceStatus='not-present';
19
+ try{await fs.access(source);sourceStatus='checked';for(const [name,expected] of Object.entries(baseline.files)){if(hash(await fs.readFile(path.join(source,name)))!==expected)errors.push('来源变更:'+name);sourceFilesChecked++;}
20
+ const manifest=JSON.parse(await fs.readFile(path.join(source,'交付校验.json'),'utf8'));for(const [name,expected] of Object.entries(manifest.files)){if(hash(await fs.readFile(path.join(source,name)))!==expected)errors.push('原版清单不符:'+name);sourceManifestFilesChecked++;}
21
+ }catch(error){if(sourceStatus==='checked')errors.push('来源校验失败:'+error.message);}
22
+ const report={checkedAt:new Date().toISOString(),syntaxFilesChecked:files.filter(f=>f.endsWith('.js')||f.endsWith('.mjs')).length,runtimeExternalImports:externalImports,businessRoutes:business.length,uniqueBusinessPages:new Set(business.map(r=>r.component)).size,htmlTemplates:files.filter(f=>f.startsWith(path.join(root,'src')+path.sep)&&f.endsWith('.html')).length,sourceStatus,sourceFilesChecked,sourceManifestFilesChecked,errors,status:errors.length?'FAIL':'PASS'};
23
+ await fs.mkdir(path.join(root,'qa'),{recursive:true});await fs.writeFile(path.join(root,'qa/integrity.json'),JSON.stringify(report,null,2)+'\n');
24
+ console.log(JSON.stringify(report,null,2));if(errors.length)process.exitCode=1;
@@ -0,0 +1,16 @@
1
+ 'use strict';
2
+ const http = require('node:http');
3
+ const fs = require('node:fs');
4
+ const path = require('node:path');
5
+ const root = path.resolve(__dirname, '..');
6
+ const types = { '.html': 'text/html', '.mjs': 'text/javascript', '.js': 'text/javascript', '.svg': 'image/svg+xml', '.png': 'image/png', '.jpg': 'image/jpeg', '.webp': 'image/webp', '.css': 'text/css', '.json': 'application/json' };
7
+ const server = http.createServer((req, res) => {
8
+ let relative;
9
+ try { relative = decodeURIComponent(new URL(req.url, 'http://localhost').pathname); } catch { res.writeHead(400).end(); return; }
10
+ if (relative === '/') { res.writeHead(302, { Location: '/app/index.html' }).end(); return; }
11
+ const file = path.resolve(root, '.' + relative);
12
+ if (!file.startsWith(root + path.sep) || !fs.existsSync(file) || !fs.statSync(file).isFile() || !fs.realpathSync(file).startsWith(fs.realpathSync(root) + path.sep)) { res.writeHead(404).end(); return; }
13
+ res.writeHead(200, { 'Content-Type': (types[path.extname(file)] || 'application/octet-stream') + '; charset=utf-8', 'Cache-Control': 'no-store' });
14
+ fs.createReadStream(file).pipe(res);
15
+ });
16
+ server.listen(Number(process.argv[2] || 0), '127.0.0.1', () => process.stdout.write(`原型预览:http://127.0.0.1:${server.address().port}/\n`));
@@ -0,0 +1,44 @@
1
+ /* Instance-level usability fixes. The complete EASEL reference stays unchanged. */
2
+ :root {
3
+ --prototype-scroll-track: #f0f0f0;
4
+ --prototype-scroll-thumb: #8c8c8c;
5
+ }
6
+
7
+ /* The captured Ant stylesheet contains temporary document scroll-lock rules.
8
+ Restore the full body and native document scrolling. Live dialogs still
9
+ apply their own inline overflow:hidden while they are open. */
10
+ html body {
11
+ width: 100%;
12
+ overflow-y: visible;
13
+ }
14
+
15
+ /* Explicit sizing keeps scrollbars visible on hosts with overlay scrollbars. */
16
+ *::-webkit-scrollbar {
17
+ width: 12px;
18
+ height: 12px;
19
+ }
20
+ *::-webkit-scrollbar-track,
21
+ *::-webkit-scrollbar-corner {
22
+ background: var(--prototype-scroll-track);
23
+ }
24
+ *::-webkit-scrollbar-thumb {
25
+ background: var(--prototype-scroll-thumb);
26
+ border: 2px solid var(--prototype-scroll-track);
27
+ border-radius: 6px;
28
+ }
29
+ *::-webkit-scrollbar-thumb:hover {
30
+ background: #595959;
31
+ }
32
+
33
+ /* Ant's exported CSS expects overflow navigation controls. The native runtime
34
+ uses real tab buttons, so expose native scrolling rather than clipping them. */
35
+ .ant-tabs > .ant-tabs-nav .ant-tabs-nav-wrap,
36
+ .ant-tabs > div > .ant-tabs-nav .ant-tabs-nav-wrap {
37
+ overflow-x: auto;
38
+ overflow-y: hidden;
39
+ }
40
+
41
+ .ant-table-content,
42
+ .ant-tabs-nav-wrap {
43
+ scrollbar-color: var(--prototype-scroll-thumb) var(--prototype-scroll-track);
44
+ }
@@ -0,0 +1,40 @@
1
+ <!doctype html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1">
5
+ <title>选择原型类型 · i3 Composer</title><link rel="icon" href="data:,">
6
+ <style>
7
+ *{box-sizing:border-box}html{height:100%}body{height:100vh;height:100dvh;display:flex;flex-direction:column;margin:0;background:#f5f5f5;color:#262626;font:14px/1.5 -apple-system,BlinkMacSystemFont,"PingFang SC","Microsoft YaHei",sans-serif}header{flex:none;padding:20px 24px 16px;background:#fff;border-bottom:1px solid #e8e8e8}h1{font-size:22px;margin:0 0 4px}p{margin:0;color:#595959}.options{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px;margin:16px 0}.option{text-align:left;border:1px solid #d9d9d9;border-radius:8px;padding:12px 14px;background:#fff;color:inherit;font:inherit;cursor:pointer}.option strong{display:block;font-size:16px;margin-bottom:4px}.option span{display:block;font-size:13px;color:#595959}.option[aria-pressed=true]{border-color:#1677ff;background:#f0f7ff}.option:disabled{cursor:default;background:#fafafa;color:#8c8c8c}.option:disabled span{color:#8c8c8c}.option:focus-visible,a:focus-visible{outline:3px solid #1677ff;outline-offset:3px}.summary{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap}.summary a{color:#0958d9;text-decoration:none;white-space:nowrap}.summary a:hover{text-decoration:underline}iframe{display:block;flex:1 0 240px;width:100%;min-height:240px;border:0;background:#fff}.error{color:#cf1322}
8
+ @media(max-width:900px){header{padding:16px}.options{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}.option{padding:10px}.option strong{font-size:14px}.summary{gap:8px}}
9
+ @media(prefers-reduced-motion:reduce){*{scroll-behavior:auto}}
10
+ </style>
11
+ </head>
12
+ <body>
13
+ <header><h1>选择原型类型</h1><p>先确定界面结构,再结合业务需求生成原型。已有项目优先沿用已确认的设计。</p>
14
+ <div class="options" aria-label="原型类型"></div>
15
+ <div class="summary"><p id="summary" role="status">正在读取模板…</p><a id="open" target="_blank" rel="noopener">打开完整演示 ↗</a></div>
16
+ </header>
17
+ <iframe title="企业管理后台完整交互演示"></iframe>
18
+ <script type="module">
19
+ const assetRoot=new URL('../',location.href),frame=document.querySelector('iframe'),summary=document.querySelector('#summary');
20
+ try{
21
+ const response=await fetch(new URL('catalog.json',assetRoot));if(!response.ok)throw new Error('无法读取模板目录');
22
+ const catalog=await response.json();let selected=false;
23
+ for(const entry of catalog.templates){
24
+ const button=document.createElement('button');button.className='option';button.type='button';
25
+ const title=document.createElement('strong');title.textContent=entry.name;button.append(title);
26
+ const hint=document.createElement('span');hint.textContent=entry.availability==='available'?'可操作演示 · 等待人工评审':'待建设';button.append(hint);
27
+ button.disabled=entry.availability!=='available';button.setAttribute('aria-pressed','false');
28
+ button.addEventListener('click',()=>{
29
+ const url=new URL(entry.preview,assetRoot);if(url.origin!==location.origin)throw new Error('模板入口必须来自本地资源');
30
+ document.querySelectorAll('.option').forEach(item=>item.setAttribute('aria-pressed',String(item===button)));
31
+ frame.src=url.href;frame.title=entry.name+'完整交互演示';document.querySelector('#open').href=url.href;
32
+ summary.textContent=entry.name+' · '+entry.version+' · 来源:'+entry.source+'。保留完整示例,当前等待人工评审。';
33
+ });
34
+ document.querySelector('.options').append(button);
35
+ if(!selected&&!button.disabled){button.click();selected=true}
36
+ }
37
+ if(!selected)throw new Error('当前没有可用模板');
38
+ }catch(error){summary.textContent=error.message;summary.classList.add('error')}
39
+ </script>
40
+ </body></html>
@@ -0,0 +1,9 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "adapter": "legacy-html",
4
+ "preset": "modern-workspace/preset.json",
5
+ "resources": {
6
+ "common": "common"
7
+ },
8
+ "defaultTitle": "立项申请"
9
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "layout": "workspace",
3
+ "primitive": { "teal": "#0f766e", "slate": "#1d3331", "spacing": [4, 8, 12, 16, 24, 32] },
4
+ "semantic": { "color-primary": "#0f766e", "color-text": "#1d3331", "color-muted": "#566b67", "color-background": "#f5f8f7", "color-surface": "#ffffff", "color-border": "#d9e5e1", "color-sidebar": "#ffffff", "color-sidebar-text": "#1d3331", "color-success": "#166534", "color-warning": "#92400e", "color-danger": "#b91c1c", "space-page": "32px", "font-body": "system-ui, -apple-system, 'PingFang SC', 'Microsoft YaHei', sans-serif" },
5
+ "component": { "radius-panel": "12px", "control-height": "44px", "table-cell-space": "20px", "sidebar-width": "220px" }
6
+ }
@@ -0,0 +1,16 @@
1
+ 'use strict';
2
+ const http = require('node:http');
3
+ const fs = require('node:fs');
4
+ const path = require('node:path');
5
+ const root = path.resolve(__dirname);
6
+ const types = { '.html': 'text/html', '.mjs': 'text/javascript', '.js': 'text/javascript', '.css': 'text/css', '.json': 'application/json', '.svg': 'image/svg+xml', '.png': 'image/png', '.jpg': 'image/jpeg', '.webp': 'image/webp' };
7
+ const server = http.createServer((req, res) => {
8
+ let relative;
9
+ try { relative = decodeURIComponent(new URL(req.url, 'http://localhost').pathname); } catch { res.writeHead(400).end(); return; }
10
+ if (relative === '/') { res.writeHead(302, { Location: '/gallery/index.html' }).end(); return; }
11
+ const file = path.resolve(root, '.' + relative);
12
+ if (!file.startsWith(root + path.sep) || !fs.existsSync(file) || !fs.statSync(file).isFile() || !fs.realpathSync(file).startsWith(root + path.sep)) { res.writeHead(404).end(); return; }
13
+ res.writeHead(200, { 'Content-Type': (types[path.extname(file)] || 'application/octet-stream') + '; charset=utf-8', 'Cache-Control': 'no-store' });
14
+ fs.createReadStream(file).pipe(res);
15
+ });
16
+ server.listen(Number(process.argv[2] || 0), '127.0.0.1', () => process.stdout.write(`模板预览:http://127.0.0.1:${server.address().port}/\n`));
@@ -0,0 +1,41 @@
1
+ # 产物与验收
2
+
3
+ <!-- i3:zh-guide:start -->
4
+ ## 中文使用说明
5
+
6
+ 按下文完整工程步骤、检查项与验证条件执行。根据任务选择适用步骤,保留证据、风险和退出条件;正文示例中的英文标签在面向用户输出时译为中文。
7
+
8
+ 默认使用简体中文解释、追问及生成报告;用户明确要求其他语言时可切换。原方法正文、引用、阈值和审批条件完整保留。代码标识、路径、命令、工具参数、JSON 键/枚举与原文引用保持原样。
9
+ <!-- i3:zh-guide:end -->
10
+
11
+ 项目 `.i3-ui-prototypes.json` 的 prototypes 列出 id、相对目录和 appliesTo。初始 appliesTo 为空,按实际业务补充模块范围;工程任务选择适用原型,不能把所有基线强加到无关模块。
12
+
13
+ 原型目录含 prototype.json、requirements-map.json、design-system/MASTER.md 与 tokens.json、app、mocks、qa、reviews、baselines、baseline.json、HANDOFF.md。企业后台生成 EASEL 完整参考示例,兼容旧模板生成通用演示;用于新业务时代理必须适配实际业务。企业后台还保留 design-system/source.json、runtime 与 purpose,记录来源、实例数据隔离及用途。模板来源与许可在技能资源中保留。生成实例 app/qa 是来源历史记录;本轮验收证据必须写入根目录 qa,不能复用历史通过状态。
14
+
15
+ 新增实例的 template.adapter 记录清单选定的运行层;模板指纹覆盖 manifest、preset、声明资源及 adapter 实现。旧实例不补写缺失字段或改写已有模板摘要,其原 contentManifest 身份与摘要保持兼容。运行身份、必需资源和保护路径由明确的运行层合同决定,未知运行层拒绝,不回退兼容演示;详见 [template-adapters.md](template-adapters.md)。
16
+
17
+ 需求映射 schemaVersion=1,每个 requirement 具有唯一 id、pages、fields、actions、roles、states、scenarios 和 confirmation。scenarios 是浏览器检查的场景 ID;涉及权限与状态变化的需求应补充可见范围、转移条件及校验。未确认规则写入 openQuestions。
18
+
19
+ 浏览器记录 qa/browser.json:
20
+
21
+ ```json
22
+ {
23
+ "schemaVersion": 1,
24
+ "revision": "r001",
25
+ "digest": "当前 manifest 命令返回的 SHA-256",
26
+ "status": "passed",
27
+ "source": "实际浏览器工具与运行记录位置",
28
+ "screenshots": ["qa/screenshots/desktop.png", "qa/screenshots/narrow.png"],
29
+ "journeys": [{"id": "需求映射中的场景ID", "status": "passed"}],
30
+ "consoleErrors": [],
31
+ "viewports": [1440, 768]
32
+ }
33
+ ```
34
+
35
+ 每个必要场景都必须实际执行。记录无法执行或失败的项,不以填写 JSON 替代运行。结构验收检查记录一致性与引用存在;其结果不能独立证明浏览器发生过执行。截图固定数据与视口,键盘和焦点采用实际交互验证。
36
+
37
+ 确认文件含当前 revision 和 digest,以及 reviewer、statement、source 三个非空字段。source 指向可信的人类确认记录;statement 保留用户认可意思。测试夹具的模拟确认仅用于验证保护逻辑。
38
+
39
+ 快照保存运行文件、需求、设计契约和专业建议记录,manifest.json 记录摘要,review.json 记录确认。baseline.json 引用当前已确认快照。新候选不覆盖旧快照;快照损坏或失去匹配时报告 corrupt-baseline。
40
+
41
+ check-prototype --enforce-baseline 对设计契约、token、需求映射或模板/模式改变返回失败,供项目选择接入门禁。它不会自动分析不同框架的生产组件;真实工程仍需组件映射、受影响页面的浏览器与业务回归。