@givolt/i3-composer-agent 2.2.3 → 2.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (439) hide show
  1. package/.agents/plugins/marketplace.json +1 -1
  2. package/.claude/commands/i3-prototype.md +23 -0
  3. package/.claude/commands/i3-review.md +1 -1
  4. package/.claude/commands/i3-ship.md +1 -1
  5. package/.claude-plugin/marketplace.json +1 -1
  6. package/.claude-plugin/plugin.json +1 -1
  7. package/.codex-plugin/plugin.json +2 -2
  8. package/.gemini/commands/i3-prototype.toml +23 -0
  9. package/.gemini/commands/i3-review.toml +1 -1
  10. package/.gemini/commands/i3-ship.toml +1 -1
  11. package/README.md +15 -5
  12. package/agents/code-reviewer.md +1 -1
  13. package/agents/test-engineer.md +1 -1
  14. package/bin/native-layout.cjs +2 -0
  15. package/commands/i3-prototype.toml +23 -0
  16. package/commands/i3-review.toml +1 -1
  17. package/commands/i3-ship.toml +1 -1
  18. package/docs/agents.md +2 -2
  19. package/docs/codebuddy-setup.md +2 -2
  20. package/docs/codex-setup.md +1 -1
  21. package/docs/copilot-setup.md +4 -0
  22. package/docs/cursor-setup.md +3 -0
  23. package/docs/other-hosts.md +44 -9
  24. package/docs/workbuddy-setup.md +2 -2
  25. package/evals/README.md +2 -0
  26. package/evals/cases/i3-documentation-and-adrs.json +18 -0
  27. package/evals/cases/i3-test-driven-development.json +8 -0
  28. package/evals/cases/i3-ui-prototype.json +49 -0
  29. package/evals/fixtures/i3-documentation-and-adrs/prose-review/README.md +19 -0
  30. package/evals/fixtures/i3-documentation-and-adrs/prose-review/queue.js +32 -0
  31. package/evals/fixtures/i3-ui-prototype/business-brief.md +7 -0
  32. package/evals/plugin/tdd-fires-on-pasted-bug/graders/failing-test-first.md +7 -0
  33. package/evals/plugin/tdd-fires-on-pasted-bug/graders/skill-fired.md +5 -0
  34. package/evals/plugin/tdd-fires-on-pasted-bug/prompt.md +15 -0
  35. package/evals/plugin/tdd-stays-quiet-on-debug/graders/not-fired.md +8 -0
  36. package/evals/plugin/tdd-stays-quiet-on-debug/prompt.md +25 -0
  37. package/evals/zh-CN/cases/i3-documentation-and-adrs.json +19 -0
  38. package/evals/zh-CN/cases/i3-test-driven-development.json +4 -0
  39. package/evals/zh-CN/cases/i3-ui-prototype.json +50 -0
  40. package/hooks/SIMPLIFY-IGNORE.md +3 -2
  41. package/hooks/simplify-ignore-test.sh +93 -1
  42. package/hooks/simplify-ignore.sh +94 -11
  43. package/package.json +31 -1
  44. package/plugin.json +1 -1
  45. package/references/performance-checklist.md +4 -2
  46. package/scripts/design-provider-discovery-test.js +190 -0
  47. package/scripts/design-provider-test.js +68 -0
  48. package/scripts/enterprise-template-test.js +179 -0
  49. package/scripts/lib/skill-lint-test.js +113 -1
  50. package/scripts/lib/skill-lint.js +62 -8
  51. package/scripts/run-evals-test.js +207 -0
  52. package/scripts/run-evals.js +47 -9
  53. package/scripts/template-adapter-test.js +155 -0
  54. package/scripts/ui-prototype-test.js +114 -0
  55. package/scripts/validate-commands-test.js +30 -0
  56. package/scripts/validate-commands.js +6 -16
  57. package/scripts/validate-reference-links-test.js +18 -0
  58. package/scripts/validate-reference-links.js +4 -2
  59. package/scripts/validate-skills.js +26 -3
  60. package/skills/i3-documentation-and-adrs/SKILL.md +9 -0
  61. package/skills/i3-frontend-ui-engineering/SKILL.md +5 -1
  62. package/skills/i3-idea-refine/SKILL.md +20 -5
  63. package/skills/i3-incremental-implementation/SKILL.md +4 -0
  64. package/skills/i3-performance-optimization/SKILL.md +10 -10
  65. package/skills/i3-security-and-hardening/references/hardening-patterns.md +1 -1
  66. package/skills/i3-shipping-and-launch/SKILL.md +6 -0
  67. package/skills/i3-test-driven-development/SKILL.md +3 -3
  68. package/skills/i3-ui-prototype/SKILL.md +119 -0
  69. package/skills/i3-ui-prototype/assets/templates/catalog.json +148 -0
  70. package/skills/i3-ui-prototype/assets/templates/classic-admin/manifest.json +9 -0
  71. package/skills/i3-ui-prototype/assets/templates/classic-admin/preset.json +6 -0
  72. package/skills/i3-ui-prototype/assets/templates/common/app/app.mjs +89 -0
  73. package/skills/i3-ui-prototype/assets/templates/common/app/config.json +1 -0
  74. package/skills/i3-ui-prototype/assets/templates/common/app/domain.mjs +20 -0
  75. package/skills/i3-ui-prototype/assets/templates/common/app/index.html +17 -0
  76. package/skills/i3-ui-prototype/assets/templates/common/app/serve.cjs +16 -0
  77. package/skills/i3-ui-prototype/assets/templates/common/app/styles.css +670 -0
  78. package/skills/i3-ui-prototype/assets/templates/common/app/tokens.css +19 -0
  79. package/skills/i3-ui-prototype/assets/templates/common/design-system/master.md +20 -0
  80. package/skills/i3-ui-prototype/assets/templates/common/gallery.html +2 -0
  81. package/skills/i3-ui-prototype/assets/templates/common/mocks/applications.json +5 -0
  82. package/skills/i3-ui-prototype/assets/templates/common/requirements-map.json +8 -0
  83. package/skills/i3-ui-prototype/assets/templates/common/serve-gallery.cjs +16 -0
  84. package/skills/i3-ui-prototype/assets/templates/credits.md +17 -0
  85. package/skills/i3-ui-prototype/assets/templates/data-operations/manifest.json +9 -0
  86. package/skills/i3-ui-prototype/assets/templates/data-operations/preset.json +6 -0
  87. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/design-system.md +32 -0
  88. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/index.html +29 -0
  89. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/manifest.json +9 -0
  90. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/origin.json +344 -0
  91. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/preset.json +928 -0
  92. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/app.js +22 -0
  93. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets/empty.svg +1 -0
  94. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets/reference-styles.json +1 -0
  95. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets/result-403.svg +1 -0
  96. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets/result-404.svg +1 -0
  97. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets-manifest.json +334 -0
  98. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/baseline.json +173 -0
  99. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/conversion.md +30 -0
  100. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/credits.md +17 -0
  101. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/design-tokens.json +881 -0
  102. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/index.html +28 -0
  103. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/licenses/@qin-ui-antdv-next-pro.txt +9 -0
  104. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/licenses/ant-design-icons.txt +22 -0
  105. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/licenses/antdv-next.txt +21 -0
  106. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/package.json +12 -0
  107. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/browser-routes.json +298 -0
  108. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/coverage.json +180 -0
  109. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/integrity.json +13 -0
  110. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/keyboard.json +11 -0
  111. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/responsive.json +125 -0
  112. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/review.md +51 -0
  113. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/rules.log +150 -0
  114. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/flow-editor-html.png +0 -0
  115. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/flow-editor-original.png +0 -0
  116. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/intent-create-html.png +0 -0
  117. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/intent-create-original.png +0 -0
  118. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/models-html.png +0 -0
  119. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/models-original.png +0 -0
  120. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/workbench-html.png +0 -0
  121. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/workbench-original.png +0 -0
  122. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/selection.json +9 -0
  123. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/visual-comparison.json +342 -0
  124. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/readme.md +73 -0
  125. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/reference.md +59 -0
  126. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/routes.json +178 -0
  127. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/controls.js +99 -0
  128. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/dialogs.js +54 -0
  129. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/dom.js +264 -0
  130. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/forms.js +47 -0
  131. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/icons.js +41 -0
  132. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/layout.js +47 -0
  133. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/router.js +63 -0
  134. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/state.js +90 -0
  135. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/table.js +41 -0
  136. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/widgets.js +8 -0
  137. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentDetail.html +3 -0
  138. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentDetail.js +36 -0
  139. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentEditor.html +2 -0
  140. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentEditor.js +51 -0
  141. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentsPage.html +3 -0
  142. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentsPage.js +48 -0
  143. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/CheckResults.html +2 -0
  144. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/CheckResults.js +6 -0
  145. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/ResourcePicker.html +2 -0
  146. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/ResourcePicker.js +13 -0
  147. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/data.js +24 -0
  148. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/domain.js +32 -0
  149. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/registry.js +25 -0
  150. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/store.js +85 -0
  151. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentClose.html +2 -0
  152. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentClose.js +17 -0
  153. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentCreate.html +2 -0
  154. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentCreate.js +66 -0
  155. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDecisions.html +3 -0
  156. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDecisions.js +38 -0
  157. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDetail.html +2 -0
  158. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDetail.js +66 -0
  159. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDocument.html +2 -0
  160. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDocument.js +5 -0
  161. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentHeader.html +2 -0
  162. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentHeader.js +12 -0
  163. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentHistory.html +2 -0
  164. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentHistory.js +11 -0
  165. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentList.html +2 -0
  166. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentList.js +116 -0
  167. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentReplan.html +2 -0
  168. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentReplan.js +32 -0
  169. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentRevision.html +2 -0
  170. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentRevision.js +49 -0
  171. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentSummary.html +2 -0
  172. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentSummary.js +10 -0
  173. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentWorkspace.html +2 -0
  174. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentWorkspace.js +77 -0
  175. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/data.js +60 -0
  176. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/domain.js +105 -0
  177. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/store.js +212 -0
  178. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/AuditPanel.html +2 -0
  179. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/AuditPanel.js +18 -0
  180. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelDetail.html +2 -0
  181. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelDetail.js +23 -0
  182. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelEditor.html +2 -0
  183. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelEditor.js +78 -0
  184. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelGrant.html +2 -0
  185. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelGrant.js +55 -0
  186. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelReferences.html +2 -0
  187. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelReferences.js +26 -0
  188. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelRelease.html +2 -0
  189. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelRelease.js +38 -0
  190. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelStatus.html +2 -0
  191. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelStatus.js +7 -0
  192. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelTable.html +2 -0
  193. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelTable.js +72 -0
  194. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelTester.html +2 -0
  195. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelTester.js +46 -0
  196. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelsPage.html +2 -0
  197. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelsPage.js +52 -0
  198. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/RowActions.html +2 -0
  199. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/RowActions.js +19 -0
  200. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/UsagePanel.html +2 -0
  201. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/UsagePanel.js +30 -0
  202. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/data.js +48 -0
  203. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/domain.js +39 -0
  204. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/store.js +129 -0
  205. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/IncidentDetail.html +4 -0
  206. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/IncidentDetail.js +21 -0
  207. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/IntentSource.html +2 -0
  208. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/IntentSource.js +8 -0
  209. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationActionDialog.html +2 -0
  210. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationActionDialog.js +37 -0
  211. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationEntry.html +2 -0
  212. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationEntry.js +10 -0
  213. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationsPage.html +2 -0
  214. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationsPage.js +37 -0
  215. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/RepairTrack.html +2 -0
  216. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/RepairTrack.js +49 -0
  217. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/RunDetail.html +4 -0
  218. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/RunDetail.js +22 -0
  219. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/SourceSummary.html +2 -0
  220. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/SourceSummary.js +9 -0
  221. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/commands.js +82 -0
  222. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/examples.js +47 -0
  223. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/model.js +61 -0
  224. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/repair.js +68 -0
  225. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/store.js +55 -0
  226. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/types.js +1 -0
  227. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/workbench.js +18 -0
  228. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ManagementTable.html +3 -0
  229. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ManagementTable.js +28 -0
  230. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcCreateEntry.html +2 -0
  231. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcCreateEntry.js +18 -0
  232. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcDetail.html +2 -0
  233. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcDetail.js +31 -0
  234. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcEditor.html +2 -0
  235. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcEditor.js +27 -0
  236. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcLifecycle.html +2 -0
  237. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcLifecycle.js +16 -0
  238. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcPage.html +2 -0
  239. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcPage.js +43 -0
  240. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcPicker.html +4 -0
  241. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcPicker.js +34 -0
  242. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcProgress.html +2 -0
  243. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcProgress.js +30 -0
  244. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcWizard.html +3 -0
  245. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcWizard.js +67 -0
  246. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcWorkspace.html +2 -0
  247. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcWorkspace.js +41 -0
  248. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcsPage.html +2 -0
  249. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcsPage.js +31 -0
  250. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ServiceEditor.html +2 -0
  251. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ServiceEditor.js +26 -0
  252. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ServiceList.html +2 -0
  253. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ServiceList.js +70 -0
  254. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/data.js +8 -0
  255. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/domain.js +62 -0
  256. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/management.js +36 -0
  257. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/managementStore.js +49 -0
  258. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/store.js +132 -0
  259. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/AdminList.html +2 -0
  260. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/AdminList.js +38 -0
  261. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/EffectiveGrants.html +2 -0
  262. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/EffectiveGrants.js +11 -0
  263. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/GrantEditor.html +2 -0
  264. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/GrantEditor.js +45 -0
  265. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/MemberEditor.html +2 -0
  266. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/MemberEditor.js +54 -0
  267. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/MembersPage.html +3 -0
  268. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/MembersPage.js +27 -0
  269. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RecordsPage.html +2 -0
  270. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RecordsPage.js +12 -0
  271. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RoleEditor.html +2 -0
  272. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RoleEditor.js +45 -0
  273. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RolesPage.html +3 -0
  274. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RolesPage.js +38 -0
  275. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/domain.js +61 -0
  276. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/state.js +51 -0
  277. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/store.js +116 -0
  278. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseActionDialog.html +2 -0
  279. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseActionDialog.js +45 -0
  280. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseDetail.html +4 -0
  281. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseDetail.js +30 -0
  282. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseEditor.html +2 -0
  283. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseEditor.js +67 -0
  284. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseExecution.html +2 -0
  285. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseExecution.js +5 -0
  286. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleasesPage.html +4 -0
  287. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleasesPage.js +60 -0
  288. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/commands.js +157 -0
  289. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/model.js +136 -0
  290. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/store.js +76 -0
  291. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewDetail.html +3 -0
  292. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewDetail.js +26 -0
  293. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewEvidence.html +2 -0
  294. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewEvidence.js +14 -0
  295. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewProcess.html +2 -0
  296. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewProcess.js +113 -0
  297. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewsPage.html +3 -0
  298. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewsPage.js +62 -0
  299. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/commands.js +97 -0
  300. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/model.js +147 -0
  301. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/store.js +13 -0
  302. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ColumnSettings.html +2 -0
  303. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ColumnSettings.js +9 -0
  304. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListBatchBar.html +2 -0
  305. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListBatchBar.js +8 -0
  306. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListDeleteDialog.html +2 -0
  307. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListDeleteDialog.js +37 -0
  308. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListMore.html +2 -0
  309. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListMore.js +8 -0
  310. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/RecordMetadata.html +2 -0
  311. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/RecordMetadata.js +17 -0
  312. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/columns.js +32 -0
  313. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/deliveryGuide.js +49 -0
  314. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/deliveryView.js +12 -0
  315. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/listBatch.js +15 -0
  316. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/listSelection.js +37 -0
  317. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/policy.js +68 -0
  318. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/session.js +44 -0
  319. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ConfirmationDialog.html +2 -0
  320. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ConfirmationDialog.js +25 -0
  321. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ConsoleShell.html +2 -0
  322. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ConsoleShell.js +53 -0
  323. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/PrototypeGuide.html +10 -0
  324. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/PrototypeGuide.js +30 -0
  325. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ScopePage.html +2 -0
  326. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ScopePage.js +10 -0
  327. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/SessionDialog.html +2 -0
  328. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/SessionDialog.js +9 -0
  329. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/confirmation.js +3 -0
  330. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/navigation.js +19 -0
  331. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecDocument.html +2 -0
  332. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecDocument.js +8 -0
  333. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecEdit.html +2 -0
  334. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecEdit.js +32 -0
  335. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecHeader.html +2 -0
  336. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecHeader.js +15 -0
  337. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecHistory.html +2 -0
  338. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecHistory.js +11 -0
  339. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecReview.html +2 -0
  340. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecReview.js +57 -0
  341. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecWorkspace.html +2 -0
  342. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecWorkspace.js +37 -0
  343. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/data.js +20 -0
  344. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/domain.js +55 -0
  345. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/store.js +151 -0
  346. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/ArtifactDetail.html +3 -0
  347. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/ArtifactDetail.js +18 -0
  348. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskCreate.html +2 -0
  349. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskCreate.js +40 -0
  350. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskDetail.html +2 -0
  351. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskDetail.js +51 -0
  352. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskLaunch.html +2 -0
  353. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskLaunch.js +9 -0
  354. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TasksPage.html +5 -0
  355. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TasksPage.js +48 -0
  356. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/domain.js +204 -0
  357. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/exampleSource.js +22 -0
  358. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/registry.js +135 -0
  359. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/store.js +137 -0
  360. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workbench/WorkbenchPage.html +3 -0
  361. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workbench/WorkbenchPage.js +36 -0
  362. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workbench/model.js +56 -0
  363. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workbench/store.js +15 -0
  364. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowCanvas.html +2 -0
  365. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowCanvas.js +27 -0
  366. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowDetail.html +4 -0
  367. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowDetail.js +31 -0
  368. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowEditor.html +2 -0
  369. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowEditor.js +68 -0
  370. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/WorkflowsPage.html +5 -0
  371. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/WorkflowsPage.js +55 -0
  372. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/data.js +16 -0
  373. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/domain.js +83 -0
  374. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/registry.js +18 -0
  375. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/store.js +61 -0
  376. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/admin.css +60 -0
  377. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/agents.css +46 -0
  378. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/antdv.css +295 -0
  379. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/app.css +102 -0
  380. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/delivery.css +4 -0
  381. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/intents.css +37 -0
  382. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/native.css +22 -0
  383. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/operations.css +2 -0
  384. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/pbc.css +3 -0
  385. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/permissions.css +22 -0
  386. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/pro.css +1 -0
  387. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/releases.css +4 -0
  388. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/reset.css +246 -0
  389. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/reviews.css +8 -0
  390. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/tasks.css +6 -0
  391. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/tokens.css +15 -0
  392. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/workbench.css +61 -0
  393. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/workflows.css +1 -0
  394. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/admin-rules.test.js +96 -0
  395. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/agents.test.js +14 -0
  396. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/intent-state.test.js +37 -0
  397. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/list-batch.test.js +44 -0
  398. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/operation-fixtures.js +19 -0
  399. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/operation-repair.test.js +14 -0
  400. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/operations.test.js +25 -0
  401. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/pbc-management.test.js +17 -0
  402. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/pbc-state.test.js +24 -0
  403. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/permission-config.test.js +23 -0
  404. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/permissions.test.js +24 -0
  405. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/releases.test.js +50 -0
  406. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/reviews.test.js +36 -0
  407. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/runtime-forms-router.test.js +28 -0
  408. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/runtime-state.test.js +42 -0
  409. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/runtime-stores.test.js +16 -0
  410. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/spec-state.test.js +11 -0
  411. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/tasks.test.js +27 -0
  412. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/workbench.test.js +34 -0
  413. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/workflows.test.js +16 -0
  414. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tools/convert.mjs +168 -0
  415. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tools/serve.mjs +7 -0
  416. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tools/styles.mjs +11 -0
  417. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tools/verify.mjs +24 -0
  418. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/serve.cjs +16 -0
  419. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/usability.css +44 -0
  420. package/skills/i3-ui-prototype/assets/templates/gallery/index.html +40 -0
  421. package/skills/i3-ui-prototype/assets/templates/modern-workspace/manifest.json +9 -0
  422. package/skills/i3-ui-prototype/assets/templates/modern-workspace/preset.json +6 -0
  423. package/skills/i3-ui-prototype/assets/templates/serve-gallery.cjs +23 -0
  424. package/skills/i3-ui-prototype/references/artifact-contract.md +41 -0
  425. package/skills/i3-ui-prototype/references/enterprise-admin.md +38 -0
  426. package/skills/i3-ui-prototype/references/expert-adapter.md +48 -0
  427. package/skills/i3-ui-prototype/references/template-adapters.md +57 -0
  428. package/skills/i3-ui-prototype/references/workflow-contract.md +19 -0
  429. package/skills/i3-ui-prototype/scripts/adapters/easel-html.cjs +30 -0
  430. package/skills/i3-ui-prototype/scripts/adapters/legacy-html.cjs +28 -0
  431. package/skills/i3-ui-prototype/scripts/check-design-provider.cjs +9 -0
  432. package/skills/i3-ui-prototype/scripts/check-prototype.cjs +14 -0
  433. package/skills/i3-ui-prototype/scripts/design-provider-discovery.cjs +128 -0
  434. package/skills/i3-ui-prototype/scripts/enterprise-template.cjs +97 -0
  435. package/skills/i3-ui-prototype/scripts/init-prototype.cjs +8 -0
  436. package/skills/i3-ui-prototype/scripts/manage-baseline.cjs +11 -0
  437. package/skills/i3-ui-prototype/scripts/prototype-lib.cjs +259 -0
  438. package/skills/i3-ui-prototype/scripts/template-adapters.cjs +89 -0
  439. package/skills/i3-using-agent-skills/SKILL.md +5 -0
@@ -0,0 +1,3 @@
1
+ <!-- 来源:src/reviews/ReviewsPage.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
2
+ <div class="page-heading"><div><h1>质量与评审</h1><p>核对问题和版本证据,处理当前交付中的确认事项。</p></div><template data-component="Button" data-on-click="(router.push('/tasks'))">查看交付任务</template></div><div class="task-metrics review-metrics"><article><span>待人工确认</span><strong>{{ (store.rows.filter(r =&gt; r.status === 'pending').length) }}</strong></article><article><span>问题待处理</span><strong>{{ (store.rows.filter(r =&gt; r.status === 'blocked').length) }}</strong></article><article><span>等待复核或恢复</span><strong>{{ (store.rows.filter(r =&gt; ['checking', 'suspended'].includes(r.status)).length) }}</strong></article><article><span>已确认或机器通过</span><strong>{{ (store.rows.filter(r =&gt; ['approved', 'automatic'].includes(r.status)).length) }}</strong></article></div><template data-component="Alert" data-if="(route.query.task)" class="page-alert" type="info" show-icon="" title="正在查看指定任务的全部评审"><template data-slot="action"><template data-component="Button" data-on-click="(router.replace('/reviews'))">查看所有任务</template></template></template><section class="auth-list review-list-panel"><template data-component="Tabs" data-model-active-key="(scope)" data-bind-items="([{ key: 'pending', label: '待处理 (' + pending.length + ')' }, { key: 'done', label: '历史与已处理 (' + (store.rows.length - pending.length) + ')' }, { key: 'all', label: '全部记录' }])"></template><div class="auth-filters review-filters"><template data-component="Input" data-model-value="(query)" placeholder="搜索任务、编号或问题" aria-label="搜索评审事项" allow-clear=""></template><template data-component="Select" data-model-value="(project)" aria-label="评审 PBC 筛选" data-bind-options="([{ value: 'all', label: '全部可见 PBC' }, ...Array.from(new Map(store.rows.map(r =&gt; [r.task.binding.pbcId, { value: r.task.binding.pbcId, label: r.project }])).values())])"></template><template data-component="Select" data-model-value="(kind)" aria-label="评审类型筛选" data-bind-options="([{ value: 'all', label: '全部评审类型' }, ...Object.entries(kindLabels).map(([value, label]) =&gt; ({ value, label }))])"></template><template data-component="Select" data-model-value="(severity)" aria-label="问题严重度筛选" data-bind-options="([{ value: 'all', label: '全部严重度' }, { value: 'high', label: '严重问题' }, { value: 'medium', label: '重要问题' }, { value: 'suggestion', label: '建议' }, { value: 'none', label: '无登记问题' }])"></template><template data-component="Select" data-model-value="(resultState)" aria-label="评审状态筛选" data-bind-options="([{ value: 'all', label: '全部评审状态' }, ...Object.entries(stateLabels).map(([value, label]) =&gt; ({ value, label }))])"></template><template data-component="Button" data-on-click="(reset)">重置</template></div><div class="auth-tools"><template data-component="Space" wrap=""><span>已选择 {{ (selection.selected.value.length) }} 项</span><template data-component="Button" size="small" data-bind-disabled="(!selection.selected.value.length)" data-on-click="(selection.clear)">清空</template><template data-component="Tooltip" title="评审与批准记录属于审计证据,不能删除。"><span><template data-component="Button" size="small" disabled="">批量删除</template></span></template></template><template data-component="Space" wrap=""><template data-component="Select" data-model-value="(sort)" aria-label="评审排序" data-bind-options="([{ value: 'newest', label: '更新时间倒序' }, { value: 'oldest', label: '更新时间正序' }])"></template><template data-component="Button" data-bind-loading="(loading)" data-on-click="(refresh)">刷新</template><template data-component="ColumnSettings" data-bind-preferences="(prefs)"></template></template></div><template data-component="Alert" data-if="(store.notice)" type="warning" show-icon="" data-bind-title="(store.notice)"></template><template data-component="Alert" data-if="(store.scene === 'error')" type="error" show-icon="" title="评审列表加载失败" description="已有记录保留,重试不会生成新评审。"><template data-slot="action"><template data-component="Button" data-on-click="(refresh)">重试</template></template></template><template data-component="ProTable" data-else="" data-bind-table="(table)" data-bind-control="(false)" data-bind-table-container="(false)" data-bind-search="(async () =&gt; { })" row-key="id" data-bind-loading="(loading)" data-bind-row-selection="(selection.rowSelection.value)" data-bind-scroll="({ x: 'max-content' })" data-bind-pagination="({ showTotal: (n) =&gt; '共 ' + n + ' 项', showSizeChanger: true, pageSizeOptions: [5, 10, 20] })"></template><template data-component="Empty" data-if="(!filtered.length &amp;&amp; store.scene !== 'error')" data-bind-description="(store.rows.length ? '当前筛选范围暂无评审事项' : '当前授权范围暂无评审记录')"><template data-component="Button" data-if="(store.rows.length)" data-on-click="reset();
3
+ scope = 'all';">查看全部记录</template></template><p class="review-footnote">评审由交付流程生成,审批记录和证据保留,不适用手工新增或删除。修改与重新规划形成新版本,生产发布另行授权。</p></section>
@@ -0,0 +1,62 @@
1
+ import { computed, ref, watch } from '../../runtime/state.js';
2
+ import { h } from '../../runtime/dom.js';
3
+ import { useRoute, useRouter } from "../../runtime/router.js";
4
+ import { Alert, Button, Input, Select, Space, Tabs, Tag, Tooltip, Empty } from "../../runtime/widgets.js";
5
+ import { ProTable, useTable } from "../../runtime/widgets.js";
6
+ import { useReviews } from "./store.js";
7
+ import { stateLabels, stateColors, kindLabels, reviewUrl } from "./model.js";
8
+ import { formatDate, tenantLabel } from "../shared/policy.js";
9
+ import { useColumns } from "../shared/columns.js";
10
+ import { useListSelection } from "../shared/listSelection.js";
11
+ import ListMore from "../shared/ListMore.js";
12
+ import ColumnSettings from "../shared/ColumnSettings.js";
13
+ import { createComponent } from '../../runtime/dom.js';
14
+ export default createComponent({ name: 'ReviewsPage', propKeys: [], template: new URL('./ReviewsPage.html', import.meta.url).href, setup(__props, __emit) {
15
+ const store = useReviews(), router = useRouter(), route = useRoute(), query = ref(''), scope = ref(route.query.task || route.query.pbc ? 'all' : 'pending'), project = ref(String(route.query.pbc || 'all')), kind = ref('all'), severity = ref('all'), resultState = ref('all'), sort = ref('newest'), loading = ref(false);
16
+ const active = ['pending', 'blocked', 'checking', 'suspended'];
17
+ const pending = computed(() => store.rows.filter(r => active.includes(r.status)));
18
+ const prefs = useColumns('reviews-v012', [{ key: 'name', label: '评审事项', locked: true }, { key: 'project', label: '所属 PBC', defaultVisible: true }, { key: 'kind', label: '评审类型', defaultVisible: true }, { key: 'status', label: '评审状态', defaultVisible: true }, { key: 'createdBy', label: '创建人', defaultVisible: true }, { key: 'createdAt', label: '创建时间', defaultVisible: true }, { key: 'updatedBy', label: '更新人' }, { key: 'updatedAt', label: '更新时间' }, { key: 'handledBy', label: '处理人' }, { key: 'handledAt', label: '处理时间' }, { key: 'tenant', label: '所属租户' }, { key: 'evidence', label: '依据版本' }, { key: 'task', label: '任务编号' }, { key: 'version', label: '记录版本' }, { key: 'actions', label: '操作', locked: true }]);
19
+ const url = (r) => reviewUrl(r.task.id, r.review.id);
20
+ function more(r) { return [{ key: 'detail', label: '查看证据详情' }, { key: 'history', label: '查看处理记录' }, { key: 'task', label: '查看交付任务' }, { key: 'pbc', label: 'PBC 交付工作区', disabled: !store.session.can('pbc:view', r.task.tenantId, r.task.binding.pbcId) }, { key: 'delete', label: '删除不适用:审批记录须保留', disabled: true }]; }
21
+ function action(key, r) { if (key === 'delete')
22
+ return; router.push(key === 'task' ? '/tasks/' + r.task.id : key === 'pbc' ? '/pbcs/' + r.task.binding.pbcId + '/workspace' : url(r) + (key === 'history' ? '?tab=history' : '')); }
23
+ const render = (f) => (_, row) => f(row);
24
+ const columns = prefs.choices.map(c => ({ key: c.key, title: c.label, width: c.key === 'name' ? 290 : c.key === 'actions' ? 140 : c.key.endsWith('At') ? 165 : 125, fixed: c.key === 'actions' ? 'right' : undefined, render: render(r => {
25
+ const v = r.review;
26
+ if (c.key === 'name')
27
+ return h('div', { class: 'review-list-name' }, [h(Button, { type: 'link', onClick: () => router.push(url(r)) }, () => r.task.name), h('small', { class: 'mono muted' }, v.code), h('span', { class: 'muted' }, v.findings.length ? v.findings.length + ' 项问题 · ' + v.findings[0].title : v.title)]);
28
+ if (c.key === 'status')
29
+ return h(Tag, { color: stateColors[r.status] }, () => stateLabels[r.status]);
30
+ if (c.key === 'actions')
31
+ return h('div', { class: 'row-actions' }, [h(Button, { type: 'link', onClick: () => router.push(url(r)) }, () => active.includes(r.status) ? '处理' : '查看'), h(ListMore, { name: v.code, items: more(r), onAction: (k) => action(k, r) })]);
32
+ if (c.key === 'project')
33
+ return r.project;
34
+ if (c.key === 'kind')
35
+ return kindLabels[v.kind];
36
+ if (c.key === 'tenant')
37
+ return tenantLabel(v.tenantId);
38
+ if (c.key === 'task')
39
+ return r.task.code;
40
+ if (c.key === 'version')
41
+ return 'v' + v.recordVersion;
42
+ if (c.key === 'evidence')
43
+ return v.refs.map(i => i.name + ' v' + i.version).join(';');
44
+ if (c.key === 'handledBy')
45
+ return v.decision?.actor || '—';
46
+ if (c.key === 'handledAt')
47
+ return formatDate(v.decision?.at || '');
48
+ if (c.key.endsWith('At'))
49
+ return formatDate(v[c.key]);
50
+ return v[c.key];
51
+ }) }));
52
+ const table = useTable({ columns, pageParam: { current: 1, pageSize: 5, total: 0 } }), allColumns = new Map(table.columns.value.map(c => [c.key, c]));
53
+ watch(prefs.keys, keys => table.columns.value = keys.map(k => allColumns.get(k)).filter(Boolean), { immediate: true });
54
+ const filtered = computed(() => store.scene === 'empty' ? [] : store.rows.filter(r => (!route.query.task || r.task.id === route.query.task) && (scope.value === 'all' || (scope.value === 'pending' ? active.includes(r.status) : !active.includes(r.status))) && (resultState.value === 'all' || r.status === resultState.value) && (project.value === 'all' || r.task.binding.pbcId === project.value) && (kind.value === 'all' || r.review.kind === kind.value) && (severity.value === 'all' || (severity.value === 'none' ? !r.review.findings.length : r.review.findings.some(f => f.severity === severity.value))) && (r.task.name + r.task.code + r.review.code + r.review.title + r.review.findings.map(f => f.title).join('')).toLowerCase().includes(query.value.trim().toLowerCase())).sort((a, b) => (sort.value === 'newest' ? -1 : 1) * a.review.updatedAt.localeCompare(b.review.updatedAt) || a.id.localeCompare(b.id)));
55
+ watch(() => route.query.task, () => { scope.value = 'all'; table.setPageParam({ current: 1 }); });
56
+ watch([query, scope, project, kind, severity, resultState, sort], () => table.setPageParam({ current: 1 }));
57
+ watch([filtered, () => table.pageParam.current, () => table.pageParam.pageSize], () => { const size = table.pageParam.pageSize || 5; table.pageParam.current = Math.min(table.pageParam.current || 1, Math.max(1, Math.ceil(filtered.value.length / size))); table.pageParam.total = filtered.value.length; table.dataSource.value = filtered.value.slice(((table.pageParam.current || 1) - 1) * size, (table.pageParam.current || 1) * size); }, { immediate: true });
58
+ const selection = useListSelection(table.dataSource, computed(() => JSON.stringify([store.session.key, query.value, scope.value, project.value, kind.value, severity.value, resultState.value, sort.value, table.pageParam.current, table.pageParam.pageSize])), computed(() => true), r => r.review.code);
59
+ async function refresh() { selection.clear(); loading.value = true; await new Promise(r => setTimeout(r, 180)); store.scene = 'normal'; loading.value = false; }
60
+ function reset() { query.value = ''; project.value = 'all'; kind.value = 'all'; severity.value = 'all'; resultState.value = 'all'; }
61
+ return { computed, ref, watch, h, useRoute, useRouter, Alert, Button, Input, Select, Space, Tabs, Tag, Tooltip, Empty, ProTable, useTable, useReviews, stateLabels, stateColors, kindLabels, reviewUrl, formatDate, tenantLabel, useColumns, useListSelection, ListMore, ColumnSettings, store, router, route, query, scope, project, kind, severity, resultState, sort, loading, active, pending, prefs, url, more, action, render, columns, table, allColumns, filtered, selection, refresh, reset };
62
+ } });
@@ -0,0 +1,97 @@
1
+ import { can } from "../shared/policy.js";
2
+ import { approveTask, artifact, enter, latestArtifact, taskEvent } from "../tasks/domain.js";
3
+ import { reviewsForTask, reviewStatus, captureDesign, actionReason, sameRequest, fingerprint, actionPermission } from "./model.js";
4
+ export function decideReview(t, id, actor, p) {
5
+ const original = reviewsForTask(t).find(r => r.id === id);
6
+ if (!original)
7
+ throw Error('评审记录不存在或已不可访问。');
8
+ if (!can(actor, 'task:view', t.tenantId, t.binding.pbcId) || !can(actor, 'artifact:view', t.tenantId, t.binding.pbcId))
9
+ throw Error('没有此任务与产物的查看权限。');
10
+ if (!can(actor, actionPermission[p.action], t.tenantId, t.binding.pbcId))
11
+ throw Error('当前没有此操作权限。');
12
+ const replay = sameRequest(t, id, p);
13
+ if (replay)
14
+ return replay;
15
+ const reason = actionReason(t, original, actor, p.action);
16
+ if (reason)
17
+ throw Error(reason);
18
+ if (!p.requestId)
19
+ throw Error('缺少提交编号。');
20
+ if (!p.note.trim() || p.note.length > 1000)
21
+ throw Error('请填写 1–1000 字的处理说明。');
22
+ if (p.action === 'confirm' && !p.checked)
23
+ throw Error('请先核对当前版本及证据。');
24
+ if (p.action === 'edit' && (!p.content?.trim() || p.content.length > 20000))
25
+ throw Error('请填写设计修改内容,不超过 20000 字。');
26
+ if (p.action === 'replan' && (!p.impact?.trim() || p.impact.length > 2000))
27
+ throw Error('请填写重新规划的影响说明,不超过 2000 字。');
28
+ if (p.action === 'edit' && p.content.trim() === (latestArtifact(t, 'design')?.content || '设计建议(模拟)\n依据规格 v' + t.binding.spec.number + '\n' + t.binding.spec.content.requirements).trim())
29
+ throw Error('设计内容没有变化,请修改后再保存。');
30
+ t.reviews = reviewsForTask(t);
31
+ const r = t.reviews.find(r => r.id === id), at = new Date().toISOString();
32
+ const decision = { requestId: p.requestId, action: p.action, actorId: actor.id, actor: actor.name, at, note: p.note.trim(), impact: p.impact?.trim() || '', fingerprint: fingerprint(p) };
33
+ if (p.action === 'confirm') {
34
+ if (r.kind === 'prototype')
35
+ approveTask(t, actor.name, r.refs.find(i => i.kind === 'prototype').version, p.note);
36
+ else if (r.kind === 'design') {
37
+ t.approvedDesignVersion = r.refs.find(i => i.kind === 'design').version;
38
+ t.reviewApproved = true;
39
+ delete t.pendingDesignReview;
40
+ const n = t.binding.flow.body.nodes.find(n => ['agent', 'loop'].includes(n.kind));
41
+ enter(t, n.id);
42
+ t.reason = '设计 v' + t.approvedDesignVersion + ' 已确认,继续实现;随后重新执行质量检查与独立验证。';
43
+ }
44
+ else {
45
+ t.reason = '当前版本质量已确认,等待后续生产发布人工授权;尚未发布。';
46
+ }
47
+ }
48
+ else {
49
+ const build = t.binding.flow.body.nodes.find(n => ['agent', 'loop'].includes(n.kind));
50
+ const prior = latestArtifact(t, 'design')?.content || '设计建议(模拟)\n依据规格 v' + t.binding.spec.number + '\n' + t.binding.spec.content.requirements;
51
+ const content = p.action === 'edit' ? p.content : prior + '\n\n重新规划意见:' + p.note + '\n影响与调整范围:' + p.impact + '\n\n以上为待复核设计建议,尚未重新实现或验证。';
52
+ if (p.action === 'edit' && content.trim() === prior.trim())
53
+ throw Error('设计内容没有变化,请修改后再保存。');
54
+ t.reworks++;
55
+ t.checksPassed = false;
56
+ t.reviewApproved = false;
57
+ delete t.approvedDesignVersion;
58
+ const reset = (id, seen = new Set()) => { if (seen.has(id))
59
+ return; seen.add(id); const s = t.stages.find(s => s.nodeId === id); s.state = 'pending'; s.detail = '设计变更后待重新执行'; delete s.finishedAt; t.binding.flow.body.edges.filter(e => e.from === id).forEach(e => reset(e.to, seen)); };
60
+ reset(build.id);
61
+ t.currentId = build.id;
62
+ artifact(t, 'design', '实现设计说明', content, 'info', actor.name);
63
+ const next = captureDesign(t, actor.name);
64
+ t.reviews.push(next);
65
+ t.pendingDesignReview = next.id;
66
+ t.status = 'waiting';
67
+ t.reason = '设计 v' + latestArtifact(t, 'design').number + ' 已保存,等待本版复核及确认。';
68
+ t.stages.find(s => s.nodeId === build.id).state = 'active';
69
+ t.stages.find(s => s.nodeId === build.id).detail = t.reason;
70
+ decision.nextReviewId = next.id;
71
+ decision.newVersion = latestArtifact(t, 'design').number;
72
+ }
73
+ r.decision = decision;
74
+ r.updatedBy = actor.name;
75
+ r.updatedAt = at;
76
+ r.recordVersion++;
77
+ taskEvent(t, actor.name, { confirm: '确认评审', edit: '修改评审设计', replan: '重新规划交付' }[p.action], r.code + ' / ' + r.refs.map(x => x.name + ' v' + x.version).join('、') + ':' + p.note);
78
+ return decision;
79
+ }
80
+ export function validateDesign(t, id, outcome) {
81
+ const rows = reviewsForTask(t), r = rows.find(r => r.id === id);
82
+ if (!r || r.kind !== 'design' || t.pendingDesignReview !== id || !['checking', 'blocked'].includes(reviewStatus(t, r)))
83
+ throw Error('当前设计无需或不能接收新的复核结果。');
84
+ const verifier = t.binding.flow.body.nodes.find(n => n.kind === 'verify');
85
+ if (!verifier || t.binding.flow.body.nodes.some(n => ['agent', 'loop'].includes(n.kind) && n.agentId === verifier.agentId))
86
+ throw Error('缺少与实现职责分离的复核者。');
87
+ t.reviews = rows;
88
+ r.verifier = (t.binding.agents.find(a => a.config.id === verifier.agentId)?.config.name || '独立复核 Agent') + '(模拟)';
89
+ r.verificationAt = new Date().toISOString();
90
+ r.checks = r.checks.map(c => ({ ...c, status: outcome, detail: outcome === 'pass' ? '本次模拟复核对照设计 v' + r.refs.find(x => x.kind === 'design').version + ' 与固定规格;未运行真实服务。' : '模拟复核仍发现设计约束未覆盖,请修改或带意见重新规划。' }));
91
+ r.updatedBy = r.verifier;
92
+ r.updatedAt = r.verificationAt;
93
+ r.recordVersion++;
94
+ artifact(t, 'review', '设计复核记录', r.checks.map(c => c.name + ':' + c.detail).join('\n'), outcome, r.verifier);
95
+ t.reason = outcome === 'pass' ? '本版设计复核通过,等待获授权的人确认。' : '设计复核发现问题,尚不能确认。';
96
+ taskEvent(t, r.verifier, '接收设计复核结果', r.code + ':' + outcome + ';原型模拟');
97
+ }
@@ -0,0 +1,147 @@
1
+ import { can } from "../shared/policy.js";
2
+ import { clone, currentNode, latestArtifact } from "../tasks/domain.js";
3
+ export const kindLabels = { prototype: '交互原型确认', quality: '质量与交付评审', design: '设计修订确认' };
4
+ export const stateLabels = { pending: '待人工确认', checking: '待重新验证', blocked: '问题待处理', suspended: '任务已暂停', approved: '已确认', edited: '已修改', replanned: '已重新规划', superseded: '版本已更新', automatic: '机器检查已通过' };
5
+ export const stateColors = { pending: 'orange', checking: 'blue', blocked: 'red', suspended: 'default', approved: 'green', edited: 'blue', replanned: 'purple', superseded: 'default', automatic: 'cyan' };
6
+ export const dimensions = [{ id: 'SEC', label: '安全' }, { id: 'ROB', label: '逻辑健壮性' }, { id: 'ARC', label: '架构与数据' }, { id: 'CON', label: '框架规范' }, { id: 'PRF', label: '性能' }, { id: 'QLT', label: '代码质量' }];
7
+ export const actionPermission = { confirm: 'workflow:approve', edit: 'review:edit', replan: 'review:replan' };
8
+ export const canReadReview = (actor, t) => !t.isDeleted && can(actor, 'task:view', t.tenantId, t.binding.pbcId) && can(actor, 'artifact:view', t.tenantId, t.binding.pbcId);
9
+ export function evidenceVersion(t, ref) { return t.artifacts.find(a => a.id === ref.id)?.versions.find(v => v.number === ref.version); }
10
+ export function refsOf(t, kinds) { return t.artifacts.filter(a => a.kind !== 'review' && (!kinds || kinds.includes(a.kind)) && a.versions.length).map(a => ({ id: a.id, name: a.name, kind: a.kind, version: a.versions.at(-1).number })); }
11
+ function base(t, kind, refs, at, by) {
12
+ const key = refs.map(r => r.id + '-' + r.version).join('_'), id = kind + '-' + t.reworks + '-' + key;
13
+ return { id, code: 'REV-' + t.code.replace('DEL-', '') + '-' + (kind === 'prototype' ? 'P' : kind === 'quality' ? 'Q' : 'D') + '-' + (refs.find(r => r.kind === (kind === 'quality' ? 'code' : kind === 'design' ? 'design' : 'prototype'))?.version || 1) + '-' + t.reworks, taskId: t.id, kind, title: kindLabels[kind], stageId: t.currentId, iteration: t.reworks, refs: clone(refs), checks: [], findings: [], verifier: '待复核', createdById: t.createdById, createdBy: by, createdAt: at, createdDept: t.createdDept, updatedBy: by, updatedAt: at, tenantId: t.tenantId, recordVersion: 1, isDeleted: false, humanRequired: true, policyReason: kind === 'prototype' ? '绑定流程要求人工确认交互原型' : kind === 'design' ? '设计内容已改变,复核后确认本版,再恢复实现' : '当前交付样例保留人工质量确认;生产发布另行授权', grade: t.reviewPolicy?.grade };
14
+ }
15
+ function prototypeRecord(t) {
16
+ const v = latestArtifact(t, 'prototype');
17
+ if (!v)
18
+ return;
19
+ const r = base(t, 'prototype', refsOf(t, ['spec', 'prototype']), v.at, v.by);
20
+ r.iteration = 0;
21
+ r.id = 'prototype-' + v.number;
22
+ r.stageId = t.binding.flow.body.nodes.find(n => n.kind === 'human' && n.gate !== 'production')?.id || v.stageId;
23
+ r.checks = [{ id: 'input', name: '绑定规格与原型已提供', status: 'pass', required: true, detail: '阅读以下固定版本后,由获授权的人核对确认;此处没有实际启动研发 Agent。' }];
24
+ const e = t.events.find(e => e.action === '确认交互原型' && e.detail.includes('原型 v' + v.number + ':'));
25
+ if (e)
26
+ r.decision = { requestId: e.id, action: 'confirm', actorId: 'legacy', actor: e.actor, at: e.at, note: e.detail, impact: '', fingerprint: 'legacy' };
27
+ return r;
28
+ }
29
+ export function captureQuality(t) {
30
+ const test = latestArtifact(t, 'test'), verify = latestArtifact(t, 'verify'), code = latestArtifact(t, 'code');
31
+ if (!test && !verify)
32
+ return;
33
+ const r = base(t, 'quality', refsOf(t), verify?.at || test.at, verify?.by || test.by);
34
+ const current = (v) => !!v && v.iteration === t.reworks && !!code && v.inputs.some(i => i.id === 'code' && i.version === code.number);
35
+ const testOk = current(test), verifyOk = current(verify);
36
+ const verifier = t.binding.flow.body.nodes.find(n => n.kind === 'verify');
37
+ const independent = !!verifier && !t.binding.flow.body.nodes.some(n => ['agent', 'loop'].includes(n.kind) && n.agentId === verifier.agentId);
38
+ r.verifier = verifyOk ? verify.by : '等待独立验证';
39
+ r.verificationAt = verifyOk ? verify.at : undefined;
40
+ r.checks = [{ id: 'quality', name: '质量检查汇总', status: testOk ? test.result === 'pass' ? 'pass' : 'fail' : 'pending', required: true, detail: testOk ? test.content : '本轮代码尚无有效质量检查报告。' },
41
+ { id: 'independent', name: '独立验证', status: verifyOk ? verify.result === 'pass' ? 'pass' : 'fail' : 'pending', required: true, detail: verifyOk ? verify.content : '须在当前代码、设计与测试版本上重新执行独立验证。' },
42
+ { id: 'separation', name: '实现与验证职责分离', status: independent ? 'pass' : 'fail', required: true, detail: independent ? '绑定流程使用不同实现与验证 Agent;原型没有启动真实隔离上下文。' : '验证者与实现者重合或缺失,禁止以自我验证通过。' },
43
+ ...['构建', '功能测试', '接口契约', 'evals'].map((name, i) => ({ id: 'item-' + i, name, status: 'unavailable', required: false, detail: '历史任务样例只提供汇总报告,未提供该分项独立证据;不能解读为本项已经通过。' }))];
44
+ if (verifyOk && verify.result === 'fail')
45
+ r.findings.push({ id: 'ROB-AC003.2', dimension: 'ROB', severity: 'high', title: '重复确认可能重复派单', detail: verify.content, artifactId: 'code', version: code.number });
46
+ else if (testOk && test.result === 'fail')
47
+ r.findings.push({ id: 'ROB-CHECK-01', dimension: 'ROB', severity: 'high', title: '质量检查执行未通过', detail: test.content, artifactId: 'test', version: test.number });
48
+ if (t.reviewPolicy) {
49
+ r.humanRequired = t.reviewPolicy.humanQuality;
50
+ r.policyReason = t.reviewPolicy.reason;
51
+ if (t.reviewPolicy.veto)
52
+ r.checks.push({ id: 'veto', name: '敏感领域停点', status: 'fail', required: true, detail: '该任务登记了不可自动放行的敏感停点;请回到任务处理,不能通过确认绕过。' });
53
+ }
54
+ return r;
55
+ }
56
+ export function captureDesign(t, by) {
57
+ const v = latestArtifact(t, 'design'), r = base(t, 'design', refsOf(t, ['spec', 'prototype', 'design']), v.at, by);
58
+ r.id = 'design-' + v.number + '-' + t.reworks;
59
+ r.checks = [{ id: 'source', name: '来源与版本一致性', status: 'pending', required: true, detail: '新设计需对照本任务绑定的规格及原型。' }, { id: 'decision', name: '设计修改复核', status: 'pending', required: true, detail: '保存修改不是复核通过;等待针对本版本的检查结果。' }];
60
+ return r;
61
+ }
62
+ export function reviewsForTask(t) {
63
+ if (t.isDeleted || !t.startedAt)
64
+ return [];
65
+ const rows = clone(t.reviews || []);
66
+ for (const r of [prototypeRecord(t), captureQuality(t)])
67
+ if (r && !rows.some(x => x.id === r.id))
68
+ rows.push(r);
69
+ return rows.sort((a, b) => b.createdAt.localeCompare(a.createdAt) || a.id.localeCompare(b.id));
70
+ }
71
+ export function reviewStatus(t, r) {
72
+ if (r.decision)
73
+ return { confirm: 'approved', edit: 'edited', replan: 'replanned' }[r.decision.action];
74
+ if (r.superseded || r.refs.some(ref => !evidenceVersion(t, ref)))
75
+ return 'superseded';
76
+ if (r.kind === 'prototype') {
77
+ if (latestArtifact(t, 'prototype')?.number !== r.refs.find(i => i.kind === 'prototype')?.version)
78
+ return 'superseded';
79
+ if (t.prototypeApproved)
80
+ return 'superseded';
81
+ }
82
+ else if (r.kind === 'design') {
83
+ if (t.pendingDesignReview !== r.id)
84
+ return 'superseded';
85
+ }
86
+ else if (t.pendingDesignReview || r.id !== captureQuality(t)?.id || r.iteration !== t.reworks || r.refs.some(ref => latestArtifact(t, ref.kind)?.number !== ref.version))
87
+ return 'superseded';
88
+ if (['paused', 'manual'].includes(t.status))
89
+ return 'suspended';
90
+ if (r.checks.some(c => c.required && c.status === 'fail'))
91
+ return 'blocked';
92
+ if (r.checks.some(c => c.required && c.status !== 'pass'))
93
+ return 'checking';
94
+ if (r.kind === 'quality' && !r.humanRequired)
95
+ return 'automatic';
96
+ if (r.kind === 'prototype' && !(t.status === 'waiting' && currentNode(t)?.gate !== 'production'))
97
+ return 'checking';
98
+ return 'pending';
99
+ }
100
+ export const actionableReview = (t) => reviewsForTask(t).find(r => ['pending', 'blocked', 'checking', 'suspended'].includes(reviewStatus(t, r)) && ((r.kind === 'design' && t.pendingDesignReview === r.id) || !t.pendingDesignReview));
101
+ export function reviewBudget(t) { const n = t.binding.flow.body.nodes.find(n => ['agent', 'loop'].includes(n.kind)); return n?.kind === 'loop' ? Math.min(t.retryLimit, n.limit || 1) : t.retryLimit; }
102
+ export function actionReason(t, r, actor, action) {
103
+ if (!canReadReview(actor, t))
104
+ return '没有此任务与产物的查看权限,或超出授权范围。';
105
+ if (!can(actor, actionPermission[action], t.tenantId, t.binding.pbcId))
106
+ return action === 'confirm' ? '缺少此 PBC 的交付人工确认权限。' : '缺少此 PBC 的' + (action === 'edit' ? '修改评审设计' : '重新规划交付') + '权限,请由权限管理员配置。';
107
+ const status = reviewStatus(t, r);
108
+ if (['approved', 'edited', 'replanned', 'automatic'].includes(status))
109
+ return '该记录已处理,请查看结果或当前版本。';
110
+ if (status === 'superseded')
111
+ return '依据版本已变化,请打开当前评审;历史记录不能继续提交。';
112
+ if (status === 'suspended')
113
+ return '任务已暂停或人工接管,请先恢复到原阶段。';
114
+ if (action === 'confirm' && status !== 'pending')
115
+ return r.checks.find(c => c.required && c.status !== 'pass')?.detail || '当前阶段尚未具备确认条件。';
116
+ if (action !== 'confirm' && r.kind === 'prototype')
117
+ return '此记录用于确认交互原型;设计修改与重新规划在原型确认后的交付评审中处理。';
118
+ if (action !== 'confirm' && t.reworks >= reviewBudget(t))
119
+ return '已达到本原型有限处理次数,请进入任务人工接管;接管不等于验证通过。';
120
+ if (action !== 'confirm' && !t.binding.flow.body.nodes.some(n => ['agent', 'loop'].includes(n.kind)))
121
+ return '绑定流程没有可返回的实现阶段。';
122
+ return '';
123
+ }
124
+ export const fingerprint = (p) => JSON.stringify([p.action, p.note.trim(), p.content || '', p.impact?.trim() || '']);
125
+ export function sameRequest(t, id, p) { const r = t.reviews?.find(r => r.decision?.requestId === p.requestId); if (r) {
126
+ if (r.id !== id || r.decision.fingerprint !== fingerprint(p))
127
+ throw Error('同一提交编号不能用于不同记录或内容,请先核实原结果。');
128
+ return r.decision;
129
+ } }
130
+ export function retainReviews(before, after) {
131
+ const previous = before ? reviewsForTask(before) : [];
132
+ const rows = after.reviews || [];
133
+ for (const r of previous)
134
+ if (!rows.some(x => x.id === r.id))
135
+ rows.push(r);
136
+ after.reviews = rows;
137
+ const derived = prototypeRecord(after);
138
+ if (derived?.decision) {
139
+ const old = rows.find(r => r.id === derived.id);
140
+ if (old && !old.decision)
141
+ old.decision = derived.decision;
142
+ }
143
+ for (const r of reviewsForTask(after))
144
+ if (!rows.some(x => x.id === r.id))
145
+ rows.push(r);
146
+ }
147
+ export const reviewUrl = (t, r) => '/reviews/' + t + '/' + encodeURIComponent(r);
@@ -0,0 +1,13 @@
1
+ import { computed, ref } from '../../runtime/state.js';
2
+ import { defineStore } from "../../runtime/state.js";
3
+ import { useTasks } from "../tasks/store.js";
4
+ import { useSession } from "../shared/session.js";
5
+ import { usePbcs } from "../pbc/store.js";
6
+ import { reviewsForTask, reviewStatus, canReadReview, actionReason } from "./model.js";
7
+ export const useReviews = defineStore('reviews', () => {
8
+ const tasks = useTasks(), session = useSession(), pbcs = usePbcs(), scene = ref('normal');
9
+ const rows = computed(() => session.state !== 'active' ? [] : tasks.records.filter(t => canReadReview(session.actor, t)).flatMap(t => reviewsForTask(t).map(review => ({ id: t.id + ':' + review.id, task: t, review, status: reviewStatus(t, review), project: session.can('pbc:view', t.tenantId, t.binding.pbcId) ? pbcs.items.find(p => p.id === t.binding.pbcId)?.name || t.binding.project : 'PBC详情未授权' }))).sort((a, b) => b.review.updatedAt.localeCompare(a.review.updatedAt) || a.id.localeCompare(b.id)));
10
+ const find = (taskId, id) => rows.value.find(r => r.task.id === taskId && r.review.id === id);
11
+ const reason = (r, action) => actionReason(r.task, r.review, session.actor, action);
12
+ return { rows, find, reason, scene, tasks, session, notice: computed(() => tasks.notice) };
13
+ });
@@ -0,0 +1,2 @@
1
+ <!-- 来源:src/shared/ColumnSettings.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
2
+ <template data-component="Button" aria-label="列设置" data-on-click="(open = true)"><template data-component="SettingOutlined"></template>列设置</template><template data-component="Drawer" data-bind-open="(open)" title="列设置" data-bind-size="(400)" data-on-close="(open = false)"><p class="muted">选择显示字段并调整顺序。设置按当前用户、范围和页面分别保存。</p><div data-each="(key, index) in (preferences.order.value)" data-bind-key="(key)" class="column-choice"><template data-component="Checkbox" data-bind-checked="(preferences.visible.value.includes(key))" data-bind-disabled="(preferences.choices.find(c =&gt; c.key === key)?.locked)" data-on-change="((e) =&gt; preferences.toggle(key, e.target.checked))">{{ (preferences.choices.find(c =&gt; c.key === key)?.label) }}</template><template data-component="Space" data-bind-size="(0)"><template data-component="Button" type="text" data-bind-aria-label="('上移' + preferences.choices.find(c =&gt; c.key === key)?.label)" data-bind-disabled="(index &lt;= 1 || preferences.choices.find(c =&gt; c.key === key)?.locked)" data-on-click="(preferences.move(key, -1))"><template data-component="ArrowUpOutlined"></template></template><template data-component="Button" type="text" data-bind-aria-label="('下移' + preferences.choices.find(c =&gt; c.key === key)?.label)" data-bind-disabled="(index &gt;= preferences.order.value.length - 2 || preferences.choices.find(c =&gt; c.key === key)?.locked)" data-on-click="(preferences.move(key, 1))"><template data-component="ArrowDownOutlined"></template></template></template></div><template data-component="Alert" data-if="(preferences.error.value)" type="warning" data-bind-title="(preferences.error.value)"></template><template data-slot="footer"><div class="drawer-footer"><template data-component="Button" data-on-click="(preferences.reset)">恢复默认</template><template data-component="Button" type="primary" data-on-click="(open = false)">完成</template></div></template></template>
@@ -0,0 +1,9 @@
1
+ import { ref } from '../../runtime/state.js';
2
+ import { Alert, Button, Checkbox, Drawer, Space } from "../../runtime/widgets.js";
3
+ import { SettingOutlined, ArrowUpOutlined, ArrowDownOutlined } from "../../runtime/icons.js";
4
+ import { createComponent } from '../../runtime/dom.js';
5
+ export default createComponent({ name: 'ColumnSettings', propKeys: ["preferences"], template: new URL('./ColumnSettings.html', import.meta.url).href, setup(__props, __emit) {
6
+ __props;
7
+ const open = ref(false);
8
+ return { ref, Alert, Button, Checkbox, Drawer, Space, SettingOutlined, ArrowUpOutlined, ArrowDownOutlined, open };
9
+ } });
@@ -0,0 +1,2 @@
1
+ <!-- 来源:src/shared/ListBatchBar.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
2
+ <div class="list-batch-bar"><template data-component="Tooltip" data-bind-title="(!allowed ? '当前身份没有删除权限' : !count ? '请先勾选记录' : '')"><span><template data-component="Button" danger="" aria-label="批量删除" data-bind-disabled="(!allowed || !count)" data-on-click="($emit('remove'))"><template data-component="DeleteOutlined"></template>批量删除</template></span></template><span class="selection-count" role="status">已选 <strong>{{ (count) }}</strong> 项</span><template data-component="Button" data-if="(count)" type="text" class="link-button" data-on-click="($emit('clear'))">清空选择</template><span class="muted selection-hint">仅选择当前页</span><span class="mobile-table-hint muted">左右滑动表格,查看全部字段与操作</span></div>
@@ -0,0 +1,8 @@
1
+ import { Button, Tooltip } from "../../runtime/widgets.js";
2
+ import { DeleteOutlined } from "../../runtime/icons.js";
3
+ import { createComponent } from '../../runtime/dom.js';
4
+ export default createComponent({ name: 'ListBatchBar', propKeys: ["count", "allowed"], template: new URL('./ListBatchBar.html', import.meta.url).href, setup(__props, __emit) {
5
+ __props;
6
+ __emit;
7
+ return { Button, Tooltip, DeleteOutlined };
8
+ } });
@@ -0,0 +1,2 @@
1
+ <!-- 来源:src/shared/ListDeleteDialog.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
2
+ <template data-component="Modal" data-bind-open="(true)" data-bind-title="('删除' + label + '确认')" data-bind-width="(640)" data-bind-mask-closable="(false)" data-on-cancel="(!busy &amp;&amp; emit('close'))"><template data-component="Alert" show-icon="" data-bind-type="(blocked.length ? 'warning' : 'info')" data-bind-title="('已选 ' + targets.length + ' 项,可删除 ' + (targets.length - blocked.length) + ' 项,不可删除 ' + blocked.length + ' 项')" description="删除后从管理列表移除,保留记录与操作痕迹。请核对对象,本次提交将整批成功或整批不变。"></template><ul class="delete-preview" aria-label="删除对象"><li data-each="item in (checked)" data-bind-key="(item.target.id)"><div><strong>{{ (item.target.name) }}</strong><template data-component="Tag" data-bind-color="(item.reason ? 'orange' : 'green')">{{ (item.reason ? '不可删除' : '可删除') }}</template></div><p data-if="(item.reason)">{{ (item.reason) }}</p></li></ul><template data-component="Alert" data-if="(error)" type="error" show-icon="" data-bind-title="(error)" description="本次未删除任何记录。选择已保留;版本冲突时请关闭后重新核对。"></template><template data-slot="footer"><div class="delete-footer"><template data-component="Button" data-if="(blocked.length)" data-bind-disabled="(blocked.length === targets.length)" data-on-click="(keepEligible)">移除不可删除项</template><span class="footer-spacer"></span><template data-component="Button" data-bind-disabled="(busy)" data-on-click="(emit('close'))">取消</template><template data-component="Button" danger="" type="primary" data-bind-loading="(busy)" data-bind-disabled="(!!blocked.length || !targets.length)" data-on-click="(remove)">确认删除 {{ (targets.length) }} 项</template></div></template></template>
@@ -0,0 +1,37 @@
1
+ import { computed, ref } from '../../runtime/state.js';
2
+ import { Alert, Button, Modal, Tag, message } from "../../runtime/widgets.js";
3
+ import { createComponent } from '../../runtime/dom.js';
4
+ export default createComponent({ name: 'ListDeleteDialog', propKeys: ["targets", "label", "check", "submit"], template: new URL('./ListDeleteDialog.html', import.meta.url).href, setup(__props, __emit) {
5
+ const props = __props;
6
+ const emit = __emit;
7
+ const busy = ref(false), error = ref('');
8
+ const checked = computed(() => props.targets.map(target => {
9
+ try {
10
+ props.check(target);
11
+ return { target, reason: '' };
12
+ }
13
+ catch (e) {
14
+ return { target, reason: e.message };
15
+ }
16
+ }));
17
+ const blocked = computed(() => checked.value.filter(item => item.reason));
18
+ function keepEligible() { emit('update:targets', checked.value.filter(item => !item.reason).map(item => item.target)); error.value = ''; }
19
+ async function remove() {
20
+ if (busy.value || blocked.value.length || !props.targets.length)
21
+ return;
22
+ busy.value = true;
23
+ error.value = '';
24
+ try {
25
+ props.submit(props.targets);
26
+ message.success('已删除 ' + props.targets.length + ' 项' + props.label);
27
+ emit('deleted');
28
+ }
29
+ catch (e) {
30
+ error.value = e.message;
31
+ }
32
+ finally {
33
+ busy.value = false;
34
+ }
35
+ }
36
+ return { computed, ref, Alert, Button, Modal, Tag, message, props, emit, busy, error, checked, blocked, keepEligible, remove };
37
+ } });
@@ -0,0 +1,2 @@
1
+ <!-- 来源:src/shared/ListMore.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
2
+ <template data-component="Dropdown" data-bind-menu="({ items, onClick: ({ key }) =&gt; emit('action', key) })" data-bind-trigger="(['click'])"><template data-component="Button" type="text" class="link-button" data-bind-aria-label="(name + '更多操作')">更多<template data-component="DownOutlined"></template></template></template>
@@ -0,0 +1,8 @@
1
+ import { Dropdown, Button } from "../../runtime/widgets.js";
2
+ import { DownOutlined } from "../../runtime/icons.js";
3
+ import { createComponent } from '../../runtime/dom.js';
4
+ export default createComponent({ name: 'ListMore', propKeys: ["name", "items"], template: new URL('./ListMore.html', import.meta.url).href, setup(__props, __emit) {
5
+ __props;
6
+ const emit = __emit;
7
+ return { Dropdown, Button, DownOutlined, emit };
8
+ } });
@@ -0,0 +1,2 @@
1
+ <!-- 来源:src/shared/RecordMetadata.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
2
+ <section data-bind-class="(compact ? 'metadata-compact' : 'drawer-section')"><h2>基础信息</h2><template data-component="Descriptions" data-bind-items="(items)" data-bind-column="(compact ? 1 : { xs: 1, sm: 2, md: 2, lg: 2, xl: 2, xxl: 2 })" bordered="" size="small"></template><p class="muted metadata-note">创建与修改信息由系统记录,列设置只影响列表展示。</p></section>
@@ -0,0 +1,17 @@
1
+ import { computed } from '../../runtime/state.js';
2
+ import { Descriptions } from "../../runtime/widgets.js";
3
+ import { formatDate, tenantLabel } from "./policy.js";
4
+ import { createComponent } from '../../runtime/dom.js';
5
+ export default createComponent({ name: 'RecordMetadata', propKeys: ["record", "compact"], template: new URL('./RecordMetadata.html', import.meta.url).href, setup(__props, __emit) {
6
+ const props = __props;
7
+ const items = computed(() => [
8
+ { key: 'scope', label: '所属范围', content: tenantLabel(props.record.tenantId) },
9
+ { key: 'creator', label: '创建人', content: props.record.createdBy },
10
+ { key: 'created', label: '创建时间', content: formatDate(props.record.createdAt) },
11
+ { key: 'department', label: '创建部门', content: props.record.createdDept },
12
+ { key: 'modifier', label: '修改人', content: props.record.updatedBy },
13
+ { key: 'updated', label: '修改时间', content: formatDate(props.record.updatedAt) },
14
+ { key: 'id', label: '记录标识', content: props.record.id, span: 'filled' },
15
+ ]);
16
+ return { computed, Descriptions, formatDate, tenantLabel, props, items };
17
+ } });
@@ -0,0 +1,32 @@
1
+ import { computed, ref, watch } from '../../runtime/state.js';
2
+ import { useSession } from "./session.js";
3
+ export function useColumns(page, choices) {
4
+ const session = useSession(), order = ref([]), visible = ref([]), error = ref('');
5
+ const key = computed(() => `i3-prototype-antdv-v010-columns:${session.key}:${page}:1`);
6
+ const defaults = () => ({ order: choices.map(c => c.key), visible: choices.filter(c => c.defaultVisible || c.locked).map(c => c.key) });
7
+ function restore() {
8
+ let value = defaults();
9
+ try {
10
+ const saved = JSON.parse(localStorage.getItem(key.value) || 'null');
11
+ if (Array.isArray(saved?.order) && Array.isArray(saved?.visible))
12
+ value = saved;
13
+ }
14
+ catch { /* Use schema defaults. */ }
15
+ order.value = [...new Set([...value.order.filter((k) => choices.some(c => c.key === k)), ...choices.map(c => c.key)])];
16
+ visible.value = [...new Set([...value.visible.filter((k) => choices.some(c => c.key === k)), ...choices.filter(c => c.locked).map(c => c.key)])];
17
+ }
18
+ function persist() { try {
19
+ localStorage.setItem(key.value, JSON.stringify({ order: order.value, visible: visible.value }));
20
+ error.value = '';
21
+ }
22
+ catch {
23
+ error.value = '浏览器无法保存列偏好,本次设置仍可使用。';
24
+ } }
25
+ function toggle(k, checked) { if (choices.find(c => c.key === k)?.locked)
26
+ return; visible.value = checked ? [...new Set([...visible.value, k])] : visible.value.filter(v => v !== k); persist(); }
27
+ function move(k, direction) { const a = [...order.value], i = a.indexOf(k), j = i + direction; if (i < 0 || j < 0 || j >= a.length || choices.find(c => c.key === k)?.locked || choices.find(c => c.key === a[j])?.locked)
28
+ return; [a[i], a[j]] = [a[j], a[i]]; order.value = a; persist(); }
29
+ function reset() { const d = defaults(); order.value = d.order; visible.value = d.visible; persist(); }
30
+ watch(key, restore, { immediate: true });
31
+ return { choices, order, visible, error, toggle, move, reset, keys: computed(() => order.value.filter(k => visible.value.includes(k))) };
32
+ }
@@ -0,0 +1,49 @@
1
+ import { can } from "./policy.js";
2
+ import { lastVersion, confirmationBusy, unresolved } from "../intents/domain.js";
3
+ import { currentVersion, pendingDecisions, specBusy } from "../specs/domain.js";
4
+ export function affiliation(i, jobs, catalog, access) {
5
+ const j = jobs.find(j => j.intentId === i.id && j.tenantId === i.tenantId);
6
+ if (!j)
7
+ return { label: i.context.startsWith('拟归属') ? i.context : '尚未归属 PBC', key: i.context.startsWith('拟归属') ? i.context : 'unassigned', state: 'unassigned', path: '' };
8
+ if (!access('pbc:view', j.tenantId, j.pbc.id))
9
+ return { label: '已有归属记录 · 无权查看', key: 'restricted', state: 'restricted', path: '' };
10
+ const p = catalog.find(p => p.id === j.pbc.id && p.tenantId === j.tenantId && !p.isDeleted);
11
+ const prefix = j.status === 'done' ? '已归属' : j.status === 'unknown' ? '归属待核实' : ['failed', 'paused'].includes(j.status) ? '归属需处理' : '归属处理中';
12
+ return { label: prefix + ':' + (p?.name || j.pbc.name), key: j.status === 'done' ? 'pbc:' + j.pbc.id : 'pending:' + j.pbc.id, state: j.status, path: '/intents/' + i.id + '/pbc' };
13
+ }
14
+ // A presentation guide only. Existing domain commands still enforce every write condition.
15
+ export function deliveryGuide(i, s, jobs, access) {
16
+ const root = '/intents/' + i.id, j = jobs.find(j => j.intentId === i.id && j.tenantId === i.tenantId);
17
+ const result = (stage, label, reason, path, action, allowed = true, create = false) => ({ stage, label, reason, path, action, allowed, create });
18
+ if (j) {
19
+ if (!access('pbc:view', j.tenantId, j.pbc.id))
20
+ return result('pbc', '已有归属记录', '当前无权查看目标 PBC,请联系业务管理员核对授权。', root, '查看意图', false);
21
+ return j.status === 'done' ? result('done', '已完成归属', '已有归属结果,请查看原结果或继续交付。', root + '/pbc', '查看归属结果') :
22
+ result('pbc', j.status === 'unknown' ? '归属待核实' : j.status === 'running' ? '归属处理中' : '归属需处理', '已有归属请求;进入原请求核实或恢复,不能重复创建。', root + '/pbc', '查看原请求');
23
+ }
24
+ if (i.status === 'closed')
25
+ return result('done', '意图已关闭', '关闭记录只读保留。', root, '查看记录', false);
26
+ if (confirmationBusy(i))
27
+ return result('intent', '确认待核实', '先核实原意图确认请求。', root, '核实确认结果', access('intent:confirm', i.tenantId));
28
+ if (i.status !== 'confirmed' || !lastVersion(i)?.confirmedAt) {
29
+ const ready = i.status === 'ready', pending = unresolved(i.decisions).length;
30
+ const op = ready && !pending ? 'intent:confirm' : 'intent:edit', allowed = access(op, i.tenantId);
31
+ return result('intent', ready ? (pending ? '意图待决策' : '意图待确认') : '意图待补充', !allowed ? '缺少此意图的' + (op === 'intent:confirm' ? '确认' : '编辑') + '权限。' : pending ? '仍有 ' + pending + ' 项意图决策待处理。' : '先完成并确认当前意图版本。', root + (ready ? '' : '/workspace'), ready && !pending ? '核对意图' : '完善意图', allowed);
32
+ }
33
+ if (!access('spec:view', i.tenantId))
34
+ return result('spec', '规格权限不足', '当前没有此需求的规格查看权限。', root, '查看意图', false);
35
+ const v = s && currentVersion(s);
36
+ if (s && specBusy(s))
37
+ return result('spec', '规格处理中', '生成进行中或确认结果待核实,请进入原规格处理。', root + '/spec', '查看规格');
38
+ if (!v || v.source.version !== lastVersion(i).number) {
39
+ const allowed = access('spec:generate', i.tenantId);
40
+ return result('spec', v ? '规格来源已变化' : '尚未生成规格', allowed ? '需要根据最新已确认意图生成规格。' : '缺少此需求的规格生成权限。', root + '/spec', '完善规格', allowed);
41
+ }
42
+ if (!v.confirmedAt) {
43
+ const n = pendingDecisions(v).length, allowed = access(n ? 'spec:edit' : 'spec:confirm', i.tenantId);
44
+ return result('spec', n ? '规格待完善' : '规格待确认', !allowed ? '缺少此规格的' + (n ? '编辑' : '确认') + '权限。' : n ? '还有 ' + n + ' 项决策需要结论和理由;保存后再确认新版本。' : '核对规格内容并确认当前版本后,才能创建 PBC。', root + '/spec' + (n ? '' : '/review'), n ? '处理未决事项' : '核对规格', allowed);
45
+ }
46
+ const view = access('pbc:view', i.tenantId), create = view && access('pbc:create', i.tenantId), link = view && access('pbc:link', i.tenantId);
47
+ return result('pbc', create ? '可创建 PBC' : link ? '可关联已有 PBC' : 'PBC 权限不足', create ? '规格 v' + v.number + ' 已确认,尚未提交归属。' : link ? '当前可以关联已有 PBC;新建 PBC 还需要对应租户的创建权限。' : '需要当前租户的 PBC 查看与创建/关联权限;功能授权在权限管理中配置。', create ? root + '/pbc?create=1' : link ? root + '/pbc' : root + '/spec/review', create ? '继续创建向导' : link ? '关联已有 PBC' : '查看已确认规格', create || link, create);
48
+ }
49
+ export const actorAccess = (actor) => (a, t, p) => can(actor, a, t, p);
@@ -0,0 +1,12 @@
1
+ import { computed } from '../../runtime/state.js';
2
+ import { useSession } from "./session.js";
3
+ import { usePbcs } from "../pbc/store.js";
4
+ import { useSpecs } from "../specs/store.js";
5
+ import { useIntents } from "../intents/store.js";
6
+ import { affiliation, deliveryGuide } from "./deliveryGuide.js";
7
+ export function useDeliveryView() {
8
+ const session = useSession(), pbcs = usePbcs(), specs = useSpecs(), intents = useIntents();
9
+ const affiliationOf = (i) => affiliation(i, pbcs.jobs, pbcs.catalog, session.can);
10
+ const candidates = computed(() => intents.items.map(i => ({ id: i.id, title: i.title, code: i.code, tenantId: i.tenantId, guide: deliveryGuide(i, specs.get(i.id), pbcs.jobs, session.can), affiliation: affiliationOf(i) })));
11
+ return { affiliationOf, candidates };
12
+ }
@@ -0,0 +1,15 @@
1
+ export function assertBatch(records, targets, check) {
2
+ if (!targets.length)
3
+ throw new Error('请至少选择一条记录。');
4
+ if (new Set(targets.map(t => t.id)).size !== targets.length)
5
+ throw new Error('选择中包含重复记录,请重新选择。');
6
+ return targets.map(target => {
7
+ const record = records.find(r => r.id === target.id && !r.isDeleted);
8
+ if (!record)
9
+ throw new Error('记录已不存在或无权访问,请重新选择。');
10
+ check(record);
11
+ if (record.recordVersion !== target.recordVersion)
12
+ throw new Error('记录已被更新,请重新打开并核对最新内容。');
13
+ return record;
14
+ });
15
+ }