@givolt/i3-composer-agent 3.0.0 → 3.2.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 (490) hide show
  1. package/.agents/plugins/marketplace.json +1 -1
  2. package/.claude/commands/i3-sop.md +3 -3
  3. package/.claude/commands/i3-ui-demo.md +21 -0
  4. package/.claude-plugin/marketplace.json +1 -1
  5. package/.claude-plugin/plugin.json +1 -1
  6. package/.codex-plugin/plugin.json +2 -2
  7. package/.gemini/commands/i3-sop.toml +3 -3
  8. package/.gemini/commands/i3-ui-demo.toml +21 -0
  9. package/README.md +29 -32
  10. package/bin/i3-composer-agent.cjs +38 -44
  11. package/bin/install.cjs +15 -3
  12. package/bin/native-layout.cjs +2 -1
  13. package/bin/native-migration.cjs +19 -2
  14. package/bin/retired-sop-fingerprints.json +213 -0
  15. package/bin/wizard.cjs +7 -18
  16. package/commands/i3-sop.toml +3 -3
  17. package/commands/i3-ui-demo.toml +21 -0
  18. package/docs/codebuddy-setup.md +20 -23
  19. package/docs/codex-setup.md +2 -2
  20. package/docs/comparison.md +131 -0
  21. package/docs/developer-onboarding.md +143 -0
  22. package/docs/opencode-setup.md +1 -1
  23. package/docs/other-hosts.md +2 -2
  24. package/docs/skill-anatomy.md +211 -0
  25. package/docs/workbuddy-setup.md +7 -10
  26. package/evals/cases/i3-enterprise-sop.json +70 -32
  27. package/evals/cases/i3-ui-demo.json +98 -0
  28. package/evals/fixtures/i3-ui-demo/asset-management.md +25 -0
  29. package/evals/zh-CN/cases/i3-enterprise-sop.json +77 -31
  30. package/evals/zh-CN/cases/i3-ui-demo.json +103 -0
  31. package/hooks/PROTOTYPE.md +16 -8
  32. package/hooks/i3-prototype.cjs +4 -10
  33. package/hooks/manage.cjs +30 -31
  34. package/package.json +20 -5
  35. package/plugin.json +1 -1
  36. package/scripts/ui-demo-dependencies-test.js +228 -0
  37. package/scripts/ui-demo-mcp-test.js +95 -0
  38. package/scripts/ui-demo-test.js +170 -0
  39. package/scripts/ui-prototype-execution-runtime-test.js +1 -1
  40. package/scripts/ui-prototype-native-test.js +25 -3
  41. package/skills/i3-enterprise-sop/SKILL.md +151 -91
  42. package/{references/engineering-skeleton-resources → skills/i3-enterprise-sop/references/engineering-skeleton}/directory-standard.md +29 -15
  43. package/skills/i3-enterprise-sop/references/handoff.py +348 -0
  44. package/skills/i3-enterprise-sop/references/read_text.py +60 -0
  45. package/{references/enterprise-sop-resources/technical-baseline/baselines//344/274/201/344/270/232/345/272/224/347/224/250-/346/212/200/346/234/257/350/247/204/347/272/246_v0.0.2.md → skills/i3-enterprise-sop/references/technical-baseline/baselines/enterprise-application-technical-baseline-v0-0-4.md} +136 -51
  46. package/skills/i3-enterprise-sop/references/technical-baseline/readme.md +23 -0
  47. package/{references/enterprise-sop-resources/technical-baseline/templates/TECHNICAL-BASELINE.md → skills/i3-enterprise-sop/references/technical-baseline/templates/technical-baseline.md} +1 -1
  48. package/{references/enterprise-sop-resources/ad/templates/AD.md → skills/i3-enterprise-sop/references/templates/ad.md} +34 -27
  49. package/{references/enterprise-sop-resources/brd/templates/BRD.md → skills/i3-enterprise-sop/references/templates/brd.md} +21 -10
  50. package/{references/enterprise-sop-resources/prd/templates/PRD.md → skills/i3-enterprise-sop/references/templates/prd.md} +57 -24
  51. package/{references/enterprise-sop-resources/testcase/templates/TestCase.md → skills/i3-enterprise-sop/references/templates/testcase.md} +32 -22
  52. package/skills/i3-ui-demo/SKILL.md +234 -0
  53. package/skills/i3-ui-demo/assets/antdv-build/package-lock.json +3363 -0
  54. package/skills/i3-ui-demo/assets/antdv-build/package.json +28 -0
  55. package/skills/i3-ui-demo/assets/design-source.json +11 -0
  56. package/skills/i3-ui-demo/assets/host-targets.json +739 -0
  57. package/skills/i3-ui-demo/assets/official-files.json +76 -0
  58. package/skills/i3-ui-demo/assets/starter/index.html +11 -0
  59. package/skills/i3-ui-demo/assets/starter/package-lock.json +2299 -0
  60. package/skills/i3-ui-demo/assets/starter/package.json +28 -0
  61. package/skills/i3-ui-demo/assets/starter/provenance.json +14 -0
  62. package/skills/i3-ui-demo/assets/starter/public/prototype-config.json +22 -0
  63. package/skills/i3-ui-demo/assets/starter/src/App.vue +64 -0
  64. package/skills/i3-ui-demo/assets/starter/src/PrototypeShell.vue +59 -0
  65. package/skills/i3-ui-demo/assets/starter/src/config.ts +23 -0
  66. package/skills/i3-ui-demo/assets/starter/src/domain/presentation.ts +30 -0
  67. package/skills/i3-ui-demo/assets/starter/src/domain/theme.ts +25 -0
  68. package/skills/i3-ui-demo/assets/starter/src/main.ts +18 -0
  69. package/skills/i3-ui-demo/assets/starter/src/style.css +26 -0
  70. package/skills/i3-ui-demo/assets/starter/tests/presentation.test.ts +23 -0
  71. package/skills/i3-ui-demo/assets/starter/tests/theme.test.ts +26 -0
  72. package/skills/i3-ui-demo/assets/starter/tsconfig.json +15 -0
  73. package/skills/i3-ui-demo/assets/starter/vite.config.ts +4 -0
  74. package/skills/i3-ui-demo/assets/templates/enterprise-admin/capability-definition.json +1395 -0
  75. package/skills/i3-ui-demo/assets/templates/enterprise-admin/component-inventory.json +707 -0
  76. package/skills/i3-ui-demo/assets/templates/enterprise-admin/design-system.md +26 -0
  77. package/skills/i3-ui-demo/assets/templates/enterprise-admin/generation.json +49 -0
  78. package/skills/i3-ui-demo/assets/templates/enterprise-admin/index.html +534 -0
  79. package/skills/i3-ui-demo/assets/templates/enterprise-admin/manifest.json +9 -0
  80. package/skills/i3-ui-demo/assets/templates/enterprise-admin/offline-build.json +265 -0
  81. package/skills/i3-ui-demo/assets/templates/enterprise-admin/offline.js +8888 -0
  82. package/skills/i3-ui-demo/assets/templates/enterprise-admin/origin.json +344 -0
  83. package/skills/i3-ui-demo/assets/templates/enterprise-admin/preset.json +928 -0
  84. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/app.js +22 -0
  85. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/assets/empty.svg +1 -0
  86. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/assets/reference-styles.json +1 -0
  87. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/assets/result-403.svg +1 -0
  88. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/assets/result-404.svg +1 -0
  89. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/assets-manifest.json +334 -0
  90. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/baseline.json +173 -0
  91. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/conversion.md +30 -0
  92. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/credits.md +17 -0
  93. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/design-tokens.json +881 -0
  94. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/index.html +28 -0
  95. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/licenses/@qin-ui-antdv-next-pro.txt +9 -0
  96. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/licenses/ant-design-icons.txt +22 -0
  97. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/licenses/antdv-next.txt +21 -0
  98. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/package.json +12 -0
  99. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/browser-routes.json +298 -0
  100. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/coverage.json +180 -0
  101. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/integrity.json +13 -0
  102. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/keyboard.json +11 -0
  103. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/responsive.json +125 -0
  104. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/review.md +51 -0
  105. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/rules.log +150 -0
  106. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/flow-editor-html.png +0 -0
  107. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/flow-editor-original.png +0 -0
  108. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/intent-create-html.png +0 -0
  109. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/intent-create-original.png +0 -0
  110. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/models-html.png +0 -0
  111. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/models-original.png +0 -0
  112. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/workbench-html.png +0 -0
  113. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/workbench-original.png +0 -0
  114. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/selection.json +9 -0
  115. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/visual-comparison.json +342 -0
  116. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/readme.md +73 -0
  117. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/reference.md +59 -0
  118. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/routes.json +178 -0
  119. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/controls.js +99 -0
  120. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/dialogs.js +54 -0
  121. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/dom.js +264 -0
  122. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/forms.js +47 -0
  123. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/icons.js +41 -0
  124. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/layout.js +47 -0
  125. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/router.js +63 -0
  126. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/state.js +90 -0
  127. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/table.js +41 -0
  128. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/widgets.js +8 -0
  129. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/AgentDetail.html +3 -0
  130. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/AgentDetail.js +36 -0
  131. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/AgentEditor.html +2 -0
  132. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/AgentEditor.js +51 -0
  133. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/AgentsPage.html +3 -0
  134. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/AgentsPage.js +48 -0
  135. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/CheckResults.html +2 -0
  136. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/CheckResults.js +6 -0
  137. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/ResourcePicker.html +2 -0
  138. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/ResourcePicker.js +13 -0
  139. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/data.js +24 -0
  140. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/domain.js +32 -0
  141. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/registry.js +25 -0
  142. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/store.js +85 -0
  143. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentClose.html +2 -0
  144. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentClose.js +17 -0
  145. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentCreate.html +2 -0
  146. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentCreate.js +66 -0
  147. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentDecisions.html +3 -0
  148. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentDecisions.js +38 -0
  149. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentDetail.html +2 -0
  150. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentDetail.js +66 -0
  151. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentDocument.html +2 -0
  152. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentDocument.js +5 -0
  153. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentHeader.html +2 -0
  154. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentHeader.js +12 -0
  155. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentHistory.html +2 -0
  156. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentHistory.js +11 -0
  157. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentList.html +2 -0
  158. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentList.js +116 -0
  159. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentReplan.html +2 -0
  160. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentReplan.js +32 -0
  161. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentRevision.html +2 -0
  162. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentRevision.js +49 -0
  163. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentSummary.html +2 -0
  164. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentSummary.js +10 -0
  165. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentWorkspace.html +2 -0
  166. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentWorkspace.js +77 -0
  167. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/data.js +60 -0
  168. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/domain.js +105 -0
  169. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/store.js +212 -0
  170. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/AuditPanel.html +2 -0
  171. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/AuditPanel.js +18 -0
  172. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelDetail.html +2 -0
  173. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelDetail.js +23 -0
  174. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelEditor.html +2 -0
  175. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelEditor.js +78 -0
  176. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelGrant.html +2 -0
  177. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelGrant.js +55 -0
  178. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelReferences.html +2 -0
  179. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelReferences.js +26 -0
  180. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelRelease.html +2 -0
  181. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelRelease.js +38 -0
  182. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelStatus.html +2 -0
  183. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelStatus.js +7 -0
  184. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelTable.html +2 -0
  185. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelTable.js +72 -0
  186. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelTester.html +2 -0
  187. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelTester.js +46 -0
  188. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelsPage.html +2 -0
  189. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelsPage.js +52 -0
  190. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/RowActions.html +2 -0
  191. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/RowActions.js +19 -0
  192. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/UsagePanel.html +2 -0
  193. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/UsagePanel.js +30 -0
  194. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/data.js +48 -0
  195. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/domain.js +39 -0
  196. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/store.js +129 -0
  197. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/IncidentDetail.html +4 -0
  198. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/IncidentDetail.js +21 -0
  199. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/IntentSource.html +2 -0
  200. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/IntentSource.js +8 -0
  201. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/OperationActionDialog.html +2 -0
  202. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/OperationActionDialog.js +37 -0
  203. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/OperationEntry.html +2 -0
  204. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/OperationEntry.js +10 -0
  205. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/OperationsPage.html +2 -0
  206. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/OperationsPage.js +37 -0
  207. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/RepairTrack.html +2 -0
  208. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/RepairTrack.js +49 -0
  209. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/RunDetail.html +4 -0
  210. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/RunDetail.js +22 -0
  211. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/SourceSummary.html +2 -0
  212. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/SourceSummary.js +9 -0
  213. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/commands.js +82 -0
  214. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/examples.js +47 -0
  215. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/model.js +61 -0
  216. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/repair.js +68 -0
  217. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/store.js +55 -0
  218. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/types.js +1 -0
  219. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/workbench.js +18 -0
  220. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/ManagementTable.html +3 -0
  221. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/ManagementTable.js +28 -0
  222. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcCreateEntry.html +2 -0
  223. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcCreateEntry.js +18 -0
  224. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcDetail.html +2 -0
  225. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcDetail.js +31 -0
  226. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcEditor.html +2 -0
  227. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcEditor.js +27 -0
  228. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcLifecycle.html +2 -0
  229. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcLifecycle.js +16 -0
  230. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcPage.html +2 -0
  231. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcPage.js +43 -0
  232. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcPicker.html +4 -0
  233. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcPicker.js +34 -0
  234. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcProgress.html +2 -0
  235. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcProgress.js +30 -0
  236. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcWizard.html +3 -0
  237. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcWizard.js +67 -0
  238. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcWorkspace.html +2 -0
  239. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcWorkspace.js +41 -0
  240. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcsPage.html +2 -0
  241. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcsPage.js +31 -0
  242. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/ServiceEditor.html +2 -0
  243. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/ServiceEditor.js +26 -0
  244. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/ServiceList.html +2 -0
  245. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/ServiceList.js +70 -0
  246. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/data.js +8 -0
  247. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/domain.js +62 -0
  248. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/management.js +36 -0
  249. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/managementStore.js +49 -0
  250. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/store.js +132 -0
  251. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/AdminList.html +2 -0
  252. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/AdminList.js +38 -0
  253. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/EffectiveGrants.html +2 -0
  254. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/EffectiveGrants.js +11 -0
  255. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/GrantEditor.html +2 -0
  256. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/GrantEditor.js +45 -0
  257. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/MemberEditor.html +2 -0
  258. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/MemberEditor.js +54 -0
  259. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/MembersPage.html +3 -0
  260. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/MembersPage.js +27 -0
  261. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/RecordsPage.html +2 -0
  262. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/RecordsPage.js +12 -0
  263. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/RoleEditor.html +2 -0
  264. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/RoleEditor.js +45 -0
  265. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/RolesPage.html +3 -0
  266. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/RolesPage.js +38 -0
  267. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/domain.js +61 -0
  268. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/state.js +51 -0
  269. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/store.js +116 -0
  270. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseActionDialog.html +2 -0
  271. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseActionDialog.js +45 -0
  272. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseDetail.html +4 -0
  273. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseDetail.js +30 -0
  274. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseEditor.html +2 -0
  275. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseEditor.js +67 -0
  276. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseExecution.html +2 -0
  277. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseExecution.js +5 -0
  278. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleasesPage.html +4 -0
  279. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleasesPage.js +60 -0
  280. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/commands.js +157 -0
  281. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/model.js +136 -0
  282. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/store.js +76 -0
  283. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewDetail.html +3 -0
  284. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewDetail.js +26 -0
  285. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewEvidence.html +2 -0
  286. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewEvidence.js +14 -0
  287. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewProcess.html +2 -0
  288. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewProcess.js +113 -0
  289. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewsPage.html +3 -0
  290. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewsPage.js +62 -0
  291. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/commands.js +97 -0
  292. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/model.js +147 -0
  293. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/store.js +13 -0
  294. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ColumnSettings.html +2 -0
  295. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ColumnSettings.js +9 -0
  296. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ListBatchBar.html +2 -0
  297. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ListBatchBar.js +8 -0
  298. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ListDeleteDialog.html +2 -0
  299. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ListDeleteDialog.js +37 -0
  300. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ListMore.html +2 -0
  301. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ListMore.js +8 -0
  302. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/RecordMetadata.html +2 -0
  303. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/RecordMetadata.js +17 -0
  304. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/columns.js +32 -0
  305. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/deliveryGuide.js +49 -0
  306. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/deliveryView.js +12 -0
  307. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/listBatch.js +15 -0
  308. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/listSelection.js +37 -0
  309. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/policy.js +68 -0
  310. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/session.js +44 -0
  311. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/ConfirmationDialog.html +2 -0
  312. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/ConfirmationDialog.js +25 -0
  313. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/ConsoleShell.html +2 -0
  314. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/ConsoleShell.js +53 -0
  315. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/PrototypeGuide.html +10 -0
  316. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/PrototypeGuide.js +30 -0
  317. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/ScopePage.html +2 -0
  318. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/ScopePage.js +10 -0
  319. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/SessionDialog.html +2 -0
  320. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/SessionDialog.js +9 -0
  321. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/confirmation.js +3 -0
  322. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/navigation.js +19 -0
  323. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecDocument.html +2 -0
  324. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecDocument.js +8 -0
  325. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecEdit.html +2 -0
  326. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecEdit.js +32 -0
  327. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecHeader.html +2 -0
  328. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecHeader.js +15 -0
  329. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecHistory.html +2 -0
  330. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecHistory.js +11 -0
  331. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecReview.html +2 -0
  332. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecReview.js +57 -0
  333. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecWorkspace.html +2 -0
  334. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecWorkspace.js +37 -0
  335. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/data.js +20 -0
  336. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/domain.js +55 -0
  337. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/store.js +151 -0
  338. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/ArtifactDetail.html +3 -0
  339. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/ArtifactDetail.js +18 -0
  340. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TaskCreate.html +2 -0
  341. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TaskCreate.js +40 -0
  342. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TaskDetail.html +2 -0
  343. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TaskDetail.js +51 -0
  344. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TaskLaunch.html +2 -0
  345. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TaskLaunch.js +9 -0
  346. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TasksPage.html +5 -0
  347. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TasksPage.js +48 -0
  348. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/domain.js +204 -0
  349. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/exampleSource.js +22 -0
  350. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/registry.js +135 -0
  351. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/store.js +137 -0
  352. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workbench/WorkbenchPage.html +3 -0
  353. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workbench/WorkbenchPage.js +36 -0
  354. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workbench/model.js +56 -0
  355. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workbench/store.js +15 -0
  356. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/FlowCanvas.html +2 -0
  357. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/FlowCanvas.js +27 -0
  358. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/FlowDetail.html +4 -0
  359. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/FlowDetail.js +31 -0
  360. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/FlowEditor.html +2 -0
  361. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/FlowEditor.js +68 -0
  362. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/WorkflowsPage.html +5 -0
  363. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/WorkflowsPage.js +55 -0
  364. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/data.js +16 -0
  365. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/domain.js +83 -0
  366. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/registry.js +18 -0
  367. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/store.js +61 -0
  368. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/admin.css +60 -0
  369. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/agents.css +46 -0
  370. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/antdv.css +295 -0
  371. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/app.css +102 -0
  372. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/delivery.css +4 -0
  373. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/intents.css +37 -0
  374. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/native.css +22 -0
  375. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/operations.css +2 -0
  376. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/pbc.css +3 -0
  377. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/permissions.css +22 -0
  378. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/pro.css +1 -0
  379. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/releases.css +4 -0
  380. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/reset.css +246 -0
  381. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/reviews.css +8 -0
  382. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/tasks.css +6 -0
  383. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/tokens.css +15 -0
  384. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/workbench.css +61 -0
  385. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/workflows.css +1 -0
  386. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/admin-rules.test.js +96 -0
  387. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/agents.test.js +14 -0
  388. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/intent-state.test.js +37 -0
  389. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/list-batch.test.js +44 -0
  390. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/operation-fixtures.js +19 -0
  391. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/operation-repair.test.js +14 -0
  392. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/operations.test.js +25 -0
  393. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/pbc-management.test.js +17 -0
  394. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/pbc-state.test.js +24 -0
  395. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/permission-config.test.js +23 -0
  396. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/permissions.test.js +24 -0
  397. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/releases.test.js +50 -0
  398. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/reviews.test.js +36 -0
  399. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/runtime-forms-router.test.js +28 -0
  400. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/runtime-state.test.js +42 -0
  401. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/runtime-stores.test.js +16 -0
  402. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/spec-state.test.js +11 -0
  403. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/tasks.test.js +27 -0
  404. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/workbench.test.js +34 -0
  405. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/workflows.test.js +16 -0
  406. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tools/convert.mjs +168 -0
  407. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tools/serve.mjs +7 -0
  408. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tools/styles.mjs +11 -0
  409. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tools/verify.mjs +24 -0
  410. package/skills/i3-ui-demo/assets/templates/enterprise-admin/serve.cjs +16 -0
  411. package/skills/i3-ui-demo/assets/templates/enterprise-admin/template-inventory.json +28791 -0
  412. package/skills/i3-ui-demo/assets/templates/enterprise-admin/template.json +9 -0
  413. package/skills/i3-ui-demo/assets/templates/enterprise-admin/usability.css +44 -0
  414. package/skills/i3-ui-demo/assets/templates.json +10 -0
  415. package/skills/i3-ui-demo/assets/versions.json +20 -0
  416. package/skills/i3-ui-demo/readme.md +350 -0
  417. package/skills/i3-ui-demo/references/browser.md +71 -0
  418. package/skills/i3-ui-demo/references/dependencies.md +67 -0
  419. package/skills/i3-ui-demo/references/resources.md +142 -0
  420. package/skills/i3-ui-demo/scripts/dependencies.cjs +364 -0
  421. package/skills/i3-ui-demo/scripts/design-install.cjs +105 -0
  422. package/skills/i3-ui-demo/scripts/design-provider.cjs +57 -0
  423. package/skills/i3-ui-demo/scripts/locations.cjs +52 -0
  424. package/skills/i3-ui-demo/scripts/mcp.cjs +112 -0
  425. package/skills/i3-ui-demo/scripts/provider-discovery.cjs +131 -0
  426. package/skills/i3-ui-demo/scripts/resources.cjs +283 -0
  427. package/skills/i3-ui-prototype/SKILL.md +1 -1
  428. package/skills/i3-ui-prototype/references/execution-evidence.md +12 -56
  429. package/skills/i3-ui-prototype/scripts/codebuddy-registration.cjs +1 -1
  430. package/skills/i3-ui-prototype/scripts/execution-runtime.cjs +5 -2
  431. package/skills/i3-ui-prototype/scripts/hosts/codebuddy.cjs +3 -2
  432. package/skills/i3-ui-prototype/scripts/native-delivery.cjs +2 -2
  433. package/skills/i3-ui-prototype/scripts/prototype-hooks.cjs +23 -20
  434. package/docs/ui-prototype-native/MAIN-SESSION-REPORT.md +0 -66
  435. package/docs/ui-prototype-native/USAGE.md +0 -93
  436. package/references/engineering-skeleton-resources/README.md +0 -52
  437. package/references/engineering-skeleton-resources/adoption.md +0 -200
  438. package/references/engineering-skeleton-resources/catalog.json +0 -17
  439. package/references/enterprise-sop-resources/README.md +0 -165
  440. package/references/enterprise-sop-resources/ad/README.md +0 -70
  441. package/references/enterprise-sop-resources/ad/assets-manifest.json +0 -106
  442. package/references/enterprise-sop-resources/ad/prompts/01-generate.md +0 -58
  443. package/references/enterprise-sop-resources/ad/prompts/02-review.md +0 -54
  444. package/references/enterprise-sop-resources/ad/prompts/03-revise.md +0 -54
  445. package/references/enterprise-sop-resources/ad/prompts/04-recheck.md +0 -54
  446. package/references/enterprise-sop-resources/assets-manifest.json +0 -199
  447. package/references/enterprise-sop-resources/brd/README.md +0 -50
  448. package/references/enterprise-sop-resources/brd/assets-manifest.json +0 -94
  449. package/references/enterprise-sop-resources/brd/prompts/01-generate.md +0 -51
  450. package/references/enterprise-sop-resources/brd/prompts/02-review.md +0 -47
  451. package/references/enterprise-sop-resources/brd/prompts/03-revise.md +0 -47
  452. package/references/enterprise-sop-resources/brd/prompts/04-recheck.md +0 -47
  453. package/references/enterprise-sop-resources/codebuddy-project-guide.md +0 -34
  454. package/references/enterprise-sop-resources/controlled-handoff.md +0 -41
  455. package/references/enterprise-sop-resources/controlled_handoff.py +0 -334
  456. package/references/enterprise-sop-resources/handoff-contract.md +0 -196
  457. package/references/enterprise-sop-resources/handoff.py +0 -277
  458. package/references/enterprise-sop-resources/lifecycle-contract.md +0 -91
  459. package/references/enterprise-sop-resources/plan-handoff.md +0 -73
  460. package/references/enterprise-sop-resources/prd/README.md +0 -137
  461. package/references/enterprise-sop-resources/prd/assets-manifest.json +0 -115
  462. package/references/enterprise-sop-resources/prd/prompts/01-generate.md +0 -64
  463. package/references/enterprise-sop-resources/prd/prompts/02-review.md +0 -49
  464. package/references/enterprise-sop-resources/prd/prompts/03-revise.md +0 -48
  465. package/references/enterprise-sop-resources/prd/prompts/04-recheck.md +0 -47
  466. package/references/enterprise-sop-resources/prd/template-contracts.md +0 -39
  467. package/references/enterprise-sop-resources/prd/templates/AD.md +0 -17
  468. package/references/enterprise-sop-resources/recovery-contract.md +0 -65
  469. package/references/enterprise-sop-resources/review-handoff.md +0 -105
  470. package/references/enterprise-sop-resources/selection-handoff.md +0 -55
  471. package/references/enterprise-sop-resources/selection_handoff.py +0 -225
  472. package/references/enterprise-sop-resources/stages.json +0 -262
  473. package/references/enterprise-sop-resources/technical-baseline/README.md +0 -132
  474. package/references/enterprise-sop-resources/technical-baseline/assets-manifest.json +0 -101
  475. package/references/enterprise-sop-resources/technical-baseline/baselines/PROVENANCE.md +0 -40
  476. package/references/enterprise-sop-resources/technical-baseline/references/engineering-directory-v0.2.0/adoption.md +0 -112
  477. package/references/enterprise-sop-resources/technical-baseline/references/engineering-directory-v0.2.0/directory-standard.md +0 -119
  478. package/references/enterprise-sop-resources/template-contracts.md +0 -142
  479. package/references/enterprise-sop-resources/testcase/README.md +0 -61
  480. package/references/enterprise-sop-resources/testcase/assets-manifest.json +0 -111
  481. package/references/enterprise-sop-resources/testcase/prompts/01-generate.md +0 -53
  482. package/references/enterprise-sop-resources/testcase/prompts/02-review.md +0 -51
  483. package/references/enterprise-sop-resources/testcase/prompts/03-revise.md +0 -49
  484. package/references/enterprise-sop-resources/testcase/prompts/04-recheck.md +0 -51
  485. package/references/enterprise-sop-resources/verification/README.md +0 -149
  486. package/references/enterprise-sop-resources/verification/check_execution.py +0 -185
  487. package/references/enterprise-sop-resources/verification/check_native_execution.py +0 -282
  488. package/references/enterprise-sop-resources/verification/check_reads.py +0 -348
  489. package/references/enterprise-sop-resources/verification/review-output.schema.json +0 -155
  490. package/references/enterprise-sop-resources/verification/review_handoff.py +0 -329
@@ -0,0 +1,43 @@
1
+ import TaskLaunch from "../tasks/TaskLaunch.js";
2
+ import { computed, ref, watch } from '../../runtime/state.js';
3
+ import { useRoute, useRouter } from "../../runtime/router.js";
4
+ import { Alert, Button, Result, Space } from "../../runtime/widgets.js";
5
+ import { useIntents } from "../intents/store.js";
6
+ import { useSpecs } from "../specs/store.js";
7
+ import { useSession } from "../shared/session.js";
8
+ import { currentVersion, sourceOf } from "../specs/domain.js";
9
+ import { usePbcs } from "./store.js";
10
+ import { confirmAction } from "../shell/confirmation.js";
11
+ import SpecHeader from "../specs/SpecHeader.js";
12
+ import PbcPicker from "./PbcPicker.js";
13
+ import PbcWizard from "./PbcWizard.js";
14
+ import PbcProgress from "./PbcProgress.js";
15
+ import { createComponent } from '../../runtime/dom.js';
16
+ export default createComponent({ name: 'PbcPage', propKeys: [], template: new URL('./PbcPage.html', import.meta.url).href, setup(__props, __emit) {
17
+ const route = useRoute(), router = useRouter(), intents = useIntents(), specs = useSpecs(), store = usePbcs(), session = useSession(), selected = ref(''), wizard = ref(route.query.create === '1'), error = ref(''), submitting = ref(false);
18
+ const id = computed(() => String(route.params.id)), intent = computed(() => intents.get(id.value)), spec = computed(() => specs.get(id.value)), version = computed(() => spec.value && currentVersion(spec.value)), job = computed(() => store.job(id.value)), target = computed(() => store.items.find(p => p.id === selected.value));
19
+ watch(id, () => { selected.value = ''; error.value = ''; wizard.value = route.query.create === '1'; });
20
+ const sourceError = computed(() => { try {
21
+ if (!intent.value || !version.value?.confirmedAt)
22
+ return '请先完成规格确认。';
23
+ if (sourceOf(intent.value).version !== version.value.source.version)
24
+ return '来源意图有新版本,请先重新生成并确认规格。';
25
+ return '';
26
+ }
27
+ catch (e) {
28
+ return e.message;
29
+ } });
30
+ function link() { if (!target.value || !version.value)
31
+ return; const p = target.value, v = version.value, binding = { specVersion: v.number, recordVersion: spec.value.recordVersion, sourceVersion: v.source.version }; confirmAction({ title: '关联至 ' + p.name + '?', content: '意图 ' + v.source.code + ' v' + v.source.version + ' / 规格 v' + v.number + ' 将登记到 ' + p.name + '。保留现有工程配置,本轮不提供改绑。', okText: '确认关联', cancelText: '继续核对', onOk: async () => { try {
32
+ submitting.value = true;
33
+ error.value = '';
34
+ await store.link(id.value, p.id, binding);
35
+ }
36
+ catch (e) {
37
+ error.value = e.message;
38
+ }
39
+ finally {
40
+ submitting.value = false;
41
+ } } }); }
42
+ return { TaskLaunch, computed, ref, watch, useRoute, useRouter, Alert, Button, Result, Space, useIntents, useSpecs, useSession, currentVersion, sourceOf, usePbcs, confirmAction, SpecHeader, PbcPicker, PbcWizard, PbcProgress, route, router, intents, specs, store, session, selected, wizard, error, submitting, id, intent, spec, version, job, target, sourceError, link };
43
+ } });
@@ -0,0 +1,4 @@
1
+ <!-- 来源:src/pbc/PbcPicker.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
2
+ <section aria-label="已有 PBC 选择器"><div class="pbc-picker-tools"><template data-component="Space" wrap=""><template data-component="Input" data-model-value="(keyword)" aria-label="查找已有 PBC" placeholder="搜索名称、标识或 EBC" data-on-press-enter="(search)"></template><template data-component="Button" data-on-click="(search)">查询</template><template data-component="Button" data-on-click="keyword = '';
3
+ search();">重置</template></template><template data-component="Space" wrap=""><template data-component="Button" data-on-click="(sort = !sort)">名称{{ (sort ? '降序' : '升序') }}</template><template data-component="ColumnSettings" data-bind-preferences="(prefs)"></template><template data-component="Button" data-on-click="(refresh)">刷新</template></template></div><template data-component="Alert" type="info" show-icon="" title="一次关联一个 PBC。此处为授权目录选择器,删除及批量删除不适用。" class="page-alert"></template><template data-component="Result" data-if="(store.scene === 'error')" status="warning" title="PBC 目录加载失败"><template data-slot="extra"><template data-component="Button" data-on-click="store.scene = 'normal';
4
+ refresh();">重试加载</template></template></template><template data-component="ProTable" data-else="" data-bind-table="(table)" data-bind-search="(async () =&gt; { })" data-bind-control="(false)" data-bind-table-container="(false)" data-bind-loading="(loading)" row-key="id" data-bind-row-selection="(selection)" data-bind-scroll="({ x: 'max-content' })" data-bind-pagination="({ showTotal: (n) =&gt; '共 ' + n + ' 个可见 PBC', showSizeChanger: true, pageSizeOptions: [5, 10, 20] })" data-bind-locale="({ emptyText: h(Empty, { description: '没有匹配的授权 PBC' }) })"></template><template data-component="Drawer" data-bind-open="(!!detail)" title="PBC 详情" data-bind-size="(620)" data-on-close="(detail = undefined)"><template data-if="(detail)"><h2>{{ (detail.name) }}</h2><p>{{ (detail.ebc) }} · 负责人 {{ (detail.owner) }}</p><p>工程标识:{{ (detail.slug) }}<br>域名:{{ (detail.domain) }}</p><template data-component="RecordMetadata" data-bind-record="(detail)"></template><template data-component="Alert" type="info" title="演示目录记录,未连接真实仓库或环境。"></template></template></template></section>
@@ -0,0 +1,34 @@
1
+ import { stateOf } from "./management.js";
2
+ import { computed, ref, watch } from '../../runtime/state.js';
3
+ import { h } from '../../runtime/dom.js';
4
+ import { Alert, Button, Drawer, Empty, Input, Result, Space } from "../../runtime/widgets.js";
5
+ import { ProTable, useTable } from "../../runtime/widgets.js";
6
+ import { usePbcs } from "./store.js";
7
+ import { useSession } from "../shared/session.js";
8
+ import { formatDate, tenantLabel } from "../shared/policy.js";
9
+ import { useColumns } from "../shared/columns.js";
10
+ import ColumnSettings from "../shared/ColumnSettings.js";
11
+ import RecordMetadata from "../shared/RecordMetadata.js";
12
+ import ListMore from "../shared/ListMore.js";
13
+ import { labeledSelection } from "../shared/listSelection.js";
14
+ import { createComponent } from '../../runtime/dom.js';
15
+ export default createComponent({ name: 'PbcPicker', propKeys: ["tenantId", "value"], template: new URL('./PbcPicker.html', import.meta.url).href, setup(__props, __emit) {
16
+ const props = __props, emit = __emit, store = usePbcs(), session = useSession(), keyword = ref(''), applied = ref(''), loading = ref(false), detail = ref(), sort = ref(false);
17
+ const prefs = useColumns('pbc-picker', [{ key: 'name', label: 'PBC 名称', locked: true }, { key: 'ebc', label: 'EBC 归属', defaultVisible: true }, { key: 'owner', label: '负责人', defaultVisible: true }, { key: 'createdBy', label: '创建人', defaultVisible: true }, { key: 'createdAt', label: '创建时间', defaultVisible: true }, { key: 'createdDept', label: '创建部门' }, { key: 'updatedBy', label: '修改人' }, { key: 'updatedAt', label: '修改时间' }, { key: 'tenantId', label: '所属租户' }, { key: 'actions', label: '操作', locked: true }]);
18
+ const table = useTable({ pageParam: { current: 1, pageSize: 5, total: 0 }, columns: [
19
+ { key: 'name', title: 'PBC 名称', dataIndex: 'name', width: 180, render: (_, row) => h(Button, { type: 'link', onClick: () => detail.value = row }, () => String(row.name)) },
20
+ { key: 'ebc', title: 'EBC 归属', dataIndex: 'ebc', width: 200 }, { key: 'owner', title: '负责人', dataIndex: 'owner', width: 100 },
21
+ { key: 'createdBy', title: '创建人', dataIndex: 'createdBy', width: 100 }, { key: 'createdAt', title: '创建时间', dataIndex: 'createdAt', width: 180, render: (v) => formatDate(String(v)) },
22
+ { key: 'createdDept', title: '创建部门', dataIndex: 'createdDept', width: 140 }, { key: 'updatedBy', title: '修改人', dataIndex: 'updatedBy', width: 100 }, { key: 'updatedAt', title: '修改时间', dataIndex: 'updatedAt', width: 180, render: (v) => formatDate(String(v)) }, { key: 'tenantId', title: '所属租户', dataIndex: 'tenantId', width: 120, render: (v) => tenantLabel(String(v)) },
23
+ { key: 'actions', title: '操作', width: 95, render: (_, row) => h(ListMore, { name: String(row.name), items: [{ key: 'detail', label: '查看 PBC 详情' }], onAction: () => detail.value = row }) },
24
+ ] });
25
+ const catalog = new Map(table.columns.value.map(c => [c.key, c]));
26
+ watch(prefs.keys, keys => table.columns.value = keys.map(k => catalog.get(k)).filter(Boolean), { immediate: true });
27
+ const visible = computed(() => store.scene === 'empty' ? [] : store.items.filter(p => stateOf(p) === 'active').filter(p => p.tenantId === props.tenantId && (p.name + p.slug + p.ebc).includes(applied.value.trim())).sort((a, b) => sort.value ? b.name.localeCompare(a.name, 'zh-CN') : a.name.localeCompare(b.name, 'zh-CN')));
28
+ watch([visible, () => table.pageParam.current, () => table.pageParam.pageSize], () => { const size = table.pageParam.pageSize || 5, max = Math.max(1, Math.ceil(visible.value.length / size)); if ((table.pageParam.current || 1) > max)
29
+ table.setPageParam({ current: max }); const start = ((table.pageParam.current || 1) - 1) * size; table.dataSource.value = visible.value.slice(start, start + size); table.setPageParam({ total: visible.value.length }); emit('change', ''); }, { immediate: true });
30
+ const selection = computed(() => ({ type: 'radio', renderCell: (_checked, p, _index, node) => labeledSelection(node, '选择 PBC ' + p.name), selectedRowKeys: props.value ? [props.value] : [], onChange: (keys) => emit('change', String(keys[0] || '')), getCheckboxProps: (p) => ({ disabled: !session.can('pbc:link', String(p.tenantId), String(p.id)), name: '选择 PBC ' + p.name }) }));
31
+ function search() { applied.value = keyword.value; table.setPageParam({ current: 1 }); emit('change', ''); }
32
+ async function refresh() { emit('change', ''); loading.value = true; await new Promise(r => setTimeout(r, 250)); loading.value = false; }
33
+ return { stateOf, computed, ref, watch, h, Alert, Button, Drawer, Empty, Input, Result, Space, ProTable, useTable, usePbcs, useSession, formatDate, tenantLabel, useColumns, ColumnSettings, RecordMetadata, ListMore, labeledSelection, props, emit, store, session, keyword, applied, loading, detail, sort, prefs, table, catalog, visible, selection, search, refresh };
34
+ } });
@@ -0,0 +1,2 @@
1
+ <!-- 来源:src/pbc/PbcProgress.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
2
+ <section class="panel delivery-main" aria-label="PBC 归属进度"><div class="section-heading"><div><h2>{{ (job.kind === 'create' ? '创建' : '关联') }} {{ (job.pbc.name) }}</h2><p class="muted">意图 v{{ (job.sourceVersion) }} → 规格 v{{ (job.specVersion) }} → {{ (job.pbc.name) }}</p></div><template data-component="Tag" data-bind-color="(job.status === 'done' ? 'green' : job.status === 'failed' ? 'red' : 'blue')">{{ (stateLabels[job.status]) }}</template></div><template data-component="Alert" data-if="(error)" type="error" show-icon="" data-bind-title="(error)" class="page-alert"></template><template data-component="Alert" type="info" show-icon="" title="已提交内容只读保留,刷新页面后可查看原请求。" data-bind-description="('操作编号:' + job.id + '。不在此改绑或重新创建;本版所有执行与回执均为本地模拟。')" class="page-alert"></template><ol class="creation-progress"><li data-each="(step,index) in (job.steps)" data-bind-key="(step.name)"><span class="step-index" data-bind-class="('step-' + step.state)">{{ (step.state === 'done' ? '✓' : index + 1) }}</span><div><strong>{{ (step.name) }}</strong><p class="muted">{{ (step.detail || '等待前序步骤完成') }}</p></div><template data-component="Tag" data-bind-color="(step.state === 'done' ? 'green' : step.state === 'failed' ? 'red' : step.state === 'unknown' ? 'orange' : 'default')">{{ ({ waiting: '等待中', running: '处理中', done: '已完成', failed: '未完成', unknown: '待核实' }[step.state]) }}</template></li></ol><template data-component="Space" wrap=""><template data-component="Button" data-if="(job.status === 'unknown')" type="primary" data-on-click="(reconcile)">核实原操作结果</template><template data-component="Button" data-if="(['paused', 'failed'].includes(job.status))" type="primary" data-bind-disabled="(!canResume)" data-on-click="(resume)">继续未完成步骤</template><template data-component="Button" data-on-click="(history = true)">查看执行记录</template></template><template data-if="(job.status === 'done')"><section class="summary-context"><h2>归属结果与产物引用</h2><p>{{ (job.kind === 'create' ? '已形成新的 PBC 演示记录' : '已在现有 PBC 下登记需求关联,未重建工程资源') }}。后续进入开发计划与设计,当前没有生产发布。</p><div class="artifact-grid"><button data-each="a in (artifacts)" data-bind-key="(a.name)" class="artifact-link" data-on-click="(artifact = a.name)"><strong>{{ (a.name) }}</strong><span>{{ (a.path) }}</span><small>查看模拟引用 →</small></button></div><p class="muted">GitLab 归档与提交号、真实 Roadmap 生成待正式实现。此处不是仓库完成凭据。</p></section></template><template data-component="RecordMetadata" data-bind-record="(job)"></template><template data-component="Drawer" data-bind-open="(history)" title="执行与操作记录" data-bind-size="(680)" data-on-close="(history = false)"><template data-component="Alert" type="info" title="只读执行历史,不适用删除或批量删除。"></template><ol class="intent-events"><li data-each="(event,index) in ([...job.events].reverse())" data-bind-key="(index)"><strong>{{ (event.text) }}</strong><p class="muted">{{ (event.actor) }} · {{ (formatDate(event.at)) }}</p></li></ol></template><template data-component="Drawer" data-bind-open="(!!artifact)" data-bind-title="(artifact + '(模拟)')" data-bind-size="(820)" data-on-close="(artifact = '')"><p>来源:{{ (job.spec.source.code) }} · 意图 v{{ (job.sourceVersion) }} · 规格 v{{ (job.specVersion) }}</p><p>确认人:{{ (job.spec.confirmedBy) }} · {{ (formatDate(job.spec.confirmedAt)) }}</p><template data-if="(artifact === '已确认规格引用')"><template data-component="SpecDocument" data-bind-version="(job.spec)"></template></template><template data-else-if="(artifact === '意图归档引用')"><h2>{{ (job.spec.source.title) }}</h2><p>此处保留来源意图的标识与已确认版本,原文可从意图详情的版本记录查看。</p><template data-component="Button" data-on-click="(router.push('/intents/' + job.intentId))">查看来源意图</template></template><template data-else=""><h2>后续计划入口</h2><p>需求拆分 → 契约与交互设计 → 实现与独立验证 → 人工放行生产。</p><p>正式 Roadmap 待后续交互包与 spec 定义;本轮仅展示归档引用位置。</p></template></template></section>
@@ -0,0 +1,30 @@
1
+ import { computed, ref } from '../../runtime/state.js';
2
+ import { Alert, Button, Drawer, Space, Tag } from "../../runtime/widgets.js";
3
+ import { useRouter } from "../../runtime/router.js";
4
+ import { usePbcs } from "./store.js";
5
+ import { useSession } from "../shared/session.js";
6
+ import { formatDate } from "../shared/policy.js";
7
+ import RecordMetadata from "../shared/RecordMetadata.js";
8
+ import SpecDocument from "../specs/SpecDocument.js";
9
+ import { createComponent } from '../../runtime/dom.js';
10
+ export default createComponent({ name: 'PbcProgress', propKeys: ["job"], template: new URL('./PbcProgress.html', import.meta.url).href, setup(__props, __emit) {
11
+ const props = __props, store = usePbcs(), session = useSession(), router = useRouter(), error = ref(''), artifact = ref(''), history = ref(false);
12
+ const stateLabels = { running: '处理中', paused: '已暂停', unknown: '结果待核实', failed: '部分步骤失败', done: '已完成(模拟)' };
13
+ const scope = computed(() => props.job.kind === 'link' ? props.job.pbc.id : undefined), canResume = computed(() => session.can(props.job.kind === 'create' ? 'pbc:create' : 'pbc:link', props.job.tenantId, scope.value));
14
+ async function resume() { try {
15
+ error.value = '';
16
+ await store.resume(props.job.intentId);
17
+ }
18
+ catch (e) {
19
+ error.value = e.message;
20
+ } }
21
+ function reconcile() { try {
22
+ error.value = '';
23
+ store.reconcile(props.job.intentId);
24
+ }
25
+ catch (e) {
26
+ error.value = e.message;
27
+ } }
28
+ const artifacts = computed(() => [{ name: '意图归档引用', path: props.job.pbc.slug + '/intent-home/' + props.job.spec.source.code + '/intent.md' }, { name: '已确认规格引用', path: props.job.pbc.slug + '/intent-home/' + props.job.spec.source.code + '/spec.md' }, { name: 'Roadmap 初稿引用', path: props.job.pbc.slug + '/intent-home/' + props.job.spec.source.code + '/roadmap.md' }]);
29
+ return { computed, ref, Alert, Button, Drawer, Space, Tag, useRouter, usePbcs, useSession, formatDate, RecordMetadata, SpecDocument, props, store, session, router, error, artifact, history, stateLabels, scope, canResume, resume, reconcile, artifacts };
30
+ } });
@@ -0,0 +1,3 @@
1
+ <!-- 来源:src/pbc/PbcWizard.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
2
+ <template data-component="Drawer" data-bind-open="(true)" title="创建 PBC" data-bind-size="(1040)" data-bind-mask="({ closable: false })" data-on-close="(close)"><template data-component="Steps" data-bind-current="(step)" size="small" class="delivery-steps" data-bind-items="([{ title: '归属与服务方案' }, { title: '工程标识与预览' }, { title: '核对并创建' }])"></template><template data-component="Alert" data-if="(error)" type="error" show-icon="" data-bind-title="(error)" class="page-alert"></template><template data-component="Alert" type="info" show-icon="" class="page-alert" data-bind-title="('复核来源:' + specVersion.source.code + ' · 意图 v' + binding.sourceVersion + ' / 规格 v' + binding.specVersion)" data-bind-description="('规格确认人:' + specVersion.confirmedBy + ';提交期间版本变化会要求重新核对。')"></template><template data-component="ProForm" data-if="(step &lt; 2)" data-bind-form="(form)" name="pbc-create" layout="vertical" data-bind-disabled="(!allowed || submitting)"></template><template data-component="ServiceList" data-if="(step === 0)" data-bind-services="(services)" data-bind-tenant-id="(draft.tenantId)" data-bind-readonly="(!allowed)" data-on-change="(services = $event)"></template><template data-if="(step &gt;= 1)"><section class="engineering-preview"><h2>{{ (step === 1 ? '工程预览' : '提交复核') }}</h2><p><strong>{{ (value.name) }}</strong> · {{ (value.ebc) }} · 负责人 {{ (value.owner) }}</p><p>仓库组 / 命名空间:{{ (value.slug) }}<br>应用入口:{{ (value.domain) }}</p><ul><li data-each="s in (included)" data-bind-key="(s.id)"><strong>{{ (s.title) }}</strong> · {{ (value.prefix) }}-{{ (s.name) }}<br><span class="muted">{{ (templates.find(t =&gt; t.value === s.template)?.label) }} v1.0(模拟) · {{ (value.slug) }}/{{ (s.name) }}</span></li></ul><template data-component="Alert" show-icon="" type="info" title="新建会固定当前意图、规格及工程模板版本。" description="仅演示 GitLab、工程骨架、Kubernetes / Dapr、APISIX、MaxKey 应用和审批回调六项进度;不启动生产发布。"></template></section></template><template data-slot="footer"><div class="drawer-footer"><template data-component="Button" data-bind-disabled="(!allowed || submitting)" data-on-click="(saveExit)">保存并退出</template><template data-component="Space" wrap=""><template data-component="Button" data-if="(step &gt; 0)" data-bind-disabled="(submitting)" data-on-click="step--;
3
+ error = '';">上一步</template><template data-component="Button" data-if="(step &lt; 2)" type="primary" data-bind-disabled="(!allowed)" data-on-click="(next)">下一步</template><template data-component="Button" data-else="" type="primary" data-bind-disabled="(!allowed)" data-bind-loading="(submitting)" data-on-click="(create)">确认并创建 PBC</template></template></div></template></template>
@@ -0,0 +1,67 @@
1
+ import { computed, ref, watch } from '../../runtime/state.js';
2
+ import { Alert, Button, Drawer, Space, Steps } from "../../runtime/widgets.js";
3
+ import { ProForm, useForm } from "../../runtime/widgets.js";
4
+ import { usePbcs } from "./store.js";
5
+ import { useSession } from "../shared/session.js";
6
+ import { clone, currentVersion } from "../specs/domain.js";
7
+ import { useSpecs } from "../specs/store.js";
8
+ import { validateDraft, templates } from "./domain.js";
9
+ import ServiceList from "./ServiceList.js";
10
+ import { confirmAction } from "../shell/confirmation.js";
11
+ import { createComponent } from '../../runtime/dom.js';
12
+ export default createComponent({ name: 'PbcWizard', propKeys: ["intentId"], template: new URL('./PbcWizard.html', import.meta.url).href, setup(__props, __emit) {
13
+ const props = __props, emit = __emit, store = usePbcs(), session = useSession(), error = ref(''), submitting = ref(false);
14
+ const draft = ref(store.draft(props.intentId)), step = ref(draft.value.step), services = ref(clone(draft.value.services)), allowed = computed(() => session.can('pbc:create', draft.value.tenantId));
15
+ const specSnapshot = clone(useSpecs().get(props.intentId)), specVersion = currentVersion(specSnapshot), binding = { specVersion: specVersion.number, recordVersion: specSnapshot.recordVersion, sourceVersion: specVersion.source.version };
16
+ const form = useForm({ name: draft.value.name, ebc: draft.value.ebc, owner: draft.value.owner, slug: draft.value.slug, prefix: draft.value.prefix, domain: draft.value.domain });
17
+ watch(step, n => {
18
+ form.fields.value = n === 0 ? [
19
+ { path: 'name', label: 'PBC 名称', component: 'input', span: 24, rules: [{ required: true, whitespace: true, message: '请填写名称' }], maxlength: 60 },
20
+ { path: 'ebc', label: 'EBC 业务能力', component: 'select', span: 12, xs: 24, md: 12, options: ['客户服务与工单履约', '业务运营与支撑', '企业研发与交付'].map(value => ({ label: value, value })), rules: [{ required: true, message: '请选择 EBC' }] },
21
+ { path: 'owner', label: 'PBC 负责人', component: 'input', span: 12, xs: 24, md: 12, rules: [{ required: true, whitespace: true, message: '请填写负责人' }] },
22
+ ] : n === 1 ? [
23
+ { path: 'slug', label: 'PBC 标识', component: 'input', span: 24, extra: '用于仓库组与命名空间,例如 heating-triage。', rules: [{ required: true, message: '请填写标识' }] },
24
+ { path: 'prefix', label: '应用标识前缀', component: 'input', span: 24, extra: '与服务标识组合形成每个服务的 Dapr appId。', rules: [{ required: true, message: '请填写前缀' }] },
25
+ { path: 'domain', label: '应用域名', component: 'input', span: 24, extra: '本版仅展示路由规划,不创建真实域名或证书。', rules: [{ required: true, message: '请填写域名' }] },
26
+ ] : [];
27
+ }, { immediate: true });
28
+ const value = computed(() => ({ ...draft.value, ...form.formData, services: services.value, step: step.value }));
29
+ const included = computed(() => services.value.filter(s => !s.isDeleted));
30
+ async function next() { try {
31
+ await form.formRef.value?.validate();
32
+ }
33
+ catch {
34
+ return;
35
+ } try {
36
+ validateDraft(value.value, store.items, step.value);
37
+ error.value = '';
38
+ step.value++;
39
+ }
40
+ catch (e) {
41
+ error.value = e.message;
42
+ } }
43
+ function saveExit() { try {
44
+ draft.value = store.saveDraft(value.value);
45
+ emit('close');
46
+ }
47
+ catch (e) {
48
+ error.value = e.message;
49
+ } }
50
+ function close() { confirmAction({ title: '保存向导后退出?', content: '保留字段和服务拆分方案,下次可继续。本操作不创建工程。', okText: '保存并退出', cancelText: '继续编辑', onOk: saveExit }); }
51
+ async function create() { try {
52
+ submitting.value = true;
53
+ error.value = '';
54
+ validateDraft(value.value, store.items);
55
+ const operation = store.create(props.intentId, value.value, binding);
56
+ if (store.job(props.intentId))
57
+ emit('close');
58
+ await operation;
59
+ }
60
+ catch (e) {
61
+ error.value = e.message;
62
+ }
63
+ finally {
64
+ submitting.value = false;
65
+ } }
66
+ return { computed, ref, watch, Alert, Button, Drawer, Space, Steps, ProForm, useForm, usePbcs, useSession, clone, currentVersion, useSpecs, validateDraft, templates, ServiceList, confirmAction, props, emit, store, session, error, submitting, draft, step, services, allowed, specSnapshot, specVersion, binding, form, value, included, next, saveExit, close, create };
67
+ } });
@@ -0,0 +1,2 @@
1
+ <!-- 来源:src/pbc/PbcWorkspace.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
2
+ <template data-component="Result" data-if="(!pbc)" status="403" title="PBC 工作区不存在或无权访问"><template data-slot="extra"><template data-component="Button" data-on-click="(router.push('/pbcs'))">返回 PBC 列表</template></template></template><template data-else=""><div class="page-heading"><div><template data-component="Button" type="link" class="agent-back" data-on-click="(router.push('/pbcs/' + id))">← 返回 PBC 概览</template><h1>{{ (pbc.name) }} · 交付工作区</h1><p>从已归属的需求,查看每次交付的阶段、问题与版本产物。</p></div><template data-component="Space" wrap=""><template data-component="Button" data-on-click="(router.push('/pbcs/' + id + '?tab=services'))">服务管理</template><template data-component="Button" type="primary" data-bind-disabled="(!sources.length || stateOf(pbc) !== 'active')" data-on-click="(router.push('/tasks/new?intent=' + sources[0].id))">发起交付</template></template></div><div class="task-metrics"><article><span>可见需求</span><strong>{{ (jobs.length) }}</strong></article><article><span>可见交付任务</span><strong>{{ (deliveries.length) }}</strong></article><article><span>等待或需处理</span><strong>{{ (deliveries.filter(t =&gt; !!currentReview(t) || ['failed', 'waiting', 'manual', 'paused'].includes(t.status)).length) }}</strong></article><article><span>待发布处理</span><strong>{{ (deliveries.filter(t =&gt; t.status === 'ready' &amp;&amp; !currentReview(t) &amp;&amp; hasPendingRelease(t)).length) }}</strong></article></div><div class="pbc-chain" aria-label="交付产物链"><button data-on-click="(tab = 'demands')">需求与规格</button><span>→</span><button data-on-click="(tab = 'tasks')">交付任务与阶段</button><span>→</span><button data-bind-disabled="(!canArtifacts)" data-on-click="(tab = 'artifacts')">版本产物</button><span>→</span><button data-bind-disabled="(!canArtifacts)" data-on-click="(router.push('/reviews?pbc=' + id))">质量与评审</button><span>→</span><button data-bind-disabled="(!canArtifacts)" data-on-click="(router.push('/releases?pbc=' + id))">门禁与发布</button><span>→</span><button data-bind-disabled="(!session.can('operation:view', pbc.tenantId, id, 'production'))" data-on-click="(router.push('/operations?pbc=' + id))">运行验收与异常</button></div><template data-component="Tabs" data-model-active-key="(tab)" data-bind-items="([{ key: 'demands', label: '需求与规格' }, { key: 'tasks', label: '交付任务' }, { key: 'artifacts', label: '版本产物', disabled: !canArtifacts }])"></template><template data-if="(tab === 'demands')"><template data-component="ManagementTable" data-bind-key="(id + 'demands')" page-key="关联需求" data-bind-rows="(sourceRows)" readonly="" context-label="来源版本" data-bind-more="(sourceMore)" data-on-action="(sourceAction)"></template><p data-if="(!jobs.length)" class="muted pbc-list-note">暂无可查看的关联需求。需求与规格权限分别由权限管理配置;新增需求先在意图工作台确认规格并归属本 PBC。</p></template><template data-if="(tab === 'tasks')"><template data-component="ManagementTable" data-bind-key="(id + 'tasks')" page-key="工作区任务" data-bind-rows="(taskRows)" readonly="" context-label="当前阶段" data-bind-more="(taskMore)" primary="进度" data-on-action="(taskAction)"></template><p class="muted pbc-list-note">此处聚合已有任务。进入任务详情可处理暂停、返工或草稿;不会另建一份交付记录。</p></template><template data-if="(tab === 'artifacts')"><template data-component="Result" data-if="(!canArtifacts)" status="403" title="没有查看产物的权限"></template><template data-else=""><div class="pbc-artifact-heading"><div><h2>按交付任务查看产物</h2><p class="muted">每份产物保留版本、生成阶段与来源引用。</p></div><template data-component="Select" data-model-value="(selected)" aria-label="产物所属交付任务" data-bind-options="(artifactTasks.map(t =&gt; ({ value: t.id, label: t.name })))" placeholder="选择交付任务"></template></div><div data-if="(chosen)" class="task-artifact-grid"><article data-each="a in (chosen.artifacts)" data-bind-key="(a.id)" class="task-artifact-card"><div><span class="task-file-icon">{{ (a.kind.toUpperCase().slice(0, 3)) }}</span><template data-component="ListMore" data-bind-name="(a.name)" data-bind-items="([{ key: 'view', label: '查看当前版本' }, { key: 'versions', label: '版本与差异' }])" data-on-action="(key =&gt; router.push('/tasks/' + chosen.id + '/artifacts/' + a.id + (key === 'versions' ? '?compare=1' : '')))"></template></div><h3>{{ (a.name) }}</h3><template data-component="Tag">v{{ (a.versions.at(-1).number) }}</template><template data-component="Tag" data-if="(a.versions.at(-1).result === 'fail')" color="red">发现问题</template><p>{{ (formatDate(a.versions.at(-1).at)) }}<br>{{ (a.versions.at(-1).by) }} · {{ (a.versions.length) }} 个版本</p><template data-component="Button" type="link" data-on-click="(router.push('/tasks/' + chosen.id + '/artifacts/' + a.id + '?version=' + a.versions.at(-1).number))">查看版本内容 →</template></article></div><p data-else="" class="muted">暂无可见产物,先查看关联需求或继续交付任务。</p><template data-component="Alert" class="page-alert" type="info" show-icon="" title="产物内容与验证结果为交互演示样例。" description="设计、代码、测试与验证不代表真实 Agent 已执行;生产发布仍待后续人工授权。"></template></template></template></template>
@@ -0,0 +1,41 @@
1
+ import { computed, ref, watch } from '../../runtime/state.js';
2
+ import { useRoute, useRouter } from "../../runtime/router.js";
3
+ import { Alert, Button, Result, Select, Space, Tabs, Tag } from "../../runtime/widgets.js";
4
+ import { usePbcManagement } from "./managementStore.js";
5
+ import { actionableReview, canReadReview, reviewStatus, stateLabels } from "../reviews/model.js";
6
+ import { taskReleaseLabel, hasPendingRelease } from "../releases/model.js";
7
+ import { useTasks } from "../tasks/store.js";
8
+ import { useSession } from "../shared/session.js";
9
+ import { stateOf } from "./management.js";
10
+ import { currentNode, statusLabels } from "../tasks/domain.js";
11
+ import { formatDate } from "../shared/policy.js";
12
+ import ManagementTable from "./ManagementTable.js";
13
+ import ListMore from "../shared/ListMore.js";
14
+ import { createComponent } from '../../runtime/dom.js';
15
+ export default createComponent({ name: 'PbcWorkspace', propKeys: [], template: new URL('./PbcWorkspace.html', import.meta.url).href, setup(__props, __emit) {
16
+ const route = useRoute(), router = useRouter(), store = usePbcManagement(), tasks = useTasks(), session = useSession(), id = computed(() => String(route.params.id)), pbc = computed(() => store.item(id.value)), tab = ref(String(route.query.tab || 'demands')), selected = ref('');
17
+ watch(() => route.query.tab, v => tab.value = String(v || 'demands'));
18
+ watch(tab, v => router.replace({ query: { ...route.query, tab: v } }));
19
+ const jobs = computed(() => store.jobsFor(id.value)), deliveries = computed(() => pbc.value ? tasks.records.filter(t => t.binding.pbcId === id.value && t.tenantId === pbc.value.tenantId) : []);
20
+ const sourceRows = computed(() => jobs.value.map(j => ({ ...j, id: j.intentId, name: j.spec.source.title, code: j.spec.source.code, status: j.status === 'done' ? '已归属' : j.status === 'unknown' ? '结果待核实' : '创建处理中', context: '规格 v' + j.specVersion + ' · 意图 v' + j.sourceVersion, owner: j.spec.confirmedBy || j.createdBy })));
21
+ const currentReview = (t) => canReadReview(session.actor, t) ? actionableReview(t) : undefined;
22
+ const taskRows = computed(() => deliveries.value.map(t => ({ ...t, context: currentNode(t)?.name || '尚未开始', status: taskReleaseLabel(t, session.actor) || (currentReview(t) ? stateLabels[reviewStatus(t, currentReview(t))] : statusLabels[t.status]) })));
23
+ const canArtifacts = computed(() => !!pbc.value && session.can('artifact:view', pbc.value.tenantId, id.value)), artifactTasks = computed(() => canArtifacts.value ? deliveries.value.filter(t => t.artifacts.length) : []);
24
+ watch(artifactTasks, ts => { if (!ts.some(t => t.id === selected.value))
25
+ selected.value = ts.find(t => t.id === 'task-example-1')?.id || ts[0]?.id || ''; }, { immediate: true });
26
+ const chosen = computed(() => artifactTasks.value.find(t => t.id === selected.value)), sources = computed(() => tasks.sources.filter(s => s.job?.pbc.id === id.value && !s.reason));
27
+ function sourceMore(r) { return [{ key: 'detail', label: '查看需求规格' }, { key: 'intent', label: '查看来源意图' }, { key: 'result', label: '查看归属/创建结果' }, { key: 'launch', label: '发起交付', disabled: !sources.value.some(s => s.id === r.id) }]; }
28
+ function sourceAction(key, r) { router.push(key === 'launch' ? '/tasks/new?intent=' + r.id : '/intents/' + r.id + (key === 'intent' ? '' : key === 'result' ? '/pbc' : '/spec')); }
29
+ function taskMore(r) { const t = deliveries.value.find(t => t.id === r.id); return [{ key: 'operations', label: '运行验收与异常', disabled: !session.can('operation:view', t.tenantId, id.value, 'production') }, { key: 'release', label: '门禁与发布记录', disabled: !canArtifacts.value }, { key: 'review', label: '质量与评审记录', disabled: !canArtifacts.value }, { key: 'detail', label: '查看阶段进度' }, { key: 'artifacts', label: '查看任务产物', disabled: !canArtifacts.value }, { key: 'edit', label: '编辑交付草稿', disabled: t.status !== 'draft' || !session.can('task:edit', t.tenantId, id.value) }]; }
30
+ function taskAction(key, r) { if (key === 'operations') {
31
+ router.push('/operations?task=' + r.id);
32
+ return;
33
+ } if (key === 'release') {
34
+ router.push('/releases?task=' + r.id);
35
+ return;
36
+ } if (key === 'review') {
37
+ router.push('/reviews?task=' + r.id);
38
+ return;
39
+ } router.push('/tasks/' + r.id + (key === 'edit' ? '/edit' : key === 'artifacts' ? '?tab=artifacts' : '')); }
40
+ return { computed, ref, watch, useRoute, useRouter, Alert, Button, Result, Select, Space, Tabs, Tag, usePbcManagement, actionableReview, canReadReview, reviewStatus, stateLabels, taskReleaseLabel, hasPendingRelease, useTasks, useSession, stateOf, currentNode, statusLabels, formatDate, ManagementTable, ListMore, route, router, store, tasks, session, id, pbc, tab, selected, jobs, deliveries, sourceRows, currentReview, taskRows, canArtifacts, artifactTasks, chosen, sources, sourceMore, sourceAction, taskMore, taskAction };
41
+ } });
@@ -0,0 +1,2 @@
1
+ <!-- 来源:src/pbc/PbcsPage.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
2
+ <div class="page-heading"><div><h1>PBC 与项目</h1><p>管理业务系统与服务,从同一个工作区继续需求、研发交付和产物回看。</p></div><template data-component="Button" type="primary" data-bind-disabled="(!session.can('pbc:create'))" data-on-click="(create = true)">新建 PBC</template></div><div class="task-metrics"><article><span>可见 PBC</span><strong>{{ (store.records.length) }}</strong></article><article><span>使用中</span><strong>{{ (store.records.filter(p =&gt; stateOf(p) === 'active').length) }}</strong></article><article><span>已归档</span><strong>{{ (store.records.filter(p =&gt; stateOf(p) === 'archived').length) }}</strong></article><article><span>可见服务与方案</span><strong>{{ (store.records.reduce((n, p) =&gt; n + p.services.filter(s =&gt; !s.isDeleted).length, 0)) }}</strong></article></div><div class="pbc-list-context"><template data-component="Space" wrap=""><span>所属租户</span><template data-component="Select" data-model-value="(scope)" aria-label="PBC 租户筛选" data-bind-options="([{ value: 'all', label: '全部授权范围' }, ...tenants.filter(t =&gt; store.records.some(p =&gt; p.tenantId === t.value))])"></template></template><p class="muted">PBC 持续管理业务能力;交付工作区汇集其需求、任务与产物。</p></div><template data-component="Alert" data-if="(pbcs.notice)" show-icon="" type="warning" data-bind-title="(pbcs.notice)"></template><template data-component="ManagementTable" data-bind-key="(scope)" page-key="PBC" data-bind-rows="(rows)" context-label="EBC 业务能力" data-bind-more="(more)" data-bind-can-delete="(session.can('pbc:delete'))" data-bind-scene="(pbcs.scene)" data-on-action="(action)" data-on-remove="(targets = $event)" data-on-refresh="(pbcs.scene = 'normal')"></template><p class="muted pbc-list-note">已有工程或存在引用的 PBC 保留记录。仅已归档、无工程且无服务/引用的规划记录允许删除。</p><template data-component="PbcEditor" data-if="(edit)" data-bind-record="(edit)" data-on-close="(edit = undefined)" data-on-saved="(saved)"></template><template data-component="PbcLifecycle" data-if="(lifecycle)" data-bind-record="(lifecycle)" data-on-close="(lifecycle = undefined)" data-on-saved="(saved)"></template><template data-component="PbcCreateEntry" data-if="(create)" data-bind-open="(create)" data-on-close="(create = false)"></template><template data-component="ListDeleteDialog" data-if="(targets.length)" data-model-targets="(targets)" label="PBC" data-bind-check="(store.checkRemove)" data-bind-submit="(store.removeMany)" data-on-close="(targets = [])" data-on-deleted="(targets = [])"></template>
@@ -0,0 +1,31 @@
1
+ import { computed, ref } from '../../runtime/state.js';
2
+ import { useRouter } from "../../runtime/router.js";
3
+ import { Alert, Button, Select, Space, message } from "../../runtime/widgets.js";
4
+ import { usePbcManagement } from "./managementStore.js";
5
+ import { usePbcs } from "./store.js";
6
+ import { useSession } from "../shared/session.js";
7
+ import { tenants } from "../shared/policy.js";
8
+ import { stateLabel, stateOf } from "./management.js";
9
+ import ManagementTable from "./ManagementTable.js";
10
+ import PbcEditor from "./PbcEditor.js";
11
+ import PbcLifecycle from "./PbcLifecycle.js";
12
+ import PbcCreateEntry from "./PbcCreateEntry.js";
13
+ import ListDeleteDialog from "../shared/ListDeleteDialog.js";
14
+ import { createComponent } from '../../runtime/dom.js';
15
+ export default createComponent({ name: 'PbcsPage', propKeys: [], template: new URL('./PbcsPage.html', import.meta.url).href, setup(__props, __emit) {
16
+ const store = usePbcManagement(), pbcs = usePbcs(), session = useSession(), router = useRouter(), scope = ref('all'), edit = ref(), lifecycle = ref(), create = ref(false), targets = ref([]);
17
+ const rows = computed(() => store.records.filter(p => scope.value === 'all' || p.tenantId === scope.value).map(p => ({ ...p, code: p.slug, status: stateLabel(p), context: p.ebc })));
18
+ const can = (action, r) => session.can(action, r.tenantId, r.id);
19
+ function more(r) { return [{ key: 'workspace', label: '进入交付工作区' }, { key: 'edit', label: '编辑资料', disabled: !can('pbc:edit', r) || r.status === '已归档' }, { key: 'lifecycle', label: r.status === '已归档' ? '恢复使用' : '归档 PBC', disabled: !can('pbc:archive', r) }, { key: 'audit', label: '操作记录', disabled: !can('pbc:audit', r) }, { key: 'delete', label: '删除 PBC', danger: true, disabled: !can('pbc:delete', r) }]; }
20
+ function action(key, r) { const p = store.item(r.id); if (!p)
21
+ return; if (key === 'edit')
22
+ edit.value = p;
23
+ else if (key === 'lifecycle')
24
+ lifecycle.value = p;
25
+ else if (key === 'delete')
26
+ targets.value = [r];
27
+ else
28
+ router.push('/pbcs/' + r.id + (key === 'workspace' ? '/workspace' : key === 'audit' ? '?tab=records' : '')); }
29
+ function saved() { edit.value = undefined; lifecycle.value = undefined; message.success('PBC 资料已保存'); }
30
+ return { computed, ref, useRouter, Alert, Button, Select, Space, message, usePbcManagement, usePbcs, useSession, tenants, stateLabel, stateOf, ManagementTable, PbcEditor, PbcLifecycle, PbcCreateEntry, ListDeleteDialog, store, pbcs, session, router, scope, edit, lifecycle, create, targets, rows, can, more, action, saved };
31
+ } });
@@ -0,0 +1,2 @@
1
+ <!-- 来源:src/pbc/ServiceEditor.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
2
+ <template data-component="Drawer" data-bind-open="(true)" data-bind-title="(readonly ? '服务详情' : service ? '编辑服务资料' : '新增服务方案')" data-bind-size="(720)" data-bind-mask="({ closable: false })" data-on-close="(close)"><template data-component="Alert" type="info" show-icon="" data-bind-title="(service?.registered ? '已登记工程 · 演示信息' : '服务方案草稿 · 尚未建工程')" data-bind-description="(service?.registered ? '服务标识、模板和来源保持固定;运行健康与部署版本尚未接入。' : '保存方案后,还需核对需求与契约,通过增量交付流程创建工程。此处不会创建仓库或上线。')" class="page-alert"></template><template data-component="Alert" data-if="(error)" type="error" show-icon="" data-bind-title="(error)" class="page-alert"></template><template data-component="Form" layout="vertical" data-bind-disabled="(!allowed)"><template data-component="FormItem" label="服务名称" required=""><template data-component="Input" data-model-value="(data.title)" aria-label="服务名称" data-bind-maxlength="(60)"></template></template><template data-component="FormItem" label="服务标识" required=""><template data-component="Input" data-model-value="(data.name)" aria-label="服务标识" data-bind-maxlength="(35)" data-bind-disabled="(!allowed || !!service?.registered)"></template></template><template data-component="FormItem" label="工程模板" required=""><template data-component="Select" data-model-value="(data.template)" aria-label="服务工程模板" data-bind-options="(templates)" data-bind-disabled="(!allowed || !!service?.registered)"></template></template><template data-component="FormItem" label="职责与边界" required=""><template data-component="Input.TextArea" data-model-value="(data.purpose)" aria-label="服务职责" data-bind-rows="(3)" data-bind-maxlength="(500)"></template></template><template data-component="FormItem" label="需求依据"><template data-component="Select" data-model-value="(data.sourceIntentId)" aria-label="服务需求依据" data-bind-options="(options)" data-bind-disabled="(!allowed || !!service?.registered)"></template></template><template data-component="FormItem" data-if="(!readonly)" label="变更原因" required=""><template data-component="Input.TextArea" data-model-value="(reason)" aria-label="服务变更原因" data-bind-rows="(2)" data-bind-maxlength="(500)"></template></template></template><p data-if="(!data.sourceIntentId)" class="muted">尚未关联需求,不能据此进入正式扩服务交付。</p><p data-if="(service)" class="muted">记录版本 {{ (service.recordVersion) }} · {{ (service.isDeleted ? '已删除' : '未删除') }}</p><template data-component="RecordMetadata" data-if="(service)" data-bind-record="(service)"></template><template data-slot="footer"><template data-component="Space"><template data-component="Button" data-on-click="(close)">{{ (readonly ? '关闭' : '取消') }}</template><template data-component="Button" data-if="(!readonly)" type="primary" data-bind-disabled="(!allowed)" data-on-click="(save)">保存服务方案</template></template></template></template>
@@ -0,0 +1,26 @@
1
+ import { computed, reactive, ref } from '../../runtime/state.js';
2
+ import { Alert, Button, Drawer, Form, FormItem, Input, Select, Space } from "../../runtime/widgets.js";
3
+ import { usePbcManagement } from "./managementStore.js";
4
+ import { useSession } from "../shared/session.js";
5
+ import { templates } from "./domain.js";
6
+ import { confirmAction } from "../shell/confirmation.js";
7
+ import RecordMetadata from "../shared/RecordMetadata.js";
8
+ import { createComponent } from '../../runtime/dom.js';
9
+ export default createComponent({ name: 'ServiceEditor', propKeys: ["pbc", "service", "readonly"], template: new URL('./ServiceEditor.html', import.meta.url).href, setup(__props, __emit) {
10
+ const props = __props, emit = __emit, store = usePbcManagement(), session = useSession(), version = props.pbc.recordVersion;
11
+ const data = reactive({ name: props.service?.name || '', title: props.service?.title || '', template: props.service?.template || 'java', purpose: props.service?.purpose || '', sourceIntentId: props.service?.sourceIntentId || '' }), initial = JSON.stringify(data), reason = ref(''), error = ref('');
12
+ const allowed = computed(() => !props.readonly && session.can('pbc:service', props.pbc.tenantId, props.pbc.id));
13
+ const options = computed(() => [{ value: '', label: '待关联需求' }, ...store.jobsFor(props.pbc.id).filter(j => j.status === 'done').map(j => ({ value: j.intentId, label: j.spec.source.title + ' · 规格 v' + j.specVersion }))]);
14
+ function close() { if (!props.readonly && (JSON.stringify(data) !== initial || reason.value))
15
+ confirmAction({ title: '放弃未保存的服务方案?', content: '已保存的服务记录保持不变。', okText: '放弃修改', cancelText: '继续编辑', onOk: () => emit('close') });
16
+ else
17
+ emit('close'); }
18
+ function save() { try {
19
+ store.serviceSave(props.pbc.id, version, props.service?.id, data, reason.value);
20
+ emit('saved');
21
+ }
22
+ catch (e) {
23
+ error.value = e.message;
24
+ } }
25
+ return { computed, reactive, ref, Alert, Button, Drawer, Form, FormItem, Input, Select, Space, usePbcManagement, useSession, templates, confirmAction, RecordMetadata, props, emit, store, session, version, data, initial, reason, error, allowed, options, close, save };
26
+ } });
@@ -0,0 +1,2 @@
1
+ <!-- 来源:src/pbc/ServiceList.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
2
+ <section aria-label="服务拆分方案" class="service-list"><div class="section-heading"><h2>服务拆分方案</h2><template data-component="Space" wrap=""><template data-component="ColumnSettings" data-bind-preferences="(prefs)"></template><template data-component="Button" data-on-click="(selection.clear())">刷新</template><template data-component="Button" data-bind-disabled="(!editable)" data-on-click="(add)">新增服务</template></template></div><p class="muted">模板版本固定为 v1.0(模拟),提交前可调整。工程创建后不在此删除服务。</p><div class="pbc-picker-tools"><template data-component="Space" wrap=""><template data-component="Input" data-model-value="(keyword)" aria-label="查找服务方案" placeholder="搜索服务名称或标识"></template><template data-component="Button" data-on-click="(keyword = '')">重置筛选</template></template><template data-component="Button" data-on-click="(descending = !descending)">服务标识{{ (descending ? '降序' : '升序') }}</template></div><template data-component="ListBatchBar" data-bind-count="(selection.selected.value.length)" data-bind-allowed="(editable)" data-on-remove="(remove(selection.keys.value))" data-on-clear="(selection.clear)"></template><template data-component="ProTable" data-bind-table="(table)" data-bind-search="(async () =&gt; { })" data-bind-control="(false)" data-bind-table-container="(false)" row-key="id" 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="Drawer" data-bind-open="(editor)" data-bind-title="(selectedId ? '编辑服务' : '新增服务')" data-bind-size="(520)" data-bind-mask="({ closable: false })" data-on-close="(editor = false)"><template data-component="Alert" data-if="(error)" type="error" data-bind-title="(error)" class="page-alert"></template><template data-component="ProForm" data-bind-form="(form)" name="pbc-service" layout="vertical" data-bind-disabled="(!editable)"></template><template data-slot="footer"><template data-component="Space"><template data-component="Button" data-on-click="(editor = false)">取消</template><template data-component="Button" type="primary" data-bind-disabled="(!editable)" data-on-click="(save)">保存服务</template></template></template></template><template data-component="Drawer" data-bind-open="(!!detail)" title="服务草稿详情" data-bind-size="(600)" data-on-close="(detail = undefined)"><template data-if="(detail)"><h2>{{ (detail.title) }}</h2><p>{{ (detail.name) }} · {{ (templates.find(t =&gt; t.value === detail?.template)?.label) }} · v1.0(模拟)</p><template data-component="RecordMetadata" data-bind-record="(detail)"></template></template></template></section>
@@ -0,0 +1,70 @@
1
+ import { computed, ref, watch } from '../../runtime/state.js';
2
+ import { h } from '../../runtime/dom.js';
3
+ import { Alert, Button, Drawer, Space, Input } from "../../runtime/widgets.js";
4
+ import { ProForm, ProTable, useForm, useTable } from "../../runtime/widgets.js";
5
+ import { useSession } from "../shared/session.js";
6
+ import { formatDate, metadata } from "../shared/policy.js";
7
+ import { useColumns } from "../shared/columns.js";
8
+ import { useListSelection } from "../shared/listSelection.js";
9
+ import ListMore from "../shared/ListMore.js";
10
+ import ListBatchBar from "../shared/ListBatchBar.js";
11
+ import ColumnSettings from "../shared/ColumnSettings.js";
12
+ import RecordMetadata from "../shared/RecordMetadata.js";
13
+ import { confirmAction } from "../shell/confirmation.js";
14
+ import { templates } from "./domain.js";
15
+ import { createComponent } from '../../runtime/dom.js';
16
+ export default createComponent({ name: 'ServiceList', propKeys: ["services", "tenantId", "readonly"], template: new URL('./ServiceList.html', import.meta.url).href, setup(__props, __emit) {
17
+ const props = __props, emit = __emit, session = useSession();
18
+ const editable = computed(() => !props.readonly && session.can('pbc:create', props.tenantId)), error = ref(''), editor = ref(false), selectedId = ref(''), detail = ref(), keyword = ref(''), descending = ref(false);
19
+ const form = useForm({ title: '', name: '', template: 'java' }, [
20
+ { path: 'title', label: '服务名称', component: 'input', span: 24, rules: [{ required: true, whitespace: true, message: '请填写服务名称' }] },
21
+ { path: 'name', label: '服务标识', component: 'input', span: 24, placeholder: '例如 workorder', rules: [{ required: true, pattern: /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/, message: '以小写字母开头,使用小写字母、数字和短横线' }] },
22
+ { path: 'template', label: '工程模板', component: 'select', span: 24, options: templates, rules: [{ required: true, message: '请选择模板' }] },
23
+ ]);
24
+ const prefs = useColumns('pbc-services', [{ key: 'title', label: '服务名称', locked: true }, { key: 'name', label: '服务标识', defaultVisible: true }, { key: 'template', label: '模板版本', defaultVisible: true }, { key: 'createdBy', label: '创建人', defaultVisible: true }, { key: 'createdAt', label: '创建时间', defaultVisible: true }, { key: 'createdDept', label: '创建部门' }, { key: 'updatedBy', label: '修改人' }, { key: 'updatedAt', label: '修改时间' }, { key: 'actions', label: '操作', locked: true }]);
25
+ function more(key, s) { if (key === 'detail') {
26
+ detail.value = s;
27
+ return;
28
+ } if (key === 'edit') {
29
+ selectedId.value = s.id;
30
+ form.setFormData({ title: s.title, name: s.name, template: s.template });
31
+ editor.value = true;
32
+ return;
33
+ } remove([s.id]); }
34
+ const table = useTable({ pageParam: { current: 1, pageSize: 5, total: 0 }, columns: [
35
+ { key: 'title', title: '服务名称', dataIndex: 'title', width: 170 }, { key: 'name', title: '服务标识', dataIndex: 'name', width: 160 },
36
+ { key: 'template', title: '工程模板', width: 240, render: (_, s) => (templates.find(t => t.value === s.template)?.label || s.template) + ' · v1.0(模拟)' },
37
+ { key: 'createdBy', title: '创建人', dataIndex: 'createdBy', width: 100 }, { key: 'createdAt', title: '创建时间', dataIndex: 'createdAt', width: 180, render: (v) => formatDate(String(v)) },
38
+ { key: 'createdDept', title: '创建部门', dataIndex: 'createdDept', width: 140 }, { key: 'updatedBy', title: '修改人', dataIndex: 'updatedBy', width: 100 }, { key: 'updatedAt', title: '修改时间', dataIndex: 'updatedAt', width: 180, render: (v) => formatDate(String(v)) },
39
+ { key: 'actions', title: '操作', width: 160, render: (_, record) => { const s = record; return h('div', { class: 'row-actions' }, [h(Button, { type: 'link', disabled: !editable.value, onClick: () => more('edit', s) }, () => '编辑'), h(ListMore, { name: s.title, items: [{ key: 'detail', label: '查看详情' }, { key: 'delete', label: '删除草稿服务', danger: true, disabled: !editable.value }], onAction: (key) => more(key, s) })]); } },
40
+ ] });
41
+ const columns = new Map(table.columns.value.map(c => [c.key, c]));
42
+ watch(prefs.keys, keys => table.columns.value = keys.map(k => columns.get(k)).filter(Boolean), { immediate: true });
43
+ const visible = computed(() => props.services.filter(s => !s.isDeleted && (s.title + s.name).includes(keyword.value.trim())).sort((a, b) => descending.value ? b.name.localeCompare(a.name) : a.name.localeCompare(b.name)));
44
+ watch([visible, () => table.pageParam.current, () => table.pageParam.pageSize], () => { const size = table.pageParam.pageSize || 5, max = Math.max(1, Math.ceil(visible.value.length / size)); if ((table.pageParam.current || 1) > max)
45
+ table.setPageParam({ current: max }); const start = ((table.pageParam.current || 1) - 1) * size; table.dataSource.value = visible.value.slice(start, start + size); table.setPageParam({ total: visible.value.length }); }, { immediate: true });
46
+ const selection = useListSelection(table.dataSource, computed(() => JSON.stringify([session.key, table.pageParam.current, table.pageParam.pageSize, keyword.value, descending.value])), editable, s => s.title);
47
+ function add() { selectedId.value = ''; form.setFormData({ title: '', name: '', template: 'java' }); error.value = ''; editor.value = true; }
48
+ async function save() {
49
+ try {
50
+ await form.formRef.value?.validate();
51
+ }
52
+ catch {
53
+ return;
54
+ }
55
+ if (!editable.value)
56
+ return;
57
+ if (form.formData.name.length > 35 || visible.value.some(s => s.id !== selectedId.value && s.name === form.formData.name)) {
58
+ error.value = '服务标识重复或超过 35 个字符。';
59
+ return;
60
+ }
61
+ const at = new Date().toISOString(), old = props.services.find(s => s.id === selectedId.value), next = { ...(old || metadata(session.actor, at, props.tenantId)), ...form.formData, templateVersion: '1.0', id: old?.id || crypto.randomUUID(), recordVersion: (old?.recordVersion || 0) + 1, updatedAt: at, updatedBy: session.actor.name };
62
+ emit('change', old ? props.services.map(s => s.id === old.id ? next : s) : [...props.services, next]);
63
+ editor.value = false;
64
+ error.value = '';
65
+ }
66
+ function remove(ids) { if (!editable.value || !ids.length)
67
+ return; const rows = visible.value.filter(s => ids.includes(s.id)); confirmAction({ title: '删除 ' + rows.length + ' 个服务草稿?', content: rows.map(s => s.title + ' (' + s.name + ')').join('、') + '。仅修改本次服务方案,保存向导后持久保留。', okText: '确认删除', cancelText: '取消', onOk: () => { if (!editable.value)
68
+ throw Error('权限已变化'); const at = new Date().toISOString(); emit('change', props.services.map(s => ids.includes(s.id) ? { ...s, isDeleted: true, recordVersion: s.recordVersion + 1, updatedBy: session.actor.name, updatedAt: at } : s)); selection.clear(); } }); }
69
+ return { computed, ref, watch, h, Alert, Button, Drawer, Space, Input, ProForm, ProTable, useForm, useTable, useSession, formatDate, metadata, useColumns, useListSelection, ListMore, ListBatchBar, ColumnSettings, RecordMetadata, confirmAction, templates, props, emit, session, editable, error, editor, selectedId, detail, keyword, descending, form, prefs, more, table, columns, visible, selection, add, save, remove };
70
+ } });
@@ -0,0 +1,8 @@
1
+ import { actors, metadata } from "../shared/policy.js";
2
+ export function seedPbcs() {
3
+ return ['供热工单', '客户服务', '能源台账', '知识助手', '运营报表', '收费管理', '巡检管理'].map((name, n) => ({ ...metadata(actors[0], new Date(Date.UTC(2026, 8, 8, 9, 10 - n)).toISOString(), n === 6 ? 'north' : 'heating'), id: 'pbc-' + n, name, resourceKey: name, ebc: n < 2 ? '客户服务与工单履约' : '业务运营与支撑', owner: n < 2 ? '林晓' : '周晨', slug: n === 0 ? 'heating-workorder' : 'business-' + n, domain: 'business-' + n + '.example.test', state: n === 4 || n === 5 ? 'archived' : 'active', provisioned: n < 4 || n === 6, description: n === 0 ? '承载供热报修、智能分诊与主管确认派单。设备控制不在本 PBC 演示范围内。' : n === 4 || n === 5 ? '未建立工程的规划样例,可用于归档、恢复与删除评审。' : '预置 PBC 资料,用于交互评审。', services: n === 0 ? [
4
+ { name: 'workorder', title: '工单管理服务', template: 'java', purpose: '管理报修与已确认派单' },
5
+ { name: 'triage-agent', title: '智能分诊 Agent', template: 'agent', purpose: '查询授权资料,形成分类与班组建议' },
6
+ { name: 'web', title: '供热业务工作台', template: 'web', purpose: '报修、主管确认与工单查询入口' },
7
+ ].map(s => ({ ...s, ...metadata(actors[0], '2026-09-08T09:00:00Z', 'heating'), id: 'heating-' + s.name, templateVersion: '1.0', registered: true, sourceIntentId: 'seed-spec-heating' })) : [] }));
8
+ }
@@ -0,0 +1,62 @@
1
+ import { can, metadata } from "../shared/policy.js";
2
+ import { currentVersion, sourceOf, clone } from "../specs/domain.js";
3
+ export const templates = [{ value: 'java', label: 'Java 服务 · Spring Boot' }, { value: 'agent', label: 'AI Agent · Python + Dapr' }, { value: 'web', label: '独立前端 · Vue 3' }];
4
+ export function assertBinding(i, s, binding) { const v = currentVersion(s); if (!binding || !v || v.number !== binding.specVersion || s.recordVersion !== binding.recordVersion || sourceOf(i).version !== binding.sourceVersion)
5
+ throw Error('复核期间意图或规格版本已变化,请重新打开归属页面核对。'); }
6
+ export const createSteps = ['创建 GitLab Group 与仓库', '生成工程骨架与文档', '配置 Kubernetes / Dapr', '登记 APISIX 路由', '登记 MaxKey 应用', '配置审批回调与产物引用'];
7
+ const slugPattern = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
8
+ export function validateDraft(d, catalog, step = 2) {
9
+ if (!d.name.trim() || !d.ebc.trim() || !d.owner.trim())
10
+ throw Error('请填写 PBC 名称、EBC 归属和负责人。');
11
+ const services = d.services.filter(s => !s.isDeleted);
12
+ if (!services.length)
13
+ throw Error('请至少保留一个服务。');
14
+ if (services.some(s => !slugPattern.test(s.name) || s.name.length > 35 || !s.title.trim() || s.templateVersion !== '1.0' || !templates.some(t => t.value === s.template)))
15
+ throw Error('服务须填写名称、有效标识和模板;标识使用小写字母、数字与短横线。');
16
+ if (new Set(services.map(s => s.name)).size !== services.length)
17
+ throw Error('服务标识不能重复。');
18
+ if (step < 1)
19
+ return;
20
+ if (!slugPattern.test(d.slug) || d.slug.length > 40 || !slugPattern.test(d.prefix) || d.prefix.length > 20)
21
+ throw Error('PBC 标识和应用前缀须以小写字母开头,仅含小写字母、数字和短横线;长度分别不超过 40 / 20。');
22
+ if (!/^(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z]{2,}$/i.test(d.domain) || d.domain.length > 253)
23
+ throw Error('请填写有效域名,例如 triage.example.test。');
24
+ if (catalog.some(p => !p.isDeleted && (p.slug === d.slug || p.domain.toLowerCase() === d.domain.toLowerCase())))
25
+ throw Error('PBC 标识或域名已被使用,请更换。');
26
+ const appIds = services.map(s => d.prefix + '-' + s.name);
27
+ if (appIds.some(id => id.length > 63))
28
+ throw Error('生成的应用标识超过 63 个字符,请缩短前缀或服务标识。');
29
+ if (catalog.some(p => p.services.some(s => !s.isDeleted && appIds.includes(s.id))))
30
+ throw Error('应用标识已被使用,请更换前缀。');
31
+ }
32
+ export function assertSource(i, s, actor, action) {
33
+ const v = currentVersion(s), source = sourceOf(i);
34
+ if (!can(actor, action, s.tenantId) || i.tenantId !== s.tenantId)
35
+ throw Error('没有此操作权限或超出授权租户范围。');
36
+ if (!v?.confirmedAt || v.source.version !== source.version || s.intentId !== i.id)
37
+ throw Error('请先确认与当前意图一致的规格版本。');
38
+ return v;
39
+ }
40
+ export function newDraft(i, actor, at) {
41
+ return { ...metadata(actor, at, i.tenantId), id: 'draft-' + i.id, intentId: i.id, name: '供热智能分诊', ebc: '客户服务与工单履约', owner: actor.name, slug: 'heating-triage', prefix: 'triage', domain: 'triage.example.test', step: 0, services: [
42
+ { id: 'draft-service-1', name: 'workorder', title: '工单管理服务', template: 'java', templateVersion: '1.0', ...metadata(actor, at, i.tenantId) },
43
+ { id: 'draft-service-2', name: 'triage-agent', title: '智能分诊 Agent', template: 'agent', templateVersion: '1.0', ...metadata(actor, at, i.tenantId) },
44
+ { id: 'draft-service-3', name: 'console', title: '业务工作台', template: 'web', templateVersion: '1.0', ...metadata(actor, at, i.tenantId) },
45
+ ] };
46
+ }
47
+ export function makeJob(i, s, actor, target, draft) {
48
+ const v = assertSource(i, s, actor, draft ? 'pbc:create' : 'pbc:link'), at = new Date().toISOString();
49
+ if (target.tenantId !== i.tenantId || !can(actor, 'pbc:view', target.tenantId, target.id) || (!draft && !can(actor, 'pbc:link', target.tenantId, target.id)))
50
+ throw Error('目标 PBC 不在当前意图租户或授权范围。');
51
+ return { ...metadata(actor, at, i.tenantId), id: crypto.randomUUID(), intentId: i.id, specVersion: v.number, sourceVersion: v.source.version, spec: clone(v), kind: draft ? 'create' : 'link', pbc: clone(target), draft: draft && clone(draft), status: 'running', steps: (draft ? createSteps : ['归档意图与规格,登记 PBC 关联']).map(name => ({ name, state: 'waiting', detail: '' })), events: [{ at, actor: actor.name, text: '提交 ' + (draft ? '创建' : '关联') + ';绑定意图 v' + v.source.version + ' / 规格 v' + v.number }] };
52
+ }
53
+ export function activeStep(job) { return job.steps.findIndex(s => s.state !== 'done'); }
54
+ export function queryReceipt(job) {
55
+ const next = clone(job), index = activeStep(next), step = next.steps[index];
56
+ if (!step || step.state !== 'unknown')
57
+ throw Error('当前没有结果待核实的步骤。');
58
+ step.state = step.receipt ? 'done' : 'waiting';
59
+ step.detail = step.receipt ? '已核实原操作已完成(模拟)' : '原操作尚未执行,可继续(模拟)';
60
+ next.status = next.steps.every(s => s.state === 'done') ? 'done' : 'paused';
61
+ return next;
62
+ }
@@ -0,0 +1,36 @@
1
+ import { metadata } from "../shared/policy.js";
2
+ import { templates } from "./domain.js";
3
+ export const stateOf = (p) => p.state || 'active';
4
+ export const stateLabel = (p) => stateOf(p) === 'archived' ? '已归档' : '使用中';
5
+ export function requireReason(reason) { if (!reason.trim() || reason.length > 500)
6
+ throw Error('请填写变更原因,最多 500 字。'); }
7
+ export function assertActive(p) { if (p.isDeleted || stateOf(p) === 'archived')
8
+ throw Error('PBC 已归档或不可用,请先恢复后操作。'); }
9
+ export function revisePbc(p, input, actor, at) {
10
+ assertActive(p);
11
+ if (!input.name.trim() || input.name.length > 60 || !input.ebc.trim() || input.ebc.length > 80 || !input.owner.trim() || input.owner.length > 60 || input.description.length > 1000)
12
+ throw Error('请填写名称、EBC 和负责人;名称/负责人最多 60 字、EBC 80 字、说明 1000 字。');
13
+ return { ...p, name: input.name.trim(), ebc: input.ebc.trim(), owner: input.owner.trim(), description: input.description.trim(), resourceKey: p.resourceKey || p.name, updatedBy: actor.name, updatedAt: at, recordVersion: p.recordVersion + 1 };
14
+ }
15
+ export function assertPbcRemovable(p, refs) {
16
+ if (stateOf(p) !== 'archived')
17
+ throw Error('请先归档,再核对删除条件。');
18
+ if (p.provisioned)
19
+ throw Error('已有工程资源,不能直接删除;需先完成正式退役流程。');
20
+ if (refs.length)
21
+ throw Error('存在关联需求、交付或资源引用,不能删除。');
22
+ if (p.services.some(s => !s.isDeleted))
23
+ throw Error('仍有服务或服务方案,不能删除。');
24
+ }
25
+ export function reviseService(p, old, input, actor, at) {
26
+ assertActive(p);
27
+ if (!/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/.test(input.name) || input.name.length > 35 || !input.title.trim() || input.title.length > 60 || !templates.some(t => t.value === input.template) || !input.purpose.trim() || input.purpose.length > 500)
28
+ throw Error('请填写有效服务标识、名称、模板及职责说明;标识最多 35 字、名称 60 字、职责 500 字。');
29
+ if (p.services.some(s => !s.isDeleted && s.id !== old?.id && s.name === input.name))
30
+ throw Error('同一 PBC 下服务标识不能重复。');
31
+ if (old?.registered && (old.name !== input.name || old.template !== input.template || old.sourceIntentId !== input.sourceIntentId))
32
+ throw Error('已登记工程的服务标识、类型和来源不可修改。');
33
+ return { ...(old || { ...metadata(actor, at, p.tenantId), id: crypto.randomUUID(), templateVersion: '1.0', registered: false }), name: input.name, title: input.title.trim(), template: input.template, purpose: input.purpose.trim(), sourceIntentId: input.sourceIntentId, updatedBy: actor.name, updatedAt: at, recordVersion: old ? old.recordVersion + 1 : 1 };
34
+ }
35
+ export function assertServiceRemovable(p, s) { assertActive(p); if (s.registered)
36
+ throw Error('已登记工程的服务不可在此删除,需按正式退役流程处理。'); }