@givolt/i3-composer-agent 2.3.7 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (497) hide show
  1. package/.agents/plugins/marketplace.json +1 -1
  2. package/.claude/commands/i3-sop.md +19 -0
  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 +19 -0
  8. package/.gemini/commands/i3-ui-demo.toml +21 -0
  9. package/README.md +42 -6
  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 +19 -0
  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/upstream-repository/AGENTS.md +92 -0
  26. package/docs/upstream-repository/CLAUDE.md +60 -0
  27. package/docs/upstream-repository/CONTRIBUTING.md +137 -0
  28. package/docs/upstream-repository/README.md +8 -0
  29. package/docs/upstream-repository/gitattributes.txt +1 -0
  30. package/docs/upstream-repository/gitignore.txt +10 -0
  31. package/docs/upstream-repository/manifest.json +71 -0
  32. package/docs/upstream-repository/opencode-skills.link +1 -0
  33. package/docs/upstream-repository/skill-gap.yml +80 -0
  34. package/docs/upstream-repository/skills-contributing.md +15 -0
  35. package/docs/upstream-repository/test-plugin-install.yml +167 -0
  36. package/docs/workbuddy-setup.md +7 -10
  37. package/evals/cases/i3-enterprise-sop.json +64 -0
  38. package/evals/cases/i3-ui-demo.json +98 -0
  39. package/evals/fixtures/i3-enterprise-sop/brief.md +11 -0
  40. package/evals/fixtures/i3-ui-demo/asset-management.md +25 -0
  41. package/evals/zh-CN/cases/i3-enterprise-sop.json +61 -0
  42. package/evals/zh-CN/cases/i3-ui-demo.json +103 -0
  43. package/hooks/PROTOTYPE.md +16 -8
  44. package/hooks/i3-prototype.cjs +4 -10
  45. package/hooks/manage.cjs +30 -31
  46. package/package.json +48 -5
  47. package/plugin.json +1 -1
  48. package/scripts/ui-demo-dependencies-test.js +228 -0
  49. package/scripts/ui-demo-mcp-test.js +95 -0
  50. package/scripts/ui-demo-test.js +170 -0
  51. package/scripts/ui-prototype-execution-runtime-test.js +1 -1
  52. package/scripts/ui-prototype-native-test.js +25 -3
  53. package/skills/i3-enterprise-sop/SKILL.md +173 -0
  54. package/skills/i3-enterprise-sop/agents/openai.yaml +2 -0
  55. package/skills/i3-enterprise-sop/references/ad/assets-manifest.json +86 -0
  56. package/skills/i3-enterprise-sop/references/ad/prompts/01-generate.md +58 -0
  57. package/skills/i3-enterprise-sop/references/ad/prompts/02-review.md +54 -0
  58. package/skills/i3-enterprise-sop/references/ad/prompts/03-revise.md +54 -0
  59. package/skills/i3-enterprise-sop/references/ad/prompts/04-recheck.md +54 -0
  60. package/skills/i3-enterprise-sop/references/ad/readme.md +70 -0
  61. package/skills/i3-enterprise-sop/references/ad/templates/ad.md +337 -0
  62. package/skills/i3-enterprise-sop/references/assets-manifest.json +230 -0
  63. package/skills/i3-enterprise-sop/references/brd/assets-manifest.json +83 -0
  64. package/skills/i3-enterprise-sop/references/brd/prompts/01-generate.md +51 -0
  65. package/skills/i3-enterprise-sop/references/brd/prompts/02-review.md +47 -0
  66. package/skills/i3-enterprise-sop/references/brd/prompts/03-revise.md +47 -0
  67. package/skills/i3-enterprise-sop/references/brd/prompts/04-recheck.md +47 -0
  68. package/skills/i3-enterprise-sop/references/brd/readme.md +50 -0
  69. package/skills/i3-enterprise-sop/references/brd/templates/brd.md +169 -0
  70. package/skills/i3-enterprise-sop/references/codebuddy-project-guide.md +34 -0
  71. package/skills/i3-enterprise-sop/references/controlled-handoff.md +41 -0
  72. package/skills/i3-enterprise-sop/references/controlled_handoff.py +379 -0
  73. package/skills/i3-enterprise-sop/references/engineering-skeleton/adoption.md +200 -0
  74. package/skills/i3-enterprise-sop/references/engineering-skeleton/catalog.json +17 -0
  75. package/skills/i3-enterprise-sop/references/engineering-skeleton/directory-standard.md +119 -0
  76. package/skills/i3-enterprise-sop/references/engineering-skeleton/readme.md +52 -0
  77. package/skills/i3-enterprise-sop/references/handoff-contract.md +196 -0
  78. package/skills/i3-enterprise-sop/references/handoff.py +277 -0
  79. package/skills/i3-enterprise-sop/references/lifecycle-contract.md +91 -0
  80. package/skills/i3-enterprise-sop/references/plan-handoff.md +73 -0
  81. package/skills/i3-enterprise-sop/references/prd/assets-manifest.json +109 -0
  82. package/skills/i3-enterprise-sop/references/prd/prompts/01-generate.md +64 -0
  83. package/skills/i3-enterprise-sop/references/prd/prompts/02-review.md +49 -0
  84. package/skills/i3-enterprise-sop/references/prd/prompts/03-revise.md +48 -0
  85. package/skills/i3-enterprise-sop/references/prd/prompts/04-recheck.md +47 -0
  86. package/skills/i3-enterprise-sop/references/prd/readme.md +137 -0
  87. package/skills/i3-enterprise-sop/references/prd/template-contracts.md +39 -0
  88. package/skills/i3-enterprise-sop/references/prd/templates/ad.md +17 -0
  89. package/skills/i3-enterprise-sop/references/prd/templates/prd.md +257 -0
  90. package/skills/i3-enterprise-sop/references/readme.md +167 -0
  91. package/skills/i3-enterprise-sop/references/recovery-contract.md +65 -0
  92. package/skills/i3-enterprise-sop/references/review-handoff.md +105 -0
  93. package/skills/i3-enterprise-sop/references/selection-handoff.md +55 -0
  94. package/skills/i3-enterprise-sop/references/selection_handoff.py +225 -0
  95. package/skills/i3-enterprise-sop/references/stages.json +271 -0
  96. package/skills/i3-enterprise-sop/references/technical-baseline/assets-manifest.json +84 -0
  97. package/skills/i3-enterprise-sop/references/technical-baseline/baselines/enterprise-application-technical-baseline-v0-0-4.md +380 -0
  98. package/skills/i3-enterprise-sop/references/technical-baseline/readme.md +132 -0
  99. package/skills/i3-enterprise-sop/references/technical-baseline/templates/technical-baseline.md +133 -0
  100. package/skills/i3-enterprise-sop/references/template-contracts.md +142 -0
  101. package/skills/i3-enterprise-sop/references/testcase/assets-manifest.json +91 -0
  102. package/skills/i3-enterprise-sop/references/testcase/prompts/01-generate.md +53 -0
  103. package/skills/i3-enterprise-sop/references/testcase/prompts/02-review.md +51 -0
  104. package/skills/i3-enterprise-sop/references/testcase/prompts/03-revise.md +49 -0
  105. package/skills/i3-enterprise-sop/references/testcase/prompts/04-recheck.md +51 -0
  106. package/skills/i3-enterprise-sop/references/testcase/readme.md +61 -0
  107. package/skills/i3-enterprise-sop/references/testcase/templates/testcase.md +269 -0
  108. package/skills/i3-enterprise-sop/references/verification/check_execution.py +185 -0
  109. package/skills/i3-enterprise-sop/references/verification/check_native_execution.py +282 -0
  110. package/skills/i3-enterprise-sop/references/verification/check_reads.py +348 -0
  111. package/skills/i3-enterprise-sop/references/verification/readme.md +149 -0
  112. package/skills/i3-enterprise-sop/references/verification/review-output.schema.json +155 -0
  113. package/skills/i3-enterprise-sop/references/verification/review_handoff.py +329 -0
  114. package/skills/i3-ui-demo/SKILL.md +234 -0
  115. package/skills/i3-ui-demo/assets/antdv-build/package-lock.json +3363 -0
  116. package/skills/i3-ui-demo/assets/antdv-build/package.json +28 -0
  117. package/skills/i3-ui-demo/assets/design-source.json +11 -0
  118. package/skills/i3-ui-demo/assets/host-targets.json +739 -0
  119. package/skills/i3-ui-demo/assets/official-files.json +76 -0
  120. package/skills/i3-ui-demo/assets/starter/index.html +11 -0
  121. package/skills/i3-ui-demo/assets/starter/package-lock.json +2299 -0
  122. package/skills/i3-ui-demo/assets/starter/package.json +28 -0
  123. package/skills/i3-ui-demo/assets/starter/provenance.json +14 -0
  124. package/skills/i3-ui-demo/assets/starter/public/prototype-config.json +22 -0
  125. package/skills/i3-ui-demo/assets/starter/src/App.vue +64 -0
  126. package/skills/i3-ui-demo/assets/starter/src/PrototypeShell.vue +59 -0
  127. package/skills/i3-ui-demo/assets/starter/src/config.ts +23 -0
  128. package/skills/i3-ui-demo/assets/starter/src/domain/presentation.ts +30 -0
  129. package/skills/i3-ui-demo/assets/starter/src/domain/theme.ts +25 -0
  130. package/skills/i3-ui-demo/assets/starter/src/main.ts +18 -0
  131. package/skills/i3-ui-demo/assets/starter/src/style.css +26 -0
  132. package/skills/i3-ui-demo/assets/starter/tests/presentation.test.ts +23 -0
  133. package/skills/i3-ui-demo/assets/starter/tests/theme.test.ts +26 -0
  134. package/skills/i3-ui-demo/assets/starter/tsconfig.json +15 -0
  135. package/skills/i3-ui-demo/assets/starter/vite.config.ts +4 -0
  136. package/skills/i3-ui-demo/assets/templates/enterprise-admin/capability-definition.json +1395 -0
  137. package/skills/i3-ui-demo/assets/templates/enterprise-admin/component-inventory.json +707 -0
  138. package/skills/i3-ui-demo/assets/templates/enterprise-admin/design-system.md +26 -0
  139. package/skills/i3-ui-demo/assets/templates/enterprise-admin/generation.json +49 -0
  140. package/skills/i3-ui-demo/assets/templates/enterprise-admin/index.html +534 -0
  141. package/skills/i3-ui-demo/assets/templates/enterprise-admin/manifest.json +9 -0
  142. package/skills/i3-ui-demo/assets/templates/enterprise-admin/offline-build.json +265 -0
  143. package/skills/i3-ui-demo/assets/templates/enterprise-admin/offline.js +8888 -0
  144. package/skills/i3-ui-demo/assets/templates/enterprise-admin/origin.json +344 -0
  145. package/skills/i3-ui-demo/assets/templates/enterprise-admin/preset.json +928 -0
  146. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/app.js +22 -0
  147. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/assets/empty.svg +1 -0
  148. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/assets/reference-styles.json +1 -0
  149. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/assets/result-403.svg +1 -0
  150. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/assets/result-404.svg +1 -0
  151. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/assets-manifest.json +334 -0
  152. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/baseline.json +173 -0
  153. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/conversion.md +30 -0
  154. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/credits.md +17 -0
  155. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/design-tokens.json +881 -0
  156. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/index.html +28 -0
  157. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/licenses/@qin-ui-antdv-next-pro.txt +9 -0
  158. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/licenses/ant-design-icons.txt +22 -0
  159. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/licenses/antdv-next.txt +21 -0
  160. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/package.json +12 -0
  161. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/browser-routes.json +298 -0
  162. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/coverage.json +180 -0
  163. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/integrity.json +13 -0
  164. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/keyboard.json +11 -0
  165. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/responsive.json +125 -0
  166. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/review.md +51 -0
  167. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/rules.log +150 -0
  168. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/flow-editor-html.png +0 -0
  169. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/flow-editor-original.png +0 -0
  170. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/intent-create-html.png +0 -0
  171. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/intent-create-original.png +0 -0
  172. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/models-html.png +0 -0
  173. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/models-original.png +0 -0
  174. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/workbench-html.png +0 -0
  175. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/screenshots/workbench-original.png +0 -0
  176. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/selection.json +9 -0
  177. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/qa/visual-comparison.json +342 -0
  178. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/readme.md +73 -0
  179. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/reference.md +59 -0
  180. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/routes.json +178 -0
  181. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/controls.js +99 -0
  182. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/dialogs.js +54 -0
  183. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/dom.js +264 -0
  184. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/forms.js +47 -0
  185. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/icons.js +41 -0
  186. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/layout.js +47 -0
  187. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/router.js +63 -0
  188. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/state.js +90 -0
  189. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/table.js +41 -0
  190. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/runtime/widgets.js +8 -0
  191. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/AgentDetail.html +3 -0
  192. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/AgentDetail.js +36 -0
  193. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/AgentEditor.html +2 -0
  194. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/AgentEditor.js +51 -0
  195. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/AgentsPage.html +3 -0
  196. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/AgentsPage.js +48 -0
  197. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/CheckResults.html +2 -0
  198. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/CheckResults.js +6 -0
  199. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/ResourcePicker.html +2 -0
  200. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/ResourcePicker.js +13 -0
  201. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/data.js +24 -0
  202. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/domain.js +32 -0
  203. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/registry.js +25 -0
  204. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/agents/store.js +85 -0
  205. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentClose.html +2 -0
  206. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentClose.js +17 -0
  207. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentCreate.html +2 -0
  208. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentCreate.js +66 -0
  209. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentDecisions.html +3 -0
  210. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentDecisions.js +38 -0
  211. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentDetail.html +2 -0
  212. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentDetail.js +66 -0
  213. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentDocument.html +2 -0
  214. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentDocument.js +5 -0
  215. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentHeader.html +2 -0
  216. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentHeader.js +12 -0
  217. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentHistory.html +2 -0
  218. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentHistory.js +11 -0
  219. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentList.html +2 -0
  220. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentList.js +116 -0
  221. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentReplan.html +2 -0
  222. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentReplan.js +32 -0
  223. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentRevision.html +2 -0
  224. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentRevision.js +49 -0
  225. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentSummary.html +2 -0
  226. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentSummary.js +10 -0
  227. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentWorkspace.html +2 -0
  228. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/IntentWorkspace.js +77 -0
  229. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/data.js +60 -0
  230. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/domain.js +105 -0
  231. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/intents/store.js +212 -0
  232. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/AuditPanel.html +2 -0
  233. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/AuditPanel.js +18 -0
  234. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelDetail.html +2 -0
  235. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelDetail.js +23 -0
  236. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelEditor.html +2 -0
  237. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelEditor.js +78 -0
  238. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelGrant.html +2 -0
  239. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelGrant.js +55 -0
  240. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelReferences.html +2 -0
  241. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelReferences.js +26 -0
  242. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelRelease.html +2 -0
  243. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelRelease.js +38 -0
  244. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelStatus.html +2 -0
  245. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelStatus.js +7 -0
  246. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelTable.html +2 -0
  247. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelTable.js +72 -0
  248. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelTester.html +2 -0
  249. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelTester.js +46 -0
  250. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelsPage.html +2 -0
  251. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/ModelsPage.js +52 -0
  252. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/RowActions.html +2 -0
  253. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/RowActions.js +19 -0
  254. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/UsagePanel.html +2 -0
  255. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/UsagePanel.js +30 -0
  256. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/data.js +48 -0
  257. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/domain.js +39 -0
  258. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/models/store.js +129 -0
  259. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/IncidentDetail.html +4 -0
  260. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/IncidentDetail.js +21 -0
  261. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/IntentSource.html +2 -0
  262. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/IntentSource.js +8 -0
  263. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/OperationActionDialog.html +2 -0
  264. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/OperationActionDialog.js +37 -0
  265. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/OperationEntry.html +2 -0
  266. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/OperationEntry.js +10 -0
  267. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/OperationsPage.html +2 -0
  268. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/OperationsPage.js +37 -0
  269. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/RepairTrack.html +2 -0
  270. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/RepairTrack.js +49 -0
  271. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/RunDetail.html +4 -0
  272. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/RunDetail.js +22 -0
  273. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/SourceSummary.html +2 -0
  274. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/SourceSummary.js +9 -0
  275. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/commands.js +82 -0
  276. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/examples.js +47 -0
  277. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/model.js +61 -0
  278. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/repair.js +68 -0
  279. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/store.js +55 -0
  280. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/types.js +1 -0
  281. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/operations/workbench.js +18 -0
  282. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/ManagementTable.html +3 -0
  283. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/ManagementTable.js +28 -0
  284. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcCreateEntry.html +2 -0
  285. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcCreateEntry.js +18 -0
  286. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcDetail.html +2 -0
  287. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcDetail.js +31 -0
  288. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcEditor.html +2 -0
  289. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcEditor.js +27 -0
  290. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcLifecycle.html +2 -0
  291. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcLifecycle.js +16 -0
  292. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcPage.html +2 -0
  293. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcPage.js +43 -0
  294. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcPicker.html +4 -0
  295. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcPicker.js +34 -0
  296. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcProgress.html +2 -0
  297. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcProgress.js +30 -0
  298. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcWizard.html +3 -0
  299. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcWizard.js +67 -0
  300. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcWorkspace.html +2 -0
  301. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcWorkspace.js +41 -0
  302. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcsPage.html +2 -0
  303. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/PbcsPage.js +31 -0
  304. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/ServiceEditor.html +2 -0
  305. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/ServiceEditor.js +26 -0
  306. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/ServiceList.html +2 -0
  307. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/ServiceList.js +70 -0
  308. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/data.js +8 -0
  309. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/domain.js +62 -0
  310. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/management.js +36 -0
  311. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/managementStore.js +49 -0
  312. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/pbc/store.js +132 -0
  313. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/AdminList.html +2 -0
  314. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/AdminList.js +38 -0
  315. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/EffectiveGrants.html +2 -0
  316. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/EffectiveGrants.js +11 -0
  317. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/GrantEditor.html +2 -0
  318. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/GrantEditor.js +45 -0
  319. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/MemberEditor.html +2 -0
  320. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/MemberEditor.js +54 -0
  321. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/MembersPage.html +3 -0
  322. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/MembersPage.js +27 -0
  323. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/RecordsPage.html +2 -0
  324. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/RecordsPage.js +12 -0
  325. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/RoleEditor.html +2 -0
  326. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/RoleEditor.js +45 -0
  327. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/RolesPage.html +3 -0
  328. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/RolesPage.js +38 -0
  329. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/domain.js +61 -0
  330. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/state.js +51 -0
  331. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/permissions/store.js +116 -0
  332. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseActionDialog.html +2 -0
  333. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseActionDialog.js +45 -0
  334. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseDetail.html +4 -0
  335. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseDetail.js +30 -0
  336. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseEditor.html +2 -0
  337. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseEditor.js +67 -0
  338. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseExecution.html +2 -0
  339. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleaseExecution.js +5 -0
  340. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleasesPage.html +4 -0
  341. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/ReleasesPage.js +60 -0
  342. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/commands.js +157 -0
  343. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/model.js +136 -0
  344. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/releases/store.js +76 -0
  345. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewDetail.html +3 -0
  346. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewDetail.js +26 -0
  347. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewEvidence.html +2 -0
  348. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewEvidence.js +14 -0
  349. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewProcess.html +2 -0
  350. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewProcess.js +113 -0
  351. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewsPage.html +3 -0
  352. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/ReviewsPage.js +62 -0
  353. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/commands.js +97 -0
  354. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/model.js +147 -0
  355. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/reviews/store.js +13 -0
  356. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ColumnSettings.html +2 -0
  357. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ColumnSettings.js +9 -0
  358. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ListBatchBar.html +2 -0
  359. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ListBatchBar.js +8 -0
  360. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ListDeleteDialog.html +2 -0
  361. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ListDeleteDialog.js +37 -0
  362. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ListMore.html +2 -0
  363. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/ListMore.js +8 -0
  364. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/RecordMetadata.html +2 -0
  365. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/RecordMetadata.js +17 -0
  366. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/columns.js +32 -0
  367. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/deliveryGuide.js +49 -0
  368. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/deliveryView.js +12 -0
  369. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/listBatch.js +15 -0
  370. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/listSelection.js +37 -0
  371. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/policy.js +68 -0
  372. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shared/session.js +44 -0
  373. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/ConfirmationDialog.html +2 -0
  374. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/ConfirmationDialog.js +25 -0
  375. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/ConsoleShell.html +2 -0
  376. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/ConsoleShell.js +53 -0
  377. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/PrototypeGuide.html +10 -0
  378. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/PrototypeGuide.js +30 -0
  379. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/ScopePage.html +2 -0
  380. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/ScopePage.js +10 -0
  381. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/SessionDialog.html +2 -0
  382. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/SessionDialog.js +9 -0
  383. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/confirmation.js +3 -0
  384. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/shell/navigation.js +19 -0
  385. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecDocument.html +2 -0
  386. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecDocument.js +8 -0
  387. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecEdit.html +2 -0
  388. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecEdit.js +32 -0
  389. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecHeader.html +2 -0
  390. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecHeader.js +15 -0
  391. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecHistory.html +2 -0
  392. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecHistory.js +11 -0
  393. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecReview.html +2 -0
  394. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecReview.js +57 -0
  395. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecWorkspace.html +2 -0
  396. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/SpecWorkspace.js +37 -0
  397. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/data.js +20 -0
  398. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/domain.js +55 -0
  399. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/specs/store.js +151 -0
  400. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/ArtifactDetail.html +3 -0
  401. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/ArtifactDetail.js +18 -0
  402. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TaskCreate.html +2 -0
  403. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TaskCreate.js +40 -0
  404. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TaskDetail.html +2 -0
  405. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TaskDetail.js +51 -0
  406. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TaskLaunch.html +2 -0
  407. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TaskLaunch.js +9 -0
  408. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TasksPage.html +5 -0
  409. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/TasksPage.js +48 -0
  410. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/domain.js +204 -0
  411. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/exampleSource.js +22 -0
  412. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/registry.js +135 -0
  413. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/tasks/store.js +137 -0
  414. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workbench/WorkbenchPage.html +3 -0
  415. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workbench/WorkbenchPage.js +36 -0
  416. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workbench/model.js +56 -0
  417. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workbench/store.js +15 -0
  418. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/FlowCanvas.html +2 -0
  419. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/FlowCanvas.js +27 -0
  420. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/FlowDetail.html +4 -0
  421. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/FlowDetail.js +31 -0
  422. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/FlowEditor.html +2 -0
  423. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/FlowEditor.js +68 -0
  424. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/WorkflowsPage.html +5 -0
  425. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/WorkflowsPage.js +55 -0
  426. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/data.js +16 -0
  427. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/domain.js +83 -0
  428. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/registry.js +18 -0
  429. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/src/workflows/store.js +61 -0
  430. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/admin.css +60 -0
  431. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/agents.css +46 -0
  432. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/antdv.css +295 -0
  433. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/app.css +102 -0
  434. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/delivery.css +4 -0
  435. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/intents.css +37 -0
  436. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/native.css +22 -0
  437. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/operations.css +2 -0
  438. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/pbc.css +3 -0
  439. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/permissions.css +22 -0
  440. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/pro.css +1 -0
  441. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/releases.css +4 -0
  442. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/reset.css +246 -0
  443. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/reviews.css +8 -0
  444. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/tasks.css +6 -0
  445. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/tokens.css +15 -0
  446. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/workbench.css +61 -0
  447. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/styles/workflows.css +1 -0
  448. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/admin-rules.test.js +96 -0
  449. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/agents.test.js +14 -0
  450. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/intent-state.test.js +37 -0
  451. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/list-batch.test.js +44 -0
  452. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/operation-fixtures.js +19 -0
  453. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/operation-repair.test.js +14 -0
  454. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/operations.test.js +25 -0
  455. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/pbc-management.test.js +17 -0
  456. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/pbc-state.test.js +24 -0
  457. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/permission-config.test.js +23 -0
  458. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/permissions.test.js +24 -0
  459. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/releases.test.js +50 -0
  460. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/reviews.test.js +36 -0
  461. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/runtime-forms-router.test.js +28 -0
  462. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/runtime-state.test.js +42 -0
  463. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/runtime-stores.test.js +16 -0
  464. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/spec-state.test.js +11 -0
  465. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/tasks.test.js +27 -0
  466. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/workbench.test.js +34 -0
  467. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tests/workflows.test.js +16 -0
  468. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tools/convert.mjs +168 -0
  469. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tools/serve.mjs +7 -0
  470. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tools/styles.mjs +11 -0
  471. package/skills/i3-ui-demo/assets/templates/enterprise-admin/reference/tools/verify.mjs +24 -0
  472. package/skills/i3-ui-demo/assets/templates/enterprise-admin/serve.cjs +16 -0
  473. package/skills/i3-ui-demo/assets/templates/enterprise-admin/template-inventory.json +28791 -0
  474. package/skills/i3-ui-demo/assets/templates/enterprise-admin/template.json +9 -0
  475. package/skills/i3-ui-demo/assets/templates/enterprise-admin/usability.css +44 -0
  476. package/skills/i3-ui-demo/assets/templates.json +10 -0
  477. package/skills/i3-ui-demo/assets/versions.json +20 -0
  478. package/skills/i3-ui-demo/readme.md +350 -0
  479. package/skills/i3-ui-demo/references/browser.md +71 -0
  480. package/skills/i3-ui-demo/references/dependencies.md +67 -0
  481. package/skills/i3-ui-demo/references/resources.md +142 -0
  482. package/skills/i3-ui-demo/scripts/dependencies.cjs +364 -0
  483. package/skills/i3-ui-demo/scripts/design-install.cjs +105 -0
  484. package/skills/i3-ui-demo/scripts/design-provider.cjs +57 -0
  485. package/skills/i3-ui-demo/scripts/locations.cjs +52 -0
  486. package/skills/i3-ui-demo/scripts/mcp.cjs +112 -0
  487. package/skills/i3-ui-demo/scripts/provider-discovery.cjs +131 -0
  488. package/skills/i3-ui-demo/scripts/resources.cjs +283 -0
  489. package/skills/i3-ui-prototype/SKILL.md +1 -1
  490. package/skills/i3-ui-prototype/references/execution-evidence.md +12 -56
  491. package/skills/i3-ui-prototype/scripts/codebuddy-registration.cjs +1 -1
  492. package/skills/i3-ui-prototype/scripts/execution-runtime.cjs +5 -2
  493. package/skills/i3-ui-prototype/scripts/hosts/codebuddy.cjs +3 -2
  494. package/skills/i3-ui-prototype/scripts/native-delivery.cjs +2 -2
  495. package/skills/i3-ui-prototype/scripts/prototype-hooks.cjs +23 -20
  496. package/docs/ui-prototype-native/MAIN-SESSION-REPORT.md +0 -66
  497. package/docs/ui-prototype-native/USAGE.md +0 -93
@@ -0,0 +1,534 @@
1
+ <!doctype html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ <title>i3-Composer · Antdv Next 交互原型 · HTML 模板</title>
7
+ <link rel="icon" href="data:,">
8
+ <link rel="stylesheet" href="reference/styles/reset.css">
9
+ <link rel="stylesheet" href="reference/styles/antdv.css">
10
+ <link rel="stylesheet" href="reference/styles/pro.css">
11
+ <link rel="stylesheet" href="reference/styles/tokens.css">
12
+ <link rel="stylesheet" href="reference/styles/app.css">
13
+ <link rel="stylesheet" href="reference/styles/intents.css">
14
+ <link rel="stylesheet" href="reference/styles/admin.css">
15
+ <link rel="stylesheet" href="reference/styles/delivery.css">
16
+ <link rel="stylesheet" href="reference/styles/permissions.css">
17
+ <link rel="stylesheet" href="reference/styles/agents.css">
18
+ <link rel="stylesheet" href="reference/styles/workflows.css">
19
+ <link rel="stylesheet" href="reference/styles/tasks.css">
20
+ <link rel="stylesheet" href="reference/styles/pbc.css">
21
+ <link rel="stylesheet" href="reference/styles/workbench.css">
22
+ <link rel="stylesheet" href="reference/styles/reviews.css">
23
+ <link rel="stylesheet" href="reference/styles/releases.css">
24
+ <link rel="stylesheet" href="reference/styles/operations.css">
25
+ <link rel="stylesheet" href="reference/styles/native.css">
26
+ <link rel="stylesheet" href="usability.css">
27
+ </head>
28
+ <body class="native-theme"><div id="app"><p class="native-boot" role="status">正在加载交互原型…</p></div><noscript>此交互原型需要启用 JavaScript。</noscript><!-- Editable page fragments: change the HTML below and refresh; no build is needed for text/layout edits. -->
29
+ <template data-source="reference/src/agents/AgentDetail.html">
30
+ <!-- 来源:src/agents/AgentDetail.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
31
+ <template data-component="Result" data-if="(!agent)" status="404" title="Agent 不存在或无权访问"><template data-slot="extra"><template data-component="Button" data-on-click="(router.push('/agents'))">返回列表</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('/agents'))">← 返回列表</template><div class="agent-title"><h1>{{ (agent.name) }}</h1><template data-component="Tag" data-bind-color="(agent.enabled ? 'green' : 'default')">{{ (agent.enabled ? '已启用' : '已停用') }}</template></div><p>{{ (agent.description || '暂无用途说明') }}</p></div><template data-component="Space" wrap=""><template data-component="Button" data-bind-disabled="(!can('agent:check'))" data-on-click="(check)">检查配置</template><template data-component="Button" data-bind-disabled="(!can('agent:status') || (!agent.enabled &amp;&amp; !!issues))" data-on-click="(toggle)">{{ (agent.enabled ? '停用 Agent' : '启用 Agent') }}</template><template data-component="Button" type="primary" data-bind-disabled="(!can('agent:edit') || agent.enabled)" data-on-click="(router.push('/agents/' + agent?.id + '/edit'))">编辑配置</template></template></div><template data-component="Alert" data-if="(error)" class="page-alert" type="error" data-bind-title="(error)" show-icon=""></template><template data-component="Alert" data-if="(issues)" class="page-alert" type="warning" show-icon="" data-bind-title="(issues + ' 项配置或授权待处理')" description="可保存配置;处理问题后才能启用。模型授权由有权成员在模型管理中配置。"><template data-slot="action"><template data-component="Button" data-on-click="(active = 'checks')">查看问题</template></template></template><div class="agent-meta-strip"><span>标识 <strong>{{ (agent.code) }}</strong></span><span>职责 <strong>{{ (duties.find(d =&gt; d.value === agent?.duty)?.label) }}</strong></span><span>项目 <strong>{{ (agent.project) }}</strong></span><span>租户 <strong>{{ (tenantLabel(agent.tenantId)) }}</strong></span><span>记录版本 <strong>v{{ (agent.recordVersion) }}</strong></span></div><section class="agent-panel"><template data-component="Tabs" data-model-active-key="(active)" data-bind-items="([{ key: 'config', label: '配置详情' }, { key: 'checks', label: '引用与检查' }, ...(can('agent:audit') ? [{ key: 'records', label: '操作记录' }] : [])])"></template><div data-if="(active === 'config')" class="agent-detail-grid"><div><h2>四要素配置</h2><div class="agent-detail-resource"><div class="agent-section-title"><span>01</span><h3>模型</h3></div><strong>{{ (model?.name || '未选择模型') }}</strong><p class="muted">{{ (model?.version ? '已发布 v' + model.version : '尚未发布') }} · {{ (model?.authorized ? '使用已授权' : '待使用授权') }}</p><p>模型凭据由平台统一托管。</p></div><div data-each="kind in (['prompt', 'skill', 'tool'])" data-bind-key="(kind)" class="agent-detail-resource"><div class="agent-section-title"><span>{{ (kind === 'prompt' ? '02' : kind === 'skill' ? '03' : '04') }}</span><h3>{{ (kind === 'prompt' ? '提示词预设' : kind === 'skill' ? '技能' : '工具白名单') }}</h3></div><template data-each="r in (resources.filter(r =&gt; r.kind === kind))" data-bind-key="(r.id)"><p><strong>{{ (r.name) }}</strong> <template data-component="Tag">{{ (r.version) }}</template></p><p class="muted">{{ (r.description) }}</p><p data-if="(kind === 'prompt')" class="agent-prompt">{{ (r.content) }}</p><p data-if="('allow' in r)" class="agent-allow"><span data-each="op in (r.allow)" data-bind-key="(op)">{{ (op) }}</span></p><small class="muted">{{ ('type' in r ? r.type + ' · ' : '') }}{{ (r.id) }}</small></template><p data-if="(!resources.some(r =&gt; r.kind === kind))" class="muted">未绑定可用资源</p></div><h3>运行边界</h3><p>记忆消息数:{{ (agent.memoryLimit) }} 条;连续工具调用上限:{{ (agent.toolLimit) }} 次。</p></div><template data-component="RecordMetadata" data-bind-record="(agent)" compact=""></template></div><div data-else-if="(active === 'checks')" class="agent-detail-grid"><section><h2>配置与资源检查</h2><template data-component="CheckResults" data-bind-items="(checks)"></template><template data-component="RouterLink" data-if="(session.can('model:grant', 'platform'))" to="/models">前往模型管理配置使用授权 →</template></section><section><h2>引用此 Agent 的流程</h2><div data-each="r in (agent.references)" data-bind-key="(r.name + ':' + r.version)" class="agent-resource"><div><strong>{{ (r.name) }}</strong><p>{{ (r.version) }} · 正在引用</p></div><template data-component="Tag">流程引用</template></div><p data-if="(!agent.references.length)" class="muted">当前没有流程模板引用。</p><p class="muted">删除前须处理草稿与发布版本中的引用;停用模板不会解除历史引用。</p><template data-component="Button" danger="" data-bind-disabled="(!can('agent:delete'))" data-on-click="(targets = [agent])">删除 Agent</template></section></div><section data-else-if="(active === 'records' &amp;&amp; can('agent:audit'))"><h2>操作记录</h2><p data-if="(!store.audit(agent).length)" class="muted">暂无操作记录。保存、启停、检查和删除操作将在此留痕。</p><ol class="agent-audit"><li data-each="entry in (store.audit(agent))" data-bind-key="(entry.id)"><strong>{{ (entry.action) }}</strong><span>{{ (entry.actor) }} · {{ (formatDate(entry.at)) }}</span><p>{{ (entry.detail) }}</p></li></ol></section></section><template data-component="ListDeleteDialog" data-if="(targets.length)" data-model-targets="(targets)" label="Agent" data-bind-check="(store.checkRemove)" data-bind-submit="(store.removeMany)" data-on-close="(targets = [])" data-on-deleted="targets = [];
32
+ router.push('/agents');"></template></template>
33
+
34
+ </template>
35
+ <template data-source="reference/src/agents/AgentEditor.html">
36
+ <!-- 来源:src/agents/AgentEditor.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
37
+ <template data-component="Result" data-if="(!isNew &amp;&amp; !original)" status="404" title="Agent 不存在或无权访问"><template data-slot="extra"><template data-component="Button" data-on-click="(router.push('/agents'))">返回列表</template></template></template><template data-else=""><div class="page-heading"><div><template data-component="Button" class="agent-back" type="link" data-on-click="(router.push(original ? '/agents/' + original.id : '/agents'))">← 返回{{ (original ? '详情' : '列表') }}</template><h1>{{ (isNew ? '注册 Agent' : '配置 Agent') }}</h1><p>组合模型、提示词、技能与工具,明确 Agent 的工作职责。</p></div><template data-component="Space"><template data-component="Button" data-on-click="(router.push('/agents'))">取消</template><template data-component="Button" type="primary" data-bind-disabled="(!allowed)" data-bind-loading="(busy)" data-on-click="(save)">保存配置</template></template></div><template data-component="Alert" data-if="(!allowed)" class="page-alert" type="warning" show-icon="" data-bind-title="(original?.enabled ? 'Agent 已启用,请先停用后编辑' : '当前身份没有此项目的配置权限')"></template><template data-component="Alert" data-if="(error)" data-agent-error="" class="page-alert" type="error" show-icon="" data-bind-title="(error)" description="本次未提交,输入已保留。"></template><div class="agent-editor-layout"><div><section class="agent-panel"><h2>基本信息</h2><template data-component="Form" layout="vertical" data-bind-disabled="(!allowed || busy)"><div class="agent-form-grid"><template data-component="FormItem" label="Agent 名称" required=""><template data-component="Input" data-model-value="(data.name)" aria-label="Agent 名称" data-bind-maxlength="(60)" placeholder="例如:工单需求规划 Agent"></template></template><template data-component="FormItem" label="Agent 标识" required="" extra="同租户唯一,创建后不可修改。"><template data-component="Input" data-model-value="(data.code)" aria-label="Agent 标识" data-bind-maxlength="(48)" data-bind-disabled="(!isNew)" placeholder="例如:workorder-planner"></template></template><template data-component="FormItem" label="所属项目 / PBC" required=""><template data-component="Select" data-bind-value="(data.pbcId)" aria-label="所属项目 / PBC" data-bind-disabled="(!isNew)" data-bind-options="(store.projects.map(p =&gt; ({ value: p.id, label: p.name + ' · ' + tenantLabel(p.tenantId) })))" data-on-change="(project)"></template></template><template data-component="FormItem" label="Agent 职责" required="" extra="描述 Agent 执行的工作,不决定成员权限。"><template data-component="Select" data-model-value="(data.duty)" aria-label="Agent 职责" data-bind-options="(duties)"></template></template></div><template data-component="FormItem" label="用途说明"><template data-component="Input.TextArea" data-model-value="(data.description)" aria-label="用途说明" data-bind-rows="(2)" data-bind-maxlength="(400)" placeholder="说明它为哪个业务环节提供什么能力"></template></template></template></section><section class="agent-panel"><div class="agent-section-title"><span>01</span><h2>模型</h2></div><p class="muted">选择已登记模型。启用前需具备该项目与 Agent 的模型使用授权。</p><template data-component="Select" data-model-value="(data.modelRef)" class="full-width" aria-label="模型" placeholder="选择模型" data-bind-disabled="(!allowed)" data-bind-options="(models.filter(m =&gt; !m.deleted || m.id === data.modelRef).map(m =&gt; ({ value: m.id, label: m.name + (m.version ? ' · v' + m.version : ' · 未发布') + (!m.enabled ? ' · 已停用' : '') })))"></template><div data-if="(chosenModel)" class="agent-model-summary"><div><strong>{{ (chosenModel.name) }}</strong><template data-component="Tag" data-bind-color="(chosenModel.enabled &amp;&amp; chosenModel.version ? 'green' : 'default')">{{ (chosenModel.version ? '已发布 v' + chosenModel.version : '未发布') }}</template><template data-component="Tag" data-bind-color="(chosenModel.authorized ? 'blue' : 'orange')">{{ (chosenModel.authorized ? '使用已授权' : '待使用授权') }}</template></div><p>{{ (chosenModel.capabilities.join(' · ')) }}</p></div><p class="muted">模型凭据由平台托管。此处只引用模型配置。</p></section><section class="agent-panel"><div class="agent-section-title"><span>02</span><h2>提示词预设</h2></div><p class="muted">选择负责该职责的预设,查看具体指令与版本。</p><template data-component="ResourcePicker" kind="prompt" data-bind-values="(data.promptRef ? [data.promptRef] : [])" data-bind-resources="(store.resources)" data-bind-tenant-id="(data.tenantId)" data-bind-disabled="(!allowed)" data-on-change="(data.promptRef = $event[0] || '')"></template></section><section class="agent-panel"><div class="agent-section-title"><span>03</span><h2>技能</h2><template data-component="Tag">可选</template></div><p class="muted">按需组合技能,每项引用固定的示例资源版本。</p><template data-component="ResourcePicker" kind="skill" data-bind-values="(data.skillRefs)" data-bind-resources="(store.resources)" data-bind-tenant-id="(data.tenantId)" data-bind-disabled="(!allowed)" data-on-change="(data.skillRefs = $event)"></template></section><section class="agent-panel"><div class="agent-section-title"><span>04</span><h2>工具</h2><template data-component="Tag">可选</template></div><p class="muted">仅允许所选工具的声明操作;工具类型与资源引用一起保存。</p><template data-component="ResourcePicker" kind="tool" data-bind-values="(data.tools.map(t =&gt; t.ref))" data-bind-resources="(store.resources)" data-bind-tenant-id="(data.tenantId)" data-bind-disabled="(!allowed)" data-on-change="(toolRefs)"></template></section><section class="agent-panel"><h2>运行边界</h2><template data-component="Form" layout="vertical" data-bind-disabled="(!allowed)"><div class="agent-form-grid"><template data-component="FormItem" label="记忆消息数"><template data-component="InputNumber" data-model-value="(data.memoryLimit)" aria-label="记忆消息数" data-bind-min="(1)" data-bind-max="(200)" data-bind-precision="(0)"></template></template><template data-component="FormItem" label="连续工具调用上限"><template data-component="InputNumber" data-model-value="(data.toolLimit)" aria-label="连续工具调用上限" data-bind-min="(1)" data-bind-max="(50)" data-bind-precision="(0)"></template></template></div></template><p class="muted">示例默认值用于原型评审,正式运行参数随规格确认。</p></section></div><aside class="agent-check-panel"><section class="agent-panel"><h2>配置检查</h2><p class="muted">先保存配置,再启用。资源尚未准备齐全时,可保留为停用草稿。</p><template data-component="Tag" data-bind-color="(issues ? 'orange' : 'green')">{{ (issues ? issues + ' 项待处理' : '配置与引用检查通过') }}</template><template data-component="Button" class="agent-check-button" data-bind-disabled="(!session.can('agent:check', data.tenantId, data.pbcId))" data-on-click="(showCheck = true)">检查当前配置</template><template data-component="CheckResults" data-if="(showCheck)" data-bind-items="(checks)"></template><div data-else="" class="agent-outline"><p>模型:{{ (chosenModel?.name || '待选择') }}</p><p>提示词:{{ (data.promptRef ? '已选择' : '待选择') }}</p><p>技能:{{ (data.skillRefs.length) }} 项</p><p>工具:{{ (data.tools.length) }} 项</p></div></section></aside></div><div class="agent-save-bar"><span>{{ (dirty ? '有未保存的修改' : '保存后可在详情中检查并启用') }}</span><template data-component="Button" type="primary" data-bind-disabled="(!allowed)" data-bind-loading="(busy)" data-on-click="(save)">保存配置</template></div></template>
38
+
39
+ </template>
40
+ <template data-source="reference/src/agents/AgentsPage.html">
41
+ <!-- 来源:src/agents/AgentsPage.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
42
+ <div class="page-heading"><div><h1>Agent 注册表</h1><p>管理交付流程所需的 Agent,组合模型、提示词、技能与工具。</p></div><template data-component="Button" type="primary" data-bind-disabled="(!session.can('agent:edit'))" data-on-click="(router.push('/agents/new'))">注册 Agent</template></div><div class="agent-overview"><span>共 <strong>{{ (store.records.length) }}</strong> 个 Agent</span><span>已启用 <strong>{{ (store.records.filter(a =&gt; a.enabled).length) }}</strong></span><span>待完善 <strong>{{ (store.records.filter(a =&gt; status(a) === '待完善').length) }}</strong></span><span class="muted">可用配置供流程模板引用</span></div><section class="auth-list"><div class="auth-filters"><template data-component="Input" data-model-value="(query)" aria-label="搜索 Agent" placeholder="搜索名称、标识或用途" allow-clear=""></template><template data-component="Select" data-model-value="(duty)" aria-label="职责筛选" data-bind-options="([{ value: 'all', label: '全部职责' }, ...duties])"></template><template data-component="Select" data-model-value="(project)" aria-label="项目筛选" data-bind-options="([{ value: 'all', label: '全部可见项目' }, ...projects.map(p =&gt; ({ value: p, label: p }))])"></template><template data-component="Select" data-model-value="(state)" aria-label="Agent 状态筛选" data-bind-options="([{ value: 'all', label: '全部状态' }, ...['已启用', '已停用', '待完善', '已启用 · 资源异常'].map(s =&gt; ({ value: s, label: s }))])"></template><template data-component="Button" data-on-click="(reset)">重置</template></div><div class="auth-tools"><template data-component="ListBatchBar" data-bind-count="(selection.selected.value.length)" data-bind-allowed="(canDelete)" data-on-remove="(targets = selection.selected.value)" data-on-clear="(selection.clear)"></template><template data-component="Space" wrap=""><template data-component="Button" data-on-click="(desc = !desc)">时间{{ (desc ? '倒序' : '正序') }}</template><template data-component="Button" data-bind-loading="(refreshing)" data-on-click="(refresh)">刷新</template><template data-component="ColumnSettings" data-bind-preferences="(prefs)"></template></template></div><template data-component="Alert" data-if="(error)" class="page-alert" type="error" show-icon="" data-bind-title="(error)" closable="" data-on-close="(error = '')"></template><template data-component="Alert" data-if="(store.scene === 'error')" type="error" show-icon="" title="Agent 列表加载失败" description="请重试,现有配置保持不变。"><template data-slot="action"><template data-component="Button" data-on-click="(refresh)">重试</template></template></template><template data-else=""><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-loading="(refreshing)" 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><p data-if="(!filtered.length)" class="muted">没有符合条件的 Agent。可调整筛选,或注册新的 Agent。</p></template></section><template data-component="ListDeleteDialog" data-if="(targets.length)" data-model-targets="(targets)" label="Agent" data-bind-check="(store.checkRemove)" data-bind-submit="(store.removeMany)" data-on-close="(targets = [])" data-on-deleted="targets = [];
43
+ selection.clear();"></template>
44
+
45
+ </template>
46
+ <template data-source="reference/src/agents/CheckResults.html">
47
+ <!-- 来源:src/agents/CheckResults.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
48
+ <ul class="agent-checks" aria-label="配置检查结果"><li data-each="c in (items)" data-bind-key="(c.key)"><div><strong>{{ (c.label) }}</strong><template data-component="Tag" data-bind-color="(c.ok ? 'green' : 'orange')">{{ (c.ok ? '通过' : '待处理') }}</template></div><p>{{ (c.detail) }}</p></li></ul><p class="muted">当前为本地配置与引用检查,不代表真实连接、静态安全扫描或运行验收通过。</p>
49
+
50
+ </template>
51
+ <template data-source="reference/src/agents/ResourcePicker.html">
52
+ <!-- 来源:src/agents/ResourcePicker.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
53
+ <template data-component="Select" class="full-width" data-bind-value="(kind === 'prompt' ? values[0] : values)" data-bind-mode="(kind === 'prompt' ? undefined : 'multiple')" data-bind-aria-label="(title)" data-bind-placeholder="('选择' + title)" data-bind-options="(options)" data-bind-disabled="(disabled)" allow-clear="" show-search="" data-bind-filter-option="((q, o) =&gt; String(o?.label).toLowerCase().includes(q.toLowerCase()))" data-on-change="(change)"></template><div class="agent-resources"><div data-each="r in (selected)" data-bind-key="(r.id)" class="agent-resource"><div><strong>{{ (r.name) }}</strong><template data-component="Tag">{{ (r.type || title) }} · {{ (r.version) }}</template><p>{{ (r.description) }}</p><div data-if="(r.allow)" class="agent-allow"><span data-each="a in (r.allow)" data-bind-key="(a)">{{ (a) }}</span></div></div><template data-component="Button" type="link" data-bind-aria-label="('查看' + r.name)" data-on-click="(shown = r)">查看</template></div></div><template data-component="Modal" data-bind-open="(!!shown)" data-bind-title="(shown?.name)" data-bind-footer="(null)" data-bind-width="(640)" data-on-cancel="(shown = undefined)"><template data-if="(shown)"><p class="muted">{{ (shown.version) }} · {{ (shown.state === 'ready' ? '可用' : '不可用') }}</p><p class="agent-prompt">{{ (shown.content) }}</p><p data-if="(shown.type)">绑定类型:{{ (shown.type) }}</p><p class="muted">资源引用:{{ (shown.id) }}</p><p data-if="(shown.allow)">允许操作:{{ (shown.allow.join('、')) }}</p></template></template>
54
+
55
+ </template>
56
+ <template data-source="reference/src/intents/IntentClose.html">
57
+ <!-- 来源:src/intents/IntentClose.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
58
+ <template data-component="Modal" data-bind-open="(true)" title="关闭未确认意图" ok-text="确认关闭" cancel-text="继续保留" data-bind-ok-button-props="({ danger: true, disabled: !store.canClose })" data-bind-mask="({ closable: false })" data-on-ok="(submit)" data-on-cancel="(emit('close'))"><template data-component="Alert" class="form-intro" type="warning" show-icon="" data-bind-title="(intent.title)" description="关闭后停止澄清和确认,保留原文、版本与操作记录;本轮不提供重新打开。"></template><label for="close-intent-reason">关闭原因</label><template data-component="Input.TextArea" id="close-intent-reason" data-model-value="(reason)" data-bind-rows="(4)" data-bind-maxlength="(500)" placeholder="说明为何不再继续这条意图"></template><template data-component="Alert" data-if="(error)" class="intent-error" type="error" data-bind-title="(error)" show-icon=""></template></template>
59
+
60
+ </template>
61
+ <template data-source="reference/src/intents/IntentCreate.html">
62
+ <!-- 来源:src/intents/IntentCreate.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
63
+ <template data-component="IntentHeader" data-bind-step="(0)"><template data-component="Button" data-bind-disabled="(!store.canEdit)" data-bind-loading="(saving)" data-on-click="(save(false))">保存草稿</template></template><template data-component="Alert" data-if="(!store.canEdit)" type="info" show-icon="" class="page-alert" title="当前为只读成员,不能发起意图。"></template><div class="intent-grid"><section class="panel intent-main"><div class="section-heading"><h2>描述业务目标</h2><template data-component="Button" data-bind-disabled="(!store.canEdit)" data-on-click="(example)"><template data-component="EditOutlined"></template>填入供热示例</template></div><p class="muted form-intro">先说清楚你想做什么,接下来逐项补充使用者、处理流程和验收标准。</p><template data-component="ProForm" name="intent-create" data-bind-form="(form)" layout="vertical" data-bind-disabled="(!store.canEdit || saving)" class="intent-form"></template><div class="intent-actions"><span class="muted">{{ (dirty ? '有尚未保存的输入' : '保存后可随时回来继续') }}</span><template data-component="Space"><template data-component="Button" data-bind-disabled="(!store.canEdit)" data-bind-loading="(saving)" data-on-click="(save(false))">保存草稿</template><template data-component="Button" type="primary" data-bind-disabled="(!store.canEdit)" data-bind-loading="(saving)" data-on-click="(save(true))">开始澄清</template></template></div></section><template data-component="IntentSummary"></template></div>
64
+
65
+ </template>
66
+ <template data-source="reference/src/intents/IntentDecisions.html">
67
+ <!-- 来源:src/intents/IntentDecisions.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
68
+ <section class="decision-register" aria-label="决策登记"><div class="section-heading"><h2>未决问题与决策登记</h2><template data-component="Tag" data-bind-color="(decisions.some(d =&gt; !d.answer) ? 'orange' : 'green')">{{ (decisions.filter(d =&gt; !d.answer).length) }} 项待确认</template></div><p class="muted">澄清回答与未决问题分别核对。{{ (newVersion ? '保存变更会形成新的意图版本。' : '仍有未决问题时,意图不能确认。') }}</p><template data-component="Empty" data-if="(!decisions.length)" data-bind-image="(Empty.PRESENTED_IMAGE_SIMPLE)" description="暂无登记的未决问题,请确认没有遗漏。"></template><div data-each="d in (decisions)" data-bind-key="(d.id)" class="decision-row"><div class="section-heading"><strong>{{ (d.question) }}</strong><template data-component="Tag" data-bind-color="(d.answer ? 'green' : 'orange')">{{ (d.answer ? '已登记结论' : '待确认') }}</template></div><p data-if="(d.answer)">{{ (d.answer) }}</p><small data-if="(d.resolvedAt)" class="muted">{{ (d.resolvedBy) }} · {{ (formatDate(d.resolvedAt)) }}</small><template data-if="(selected === d.id)"><label data-bind-for="('conclusion-' + d.id)">决策结论</label><template data-component="Input.TextArea" data-bind-id="('conclusion-' + d.id)" data-model-value="(conclusion)" data-bind-maxlength="(1000)" data-bind-rows="(3)"></template><div class="decision-actions"><template data-component="Button" data-on-click="(selected = '')">取消</template><template data-component="Button" type="primary" data-on-click="(resolve)">保存结论</template></div></template><template data-component="Button" data-else-if="(editable)" type="link" data-on-click="selected = d.id;
69
+ conclusion = d.answer;">{{ (d.answer ? '修订结论' : '登记结论') }}</template></div><div data-if="(editable)" class="decision-add"><label for="new-decision">补充待确认问题</label><template data-component="Input.TextArea" id="new-decision" data-model-value="(question)" data-bind-maxlength="(500)" data-bind-rows="(2)" placeholder="例如:超时后由哪个岗位复核?"></template><template data-component="Button" data-on-click="(add)">登记问题</template></div><template data-component="Alert" data-if="(error)" type="error" data-bind-title="(error)" show-icon=""></template></section>
70
+
71
+ </template>
72
+ <template data-source="reference/src/intents/IntentDetail.html">
73
+ <!-- 来源:src/intents/IntentDetail.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
74
+ <template data-component="Result" data-if="(!intent)" status="403" title="记录不存在或当前身份无权访问"><template data-slot="extra"><template data-component="Button" type="primary" data-on-click="(router.push('/intents'))">返回意图池</template></template></template><template data-else=""><template data-component="IntentSource" data-bind-intent="(intent)"></template><template data-component="IntentHeader" data-bind-intent="(intent)" data-bind-step="(intent.status === 'confirmed' ? 3 : 2)"><template data-component="Space" wrap=""><template data-component="Button" data-if="(store.canClose &amp;&amp; !closed &amp;&amp; intent.status !== 'confirmed')" danger="" data-bind-disabled="(busy)" data-on-click="(closing = true)">关闭意图</template><template data-component="Button" data-on-click="(history = true)"><template data-component="HistoryOutlined"></template>版本记录</template></template></template><template data-component="Alert" data-if="(store.notice || error)" class="page-alert" type="error" show-icon="" data-bind-title="(error || store.notice)"></template><template data-component="Alert" data-if="(intent.confirmation === 'pending')" class="page-alert" type="info" show-icon="" title="正在提交确认,请稍候…"></template><template data-component="Alert" data-if="(intent.confirmation === 'unknown')" class="page-alert" type="warning" show-icon="" title="确认结果待核实,请勿重复提交" description="本演示模拟确认请求已被接受、响应丢失。先核实这一次请求的结果,再决定后续操作。"><template data-slot="action"><template data-component="Button" data-bind-disabled="(!canConfirm)" data-on-click="(reconcile)">核实确认结果</template></template></template><template data-component="Alert" data-if="(intent.confirmation === 'failed')" class="page-alert" type="error" show-icon="" data-bind-title="(intent.error)"></template><template data-component="Alert" data-if="(intent.status === 'confirmed')" class="page-alert" type="success" show-icon="" data-bind-title="('意图 v' + version?.number + ' 已确认')" description="进入需求规格工作区,完善需求与验收后确认版本。"><template data-slot="action"><template data-component="Button" data-bind-disabled="(!session.can('spec:view', intent.tenantId))" data-on-click="(router.push('/intents/' + intent.id + '/spec'))">查看需求规格</template></template></template><template data-component="Alert" data-if="(closed)" class="page-alert" type="warning" show-icon="" title="意图已关闭" data-bind-description="(intent.closedBy + ' · ' + dateText(intent.closedAt) + ';原因:' + intent.closedReason)"></template><template data-component="Alert" data-if="(!canConfirm &amp;&amp; intent.status === 'ready')" class="page-alert" type="info" show-icon="" title="当前没有意图确认权限" description="未决问题为零仍需确认权限。请在独立的权限管理中配置当前租户的“确认意图”权限,或联系业务管理员。"></template><template data-component="Alert" data-if="(intent.status === 'ready' &amp;&amp; unresolved(intent.decisions).length)" class="page-alert" type="warning" show-icon="" data-bind-title="('还有 ' + unresolved(intent.decisions).length + ' 项决策未处理,暂不能确认意图')" description="在下方决策登记填写结论并保存为新版本,再确认。"></template><div class="intent-grid"><section class="panel intent-main"><div class="section-heading"><h2>意图内容</h2><template data-component="Tag" color="blue" data-bind-bordered="(false)">{{ (version ? 'v' + version.number : '未形成版本') }}</template></div><template data-component="IntentDocument" data-bind-value="(version || intent)"></template><template data-component="IntentDecisions" data-bind-decisions="(intent.decisions)" data-bind-editable="(store.canEdit &amp;&amp; !closed &amp;&amp; !busy &amp;&amp; intent.status !== 'confirmed')" data-bind-new-version="(!!version)" data-bind-commit="(saveDecisions)"></template><div data-if="(!closed)" class="intent-actions"><span class="muted">{{ (unresolved(intent.decisions).length ? '请先处理未决问题' : '内容变更将形成新版本') }}</span><template data-component="Space" wrap=""><template data-component="Button" data-bind-disabled="(!store.canEdit || busy)" data-on-click="(replan = true)">重新规划</template><template data-component="Button" data-bind-disabled="(!store.canEdit || busy)" data-on-click="(edit = true)">修改</template><template data-component="Button" data-if="(intent.status === 'ready')" type="primary" data-bind-loading="(intent.confirmation === 'pending')" data-bind-disabled="(!canConfirm || busy || !!unresolved(intent.decisions).length)" data-on-click="(confirm)">{{ (intent.confirmation === 'failed' ? '重试确认' : '确认意图') }}</template></template></div></section><aside class="panel intent-summary" aria-label="确认信息"><h2>确认信息</h2><dl class="intent-info"><dt>当前版本</dt><dd>{{ (version ? '意图 v' + version.number : '草稿') }}</dd><dt>PBC 归属</dt><dd>{{ (affiliationOf(intent).label) }}</dd><dt>发起人</dt><dd>{{ (intent.owner) }}</dd></dl><div class="summary-context"><h3>{{ (version?.confirmedAt ? '确认记录' : '确认前请核对') }}</h3><p data-if="(version?.confirmedAt)"><template data-component="CheckCircleOutlined" class="answered"></template> {{ (version.confirmedBy) }} · {{ (dateText(version.confirmedAt)) }}</p><ul data-else="" class="confirmation-checks"><li>问题、预期结果与范围一致</li><li>未决问题已有明确结论</li><li>以有权身份确认当前版本</li></ul></div><div class="summary-context"><template data-component="RecordMetadata" data-bind-record="(intent)" compact=""></template></div></aside></div><template data-component="IntentRevision" data-if="(edit)" data-bind-intent="(intent)" data-on-close="(edit = false)"></template><template data-component="IntentReplan" data-if="(replan)" data-bind-intent="(intent)" data-on-close="(replan = false)"></template><template data-component="IntentHistory" data-if="(history)" data-bind-intent="(intent)" data-on-close="(history = false)"></template><template data-component="IntentClose" data-if="(closing)" data-bind-intent="(intent)" data-on-close="(closing = false)"></template></template>
75
+
76
+ </template>
77
+ <template data-source="reference/src/intents/IntentDocument.html">
78
+ <!-- 来源:src/intents/IntentDocument.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
79
+ <div class="intent-document"><section><h3>1. 要解决的问题</h3><p>{{ (value.request) }}</p></section><section><h3>2. 预期结果</h3><p>{{ (value.outcome || '待补充') }}</p><h4>验收标准</h4><p>{{ (value.answers.acceptance || '待补充') }}</p></section><section><h3>3. 影响的用户与系统</h3><p>{{ (value.answers.audience || '待补充') }}</p><h4>处理流程与系统边界</h4><p>{{ (value.answers.process || '待补充') }}</p></section><section><h3>4. 约束与限制</h3><p>{{ (value.answers.boundary || '待补充') }}</p></section><section><h3>5. 未决问题</h3><p data-if="(!value.decisions?.length)">暂无登记的未决问题。</p><div data-each="d in (value.decisions || [])" data-bind-key="(d.id)" class="document-decision"><strong>{{ (d.question) }}</strong><p>{{ (d.answer || '待确认,阻断意图确认') }}</p></div></section></div>
80
+
81
+ </template>
82
+ <template data-source="reference/src/intents/IntentHeader.html">
83
+ <!-- 来源:src/intents/IntentHeader.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
84
+ <template data-component="RouterLink" to="/intents" class="text-button intent-back"><template data-component="LeftOutlined"></template>返回意图池</template><div class="page-heading intent-heading"><div><h1>{{ (intent?.title || '发起意图') }}</h1><p data-if="(intent)" class="intent-meta"><span class="mono">{{ (intent.code) }}</span><template data-component="Tag" data-bind-color="(statusMeta[intent.status].color)" data-bind-bordered="(false)">{{ (statusMeta[intent.status].label) }}</template><span>{{ (affiliationOf(intent).label) }}</span></p><p data-else="">描述你想解决的问题,先把业务目标说清楚。</p></div><div class="intent-header-actions"><slot><template data-component="Button" data-on-click="(router.push('/intents'))">返回列表</template></slot></div></div><template data-component="Steps" class="intent-steps" title-placement="vertical" data-bind-current="(step)" data-bind-items="([{ title: '发起需求' }, { title: '澄清范围' }, { title: '确认意图' }])"></template>
85
+
86
+ </template>
87
+ <template data-source="reference/src/intents/IntentHistory.html">
88
+ <!-- 来源:src/intents/IntentHistory.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
89
+ <template data-component="Drawer" data-bind-open="(true)" title="版本与操作记录" data-bind-size="(720)" data-on-close="(emit('close'))"><template data-component="Tabs" data-model-active-key="(tab)" data-bind-items="([{ key: 'versions', label: '意图版本' }, { key: 'events', label: '操作记录' }])"></template><template data-if="(tab === 'versions')"><div class="version-toolbar"><label for="intent-history-version">版本</label><template data-component="Select" id="intent-history-version" data-model-value="(number)" data-bind-options="(intent.versions.map(v =&gt; ({ label: '意图 v' + v.number, value: v.number })))"></template><template data-component="Tag" data-if="(version)" data-bind-color="(version.confirmedAt ? 'green' : 'default')">{{ (version.confirmedAt ? '已确认版本' : '未确认版本') }}</template></div><template data-if="(version)"><template data-component="Alert" type="info" show-icon="" data-bind-title="(version.title)" data-bind-description="(version.reason + ' · ' + dateText(version.createdAt))"></template><p data-if="(version.confirmedAt)" class="version-confirmed">{{ (version.confirmedBy) }} · {{ (dateText(version.confirmedAt)) }} 确认</p><template data-component="IntentDocument" data-bind-value="(version)"></template></template></template><ol data-else="" class="intent-events"><li data-each="(event, index) in ([...intent.events].reverse())" data-bind-key="(index)"><p>{{ (event.label) }}</p><span class="muted">{{ (event.actor || intent.createdBy) }} · {{ (dateText(event.at)) }}</span></li></ol></template>
90
+
91
+ </template>
92
+ <template data-source="reference/src/intents/IntentList.html">
93
+ <!-- 来源:src/intents/IntentList.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
94
+ <div class="page-heading"><div><h1>意图与需求</h1><p>从业务问题开始,形成可以核对和确认的意图。</p></div><template data-component="Button" type="primary" data-bind-disabled="(!store.canEdit)" data-on-click="(router.push('/intents/new'))"><template data-component="PlusOutlined"></template>发起意图</template></div><template data-component="Alert" data-if="(store.notice)" class="page-alert" type="warning" show-icon="" data-bind-title="(store.notice)"></template><template data-component="Alert" data-if="(!store.canEdit)" class="page-alert" type="info" show-icon="" title="当前身份仅可查看意图和版本。"></template><template data-component="Tabs" data-model-active-key="(tab)" data-bind-items="(tabs)" class="model-tabs"></template><section class="filter-panel panel" aria-label="意图筛选"><template data-component="ProForm" name="intent-search" data-bind-form="(form)" class="filter-form" data-bind-grid="({ gutter: 24 })" data-on-keydown.enter.prevent="(search)"></template><div class="filter-actions"><template data-component="Button" data-on-click="(search)">查询</template><template data-component="Button" data-on-click="(reset)">重置</template></div></section><section class="panel model-table-panel" aria-label="意图池列表"><template data-component="Result" data-if="(store.scene === 'error')" status="warning" title="意图池加载失败"><template data-slot="extra"><template data-component="Button" type="primary" data-on-click="(retry)">重试</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)" data-bind-row-selection="(selection.rowSelection.value)" row-key="id" size="middle" data-bind-scroll="({ x: 'max-content' })" data-bind-pagination="({ showTotal: (n) =&gt; '共 ' + n + ' 条', showSizeChanger: true, pageSizeOptions: [10, 20, 50, 100] })" data-bind-locale="({ emptyText: h(Empty, { description: store.scene === 'empty' ? '还没有意图,从一个业务目标开始' : '没有符合条件的意图' }, { default: () =&gt; h(Button, { disabled: store.scene === 'empty' &amp;&amp; !store.canEdit, onClick: store.scene === 'empty' ? () =&gt; router.push('/intents/new') : reset }, () =&gt; store.scene === 'empty' ? '发起第一个意图' : '清除筛选') }) })"><template data-slot="button-bar"><div class="list-heading"><h2>意图池 · {{ (visible.length) }}</h2><template data-component="ListBatchBar" data-bind-count="(selection.keys.value.length)" data-bind-allowed="(session.can('intent:delete'))" data-on-remove="(batchDelete)" data-on-clear="(selection.clear)"></template></div></template><template data-slot="toolbar"><div class="table-tools"><template data-component="Select" data-model-value="(scope)" aria-label="意图可见范围" data-bind-options="([{ label: '全部可见', value: 'visible' }, { label: '我发起的', value: 'mine' }])"></template><template data-component="Select" data-model-value="(sort)" aria-label="意图排序" data-bind-options="([{ label: '创建时间倒序', value: 'created' }, { label: '修改时间倒序', value: 'updated' }, { label: '名称排序', value: 'name' }])"></template><template data-component="ColumnSettings" data-bind-preferences="(prefs)"></template><template data-component="Button" aria-label="刷新意图池" data-bind-loading="(loading)" data-on-click="(refresh)"><template data-component="ReloadOutlined"></template></template></div> <template data-component="IntentHistory" data-if="(selected &amp;&amp; overlay === 'history')" data-bind-intent="(selected)" data-on-close="(overlay = '')"></template><template data-component="IntentRevision" data-if="(selected &amp;&amp; overlay === 'edit')" data-bind-intent="(selected)" data-on-close="(overlay = '')"></template><template data-component="IntentReplan" data-if="(selected &amp;&amp; overlay === 'replan')" data-bind-intent="(selected)" data-on-close="(replanned)"></template><template data-component="ListDeleteDialog" data-if="(deleteTargets.length)" data-model-targets="(deleteTargets)" label="意图" data-bind-check="(store.checkRemove)" data-bind-submit="(store.removeMany)" data-on-close="(deleteTargets = [])" data-on-deleted="(deleted)"></template></template></template></section><p class="intent-list-note muted">“全部可见”受当前身份与租户范围限制。删除移出列表并保留操作痕迹,已确认版本受保护。</p><template data-component="IntentClose" data-if="(closing)" data-bind-intent="(closing)" data-on-close="(closingId = '')"></template>
95
+
96
+ </template>
97
+ <template data-source="reference/src/intents/IntentReplan.html">
98
+ <!-- 来源:src/intents/IntentReplan.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
99
+ <template data-component="Modal" data-bind-open="(true)" title="重新规划" data-bind-width="(600)" ok-text="返回澄清" cancel-text="取消" data-bind-mask="({ closable: false })" data-bind-ok-button-props="({ disabled: !store.canEdit })" data-on-cancel="(emit('close'))" data-on-ok="(save)"><template data-component="Alert" class="form-intro" type="info" show-icon="" title="保留当前意图和确认记录" description="仅清空选中的澄清回答,其他内容保留。补充后再整理为新版本并确认。"></template><template data-component="ProForm" name="intent-replan" data-bind-form="(form)" layout="vertical" data-bind-disabled="(!store.canEdit)"></template></template>
100
+
101
+ </template>
102
+ <template data-source="reference/src/intents/IntentRevision.html">
103
+ <!-- 来源:src/intents/IntentRevision.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
104
+ <template data-component="Drawer" data-bind-open="(true)" title="修改意图" data-bind-size="(720)" data-bind-mask="({ closable: false })" data-on-close="(close)"><template data-component="Alert" class="form-intro" type="info" show-icon="" data-bind-title="('保存后形成 v' + ((lastVersion(intent)?.number || 0) + 1) + ',需要重新确认。旧版本继续保留。')"></template><template data-component="Alert" data-if="(error)" class="form-intro" type="error" show-icon="" data-bind-title="(error)"></template><template data-component="ProForm" name="intent-revision" data-bind-form="(form)" layout="vertical" data-bind-disabled="(!store.canEdit)" class="intent-form"></template><template data-component="IntentDecisions" data-bind-decisions="(decisions)" data-bind-editable="(store.canEdit)" data-on-change="(decisions = $event)"></template><template data-slot="footer"><div class="drawer-footer"><span class="muted">修改仅保存在演示数据中</span><template data-component="Space"><template data-component="Button" data-on-click="(close)">取消</template><template data-component="Button" type="primary" data-bind-disabled="(!store.canEdit || !dirty)" data-on-click="(save)">保存新版本</template></template></div></template></template>
105
+
106
+ </template>
107
+ <template data-source="reference/src/intents/IntentSummary.html">
108
+ <!-- 来源:src/intents/IntentSummary.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
109
+ <aside class="panel intent-summary" aria-label="意图摘要"><h2>意图摘要</h2><ol class="intent-outline"><li data-each="(q, index) in (questions)" data-bind-key="(q.key)" data-bind-class="({ active: selectable &amp;&amp; intent?.activeQuestion === index })"><button data-if="(selectable &amp;&amp; intent)" data-bind-disabled="(intent.generating)" class="outline-item" data-bind-aria-current="(intent.activeQuestion === index ? 'step' : undefined)" data-on-click="(emit('select', index))"><span class="outline-number">{{ (index + 1) }}</span><span><strong>{{ (q.label) }}</strong><small data-bind-class="({ answered: !!intent.answers[q.key].trim() })"><template data-component="CheckCircleFilled" data-if="(intent.answers[q.key].trim())"></template>{{ (intent.answers[q.key].trim() ? '已回答' : '待补充') }}</small></span></button><div data-else="" class="outline-item"><span class="outline-number">{{ (index + 1) }}</span><span><strong>{{ (q.label) }}</strong><small data-bind-class="({ answered: !!intent?.answers[q.key].trim() })"><template data-component="CheckCircleFilled" data-if="(intent?.answers[q.key].trim())"></template>{{ (intent?.answers[q.key].trim() ? '已回答' : '待补充') }}</small></span></div></li></ol><div class="summary-context"><h3>PBC 归属</h3><p>{{ (intent ? affiliationOf(intent).label : '尚未归属 PBC') }}</p><p class="muted">归属完成后显示当前 PBC;意图历史内容保留。</p></div><div data-if="(intent?.versions.length)" class="summary-context"><h3>已保留版本</h3><p>{{ (intent.versions.length) }} 个意图版本</p><p class="muted">修改和重新规划会保留历史记录。</p></div></aside>
110
+
111
+ </template>
112
+ <template data-source="reference/src/intents/IntentWorkspace.html">
113
+ <!-- 来源:src/intents/IntentWorkspace.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
114
+ <template data-component="Result" data-if="(!intent)" status="403" title="记录不存在或当前身份无权访问"><template data-slot="extra"><template data-component="RouterLink" to="/intents"><template data-component="Button" type="primary">返回意图池</template></template></template></template><template data-else=""><template data-component="IntentSource" data-bind-intent="(intent)"></template><template data-component="IntentHeader" data-bind-intent="(intent)" data-bind-step="(1)"><template data-component="Button" data-if="(store.canClose)" danger="" data-bind-disabled="(intent.generating)" data-on-click="(closing = true)">关闭意图</template><template data-component="Button" data-on-click="(preview = true)">预览意图</template><template data-component="Button" data-on-click="(router.push('/intents'))">返回列表</template></template><template data-component="Alert" data-if="(store.notice)" class="page-alert" type="warning" show-icon="" data-bind-title="(store.notice)"></template><template data-component="Alert" data-if="(!store.canEdit)" class="page-alert" type="info" show-icon="" title="只读查看:当前不能补充、整理或确认意图。"></template><template data-component="Alert" data-if="(intent.replanNote)" class="page-alert" type="info" show-icon="" title="正在重新澄清" data-bind-description="(intent.replanNote)"></template><div class="intent-grid"><section class="panel intent-main"><h2>需求澄清</h2><p class="muted intent-subtitle">按问题补充信息,形成可确认的意图。</p><div class="request-brief"><h3>要解决的问题</h3><p>{{ (intent.request) }}</p><h3 class="brief-outcome">预期结果</h3><p>{{ (intent.outcome) }}</p></div><div data-if="(intent.generating)" class="intent-generating" role="status" aria-live="polite"><h3>正在整理意图…</h3><p class="muted">根据已补充的四项内容生成演示意图。</p><template data-component="Skeleton" active="" data-bind-paragraph="({ rows: 4 })"></template></div><div data-else="" class="clarification-block"><div class="assistant-label"><template data-component="CommentOutlined"></template><span>需求规划助手 · 演示</span><small>第 {{ (intent.activeQuestion + 1) }} 项,共 4 项</small></div><h3 class="question-title">{{ (question.title) }}</h3><p class="muted question-hint">{{ (question.hint) }}</p><template data-component="Button" class="example-answer" data-bind-disabled="(!store.canEdit)" data-on-click="(example)"><template data-component="EditOutlined"></template>{{ (/供热|报修|派单/.test(intent.request) ? '填入供热示例' : '填入回答示例') }}</template><label for="clarification-answer" class="answer-label">我的补充</label><template data-component="Input.TextArea" id="clarification-answer" data-model-value="(answer)" data-bind-rows="(5)" data-bind-maxlength="(2000)" show-count="" data-bind-disabled="(!store.canEdit)" data-bind-placeholder="(question.placeholder)" data-bind-aria-invalid="(!!validation)" data-bind-aria-describedby="(validation ? 'answer-error' : undefined)"></template><p data-if="(validation)" id="answer-error" class="input-error" role="alert">{{ (validation) }}</p></div><template data-component="Alert" data-if="(intent.error)" class="intent-error" type="error" show-icon="" title="意图整理失败" data-bind-description="(intent.error)"><template data-slot="action"><template data-component="Button" data-bind-disabled="(!store.canEdit)" data-on-click="(generate)">重试生成</template></template></template><div class="intent-actions"><span class="muted" role="status"><template data-component="InfoCircleOutlined"></template> 回答保存在当前浏览器</span><template data-component="Button" type="primary" data-bind-loading="(intent.generating)" data-bind-disabled="(!store.canEdit)" data-on-click="(next)">{{ (allDone ? '生成意图' : '保存并继续') }}</template></div><template data-component="IntentDecisions" data-bind-decisions="(intent.decisions)" data-bind-editable="(store.canEdit &amp;&amp; !intent.generating)" data-bind-commit="(saveDecisions)"></template></section><div class="intent-side-stack"><template data-component="IntentSummary" data-bind-intent="(intent)" selectable="" data-on-select="(select)"></template><div class="panel intent-summary"><template data-component="RecordMetadata" data-bind-record="(intent)" compact=""></template></div></div></div><template data-component="IntentClose" data-if="(closing)" data-bind-intent="(intent)" data-on-close="(closing = false)"></template><template data-component="Drawer" data-bind-open="(preview)" title="意图草稿预览" data-bind-size="(720)" data-on-close="(preview = false)"><template data-component="Alert" type="info" show-icon="" title="根据当前已保存的输入展示,未填写的内容保持待补充。"></template><template data-component="IntentDocument" data-bind-value="(intent)"></template></template></template>
115
+
116
+ </template>
117
+ <template data-source="reference/src/models/AuditPanel.html">
118
+ <!-- 来源:src/models/AuditPanel.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
119
+ <section class="panel audit-panel"><h2>模型操作记录</h2><template data-component="Alert" class="form-intro" type="info" show-icon="" title="本地演示记录,不构成正式审计或审批证据。"></template><template data-component="ProTable" data-bind-table="(table)" data-bind-table-container="(false)" data-bind-control="(false)" row-key="id" data-bind-scroll="({ x: 1020 })" data-bind-search="(async () =&gt; { })" data-bind-pagination="({ showTotal: (t) =&gt; `共 ${t} 条`, showSizeChanger: true, pageSizeOptions: [10, 20, 50, 100], hideOnSinglePage: false })"></template></section>
120
+
121
+ </template>
122
+ <template data-source="reference/src/models/ModelDetail.html">
123
+ <!-- 来源:src/models/ModelDetail.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
124
+ <template data-component="Drawer" data-bind-open="(true)" title="模型详情" data-bind-size="(760)" data-on-close="(emit('close'))"><div class="detail-heading"><div><h2>{{ (model.name) }}</h2><p class="mono muted">{{ (model.alias) }}</p></div><template data-component="ModelStatus" data-bind-model="(model)"></template></div><template data-component="Space" wrap="" class="detail-tags"><template data-component="Tag">平台统一接入</template><template data-component="Tag" data-each="cap in (model.capabilities)" data-bind-key="(cap)">{{ (cap) }}</template></template><template data-component="Descriptions" data-bind-items="(items)" data-bind-column="({ xs: 1, sm: 2, md: 2, lg: 2, xl: 2, xxl: 2 })" size="middle" bordered=""></template><section data-if="(session.readable('model:view', 'platform'))" class="drawer-section"><div class="section-heading"><h2>配置发布</h2><template data-component="Button" type="link" data-on-click="(emit('action', 'release', model))">查看发布</template></div><template data-component="Alert" show-icon="" data-bind-type="(model.publishState === 'failed' ? 'error' : 'info')" data-bind-title="('配置 v' + model.version + ' · ' + ({ draft: '待测试或发布', review: '评审中', published: '已发布', failed: '发布失败' }[model.publishState]))" data-bind-description="(model.liveVersion !== model.version ? '当前生效配置与草稿分别保留,新草稿不会自动覆盖当前运行版本。' : '当前配置已经发布,启停状态单独管理。')"></template></section><section class="drawer-section"><div class="section-heading"><h2>使用授权</h2><template data-component="Button" type="link" data-bind-disabled="(!session.can('model:grant', 'platform'))" data-on-click="(emit('action', 'grant', model))">管理授权</template></div><div data-each="g in (model.grants)" data-bind-key="(g.tenantId)" class="grant-scope"><h3>{{ (tenantLabel(g.tenantId)) }}</h3><p><template data-component="Tag" data-each="project in (g.projects)" data-bind-key="(project)">{{ (project) }}</template></p><p class="muted">Agent:{{ (g.agents.map(modelAgentLabel).join('、') || '未授权') }}</p></div><p data-if="(!model.grants.length)" class="muted">尚未分配使用授权</p><p>共享月额度:{{ (fmtNumber(model.quota)) }} Token</p></section><section data-if="(session.readable('model:view', 'platform'))" class="drawer-section"><div class="section-heading"><h2>资源引用 · {{ (model.references.length) }}</h2><template data-component="Button" type="link" data-on-click="(emit('action', 'references', model))">查看引用</template></div><p class="muted">{{ (model.references.length ? '被引用的模型不能直接删除,请先调整关联资源。' : '当前没有资源引用。') }}</p></section><template data-component="RecordMetadata" data-bind-record="(model)"></template><template data-slot="footer"><div class="drawer-footer"><template data-component="Button" data-on-click="(emit('close'))">关闭</template><template data-component="Space"><template data-component="Button" data-bind-disabled="(!session.can('model:edit', 'platform') || model.publishState === 'review')" data-on-click="(emit('action', 'edit', model))">编辑配置</template><template data-component="Button" type="primary" data-bind-disabled="(!session.can('model:test', 'platform') || model.publishState === 'review')" data-on-click="(emit('action', 'test', model))">连接测试</template></template></div></template></template>
125
+
126
+ </template>
127
+ <template data-source="reference/src/models/ModelEditor.html">
128
+ <!-- 来源:src/models/ModelEditor.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
129
+ <template data-component="Drawer" data-bind-open="(true)" data-bind-title="(model ? '编辑模型' : '接入模型')" data-bind-size="(720)" data-bind-mask="({ closable: false })" data-bind-keyboard="(!saving)" data-bind-closable="(!saving)" data-on-close="(close)"><template data-slot="extra"><template data-component="Button" size="small" type="text" data-bind-disabled="(saving)" data-on-click="(session.state = 'expired')">模拟登录失效</template></template><template data-component="Alert" class="form-intro" type="info" show-icon="" title="平台统一管理接入配置" data-bind-description="(model ? '保存生成新草稿;当前生效版本继续保留。新配置需测试并通过发布评审后生效。' : '保存为平台配置草稿,完成测试与发布评审后再启用并分配使用授权。')"></template><template data-component="Alert" data-if="(error)" class="form-intro" type="error" show-icon="" data-bind-title="(error)"></template><template data-component="ProForm" name="model-editor" data-bind-form="(form)" data-bind-grid="({ gutter: 24 })" data-bind-disabled="(saving || !store.canEdit)" data-bind-label-col="({ style: { width: '88px' } })" data-bind-wrapper-col="({ flex: 'auto' })" class="editor-form"></template><template data-component="RecordMetadata" data-if="(model)" data-bind-record="(model)"></template><template data-slot="footer"><div class="drawer-footer"><span class="muted">保存草稿不会直接发布</span><template data-component="Space"><template data-component="Button" data-bind-disabled="(saving)" data-on-click="(close)">取消</template><template data-component="Button" type="primary" data-bind-loading="(saving)" data-bind-disabled="(!store.canEdit)" data-on-click="(save)">保存草稿</template></template></div></template></template>
130
+
131
+ </template>
132
+ <template data-source="reference/src/models/ModelGrant.html">
133
+ <!-- 来源:src/models/ModelGrant.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
134
+ <template data-component="Drawer" data-bind-open="(true)" title="管理模型使用授权" data-bind-size="(660)" data-bind-mask="({ closable: false })" data-on-close="(!saving &amp;&amp; emit('close'))"><h2>{{ (model.name) }}</h2><template data-component="Alert" class="form-intro" type="info" show-icon="" title="模型配置由平台维护" description="所选 Agent 会获准在该租户的全部所选项目中使用此模型,候选项随项目联动。调用须同时匹配租户、项目和 Agent。使用授权不包含编辑源配置或转授权;全部留空表示撤销使用授权。"></template><template data-component="ProForm" name="model-grant" data-bind-form="(form)" data-bind-disabled="(saving || !session.can('model:grant', 'platform'))" data-bind-grid="({ gutter: 24 })" data-bind-label-col="({ style: { width: '104px' } })" data-bind-wrapper-col="({ flex: 'auto' })"></template><template data-component="Alert" data-if="(error)" type="error" show-icon="" data-bind-title="(error)"></template><template data-slot="footer"><div class="drawer-footer"><span class="muted">授权关系与资源引用分别管理</span><template data-component="Space"><template data-component="Button" data-bind-disabled="(saving)" data-on-click="(emit('close'))">取消</template><template data-component="Button" type="primary" data-bind-loading="(saving)" data-bind-disabled="(!session.can('model:grant', 'platform'))" data-on-click="(save)">保存授权</template></template></div></template></template>
135
+
136
+ </template>
137
+ <template data-source="reference/src/models/ModelReferences.html">
138
+ <!-- 来源:src/models/ModelReferences.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
139
+ <template data-component="Drawer" data-bind-open="(true)" data-bind-title="(deleting ? '删除模型' : '资源引用')" data-bind-size="(600)" data-on-close="(emit('close'))"><h2>{{ (model.name) }}</h2><template data-component="Alert" data-if="(deleting)" class="form-intro" data-bind-type="(reason ? 'warning' : 'info')" show-icon="" data-bind-title="(reason || '确认删除此模型?')" description="删除后从可用列表移除,基础信息和操作记录仍保留。提交时会再次检查资源引用。"></template><section class="drawer-section"><h2>引用此模型的资源 · {{ (model.references.length) }}</h2><div data-each="item in (model.references)" data-bind-key="(item.name)" class="reference-row"><div><strong>{{ (item.name) }}</strong><p class="muted">{{ (item.kind) }} · {{ (item.version) }}</p></div><template data-component="Tag">正在引用</template></div><p data-if="(!model.references.length)" class="muted">当前没有资源引用。授权关系不等同于资源引用。</p></section><template data-component="Alert" data-if="(error)" type="error" data-bind-title="(error)"></template><template data-slot="footer"><div class="drawer-footer"><template data-component="Button" data-on-click="(emit('close'))">返回</template><template data-component="Button" data-if="(deleting)" danger="" type="primary" data-bind-disabled="(!!reason || !session.can('model:delete', 'platform'))" data-on-click="(remove)">确认删除</template></div></template></template>
140
+
141
+ </template>
142
+ <template data-source="reference/src/models/ModelRelease.html">
143
+ <!-- 来源:src/models/ModelRelease.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
144
+ <template data-component="Drawer" data-bind-open="(true)" title="配置发布" data-bind-size="(640)" data-bind-mask="({ closable: false })" data-on-close="(!busy &amp;&amp; emit('close'))"><div class="detail-heading"><div><h2>{{ (model.name) }}</h2><p class="mono muted">{{ (model.alias) }}</p></div><template data-component="Tag" data-bind-color="(model.publishState === 'published' ? 'green' : 'blue')">{{ ({ draft: '待发布', review: '评审中', published: '已发布', failed: '发布失败' }[model.publishState]) }}</template></div><div class="version-comparison"><div><span>当前生效版本</span><strong>{{ (model.liveVersion ? 'v' + model.liveVersion : '尚未发布') }}</strong><small>{{ (model.publishedBy || '平台初始配置') }} {{ (model.publishedAt ? formatDate(model.publishedAt) : '') }}</small></div><div><span>本次配置</span><strong>v{{ (model.version) }}</strong><small>{{ (model.testedVersion === model.version ? '本版本模拟测试通过' : '等待本版本测试') }}</small></div></div><section class="drawer-section"><h2>变更内容</h2><p data-if="(!changes.length)">与当前发布版本一致</p><div data-else="" class="config-diff"><table><thead><tr><th>字段</th><th>当前生效</th><th>待发布</th></tr></thead><tbody><tr data-each="d in (diff)" data-bind-key="(d.key)"><th>{{ (d.label) }}</th><td>{{ (d.before) }}</td><td>{{ (d.after) }}</td></tr></tbody></table></div><p class="muted">配置草稿、测试结果和发布结果分别记录。发布成功前,当前生效配置保持不变。</p></section><template data-component="Alert" data-if="(model.requestId)" class="form-intro" type="info" show-icon="" title="发布申请(演示)" data-bind-description="(model.requestId + ' · 申请人:' + model.requestName)"></template><template data-component="Alert" data-if="(model.publishState === 'review' &amp;&amp; !session.can('model:publish', 'platform'))" class="form-intro" type="info" show-icon="" title="等待配置审核员评审" description="可在页头切换到配置审核员,查看同一申请并给出评审结果。"></template><section data-if="(model.publishState === 'review' &amp;&amp; session.can('model:publish', 'platform'))" class="drawer-section"><label for="release-note" class="answer-label">评审意见</label><template data-component="Input.TextArea" id="release-note" data-model-value="(note)" data-bind-rows="(3)" data-bind-maxlength="(500)" placeholder="请说明发布或退回的理由"></template></section><template data-component="Alert" data-if="(model.publishNote)" class="form-intro" data-bind-type="(model.publishState === 'failed' ? 'error' : model.publishState === 'published' ? 'success' : 'warning')" show-icon="" data-bind-title="(model.publishNote)"></template><template data-component="Alert" data-if="(error)" type="error" show-icon="" data-bind-title="(error)"></template><p class="muted">本页模拟配置评审与发布,不提交真实 GitLab PR 或修改运行环境。</p><template data-slot="footer"><div class="drawer-footer"><template data-component="Button" data-bind-disabled="(busy)" data-on-click="(emit('close'))">关闭</template><template data-component="Space" data-if="(model.publishState === 'review' &amp;&amp; session.can('model:publish', 'platform'))"><template data-component="Button" danger="" data-bind-disabled="(busy)" data-on-click="(act('reject'))">退回修改</template><template data-component="Button" type="primary" data-bind-loading="(busy)" data-on-click="(act('approve'))">同意并发布</template></template><template data-component="Button" data-else="" type="primary" data-bind-loading="(busy)" data-bind-disabled="(!session.can('model:edit', 'platform') || model.publishState === 'review' || model.liveVersion === model.version || model.testedVersion !== model.version)" data-on-click="(act('submit'))">提交发布申请</template></div></template></template>
145
+
146
+ </template>
147
+ <template data-source="reference/src/models/ModelStatus.html">
148
+ <!-- 来源:src/models/ModelStatus.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
149
+ <div class="model-status"><div><span class="status-dot" data-bind-class="(model.enabled ? (model.health === 'error' ? 'error' : 'success') : 'neutral')"></span><span>{{ (model.enabled ? '已启用' : '已停用') }}</span></div><span class="health-text" data-bind-class="(model.health)">{{ (healthText) }}</span></div>
150
+
151
+ </template>
152
+ <template data-source="reference/src/models/ModelTable.html">
153
+ <!-- 来源:src/models/ModelTable.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
154
+ <section class="filter-panel panel" aria-label="模型筛选"><template data-component="ProForm" name="model-search" data-bind-form="(filters)" data-bind-grid="({ gutter: 24 })" class="filter-form" data-on-keydown.enter.prevent="(search)"></template><div class="filter-actions"><template data-component="Button" data-on-click="(search)">查询</template><template data-component="Button" data-on-click="(reset)">重置</template></div></section><section class="panel model-table-panel" aria-label="已接入模型列表"><template data-component="Result" data-if="(store.scene === 'error')" status="warning" title="模型列表加载失败"><template data-slot="extra"><template data-component="Button" type="primary" data-on-click="(retry)">重试</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)" data-bind-row-selection="(selection.rowSelection.value)" row-key="id" size="middle" data-bind-scroll="({ x: 'max-content' })" data-bind-pagination="({ showTotal: (n) =&gt; '共 ' + n + ' 条', showSizeChanger: true, pageSizeOptions: [10, 20, 50, 100] })" data-bind-locale="({ emptyText: h(Empty, { description: store.scene === 'empty' ? '还没有接入模型' : '没有符合条件的模型' }, { default: () =&gt; h(Button, { onClick: store.scene === 'empty' ? () =&gt; emit('create') : reset, disabled: store.scene === 'empty' &amp;&amp; !store.canEdit }, () =&gt; store.scene === 'empty' ? '接入第一个模型' : '清除筛选') }) })"><template data-slot="button-bar"><div class="list-heading"><h2>已接入模型 · {{ (filtered.length) }}</h2><template data-component="ListBatchBar" data-bind-count="(selection.keys.value.length)" data-bind-allowed="(session.can('model:delete', 'platform'))" data-on-remove="(batchDelete)" data-on-clear="(selection.clear)"></template></div></template><template data-slot="toolbar"><div class="table-tools"><template data-component="Select" data-model-value="(sort)" aria-label="模型排序" data-bind-options="([{ label: '创建时间倒序', value: 'created' }, { label: '修改时间倒序', value: 'updated' }, { label: '名称排序', value: 'name' }])"></template><template data-component="ColumnSettings" data-bind-preferences="(prefs)"></template><template data-component="Button" aria-label="刷新模型列表" data-bind-loading="(loading)" data-on-click="(refresh)"><template data-component="ReloadOutlined"></template></template></div></template></template></section><template data-component="ListDeleteDialog" data-if="(deleteTargets.length)" data-model-targets="(deleteTargets)" label="模型" data-bind-check="(store.checkRemove)" data-bind-submit="(store.removeMany)" data-on-close="(deleteTargets = [])" data-on-deleted="(deleted)"></template>
155
+
156
+ </template>
157
+ <template data-source="reference/src/models/ModelTester.html">
158
+ <!-- 来源:src/models/ModelTester.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
159
+ <template data-component="Drawer" data-bind-open="(true)" title="模型连接测试" data-bind-size="(640)" data-on-close="(close)"><div class="detail-heading"><div><h2>{{ (model.name) }}</h2><p class="mono muted">{{ (model.alias) }} · v{{ (model.version) }}</p></div><template data-component="Tag">模拟测试</template></div><template data-component="Alert" type="info" show-icon="" title="本次测试仅演示交互,不会调用真实模型。" description="可切换成功与失败场景,观察结果和后续操作。"></template><section class="drawer-section"><h2>模拟结果</h2><template data-component="RadioGroup" data-model-value="(outcome)" data-bind-disabled="(running)" data-bind-options="([{ label: '连接成功', value: 'success' }, { label: '连接超时', value: 'failure' }])"></template></section><section class="drawer-section"><template data-component="Steps" data-bind-current="(result === 'success' ? 3 : stage)" data-bind-status="(result === 'failure' ? 'error' : 'process')" data-bind-items="(stages)" size="small"></template></section><div data-if="(running)" class="test-wait" role="status"><template data-component="LoadingOutlined" spin=""></template><h2>正在验证模型接入</h2><p>正在模拟{{ (stages[stage]?.title) }}…</p></div><div data-else-if="(result)" class="test-result" data-bind-class="(result)" role="status"><template data-component="CheckCircleOutlined" data-if="(result === 'success')"></template><template data-component="CloseCircleOutlined" data-else=""></template><h2>{{ (result === 'success' ? '模型连接测试通过' : '模型连接超时') }}</h2><p>{{ (result === 'success' ? '配置与声明能力已通过模拟检查。' : '请检查服务地址、凭据引用及供应商服务状态。') }}</p><p data-if="(result === 'success')" class="muted">模拟响应耗时:480 ms · 此数值不代表真实性能</p><p data-else="" class="mono muted">DEMO_CONNECTION_TIMEOUT · 模拟错误</p></div><div data-else="" class="test-wait"><p class="muted">开始测试后,这里将显示各项检查结果。</p></div><template data-component="Alert" data-if="(error)" type="error" show-icon="" data-bind-title="(error)"></template><template data-component="Alert" data-if="(result === 'success')" type="info" show-icon="" title="测试通过后,请前往“配置发布”提交评审。" description="本地测试不代表真实协议兼容或发布成功;正式验证需要分别覆盖工具调用、结构化输出、流式、usage 和错误语义。"></template><template data-slot="footer"><div class="drawer-footer"><template data-component="Button" data-on-click="(close)">{{ (running ? '取消测试并关闭' : '关闭') }}</template><template data-component="Button" type="primary" data-bind-loading="(running)" data-bind-disabled="(!session.can('model:test', 'platform'))" data-on-click="(run)">{{ (result ? '重新测试' : '开始测试') }}</template></div></template></template>
160
+
161
+ </template>
162
+ <template data-source="reference/src/models/ModelsPage.html">
163
+ <!-- 来源:src/models/ModelsPage.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
164
+ <div class="page-heading"><div><h1>模型管理</h1><p>平台统一接入,按租户、项目与 Agent 分配使用授权。</p></div><template data-component="Button" type="primary" data-bind-disabled="(!session.can('model:edit', 'platform'))" data-on-click="(create)"><template data-component="PlusOutlined"></template>接入模型</template></div><template data-component="Alert" data-if="(!session.readable('model:view', 'platform'))" class="page-alert" type="info" show-icon="" title="当前展示本租户已获授权的模型" description="接入配置由平台维护;使用授权不包含编辑或转授权权限。"></template><template data-component="Alert" data-if="(store.persistenceError)" class="page-alert" type="warning" show-icon="" title="浏览器暂时无法保存演示数据,请保留当前输入后重试。"></template><template data-component="Tabs" data-model-active-key="(tab)" data-bind-items="(tabs)" class="model-tabs"></template><template data-component="ModelTable" data-if="(tab === 'list')" data-on-action="(action)" data-on-create="(create)"></template><template data-component="UsagePanel" data-else-if="(tab === 'usage')"></template><template data-component="AuditPanel" data-else-if="(session.can('model:audit', 'platform'))"></template><template data-component="ModelEditor" data-if="(overlay === 'edit')" data-bind-model="(selected)" data-on-close="(close)" data-on-saved="(saved)"></template><template data-component="ModelDetail" data-if="(overlay === 'detail' &amp;&amp; selected)" data-bind-model="(selected)" data-on-close="(close)" data-on-action="(action)"></template><template data-component="ModelTester" data-if="(overlay === 'test' &amp;&amp; selected)" data-bind-model="(selected)" data-on-close="(close)"></template><template data-component="ModelGrant" data-if="(overlay === 'grant' &amp;&amp; selected)" data-bind-model="(selected)" data-on-close="(close)"></template><template data-component="ModelRelease" data-if="(overlay === 'release' &amp;&amp; selected)" data-bind-model="(selected)" data-on-close="(close)"></template><template data-component="ModelReferences" data-if="((overlay === 'references' || overlay === 'delete') &amp;&amp; selected)" data-bind-model="(selected)" data-bind-deleting="(overlay === 'delete')" data-on-close="(close)"></template><template data-component="Drawer" data-if="(overlay === 'detail' &amp;&amp; !selected)" data-bind-open="(true)" title="模型访问" data-bind-size="(600)" data-on-close="(close)"><template data-component="Result" status="403" title="无法访问此模型" sub-title="记录不存在、已被删除或不在当前授权范围。"><template data-slot="extra"><template data-component="Button" data-on-click="(close)">返回列表</template></template></template></template>
165
+
166
+ </template>
167
+ <template data-source="reference/src/models/RowActions.html">
168
+ <!-- 来源:src/models/RowActions.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
169
+ <div class="row-actions"><template data-component="Button" type="text" class="link-button" data-bind-disabled="(!session.can('model:test', 'platform') || model.publishState === 'review')" data-bind-aria-label="('测试' + model.name)" data-on-click="(emit('action', 'test', model))">测试</template><template data-component="ListMore" data-bind-name="(model.name)" data-bind-items="(items)" data-on-action="(emit('action', $event, model))"></template></div>
170
+
171
+ </template>
172
+ <template data-source="reference/src/models/UsagePanel.html">
173
+ <!-- 来源:src/models/UsagePanel.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
174
+ <section class="panel usage-panel"><div class="section-heading"><h2>模型用量</h2><div class="usage-filters"><template data-component="Select" data-model-value="(period)" aria-label="用量周期" data-bind-options="([{ label: '最近 7 天', value: 7 }, { label: '最近 30 天', value: 30 }])"></template><template data-component="Select" data-model-value="(project)" aria-label="用量项目" data-bind-options="([{ label: '全部项目', value: 'all' }, ...projects.map(p =&gt; ({ label: p, value: p }))])"></template></div></div><template data-component="Alert" type="info" show-icon="" title="演示用量与价格,仅用于确认展示口径;不代表真实账单。"></template><div class="usage-metrics"><div><span>Token 总量</span><strong>{{ (fmtNumber(totals.tokens)) }}</strong><small>输入 + 输出</small></div><div><span>模型调用</span><strong>{{ (fmtNumber(totals.requests)) }}</strong><small>次 · 所选周期</small></div><div><span>估算费用</span><strong>{{ (money(totals.cost)) }}</strong><small>人民币 · 按演示单价计算</small></div></div><template data-component="ProTable" data-bind-table="(table)" data-bind-table-container="(false)" data-bind-control="(false)" row-key="id" data-bind-scroll="({ x: 780 })" data-bind-pagination="({ showTotal: (t) =&gt; `共 ${t} 条`, hideOnSinglePage: false })"></template><p class="muted">估算公式:输入 Token × 输入单价 + 输出 Token × 输出单价;单价以每百万 Token 计。</p></section>
175
+
176
+ </template>
177
+ <template data-source="reference/src/operations/IncidentDetail.html">
178
+ <!-- 来源:src/operations/IncidentDetail.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
179
+ <template data-component="Result" data-if="(!row || !incident)" status="403" title="异常不存在或无权访问"><template data-slot="extra"><template data-component="Button" data-on-click="(router.push('/operations'))">返回运行管理</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('/operations?tab=incidents'))">← 异常队列</template><h1>{{ (incident.title) }}</h1><p>{{ (incident.code) }} · {{ (formatDate(incident.observedAt)) }} · 证据 v{{ (incident.evidenceVersion) }}</p></div><template data-component="Tag" data-bind-color="(incident.closed ? 'green' : 'orange')">{{ (row.run.unconfirmed ? '结果待核实' : incidentLabel(incident)) }}</template></div><template data-component="Alert" data-if="(row.run.unconfirmed)" type="warning" show-icon="" title="异常处理结果待核实"><template data-slot="action"><template data-component="Button" data-on-click="(verify)">查询原请求回执</template></template></template><template data-else=""><div class="ops-layout"><div><section class="ops-card"><div class="ops-section-head"><h2>已观测事实</h2><template data-component="Tag" color="red">{{ (incident.band) }} · 模拟提示</template></div><p>{{ (incident.signal) }}</p><p>异常发生于 {{ (incident.source.version) }} / {{ (incident.source.config) }};来源证据固定,后续修复不会覆盖。</p><p class="muted">偏差等级仅为本地样例提示,未据此配置生产阈值或自动执行操作。</p><h3>请求与日志线索</h3><p class="mono">{{ (incident.traceId) }}</p><pre class="ops-logs">{{ (incident.logs.map(l =&gt; formatDate(l.at) + ' [' + l.level + '] ' + l.text).join('\n')) }}</pre></section><section class="ops-card"><div class="ops-section-head"><h2>调查报告</h2><template data-component="Button" data-bind-disabled="(!!store.reason(row, 'diagnose', incident.id))" data-bind-title="(store.reason(row, 'diagnose', incident.id))" data-on-click="(action = 'diagnose')">补充调查</template></div><template data-component="Select" data-if="(incident.reports.length)" data-model-value="(reportVersion)" aria-label="调查报告版本" data-bind-placeholder="('当前报告 v' + incident.reports.at(-1).number)" data-bind-options="([...incident.reports].reverse().map(r =&gt; ({ value: r.number, label: '报告 v' + r.number + ' · ' + formatDate(r.at) })))"></template><p data-if="(!report)" class="ops-empty">尚无调查报告。先结合日志线索补充调查,再决定如何处理。</p><template data-else=""><template data-component="Alert" data-if="(report.status === 'incomplete')" type="warning" title="资料未齐备,需继续调查"></template><h3>事实</h3><ul><li data-each="f in (report.facts)" data-bind-key="(f)">{{ (f) }}</li></ul><h3>待验证假设</h3><ul><li data-each="f in (report.hypotheses)" data-bind-key="(f)">{{ (f) }}</li></ul><p data-if="(!report.hypotheses.length)" class="muted">资料不足,暂不形成根因判断。</p><h3>待补充问题</h3><ul><li data-each="q in (report.questions)" data-bind-key="(q)">{{ (q) }}</li></ul><p>{{ (report.suggestion) }}</p><small class="muted">{{ (report.by) }} · 报告 v{{ (report.number) }} · {{ (formatDate(report.at)) }}</small></template></section></div><aside><section class="ops-card"><h2>分诊与处理</h2><p>根据最新调查报告选择处理方向。立即修复和排期修复都通过需求交付流程推进。</p><template data-component="Space" direction="vertical" style="width:100%"><template data-component="Button" data-each="a in ['triageNow', 'triagePlan', 'triageReject']" data-bind-key="(a)" block="" data-bind-type="(a === 'triageNow' ? 'primary' : 'default')" data-bind-disabled="(!!store.reason(row, a, incident.id) || !!linked)" data-bind-title="(linked ? '已关联修复需求,请在修复跟踪继续。' : store.reason(row, a, incident.id))" data-on-click="reportVersion = undefined;
180
+ action = a;">{{ (({ triageNow: '立即修复', triagePlan: '排期修复', triageReject: '驳回异常' })[a]) }}</template></template><div data-if="(incident.triage)" class="ops-check"><strong>已记录:{{ (incidentLabel(incident)) }}</strong><p>{{ (incident.triage.note) }}</p><small>{{ (incident.triage.actor) }} · 报告 v{{ (incident.triage.reportVersion) }} · {{ (formatDate(incident.triage.at)) }}</small></div><template data-component="Button" style="margin-top:16px" block="" data-bind-disabled="(!store.session.can('intent:view', incident.tenantId))" data-on-click="(router.push(route.path + '/repair'))">{{ (linked ? '查看修复跟踪' : '关联或创建修复需求') }} →</template></section><section data-if="(incident.closed)" class="ops-card"><h2>修复关闭记录</h2><p>{{ (incident.closed.note) }}</p><p>修复版本 {{ (incident.closed.target.version) }} · 证据 v{{ (incident.closed.target.evidenceVersion) }}</p><small>{{ (incident.closed.actor) }} · {{ (formatDate(incident.closed.at)) }}</small></section></aside></div></template><section data-if="(!row.run.unconfirmed)" class="ops-card"><h2>异常处理历史</h2><article data-each="e in (row.run.events.filter(e =&gt; e.incidentId === incident.id).slice().reverse())" data-bind-key="(e.id)" class="ops-check"><strong>{{ (e.action) }}</strong><p>{{ (e.detail) }}</p><small>{{ (e.actor) }} · {{ (formatDate(e.at)) }}</small></article><h3 data-if="(incident.triageHistory?.length)">分诊依据</h3><p data-each="(t,n) in (incident.triageHistory || [])" data-bind-key="(n)">{{ (({ now: '立即修复', plan: '排期修复', reject: '驳回异常' })[t.choice]) }} · 报告 v{{ (t.reportVersion) }} · {{ (t.actor) }} · {{ (formatDate(t.at)) }}</p></section><template data-component="SourceSummary" data-bind-source="(incident.source)"></template><template data-component="RecordMetadata" data-bind-record="(incident)"></template><template data-component="OperationActionDialog" data-if="(action)" data-bind-row="(row)" data-bind-action="(action)" data-bind-incident-id="(incident.id)" data-on-close="(action = undefined)" data-on-done="action = undefined;
181
+ reportVersion = undefined;"></template></template>
182
+
183
+ </template>
184
+ <template data-source="reference/src/operations/IntentSource.html">
185
+ <!-- 来源:src/operations/IntentSource.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
186
+ <template data-component="Alert" data-each="l in (intent.operationLinks || [])" data-bind-key="(l.incidentId)" class="page-alert" type="info" data-bind-title="(l.unconfirmed ? '运行异常关联结果待核实' : '来源运行异常:' + l.incidentCode)" data-bind-description="(l.incidentTitle + ' · ' + l.project + ' · 发布版本 ' + l.sourceVersion)"><template data-slot="action"><template data-component="Button" data-bind-disabled="(!session.can('operation:view', l.tenantId, l.pbcId, 'production'))" data-on-click="(router.push('/operations/' + l.taskId + '/' + l.runId + '/incidents/' + l.incidentId + '/repair'))">查看修复跟踪</template></template></template>
187
+
188
+ </template>
189
+ <template data-source="reference/src/operations/OperationActionDialog.html">
190
+ <!-- 来源:src/operations/OperationActionDialog.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
191
+ <template data-component="Modal" open="" data-bind-title="(operationLabels[action])" data-bind-width="(600)" data-bind-footer="(null)" data-on-cancel="(emit('close'))"><div class="ops-form"><p>{{ (row.run.source.service) }} · {{ (row.run.source.version) }} · 生产环境</p><p class="muted">绑定运行记录 v{{ (expected) }};处理人 {{ (store.session.actor.name) }}。{{ (action === 'closeIncident' ? '关闭前须核对新修复版本的验收与回归证据。' : '提交会保留来源、说明和操作回执。') }}</p><template data-component="Alert" data-if="(stale)" type="warning" title="页面版本已变化,原说明保留"><template data-slot="action"><template data-component="Button" data-on-click="(rebase)">核对当前版本</template></template></template><template data-component="Alert" data-if="(why || error)" data-bind-type="(why ? 'warning' : 'info')" data-bind-title="(error || why)" show-icon=""></template><template data-component="Alert" data-if="(target)" type="info" data-bind-title="('本次关闭依据:修复版本 ' + target.version + ' · 证据 v' + target.evidenceVersion)" data-bind-description="(target.digest + ' / ' + target.config)"></template><p data-if="(incidentId)" class="muted">异常处理依据:最新报告 v{{ (row.run.incidents.find(i =&gt; i.id === incidentId)?.reports.at(-1)?.number || 0) }}。</p><label>处理说明 <template data-component="TextArea" data-model-value="(note)" aria-label="处理说明" data-bind-rows="(4)" data-bind-maxlength="(2000)" placeholder="填写核对结果、处理理由或后续安排"></template></label><template data-component="Checkbox" data-if="(['accept', 'rejectAcceptance', 'closeIncident'].includes(action))" data-model-checked="(checked)">已核对本次版本、证据与处理影响</template><details class="ops-demo"><summary>原型演示控件</summary><label data-if="(action === 'observe' || action === 'diagnose')">本轮模拟证据 <template data-component="Select" data-model-value="(outcome)" aria-label="本轮模拟证据" data-bind-options="([{ value: 'pass', label: '完整 / 通过' }, { value: 'fail', label: '业务失败 / 调查不完整' }, { value: 'missing', label: '证据缺失' }, { value: 'stale', label: '证据过期' }])"></template></label><label>本次模拟响应 <template data-component="Select" data-model-value="(store.response)" aria-label="本次模拟响应" data-bind-options="([{ value: 'success', label: '成功' }, { value: 'failure', label: '服务失败,保留输入' }, { value: 'unknown', label: '响应不明,查询原请求' }])"></template></label><p>仅改变本地演示结果,不连接监控或生产服务。</p></details><div class="ops-buttons"><template data-component="Button" data-on-click="(emit('close'))">取消</template><template data-component="Button" type="primary" data-bind-loading="(busy)" data-bind-disabled="(!!why || stale)" data-on-click="(submit)">提交{{ (operationLabels[action]) }}</template></div></div></template>
192
+
193
+ </template>
194
+ <template data-source="reference/src/operations/OperationEntry.html">
195
+ <!-- 来源:src/operations/OperationEntry.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
196
+ <template data-component="Alert" data-if="(runs.length)" class="page-alert" type="info" show-icon="" title="已进入运行验收" data-bind-description="(runs.map(r =&gt; r.source.version + ' · ' + acceptanceLabel(r) + ' · ' + healthLabel(r)).join(';'))"><template data-slot="action"><template data-component="Button" data-on-click="(router.push('/operations?task=' + task.id + (releaseId ? '&amp;run=' + runs[0].id : '')))">运行记录与异常</template></template></template>
197
+
198
+ </template>
199
+ <template data-source="reference/src/operations/OperationsPage.html">
200
+ <!-- 来源:src/operations/OperationsPage.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
201
+ <div class="page-heading"><div><h1>运行管理</h1><p>核对业务运行结果,分诊异常,跟踪修复后的重新验收。</p></div><template data-component="Button" data-bind-disabled="(!store.session.can('artifact:view'))" data-on-click="(router.push('/releases'))">查看发布记录</template></div><div class="task-metrics"><article><span>待运行验收</span><strong>{{ (rows.filter(r =&gt; !sourceReason(r.task, r.run) &amp;&amp; acceptanceLabel(r.run) === '待验收').length) }}</strong></article><article><span>当前运行异常</span><strong>{{ (rows.filter(r =&gt; !sourceReason(r.task, r.run) &amp;&amp; healthLabel(r.run) === '运行异常').length) }}</strong></article><article><span>未结束异常</span><strong>{{ (incidents.filter(i =&gt; !['已关闭', '已驳回'].includes(i.status)).length) }}</strong></article><article><span>验收通过</span><strong>{{ (rows.filter(r =&gt; acceptanceLabel(r.run) === '验收通过').length) }}</strong></article></div><template data-component="Alert" data-if="(error || store.notice)" type="error" show-icon="" data-bind-title="(error || store.notice)" class="page-alert"></template><template data-component="Alert" data-if="(route.query.task)" class="page-alert" type="info" title="当前仅显示来源任务的运行记录"><template data-slot="action"><template data-component="Button" data-on-click="(router.replace('/operations'))">查看全部</template></template></template><template data-component="Alert" data-if="(!store.rows.length)" class="page-alert" type="info" show-icon="" title="尚无可见的生产运行记录" description="从已核实成功的生产发布进入运行验收;评审原型可载入一组独立模拟样例。"><template data-slot="action"><template data-component="Button" data-bind-disabled="(!store.session.can('operation:observe') || !store.session.can('task:create'))" data-on-click="(addExamples)">载入运行演示样例</template></template></template><div class="ops-section-head"><template data-component="Tabs" data-model-active-key="(tab)" data-bind-items="([{ key: 'runs', label: '运行记录与验收' }, { key: 'incidents', label: '异常队列' }])"></template><template data-component="Select" data-model-value="(pbc)" aria-label="运行 PBC 筛选" data-bind-options="([{ value: 'all', label: '全部可见 PBC' }, ...Array.from(new Map(store.rows.map(r =&gt; [r.run.source.pbcId, { value: r.run.source.pbcId, label: r.run.source.project }])).values())])"></template></div><template data-component="Alert" data-if="(rows.some(r =&gt; r.run.unconfirmed))" class="page-alert" type="warning" title="存在待核实的运行记录" description="请在运行记录中查询原请求回执。未核实结果暂不计入异常统计。"></template><template data-component="ManagementTable" data-bind-key="(tab)" data-bind-page-key="(tab === 'runs' ? '运行记录' : '运行异常')" data-bind-rows="(tab === 'runs' ? runs : incidents)" readonly="" data-bind-scene="(store.scene)" data-bind-more="(more)" data-bind-owner-label="(tab === 'runs' ? '验收人' : '处理人')" data-bind-context-label="(tab === 'runs' ? 'PBC / 版本 / 最近观测' : 'PBC / 异常版本')" data-on-action="(action)" data-on-refresh="(store.scene = 'normal')"></template><p class="review-footnote">运行记录由已核实成功的生产发布产生。验收与异常证据不可删除或批量删除,业务处理通过详情页记录;预发布仍在发布模块查看。</p><details class="ops-demo"><summary>原型评审:样例与列表状态</summary><template data-component="Space" wrap=""><template data-component="Button" data-if="(store.rows.length)" data-bind-disabled="(!store.session.can('operation:observe') || !store.session.can('task:create'))" data-on-click="(addExamples)">载入运行演示样例</template><template data-component="Select" data-model-value="(store.scene)" aria-label="运行列表演示状态" data-bind-options="([{ value: 'normal', label: '正常列表' }, { value: 'empty', label: '空列表' }, { value: 'error', label: '加载失败' }])"></template></template><p>包含正常、缺失证据、新异常、已关联需求和等待修复验证;全部为本地模拟,保留已有数据。</p></details><template data-component="RunDetail" data-if="(route.query.run)" data-bind-id="(String(route.query.run))" data-on-close="(router.replace({ query: { ...route.query, run: undefined } }))"></template>
202
+
203
+ </template>
204
+ <template data-source="reference/src/operations/RepairTrack.html">
205
+ <!-- 来源:src/operations/RepairTrack.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
206
+ <template data-component="Result" data-if="(!row || !incident || !store.session.can('intent:view', row.run.tenantId))" status="403" title="修复记录不存在或无权访问"><template data-slot="extra"><template data-component="Button" data-on-click="(router.push('/operations'))">返回运行管理</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(route.path.replace('/repair', '')))">← 异常详情</template><h1>修复跟踪</h1><p>{{ (incident.code) }} · {{ (incident.title) }}</p></div><template data-component="Tag" data-bind-color="(incident.closed ? 'green' : 'orange')">{{ (row.run.unconfirmed || link?.unconfirmed ? '结果待核实' : incident.closed ? '修复已关闭' : intent ? '修复进行中' : '待关联修复需求') }}</template></div><template data-component="Alert" data-if="(error)" class="page-alert" type="warning" show-icon="" data-bind-title="(error)"></template><template data-component="Alert" data-if="(row.run.unconfirmed)" class="page-alert" type="warning" title="原处理结果待核实,请返回异常详情查询原请求回执。"></template><section data-if="(!intent &amp;&amp; !row.run.unconfirmed)" class="ops-card ops-link-form"><h2>把异常接入需求交付流程</h2><p>新建需求从意图草稿开始;关联已有需求则沿用其规格与交付记录。保留异常来源,不自动确认规格或创建 PBC。</p><template data-component="Alert" data-if="(linkReason)" type="info" data-bind-title="(linkReason)"></template><div class="ops-form"><label>处理方式 <template data-component="Select" data-model-value="(mode)" aria-label="修复需求处理方式" data-bind-options="([{ value: 'new', label: '创建修复意图草稿' }, { value: 'existing', label: '关联已有需求' }])"></template></label><label data-if="(mode === 'existing')">已有需求 <template data-component="Select" data-model-value="(targetId)" show-search="" option-filter-prop="label" aria-label="关联已有修复需求" placeholder="选择同租户已有需求" data-bind-options="(store.intents.items.filter(i =&gt; i.tenantId === incident.tenantId &amp;&amp; i.status !== 'closed').map(i =&gt; ({ value: i.id, label: i.code + ' · ' + i.title })))"></template></label><label>修复与关联说明 <template data-component="TextArea" data-model-value="(note)" aria-label="修复与关联说明" data-bind-rows="(4)" data-bind-maxlength="(2000)" placeholder="说明要解决的问题、影响范围及如何验证"></template></label><div data-if="(expected !== row.run.recordVersion || error)" class="ops-buttons"><template data-component="Button" data-on-click="(rebase)">核对当前版本</template></div><details class="ops-demo"><summary>原型演示:提交响应</summary><template data-component="Select" data-model-value="(store.response)" aria-label="关联模拟响应" data-bind-options="([{ value: 'success', label: '成功' }, { value: 'failure', label: '保存失败' }, { value: 'unknown', label: '响应不明' }])"></template></details><div class="ops-buttons"><template data-component="Button" type="primary" data-bind-disabled="(!!linkReason || expected !== row.run.recordVersion)" data-on-click="(submit)">{{ (mode === 'new' ? '创建修复意图草稿' : '确认关联需求') }}</template></div></div></section><template data-component="Alert" data-if="(link?.unconfirmed)" class="page-alert" type="warning" show-icon="" title="关联结果待核实" description="保留原请求,查询实际关联结果;不会重复创建需求。"><template data-slot="action"><template data-component="Button" data-on-click="(verify)">查询原关联回执</template></template></template><template data-if="(intent &amp;&amp; !link?.unconfirmed &amp;&amp; !row.run.unconfirmed)"><div class="ops-chain"><article><span>01</span><h3>修复需求</h3><p>{{ (intent.code) }}</p><template data-component="Tag">{{ (intent.status === 'confirmed' ? '意图已确认' : intent.status === 'ready' ? '待确认意图' : intent.status === 'closed' ? '需求已关闭' : '待澄清 / 草稿') }}</template></article><article><span>02</span><h3>规格与交付</h3><p>{{ (linkedTasks.length ? '已有 ' + linkedTasks.length + ' 个后续交付任务' : '等待需求确认与交付') }}</p></article><article><span>03</span><h3>新版本与回归</h3><p>{{ (candidates.length ? '已有 ' + candidates.length + ' 个生产修复版本' : '尚无新生产修复版本') }}</p></article><article><span>04</span><h3>运行验收与关闭</h3><p>{{ (incident.closed ? '已保留关闭证据' : '待核对新版本验收') }}</p></article></div><section class="ops-card"><div class="ops-section-head"><h2>{{ (intent.title) }}</h2><template data-component="Button" type="primary" data-on-click="(router.push('/intents/' + intent.id + '/workspace'))">继续处理需求</template></div><p>{{ (link?.note) }}</p><p class="muted">关联人 {{ (link?.actor) }} · 原异常版本 {{ (link?.sourceVersion) }}。需求已有的确认记录保持,新修复范围仍需核对规格。</p><template data-component="Space" wrap=""><template data-component="Button" data-on-click="(router.push('/intents/' + intent.id))">需求详情与来源</template><template data-component="Button" data-if="(store.session.can('spec:view', intent.tenantId))" data-on-click="(router.push('/intents/' + intent.id + '/spec'))">需求规格</template><template data-component="Button" data-if="(store.session.can('task:create', intent.tenantId, incident.source.pbcId))" data-on-click="(router.push('/tasks/new?intent=' + intent.id))">发起交付</template></template></section><section class="ops-card"><h2>后续交付与生产修复版本</h2><p data-if="(!linkedTasks.length)" class="muted">尚无异常发生后创建的交付任务。创建需求、生成代码或发布成功均不会自动关闭异常。</p><article data-each="t in (linkedTasks)" data-bind-key="(t.id)" class="ops-check"><template data-component="Button" type="link" data-on-click="(router.push('/tasks/' + t.id))">{{ (t.code) }} · {{ (t.name) }}</template><template data-component="Tag">{{ (taskReleaseLabel(t, store.session.actor) || statusLabels[t.status]) }}</template></article><label data-if="(candidates.length)" class="ops-target">用于关闭的修复版本 <template data-component="Select" data-model-value="(chosen)" aria-label="选择修复版本" placeholder="选择新生产版本,核对回归和人工验收" data-bind-options="(candidates.map(c =&gt; ({ value: c.runId, label: c.version + ' · ' + store.find(c.runId)?.run.source.service })))"></template></label><div data-if="(targetRow)" class="ops-check"><p>人工验收:{{ (acceptanceLabel(targetRow.run)) }} · 当前健康:{{ (healthLabel(targetRow.run)) }}</p><p>证据 v{{ (target?.evidenceVersion) }} · {{ (target?.digest) }} · {{ (target?.config) }}</p><template data-component="Button" data-on-click="(router.push('/operations?run=' + target.runId))">补齐观测与运行验收</template></div></section><section class="ops-card"><h2>{{ (incident.closed ? '关闭证据' : '确认修复结果') }}</h2><template data-if="(incident.closed)"><p>{{ (incident.closed.note) }}</p><p>{{ (incident.closed.actor) }} · 修复版本 {{ (incident.closed.target.version) }} · 证据 v{{ (incident.closed.target.evidenceVersion) }}</p></template><template data-else=""><template data-component="Alert" data-if="(closeReason)" type="info" show-icon="" data-bind-title="(closeReason)"></template><p>关闭会绑定所选生产修复版本、回归证据、验收人和处理说明,旧异常与旧版本继续保留。</p><template data-component="Button" type="primary" data-bind-disabled="(!!closeReason)" data-on-click="(closing = true)">确认修复并关闭</template></template></section></template><template data-component="SourceSummary" data-bind-source="(incident.source)"></template><template data-component="OperationActionDialog" data-if="(closing)" data-bind-row="(row)" action="closeIncident" data-bind-incident-id="(incident.id)" data-bind-target="(target)" data-on-close="(closing = false)" data-on-done="(closing = false)"></template></template>
207
+
208
+ </template>
209
+ <template data-source="reference/src/operations/RunDetail.html">
210
+ <!-- 来源:src/operations/RunDetail.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
211
+ <template data-component="Drawer" open="" data-bind-size="(860)" title="运行记录与验收" data-on-close="(emit('close'))"><template data-if="(row)"><div class="ops-title"><div><h2>{{ (row.run.source.service) }}</h2><p class="mono muted">{{ (row.run.code) }}</p></div><template data-component="Space"><template data-component="Tag" data-bind-color="(acceptanceLabel(row.run) === '验收通过' ? 'green' : 'orange')">{{ (acceptanceLabel(row.run)) }}</template><template data-component="Tag" data-bind-color="(healthLabel(row.run) === '运行异常' ? 'red' : 'blue')">{{ (healthLabel(row.run)) }}</template></template></div><template data-component="SourceSummary" data-bind-source="(row.run.source)"></template><template data-component="Alert" data-if="(row.run.unconfirmed)" type="warning" show-icon="" title="上次操作结果待核实" description="先查询原请求回执,确认实际结果后再继续。"><template data-slot="action"><template data-component="Button" data-on-click="(verify)">查询原请求回执</template></template></template><template data-else=""><template data-component="Alert" data-if="(sourceReason(row.task, row.run))" type="warning" data-bind-title="(sourceReason(row.task, row.run))"></template><section class="ops-card"><div class="ops-section-head"><h2>运行观测与业务证据</h2><template data-component="Button" data-bind-disabled="(!!store.reason(row, 'observe'))" data-bind-title="(store.reason(row, 'observe'))" data-on-click="(action = 'observe')">获取最新观测</template></div><p class="muted">观测健康与人工验收分别记录。下列数据为本地模拟,实际指标由绑定规格和业务场景确定。</p><template data-component="Select" data-if="(row.run.observations.length)" data-model-value="(version)" aria-label="观测证据版本" data-bind-placeholder="('当前证据 v' + row.run.observations.at(-1).number)" data-bind-options="([...row.run.observations].reverse().map(e =&gt; ({ value: e.number, label: '证据 v' + e.number + ' · ' + formatDate(e.at) })))"></template><p data-if="(!selected)" class="ops-empty">尚未取得运行观测。发布成功后,需要先补齐业务证据,再进行人工验收。</p><template data-else=""><div data-if="(selected.errorRate !== undefined)" class="ops-signals"><div><span>错误率(模拟)</span><strong>{{ (selected.errorRate) }}%</strong></div><div><span>P95 延迟(模拟)</span><strong>{{ (selected.p95) }} ms</strong></div><div><span>证据版本</span><strong>v{{ (selected.number) }}</strong></div></div><article data-each="check in (selected.checks)" data-bind-key="(check.id)" class="ops-check"><div><strong>{{ (check.name) }}</strong><template data-component="Tag" data-bind-color="(check.status === 'pass' ? 'green' : check.status === 'fail' ? 'red' : 'orange')">{{ (({ pass: '通过', fail: '失败', missing: '缺失', stale: '过期' })[check.status]) }}</template></div><p>{{ (check.criterion) }}</p><small class="muted">{{ (check.detail) }}</small></article></template><template data-component="Alert" data-if="(store.reason(row, 'accept'))" type="info" data-bind-title="(store.reason(row, 'accept'))"></template><div class="ops-buttons"><template data-component="Button" data-bind-disabled="(!!store.reason(row, 'rejectAcceptance'))" data-on-click="(action = 'rejectAcceptance')">记录验收不通过</template><template data-component="Button" type="primary" data-bind-disabled="(!!store.reason(row, 'accept'))" data-on-click="version = undefined;
212
+ action = 'accept';">记录验收通过</template></div></section><section class="ops-card"><h2>异常记录 <span class="muted">{{ (row.run.incidents.length) }}</span></h2><p data-if="(!row.run.incidents.length)" class="muted">当前没有关联异常。暂无异常不等于已通过验收。</p><article data-each="i in (row.run.incidents)" data-bind-key="(i.id)" class="ops-check"><template data-component="Button" type="link" data-on-click="router.push(path(i.id));
213
+ emit('close');">{{ (i.code) }} · {{ (i.title) }}</template><template data-component="Tag">{{ (incidentLabel(i)) }}</template><p>{{ (i.signal) }}</p></article></section><section class="ops-card"><h2>人工验收历史</h2><p data-if="(!row.run.acceptances.length)" class="muted">尚无人工验收结论。</p><article data-each="a in ([...row.run.acceptances].reverse())" data-bind-key="(a.id)" class="ops-check"><strong>{{ (a.verdict === 'pass' ? '验收通过' : '验收不通过') }} · 证据 v{{ (a.evidenceVersion) }}</strong><p>{{ (a.note) }}</p><small class="muted">{{ (a.actor) }} · {{ (formatDate(a.at)) }}</small></article></section><section class="ops-card"><h2>操作记录</h2><article data-each="e in ([...row.run.events].reverse())" data-bind-key="(e.id)" class="ops-check"><strong>{{ (e.action) }}</strong><p>{{ (e.detail) }}</p><small>{{ (e.actor) }} · {{ (formatDate(e.at)) }}</small></article></section></template><template data-component="RecordMetadata" data-bind-record="(row.run)"></template><template data-component="OperationActionDialog" data-if="(action)" data-bind-row="(row)" data-bind-action="(action)" data-on-close="(action = undefined)" data-on-done="(action = undefined)"></template></template><template data-component="Alert" data-else="" type="warning" title="运行记录不存在或不在当前授权范围。"></template></template>
214
+
215
+ </template>
216
+ <template data-source="reference/src/operations/SourceSummary.html">
217
+ <!-- 来源:src/operations/SourceSummary.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
218
+ <section class="ops-card"><h2>绑定的生产版本</h2><template data-component="Descriptions" size="small" bordered="" data-bind-column="({ xs: 1, sm: 2 })" data-bind-items="([{ key: 'service', label: '应用 / 服务', content: source.service }, { key: 'pbc', label: 'PBC', content: source.project }, { key: 'version', label: '发布版本', content: source.version + ' / 修订 v' + source.revision }, { key: 'env', label: '环境', content: '生产环境' }, { key: 'digest', label: '制品摘要', content: source.digest }, { key: 'config', label: '配置快照', content: source.config }, { key: 'spec', label: '来源版本', content: '规格 v' + source.specVersion + ' / 流程 v' + source.flowVersion }, { key: 'at', label: '发布时间', content: formatDate(source.publishedAt) }])"></template><div class="ops-buttons"><template data-component="Button" data-if="(session.can('artifact:view', source.tenantId, source.pbcId))" data-on-click="(router.push('/releases/' + source.taskId + '/' + source.releaseId))">发布来源</template><template data-component="Button" data-on-click="(router.push('/tasks/' + source.taskId))">交付任务</template><template data-component="Button" data-if="(session.can('pbc:view', source.tenantId, source.pbcId))" data-on-click="(router.push('/pbcs/' + source.pbcId + '/workspace'))">PBC 工作区</template></div></section>
219
+
220
+ </template>
221
+ <template data-source="reference/src/pbc/ManagementTable.html">
222
+ <!-- 来源:src/pbc/ManagementTable.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
223
+ <section class="auth-list" data-bind-aria-label="(pageKey + '列表')"><div class="auth-filters"><template data-component="Input" data-model-value="(query)" data-bind-aria-label="('搜索' + pageKey)" placeholder="搜索名称、标识或负责人" allow-clear=""></template><template data-component="Select" data-model-value="(state)" aria-label="记录状态筛选" data-bind-options="([{ value: 'all', label: '全部状态' }, ...[...new Set(rows.map(r =&gt; r.status))].map(value =&gt; ({ value, label: value }))])"></template><template data-component="Button" data-on-click="query = '';
224
+ state = 'all';">重置</template></div><div class="auth-tools"><template data-component="ListBatchBar" data-if="(!readonly)" data-bind-count="(selection.selected.value.length)" data-bind-allowed="(!!canDelete)" data-on-remove="(emit('remove', selection.selected.value))" data-on-clear="(selection.clear)"></template><p data-else="" class="muted">关联与版本证据只读;删除不适用,业务操作请进入对应详情。</p><template data-component="Space" wrap=""><template data-component="Button" data-on-click="(desc = !desc)">时间{{ (desc ? '倒序' : '正序') }}</template><template data-component="Button" data-bind-loading="(loading)" data-on-click="(refresh)">刷新</template><template data-component="ColumnSettings" data-bind-preferences="(prefs)"></template></template></div><template data-component="Alert" data-if="(scene === 'error')" type="error" show-icon="" title="列表加载失败,已有记录保留。"><template data-slot="action"><template data-component="Button" data-on-click="(refresh)">重试</template></template></template><template data-else=""><template data-component="ProTable" data-bind-table="(table)" data-bind-control="(false)" data-bind-search="(async () =&gt; { })" data-bind-table-container="(false)" row-key="id" data-bind-loading="(loading)" data-bind-row-selection="(readonly ? undefined : selection.rowSelection.value)" data-bind-scroll="({ x: 'max-content' })" data-bind-pagination="({ showTotal: (n) =&gt; '共 ' + n + ' 项', showSizeChanger: true, pageSizeOptions: [5, 10, 20] })"></template><p data-if="(!filtered.length)" class="pbc-empty muted">{{ (readonly ? '暂无符合条件的记录,请调整筛选或核对来源业务。' : '暂无符合条件的记录,可调整筛选或使用页面上方的创建入口。') }}</p></template></section>
225
+
226
+ </template>
227
+ <template data-source="reference/src/pbc/PbcCreateEntry.html">
228
+ <!-- 来源:src/pbc/PbcCreateEntry.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
229
+ <template data-component="Modal" data-bind-open="(open)" title="从需求规格创建 PBC" data-on-cancel="(emit('close'))" data-bind-width="(720)"><p>先选择需求,核对规格与归属状态后继续。</p><label for="create-pbc-source" class="pbc-label">需求来源</label><template data-component="Select" id="create-pbc-source" data-model-value="(selected)" aria-label="PBC 创建来源" class="full-width" show-search="" option-filter-prop="label" data-bind-options="(candidates.map(s =&gt; ({ value: s.id, label: s.code + ' · ' + s.title + ' · ' + s.guide.label })))" placeholder="搜索需求名称或编号"></template><p class="muted">显示全部有权查看的需求;其中 {{ (candidates.filter(s =&gt; s.guide.create).length) }} 条当前可创建 PBC。</p><template data-component="Alert" data-if="(!candidates.length)" class="page-alert" type="info" show-icon="" title="暂无可见需求" description="请先发起意图,或联系业务管理员核对数据范围。"></template><section data-if="(source)" class="source-choice" aria-label="所选需求的创建条件"><h3>{{ (source.title) }}</h3><p><span class="mono">{{ (source.code) }}</span> · {{ (tenantLabel(source.tenantId)) }}</p><template data-component="Tag" data-bind-color="(source.guide.create ? 'green' : 'orange')">{{ (source.guide.label) }}</template><template data-component="Alert" data-bind-type="(source.guide.create ? 'success' : 'info')" show-icon="" data-bind-title="(source.guide.reason)" class="page-alert"></template><p class="muted">{{ (source.affiliation.label) }}</p></section><template data-slot="footer"><template data-component="Button" data-on-click="(emit('close'))">取消</template><template data-component="Button" data-if="(source &amp;&amp; !source.guide.create)" data-on-click="(next)">{{ (source.guide.action) }}</template><template data-component="Button" type="primary" data-bind-disabled="(!source?.guide.create)" data-on-click="(next)">继续创建向导</template></template></template>
230
+
231
+ </template>
232
+ <template data-source="reference/src/pbc/PbcDetail.html">
233
+ <!-- 来源:src/pbc/PbcDetail.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
234
+ <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'))">← 返回 PBC 列表</template><h1>{{ (pbc.name) }}</h1><p>{{ (pbc.ebc) }} · {{ (tenantLabel(pbc.tenantId)) }} · 负责人 {{ (pbc.owner) }}</p></div><template data-component="Space" wrap=""><template data-component="Tag">{{ (stateLabel(pbc)) }}</template><template data-component="Button" data-bind-disabled="(!can('pbc:edit') || !active)" data-on-click="(edit = pbc)">编辑资料</template><template data-component="Button" type="primary" data-on-click="(router.push('/pbcs/' + pbc.id + '/workspace'))">进入交付工作区</template></template></div><template data-component="Alert" data-if="(!active)" type="info" show-icon="" title="PBC 已归档,历史记录可查看。" class="page-alert"><template data-slot="action"><template data-component="Button" data-bind-disabled="(!can('pbc:archive'))" data-on-click="(lifecycle = pbc)">恢复使用</template></template></template><template data-component="Tabs" data-model-active-key="(tab)" data-bind-items="([{ key: 'overview', label: 'PBC 概览' }, { key: 'services', label: '服务管理' }, { key: 'metadata', label: '基础信息' }, { key: 'records', label: '操作记录', disabled: !can('pbc:audit') }])"></template><section data-if="(tab === 'overview')" class="pbc-overview"><article class="agent-panel"><h2>业务职责</h2><p class="pbc-description">{{ (pbc.description || '暂未填写职责与边界,可通过编辑资料补充。') }}</p><dl class="task-info-grid"><div><dt>PBC 标识</dt><dd>{{ (pbc.slug) }}</dd></div><div><dt>EBC 业务能力</dt><dd>{{ (pbc.ebc) }}</dd></div><div><dt>服务与方案</dt><dd>{{ (services.length) }} 项 <template data-component="Button" type="link" data-on-click="(tab = 'services')">查看服务</template></dd></div><div><dt>管理状态</dt><dd>{{ (stateLabel(pbc)) }} <template data-component="Button" type="link" data-bind-disabled="(!can('pbc:archive'))" data-on-click="(lifecycle = pbc)">{{ (active ? '归档' : '恢复') }}</template></dd></div></dl><h2>工程信息</h2><dl class="task-info-grid"><div><dt>GitLab Group(规划标识)</dt><dd>{{ (pbc.slug) }}</dd></div><div><dt>业务应用域名(规划)</dt><dd>{{ (pbc.domain) }}</dd></div></dl><template data-component="Alert" type="info" show-icon="" data-bind-title="(pbc.provisioned ? '工程登记为演示数据,未连接真实仓库或运行环境。' : '此记录尚未建立工程。')" description="一个 PBC 可包含多个服务仓库;运行健康、拓扑和环境配置后续接入。"></template></article><aside class="agent-panel"><h2>从这里继续交付</h2><ol class="pbc-next"><li><strong>查看需求与规格</strong><p>追溯每次建设与迭代的目标。</p></li><li><strong>继续交付任务</strong><p>核对当前阶段、等待与返工。</p></li><li><strong>回看版本产物</strong><p>查看任务生成的内容与验证结果。</p></li></ol><template data-component="Button" block="" type="primary" data-on-click="(router.push('/pbcs/' + pbc.id + '/workspace'))">打开工作区</template><p class="muted">质量确认与生产发布将在后续原型包继续衔接。</p></aside></section><template data-if="(tab === 'services')"><div class="section-heading pbc-section"><div><h2>服务与扩展方案</h2><p class="muted">已登记工程保持标识;新增方案经需求、契约及增量交付后建工程。</p></div><template data-component="Button" type="primary" data-bind-disabled="(!can('pbc:service') || !active)" data-on-click="(serviceDialog = {})">新增服务方案</template></div><template data-component="ManagementTable" data-bind-key="(id)" page-key="服务" data-bind-rows="(services)" context-label="工程类型" data-bind-more="(more)" data-bind-can-delete="(can('pbc:service') &amp;&amp; !!active)" data-on-action="(action)" data-on-remove="(remove)"></template><p class="muted pbc-list-note">只删除未建工程的方案;不会删除运行中的服务、仓库或历史产物。</p></template><section data-if="(tab === 'metadata')" class="agent-panel"><template data-component="RecordMetadata" data-bind-record="(pbc)"></template><p>管理状态:{{ (stateLabel(pbc)) }} · 记录版本 {{ (pbc.recordVersion) }} · 逻辑删除标记:{{ (pbc.isDeleted ? '已删除' : '未删除') }}</p></section><section data-if="(tab === 'records')" class="agent-panel"><template data-if="(can('pbc:audit'))"><h2>操作记录</h2><p class="muted">记录只读,删除与批量删除不适用。正式审计将由服务端可靠记录。</p><article data-each="e in (store.eventsFor(id))" data-bind-key="(e.id)" class="pbc-event"><h3>{{ (e.action) }}</h3><p>{{ (e.actor) }} · {{ (formatDate(e.at)) }} · {{ (e.reason) }}</p><details><summary>查看变更前后</summary><div class="pbc-diff"><pre>{{ (e.before) }}</pre><pre>{{ (e.after) }}</pre></div></details></article><p data-if="(!store.eventsFor(id).length)" class="muted">暂无管理操作记录;新建与归属执行记录可在工作区的来源结果中查看。</p></template><template data-component="Result" data-else="" status="403" title="没有查看操作记录的权限"></template></section><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="ServiceEditor" data-if="(serviceDialog)" data-bind-pbc="(pbc)" data-bind-service="(serviceDialog.service)" data-bind-readonly="(serviceDialog.readonly)" data-on-close="(serviceDialog = undefined)" data-on-saved="(saved)"></template><template data-component="ListDeleteDialog" data-if="(targets.length)" data-model-targets="(targets)" label="服务方案" data-bind-check="(t =&gt; store.serviceCheck(id, t))" data-bind-submit="(ts =&gt; store.serviceRemove(id, deleteVersion, ts))" data-on-close="(targets = [])" data-on-deleted="(targets = [])"></template></template>
235
+
236
+ </template>
237
+ <template data-source="reference/src/pbc/PbcEditor.html">
238
+ <!-- 来源:src/pbc/PbcEditor.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
239
+ <template data-component="Drawer" data-bind-open="(true)" title="编辑 PBC 基础资料" data-bind-size="(680)" data-bind-mask="({ closable: false })" data-on-close="(close)"><template data-component="Alert" data-if="(error)" type="error" show-icon="" data-bind-title="(error)" class="page-alert"></template><p class="muted">{{ (record.slug) }} · 租户与工程标识保持固定。此处保存不改变部署或历史交付快照。</p><template data-component="Form" layout="vertical" data-bind-disabled="(!allowed || busy)"><template data-component="FormItem" label="PBC 名称" required=""><template data-component="Input" data-model-value="(data.name)" aria-label="PBC 名称" data-bind-maxlength="(60)"></template></template><template data-component="FormItem" label="EBC 业务能力" required=""><template data-component="Input" data-model-value="(data.ebc)" aria-label="EBC 业务能力" data-bind-maxlength="(80)"></template></template><template data-component="FormItem" label="负责人" required=""><template data-component="Input" data-model-value="(data.owner)" aria-label="PBC 负责人" data-bind-maxlength="(60)"></template></template><template data-component="FormItem" label="职责与边界"><template data-component="Input.TextArea" data-model-value="(data.description)" aria-label="PBC 职责与边界" data-bind-rows="(4)" data-bind-maxlength="(1000)"></template></template><template data-component="FormItem" label="变更原因" required=""><template data-component="Input.TextArea" data-model-value="(reason)" aria-label="PBC 变更原因" data-bind-maxlength="(500)" data-bind-rows="(3)"></template></template></template><template data-slot="footer"><template data-component="Space"><template data-component="Button" data-on-click="(close)">取消</template><template data-component="Button" type="primary" data-bind-disabled="(!allowed)" data-bind-loading="(busy)" data-on-click="(save)">保存资料</template></template></template></template>
240
+
241
+ </template>
242
+ <template data-source="reference/src/pbc/PbcLifecycle.html">
243
+ <!-- 来源:src/pbc/PbcLifecycle.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
244
+ <template data-component="Modal" data-bind-open="(true)" data-bind-title="(verb + ' ' + record.name)" data-bind-mask-closable="(false)" data-on-cancel="(emit('close'))"><template data-component="Alert" show-icon="" type="info" data-bind-title="(verb === '归档' ? '归档后保留历史,停止新增归属与配置。' : '恢复后可继续新增需求归属与配置。')" description="这项管理操作不会停止服务、删除仓库或变更生产环境。"></template><label for="pbc-lifecycle-reason" class="pbc-label">{{ (verb) }}原因</label><template data-component="Input.TextArea" id="pbc-lifecycle-reason" data-model-value="(reason)" aria-label="状态变更原因" data-bind-rows="(3)" data-bind-maxlength="(500)"></template><template data-component="Alert" data-if="(error)" type="error" show-icon="" data-bind-title="(error)" class="page-alert"></template><template data-slot="footer"><template data-component="Button" data-on-click="(emit('close'))">取消</template><template data-component="Button" type="primary" data-on-click="(save)">确认{{ (verb) }}</template></template></template>
245
+
246
+ </template>
247
+ <template data-source="reference/src/pbc/PbcPage.html">
248
+ <!-- 来源:src/pbc/PbcPage.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
249
+ <template data-component="Result" data-if="(!intent || !spec || !session.readable('pbc:view', intent.tenantId))" status="403" title="归属页面不可访问或尚未生成规格"><template data-slot="extra"><template data-component="Button" data-on-click="(router.push('/intents/' + id + '/spec'))">返回规格工作区</template></template></template><template data-else=""><template data-component="SpecHeader" data-bind-intent="(intent)" data-bind-version="(version)" data-bind-step="(2)"><template data-component="Button" data-on-click="(router.push('/intents/' + id + '/spec/review'))">查看规格评审</template></template><template data-component="Alert" data-if="(error || store.notice)" type="error" show-icon="" data-bind-title="(error || store.notice)" class="page-alert"></template><template data-component="Alert" data-if="(sourceError)" type="warning" show-icon="" data-bind-title="(sourceError)" class="page-alert"></template><section data-if="(job?.status === 'done')" class="panel delivery-main"><div class="section-heading"><div><h2>PBC 归属已完成,可以发起研发交付</h2><p class="muted">将本次已确认规格交给所选交付流程,查看执行阶段和产物。</p></div><template data-component="Space" wrap=""><template data-component="Button" data-on-click="(router.push('/pbcs/' + job.pbc.id))">打开 PBC 概览</template><template data-component="Button" data-on-click="(router.push('/pbcs/' + job.pbc.id + '/workspace'))">进入交付工作区</template><template data-component="TaskLaunch" data-bind-intent-id="(id)"></template></template></div></section><template data-component="PbcProgress" data-if="(job)" data-bind-job="(job)"></template><template data-else=""><section class="panel delivery-main"><div class="section-heading"><div><h2>关联已有 PBC</h2><p class="muted">为当前需求确定业务归属。优先复用已有业务系统,按授权选择。</p></div><template data-component="Button" data-bind-disabled="(!!sourceError || !session.can('pbc:create', intent.tenantId))" data-on-click="(wizard = true)">创建新 PBC</template></div><template data-component="PbcPicker" data-bind-tenant-id="(intent.tenantId)" data-bind-value="(selected)" data-on-change="(selected = $event)"></template><div class="pbc-link-review"><div><strong>{{ (target ? '已选择:' + target.name : '请选择一个 PBC') }}</strong><p class="muted">来源意图 v{{ (version?.source.version) }} · 规格 v{{ (version?.number) }} · {{ (target?.ebc || '选择后核对 EBC 归属与负责人') }}</p></div><template data-component="Button" type="primary" data-bind-disabled="(!target || !!sourceError || !session.can('pbc:link', intent.tenantId, target?.id))" data-bind-loading="(submitting)" data-on-click="(link)">核对并关联</template></div></section></template><template data-component="PbcWizard" data-if="(wizard &amp;&amp; !job &amp;&amp; !sourceError &amp;&amp; session.can('pbc:create', intent.tenantId))" data-bind-key="(id)" data-bind-intent-id="(id)" data-on-close="(wizard = false)"></template></template>
250
+
251
+ </template>
252
+ <template data-source="reference/src/pbc/PbcPicker.html">
253
+ <!-- 来源:src/pbc/PbcPicker.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
254
+ <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 = '';
255
+ 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';
256
+ 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>
257
+
258
+ </template>
259
+ <template data-source="reference/src/pbc/PbcProgress.html">
260
+ <!-- 来源:src/pbc/PbcProgress.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
261
+ <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>
262
+
263
+ </template>
264
+ <template data-source="reference/src/pbc/PbcWizard.html">
265
+ <!-- 来源:src/pbc/PbcWizard.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
266
+ <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--;
267
+ 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>
268
+
269
+ </template>
270
+ <template data-source="reference/src/pbc/PbcWorkspace.html">
271
+ <!-- 来源:src/pbc/PbcWorkspace.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
272
+ <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>
273
+
274
+ </template>
275
+ <template data-source="reference/src/pbc/PbcsPage.html">
276
+ <!-- 来源:src/pbc/PbcsPage.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
277
+ <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>
278
+
279
+ </template>
280
+ <template data-source="reference/src/pbc/ServiceEditor.html">
281
+ <!-- 来源:src/pbc/ServiceEditor.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
282
+ <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>
283
+
284
+ </template>
285
+ <template data-source="reference/src/pbc/ServiceList.html">
286
+ <!-- 来源:src/pbc/ServiceList.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
287
+ <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>
288
+
289
+ </template>
290
+ <template data-source="reference/src/permissions/AdminList.html">
291
+ <!-- 来源:src/permissions/AdminList.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
292
+ <div class="page-heading"><div><h1>{{ (title) }}</h1><p>{{ (description) }}</p></div><template data-component="Button" data-if="(!readonly)" type="primary" data-bind-disabled="(!session.can(createAction))" data-on-click="(emit('create'))">{{ (kind === 'roles' ? '新增角色' : '添加成员') }}</template></div><section class="auth-list"><div class="auth-filters"><template data-component="Input" data-model-value="(query)" aria-label="查找权限记录" placeholder="搜索名称、编码或说明" allow-clear=""></template><template data-component="Select" data-model-value="(scope)" aria-label="所属范围筛选" data-bind-options="(scopeOptions)"></template><template data-component="Select" data-if="(kind === 'roles')" data-model-value="(status)" aria-label="角色状态筛选" data-bind-options="([{ label: '全部状态', value: 'all' }, { label: '启用', value: '启用' }, { label: '停用', value: '停用' }])"></template><template data-component="Button" data-on-click="(reset)">重置</template></div><div class="auth-tools"><template data-component="ListBatchBar" data-if="(!readonly)" data-bind-count="(selection.selected.value.length)" data-bind-allowed="(canDelete)" data-on-remove="(emit('remove', selection.selected.value))" data-on-clear="(selection.clear)"></template><p data-else="" class="muted">授权记录只读,保留变更前后内容;删除不适用。</p><template data-component="Space" wrap=""><template data-component="Button" data-on-click="(desc = !desc)">时间{{ (desc ? '倒序' : '正序') }}</template><template data-component="Button" data-bind-loading="(refreshing)" data-on-click="(refresh)">刷新</template><template data-component="ColumnSettings" data-bind-preferences="(prefs)"></template></template></div><template data-component="Alert" data-if="(kind === 'members')" class="page-alert" type="info" show-icon="" title="此处管理业务关联与角色授权" description="账号、姓名和部门来自 MaxKey 身份目录;移除业务关联会撤去该范围的角色授权,账号保留。"></template><template data-component="Alert" data-if="(store.scene === 'error')" type="error" title="权限数据加载失败" description="请刷新重试;现有授权未改变。" show-icon=""><template data-slot="action"><template data-component="Button" data-on-click="(refresh)">重试</template></template></template><template data-component="ProTable" data-else="" data-bind-table="(table)" data-bind-search="(async () =&gt; { })" data-bind-control="(false)" data-bind-table-container="(false)" row-key="id" data-bind-loading="(refreshing)" data-bind-row-selection="(readonly ? undefined : selection.rowSelection.value)" data-bind-scroll="({ x: 'max-content' })" data-bind-pagination="({ showTotal: (n) =&gt; '共 ' + n + ' 项', showSizeChanger: true, pageSizeOptions: [5, 10, 20] })"></template></section>
293
+
294
+ </template>
295
+ <template data-source="reference/src/permissions/EffectiveGrants.html">
296
+ <!-- 来源:src/permissions/EffectiveGrants.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
297
+ <template data-component="Empty" data-if="(!grants.length)" description="当前没有生效的业务权限"></template><section data-each="grant in (grants)" data-bind-key="(grant.id)" class="auth-grant"><h3>{{ (grant.name) }}</h3><p><strong>范围:</strong>{{ (grant.tenantIds.map(t =&gt; t === '*' ? '全部范围' : tenantLabel(t)).join('、')) }}</p><p><strong>PBC:</strong>{{ ((grant.pbcIds || ['*']).map(pbc).join('、')) }}</p><div class="auth-tags"><template data-component="Tag" data-each="code in (grant.actions)" data-bind-key="(code)">{{ (label(code)) }}</template></div></section>
298
+
299
+ </template>
300
+ <template data-source="reference/src/permissions/GrantEditor.html">
301
+ <!-- 来源:src/permissions/GrantEditor.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
302
+ <template data-component="Drawer" data-bind-open="(true)" data-bind-title="('配置权限 · ' + role.name)" data-bind-size="(780)" data-bind-mask="({ closable: false })" data-on-close="(close)"><template data-component="Alert" type="info" show-icon="" data-bind-title="('本次变更影响 ' + affected.length + ' 条成员关联')" data-bind-description="(affected.join('、') || '当前尚无成员使用此角色。')" 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="Tabs" data-model-active-key="(tab)" data-bind-items="([{ key: 'features', label: '功能与数据范围' }, { key: 'explain', label: '授权规则' }])"></template><div data-if="(tab === 'features')"><section data-each="(grant,index) in (value.grants)" data-bind-key="(grant.id)" class="auth-grant"><div class="section-heading"><h2>授权组 {{ (index + 1) }}</h2><template data-component="Button" danger="" type="text" data-bind-disabled="(!allowed)" data-on-click="(value.grants.splice(index, 1))">移除此组</template></div><label data-bind-for="('auth-group-' + index)">授权组名称</label><template data-component="Input" data-bind-id="('auth-group-' + index)" data-model-value="(grant.name)" data-bind-disabled="(!allowed)"></template><div class="auth-grant-columns"><div><h3>菜单与功能</h3><template data-component="Tree" checkable="" default-expand-all="" data-bind-tree-data="(tree)" data-bind-checked-keys="(grant.actions)" data-bind-disabled="(!allowed)" data-on-check="((keys) =&gt; update(index, keys))"></template></div><div><h3>数据与资源范围</h3><label data-bind-for="('auth-tenants-' + index)">租户 / 平台范围</label><template data-component="Select" data-bind-id="('auth-tenants-' + index)" data-model-value="(grant.tenantIds)" mode="multiple" data-bind-options="(scopeOptions)" data-bind-disabled="(!allowed)"></template><label data-bind-for="('auth-pbc-' + index)">PBC 范围</label><template data-component="Select" data-bind-id="('auth-pbc-' + index)" data-model-value="(grant.pbcIds)" mode="multiple" data-bind-options="(pbcOptions)" data-bind-disabled="(!allowed)"></template><template data-if="(grant.actions.some(a =&gt; a.startsWith('release:')))"><label data-bind-for="('auth-env-' + index)">发布目标环境</label><template data-component="Select" data-bind-id="('auth-env-' + index)" data-model-value="(grant.environmentIds)" mode="multiple" data-bind-options="([{ value: '*', label: '全部环境' }, { value: 'staging', label: '预发布环境' }, { value: 'production', label: '生产环境' }])" data-bind-disabled="(!allowed)" placeholder="未限定时适用全部环境"></template></template><p class="muted">此范围只约束本组所选功能。意图与规格在立项前按租户控制;PBC 查看、关联和结果还核对具体资源。</p></div></div></section><template data-component="Button" block="" data-bind-disabled="(!allowed)" data-on-click="(add)">新增授权组</template><p data-if="(!value.grants.length)" class="muted">角色将没有功能权限;保存后关联成员失去此角色提供的授权。</p></div><div data-else="" class="auth-explanation"><h2>统一配置,业务页面按权限开放</h2><p>同一人可以关联多个角色;角色名称仅用于识别,实际按每组功能和资源范围判定。</p><h3>菜单、按钮与接口</h3><p>查看权限控制页面入口,操作权限控制按钮与业务动作。正式后端必须独立校验对应接口,不能仅依赖按钮隐藏。</p><p class="muted">本原型沿用现有业务动作标识。正式领域权限码及 OpenAPI 映射尚待 spec/design,本页不虚构已接通的接口清单。</p><h3>授权范围与变更生效</h3><p>管理员只能授出受管范围内的权限;转授管理能力还需专门授权。生产人工确认、独立评审和版本检查继续有效。</p></div><template data-component="ProForm" name="role-grant-reason" data-bind-form="(form)" layout="vertical" data-bind-disabled="(!allowed || busy)" class="auth-reason"></template><template data-slot="footer"><template data-component="Space" class="auth-footer"><template data-component="Button" data-bind-disabled="(busy)" data-on-click="(close)">取消</template><template data-component="Button" type="primary" data-bind-disabled="(!allowed)" data-bind-loading="(busy)" data-on-click="(save)">保存权限</template></template></template></template>
303
+
304
+ </template>
305
+ <template data-source="reference/src/permissions/MemberEditor.html">
306
+ <!-- 来源:src/permissions/MemberEditor.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
307
+ <template data-component="Drawer" data-bind-open="(true)" data-bind-title="(member ? '修改成员授权' : '添加成员')" data-bind-size="(640)" data-bind-mask="({ closable: false })" data-on-close="(close)"><template data-component="Alert" type="info" show-icon="" title="关联已有身份,不创建新账号" description="姓名、部门、账号状态由 MaxKey 管理;本页仅维护 i3-Composer 业务角色关联。" class="page-alert"></template><template data-component="Alert" data-if="(error)" type="error" data-bind-title="(error)" show-icon="" class="page-alert"></template><template data-component="ProForm" name="business-member" data-bind-form="(form)" layout="vertical" data-bind-disabled="(!allowed || busy)"></template><template data-component="RecordMetadata" data-if="(member)" data-bind-record="(member)"></template><template data-slot="footer"><template data-component="Space" class="auth-footer"><template data-component="Button" data-bind-disabled="(busy)" data-on-click="(close)">取消</template><template data-component="Button" type="primary" data-bind-disabled="(!allowed)" data-bind-loading="(busy)" data-on-click="(save)">保存成员授权</template></template></template></template>
308
+
309
+ </template>
310
+ <template data-source="reference/src/permissions/MembersPage.html">
311
+ <!-- 来源:src/permissions/MembersPage.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
312
+ <template data-component="AdminList" kind="members" title="成员授权" description="关联已有成员,按角色统一分配功能和资源权限。" data-bind-rows="(rows)" data-on-create="selected = undefined;
313
+ overlay = 'edit';" data-on-action="(action)" data-on-remove="(remove)"></template><template data-component="MemberEditor" data-if="(overlay === 'edit')" data-bind-member="(selected)" data-on-close="(close)" data-on-saved="(close)"></template><template data-component="Drawer" data-bind-open="(overlay === 'detail')" title="成员有效权限" data-bind-size="(720)" data-on-close="(close)"><template data-if="(current)"><h2>{{ (store.actorName(current.actorId)) }}</h2><p>关联角色:{{ (current.roleIds.map(store.roleName).join('、')) }}</p><p class="muted">以下显示本条业务关联范围内各角色的生效权限;停用角色不参与授权。账号由 MaxKey 管理。</p><template data-component="EffectiveGrants" data-bind-grants="(store.effective(current.actorId, current.tenantId).grants)"></template><template data-component="RecordMetadata" data-bind-record="(current)"></template></template></template><template data-component="ListDeleteDialog" data-if="(targets.length)" data-model-targets="(targets)" label="业务关联(账号保留)" data-bind-check="(store.checkDeleteMember)" data-bind-submit="(store.deleteMembers)" data-on-close="(targets = [])" data-on-deleted="(targets = [])"></template>
314
+
315
+ </template>
316
+ <template data-source="reference/src/permissions/RecordsPage.html">
317
+ <!-- 来源:src/permissions/RecordsPage.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
318
+ <template data-component="AdminList" data-bind-key="(route.fullPath)" kind="records" title="授权记录" description="按对象和时间追溯角色及成员授权变更。" data-bind-initial-query="(String(route.query.target || ''))" data-bind-rows="(rows)" data-on-action="((_key, row) =&gt; selected = row.id)"></template><template data-component="Drawer" data-bind-open="(!!record)" title="授权变更详情" data-bind-size="(780)" data-on-close="(selected = '')"><template data-if="(record)"><h2>{{ (record.operation) }} · {{ (record.target) }}</h2><p>{{ (record.actorName) }} · {{ (new Date(record.at).toLocaleString('zh-CN')) }}</p><p><strong>变更原因:</strong>{{ (record.reason) }}</p><div class="auth-diff"><section><h3>变更前</h3><pre>{{ (record.before) }}</pre></section><section><h3>变更后</h3><pre>{{ (record.after) }}</pre></section></div><p class="muted">本地原型记录;真实后端审计和不可篡改存储尚未接入。</p></template></template>
319
+
320
+ </template>
321
+ <template data-source="reference/src/permissions/RoleEditor.html">
322
+ <!-- 来源:src/permissions/RoleEditor.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
323
+ <template data-component="Drawer" data-bind-open="(true)" data-bind-title="(role ? '编辑角色' : '新增角色')" data-bind-size="(600)" data-bind-mask="({ closable: false })" data-on-close="(close)"><template data-component="Alert" data-if="(error)" class="page-alert" type="error" show-icon="" data-bind-title="(error)"></template><template data-component="ProForm" name="business-role" data-bind-form="(form)" layout="vertical" data-bind-disabled="(busy || !allowed)"></template><p class="muted">新增角色初始没有功能权限,保存后通过「配置权限」授予。</p><template data-component="RecordMetadata" data-if="(role)" data-bind-record="(role)"></template><template data-slot="footer"><template data-component="Space" class="auth-footer"><template data-component="Button" data-bind-disabled="(busy)" data-on-click="(close)">取消</template><template data-component="Button" type="primary" data-bind-disabled="(!allowed)" data-bind-loading="(busy)" data-on-click="(save)">保存角色</template></template></template></template>
324
+
325
+ </template>
326
+ <template data-source="reference/src/permissions/RolesPage.html">
327
+ <!-- 来源:src/permissions/RolesPage.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
328
+ <template data-component="AdminList" kind="roles" title="角色管理" description="配置角色的功能与资源范围,按需关联成员。" data-bind-rows="(rows)" data-on-create="selected = undefined;
329
+ overlay = 'edit';" data-on-action="(action)" data-on-remove="(remove)"></template><template data-component="RoleEditor" data-if="(overlay === 'edit')" data-bind-role="(selected)" data-on-close="(close)" data-on-saved="(close)"></template><template data-component="GrantEditor" data-if="(overlay === 'grant' &amp;&amp; selected)" data-bind-role="(selected)" data-on-close="(close)" data-on-saved="(close)"></template><template data-component="Drawer" data-bind-open="(overlay === 'detail')" title="角色详情" data-bind-size="(720)" data-on-close="(close)"><template data-if="(current)"><h2>{{ (current.name) }} <template data-component="Tag">{{ (current.enabled ? '启用' : '停用') }}</template></h2><p>{{ (current.code) }} · {{ (current.description) }}</p><p>关联成员 {{ (affected.length) }} 条:{{ (affected.join('、') || '暂无') }}</p><template data-component="Alert" data-if="(!current.enabled)" type="warning" title="角色已停用,以下配置暂不生效。"></template><template data-component="EffectiveGrants" data-bind-grants="(current.grants)"></template><template data-component="RecordMetadata" data-bind-record="(current)"></template></template></template><template data-component="Drawer" data-bind-open="(overlay === 'toggle')" data-bind-title="(selected?.enabled ? '停用角色' : '启用角色')" data-bind-size="(560)" data-bind-mask="({ closable: false })" data-on-close="(close)"><template data-if="(selected)"><template data-component="Alert" show-icon="" data-bind-type="(selected.enabled ? 'warning' : 'info')" data-bind-title="(selected.name)" data-bind-description="('影响 ' + affected.length + ' 条成员关联:' + (affected.join('、') || '暂无'))"></template><p>保存后按新状态计算业务权限;其他角色提供的权限仍保留。</p><label for="role-status-reason">变更原因</label><template data-component="Input.TextArea" id="role-status-reason" data-model-value="(reason)"></template><template data-component="Alert" data-if="(error)" type="error" data-bind-title="(error)"></template><template data-if="(selected.protected)"><p>系统引导角色受保护。</p></template></template><template data-slot="footer"><template data-component="Space" class="auth-footer"><template data-component="Button" data-on-click="(close)">取消</template><template data-component="Button" type="primary" data-bind-danger="(selected?.enabled)" data-bind-disabled="(!selected || selected.protected || !session.can('permission:roles', selected.tenantId))" data-on-click="(toggle)">{{ (selected?.enabled ? '确认停用' : '确认启用') }}</template></template></template></template><template data-component="ListDeleteDialog" data-if="(targets.length)" data-model-targets="(targets)" label="角色" data-bind-check="(store.checkDeleteRole)" data-bind-submit="(store.deleteRoles)" data-on-close="(targets = [])" data-on-deleted="(targets = [])"></template>
330
+
331
+ </template>
332
+ <template data-source="reference/src/releases/ReleaseActionDialog.html">
333
+ <!-- 来源:src/releases/ReleaseActionDialog.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
334
+ <template data-component="Modal" data-bind-open="(true)" data-bind-title="(actionLabels[action])" data-bind-width="(650)" data-bind-mask-closable="(false)" data-on-cancel="(emit('close'))"><div class="release-note"><strong>{{ (v.name) }} · {{ (v.version) }}</strong><p>{{ (environmentLabel(v.environment)) }} · 发布单修订 v{{ (v.number) }} · 配置 {{ (v.config) }}</p><p>制品 {{ (v.materials?.digest || '缺失') }} · 首次灰度 {{ (v.traffic) }}%</p></div><template data-component="Alert" data-if="(action === 'approve')" type="warning" show-icon="" data-bind-title="('此授权仅覆盖本版本在' + environmentLabel(v.environment) + '的首次灰度及后续全量')" description="变更制品、配置、环境或灰度方案后,必须重新检查和人工授权。" class="page-alert"></template><template data-component="Alert" data-if="(['rollback', 'stop'].includes(action))" class="page-alert" type="warning" show-icon="" data-bind-title="(action === 'rollback' ? '目标稳定版本:' + (v.materials?.rollback?.version || '无') : '停止本次发布并撤除本版本流量')" description="应用恢复不会自动还原数据库;按本版迁移与恢复方案单独核查。"></template><template data-component="Alert" data-if="(stale)" type="warning" show-icon="" title="记录已变化,操作说明保留"><template data-slot="action"><template data-component="Button" data-on-click="(rebase)">已核对当前版本</template></template></template><template data-component="Alert" data-if="(reason || error)" type="error" show-icon="" data-bind-title="(error || reason)" class="page-alert"></template><template data-component="ProForm" name="release-action" data-bind-form="(form)" layout="vertical" data-bind-disabled="(busy)"></template><template data-component="Checkbox" data-if="(action === 'approve')" data-model-checked="(checked)">已核对本版证据、目标环境、灰度阈值及恢复方案</template><p class="muted">关闭后保留本账号的说明;登录失效或版本变化时不会自动提交。</p><template data-slot="footer"><template data-component="Space" wrap=""><template data-component="Button" data-on-click="(emit('close'))">取消并保留说明</template><template data-component="Button" type="primary" data-bind-danger="(['rollback', 'stop'].includes(action))" data-bind-loading="(busy)" data-bind-disabled="(!!reason || stale || (action === 'approve' &amp;&amp; !checked))" data-on-click="(submit)">{{ (actionLabels[action]) }}</template></template></template></template>
335
+
336
+ </template>
337
+ <template data-source="reference/src/releases/ReleaseDetail.html">
338
+ <!-- 来源:src/releases/ReleaseDetail.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
339
+ <template data-component="Result" data-if="(!row || !r || !v)" status="403" title="发布单不存在或无权访问"><template data-slot="extra"><template data-component="Button" data-on-click="(router.push('/releases'))">返回发布列表</template></template></template><template data-else=""><template data-component="OperationEntry" data-bind-task="(row.task)" data-bind-release-id="(r.id)"></template><div class="page-heading"><div><template data-component="Button" type="link" class="agent-back" data-on-click="(router.push('/releases'))">← 返回门禁与发布</template><div class="release-title"><h1>{{ (execution ? '发布执行与结果' : v.name) }}</h1><template data-component="Tag" data-bind-color="(r.unconfirmed ? 'orange' : releaseColors[r.state])">{{ (r.unconfirmed ? '结果待核实' : releaseLabels[r.state]) }}</template></div><p>{{ (r.code) }} · {{ (execution ? v.name + ' · ' : '') }}{{ (v.version) }} · {{ (environmentLabel(v.environment)) }} · 修订 v{{ (v.number) }}</p></div><template data-component="Space" wrap=""><template data-component="Button" data-on-click="(router.push('/tasks/' + row.task.id))">来源任务</template><template data-component="Button" data-on-click="(router.push(releaseUrl(r, !execution)))">{{ (execution ? '审核与版本证据' : '执行与结果') }}</template></template></div><template data-component="Alert" data-if="(r.unconfirmed)" class="page-alert" type="warning" show-icon="" title="上次提交响应不明,请查询原请求回执" data-bind-description="('原编号 ' + r.unconfirmed + ';查询结果前不会再次推进。')"></template><template data-component="Alert" data-if="(execution &amp;&amp; !r.unconfirmed)" class="page-alert" data-bind-type="(r.state === 'failed' ? 'error' : r.state === 'succeeded' ? 'success' : 'info')" show-icon="" data-bind-title="(releaseSummary(r))" data-bind-description="(r.state === 'succeeded' ? '本次发布完成;运行验收与归档属于后续范围。' : '当前展示模拟部署和观测结果,每一步均保留原版本、当前流量及回执。')"></template><div class="release-layout"><section class="agent-panel release-content"><template data-if="(execution)"><template data-if="(!r.unconfirmed)"><ol class="release-steps" aria-label="发布阶段"><li data-each="(name,i) in (stages)" data-bind-key="(name)" data-bind-class="({ done: stepDone(i), current: i === step })"><span>{{ (i + 1) }}</span><strong>{{ (name) }}</strong></li></ol><div class="release-traffic"><div><span class="muted">本次版本 {{ (v.version) }} 的流量</span><strong>{{ (r.traffic) }}<small>%</small></strong><p>{{ (r.state === 'rolledBack' ? '已切回 ' + v.materials?.rollback?.version : r.state === 'stopped' ? '本次版本流量已撤除' : r.traffic === 100 ? '本次版本已接入全部流量' : r.traffic === 0 ? '新版本尚未接入流量' : '保留当前比例,按本版阈值判断后续动作') }}</p></div><template data-component="Progress" type="circle" data-bind-percent="(r.traffic)" data-bind-size="(140)" data-bind-status="(r.state === 'failed' ? 'exception' : 'normal')"></template></div><div class="release-stat-grid"><article><span>错误率</span><strong>{{ (r.observation ? r.observation.errorRate + '%' : '待灰度后采集') }}</strong><small>上限 {{ (v.errorLimit) }}%</small></article><article><span>P95 延迟</span><strong>{{ (r.observation ? r.observation.latency + ' ms' : '待灰度后采集') }}</strong><small>上限 {{ (v.latencyLimit) }} ms</small></article><article><span>有限重试</span><strong>{{ (r.retries) }} / 2</strong><small>只重试失败步骤</small></article></div><p data-if="(r.observation)" class="muted">观测时间 {{ (formatDate(r.observation.at)) }} · {{ (r.observation.pass ? '达到本版阈值' : '未达到本版阈值,禁止全量') }} · 指标均为模拟</p></template><template data-component="Alert" data-else="" type="info" show-icon="" title="本次提交的执行结果尚待核实" description="核实前不展示本次提交的阶段、流量或观测结论;已有执行记录保留,下方待核实回执不作为完成依据。" class="page-alert"></template><div class="release-note"><strong>{{ (v.materials?.rollback ? '稳定版本恢复目标:' + v.materials.rollback.version : '首次发布:暂无稳定版本可回滚') }}</strong><p>{{ (v.rollbackPlan) }}</p><p>{{ (v.materials?.migration === 'expand-contract' ? '本次包含兼容扩展迁移;应用回滚后,数据库保持当前迁移状态,需单独核查。' : '本次材料登记无数据库变更;停止或回滚仍须保留恢复记录。') }}</p></div><h2>执行与恢复记录</h2><ol class="release-events"><li data-each="event in ([...r.events].reverse())" data-bind-key="(event.id)"><div><strong>{{ (event.action) }}</strong><template data-component="Tag" data-if="(event.id === r.unconfirmed)" color="orange">待核实回执</template><template data-component="Tag">本版流量 {{ (event.traffic) }}%</template></div><p>{{ (event.detail) }}</p><small>{{ (event.actor) }} · {{ (formatDate(event.at)) }} · 修订 v{{ (event.version) }}</small><code>{{ (event.id) }}</code></li></ol></template><template data-else=""><template data-component="Tabs" data-model-active-key="(tab)" data-bind-items="([{ key: 'evidence', label: '发布前证据' }, { key: 'versions', label: '版本快照 (' + r.versions.length + ')' }, { key: 'history', label: '操作与授权记录' }])"></template><template data-if="(tab === 'evidence')"><div class="section-heading"><h2>发布前检查</h2><template data-component="Tag" data-bind-color="(checks.every(c =&gt; ['pass', 'na'].includes(c.status)) ? 'green' : 'orange')">{{ (checks.filter(c =&gt; !['pass', 'na'].includes(c.status)).length) }} 项待补齐</template></div><p class="muted">核对固定版本的材料;灰度观测在授权、部署及接入流量之后进行。</p><p data-if="(v.preflight)">最近检查:{{ (v.preflight.by) }} · {{ (formatDate(v.preflight.at)) }}</p><template data-component="Alert" data-else="" type="info" show-icon="" title="本修订版尚未执行发布前检查" class="page-alert"></template><div class="review-checks"><details data-each="c in (checks)" data-bind-key="(c.id)"><summary><template data-component="Tag" data-bind-color="(c.status === 'pass' || c.status === 'na' ? 'green' : c.status === 'fail' ? 'red' : 'orange')">{{ (c.status === 'pass' ? '通过' : c.status === 'na' ? '不适用' : c.status === 'fail' ? '失败' : '缺失') }}</template><strong>{{ (c.name) }}</strong></summary><p class="release-check-detail">{{ (c.detail) }}</p></details></div><h2 class="release-section-title">固定的交付产物</h2><div class="release-ref-list"><template data-component="RouterLink" data-each="ref in (v.refs)" data-bind-key="(ref.id)" data-bind-to="('/tasks/' + row.task.id + '/artifacts/' + ref.id + '?version=' + ref.version)">{{ (ref.name) }} v{{ (ref.version) }} →</template></div><h3>发布说明</h3><p class="review-text">{{ (v.description || '尚未填写') }}</p><h3>灰度与恢复方案</h3><p>首次 {{ (v.traffic) }}% → 观测达标 → 全量;错误率 ≤ {{ (v.errorLimit) }}%,P95 ≤ {{ (v.latencyLimit) }}ms。</p><p class="review-text">{{ (v.rollbackPlan || '尚未填写') }}</p></template><template data-else-if="(tab === 'versions')"><div class="section-heading"><h2>不可变版本依据</h2><template data-component="Select" data-model-value="(selectedVersion)" aria-label="发布修订版" data-bind-options="([{ value: 0, label: '当前修订 v' + v.number }, ...r.versions.filter(x =&gt; x.number !== v?.number).map(x =&gt; ({ value: x.number, label: '历史修订 v' + x.number }))])"></template></div><template data-if="(evidence)"><dl class="task-trace"><dt>应用 / 修订版本</dt><dd>{{ (evidence.version) }} / v{{ (evidence.number) }}</dd><dt>目标环境 / 配置</dt><dd>{{ (environmentLabel(evidence.environment)) }} / {{ (evidence.config) }}</dd><dt>来源任务 / 规格 / 流程</dt><dd>{{ (evidence.sourceCode) }} / v{{ (evidence.specVersion) }} / {{ (evidence.flowName) }} v{{ (evidence.flowVersion) }}</dd><dt>提交标识</dt><dd>{{ (evidence.materials?.commit || '缺失') }}</dd><dt>制品摘要</dt><dd class="mono">{{ (evidence.materials?.digest || '缺失') }}</dd><dt>发布说明</dt><dd class="review-text">{{ (evidence.description) }}</dd><dt>首次灰度与阈值</dt><dd>{{ (evidence.traffic) }}% · 错误率 ≤ {{ (evidence.errorLimit) }}% · P95 ≤ {{ (evidence.latencyLimit) }} ms</dd><dt>回退与恢复</dt><dd class="review-text">{{ (evidence.rollbackPlan) }}</dd><dt>修订人 / 时间</dt><dd>{{ (evidence.by) }} · {{ (formatDate(evidence.at)) }}</dd></dl><template data-component="Alert" data-if="(evidence.number !== v.number)" type="info" show-icon="" title="正在查看历史快照,不能用于当前发布授权"></template></template></template><ol data-else="" class="release-events"><li data-each="event in ([...r.events].reverse())" data-bind-key="(event.id)"><strong>{{ (event.action) }} · 修订 v{{ (event.version) }}</strong><p>{{ (event.detail) }}</p><small>{{ (event.actor) }} · {{ (formatDate(event.at)) }}</small><code>{{ (event.id) }}</code></li></ol></template></section><aside class="release-aside"><section class="agent-panel"><h2>{{ (execution ? '执行操作' : '当前待办') }}</h2><p>{{ (releaseSummary(r)) }}</p><div class="release-action-stack"><div data-each="a in (actions)" data-bind-key="(a)"><template data-component="Button" data-bind-type="(a === actions[0] ? 'primary' : 'default')" data-bind-disabled="(!!store.reason(row, a))" data-on-click="(action = a)">{{ (label(a)) }}</template><small data-if="(store.reason(row, a))">{{ (store.reason(row, a)) }}</small></div><template data-component="Button" data-if="(!execution &amp;&amp; !r.startedAt)" data-bind-disabled="(!!store.reason(row, 'edit'))" data-on-click="(editing = true)">修改发布单</template><small data-if="(!execution &amp;&amp; !r.startedAt &amp;&amp; store.reason(row, 'edit'))">{{ (store.reason(row, 'edit')) }}</small><template data-if="(showRecovery)"><template data-component="Button" danger="" data-bind-disabled="(!!store.reason(row, 'rollback'))" data-on-click="(action = 'rollback')">回滚至稳定版本</template><small data-if="(store.reason(row, 'rollback'))">{{ (store.reason(row, 'rollback')) }}</small><template data-component="Button" danger="" data-bind-disabled="(!!store.reason(row, 'stop'))" data-on-click="(action = 'stop')">停止并撤流</template></template></div><p data-if="(!actions.length)" class="muted">{{ (r.state === 'succeeded' ? '发布已完成,可查看结果和恢复记录。' : '当前没有待提交动作,可查看历史或返回列表。') }}</p></section><section class="agent-panel"><h2>本次授权</h2><template data-if="(r.approval)"><template data-component="Tag" color="green">已授权修订 v{{ (r.approval.version) }}</template><p>{{ (r.approval.actor) }} · {{ (formatDate(r.approval.at)) }}</p><p class="review-text">{{ (r.approval.note) }}</p></template><p data-else="" class="muted">本修订版尚无有效人工授权。</p><p>目标:{{ (environmentLabel(v.environment)) }}<br>首次流量:{{ (v.traffic) }}%</p></section><section class="agent-panel"><h2>来源与记录</h2><template data-component="RouterLink" data-bind-to="('/tasks/' + row.task.id)">{{ (row.task.code) }} →</template><p><template data-component="RouterLink" data-if="(store.session.can('pbc:view', row.task.tenantId, r.pbcId))" data-bind-to="('/pbcs/' + r.pbcId + '/workspace')">{{ (row.project) }} →</template><span data-else="">{{ (row.project) }}</span></p><template data-component="Button" type="link" data-on-click="(router.push('/reviews?task=' + row.task.id))">查看质量确认</template><template data-component="RecordMetadata" data-bind-record="(r)"></template><p class="muted">记录版本 v{{ (r.recordVersion) }} · 逻辑删除:否</p></section><section data-if="(execution)" class="agent-panel release-demo"><h2>原型演示</h2><p class="muted">控制下一步模拟结果,不触发真实发布。</p><label for="release-event-outcome">下一步事件结果</label><template data-component="Select" id="release-event-outcome" data-model-value="(outcome)" data-bind-options="([{ value: 'pass', label: '成功' }, { value: 'fail', label: '步骤失败' }])"></template><label for="release-response">下一次提交响应</label><template data-component="Select" id="release-response" data-model-value="(store.response)" data-bind-options="([{ value: 'success', label: '正常返回' }, { value: 'failure', label: '提交失败(未执行)' }, { value: 'unknown', label: '响应不明(先查回执)' }])"></template></section></aside></div><template data-component="ReleaseEditor" data-if="(editing)" data-bind-row="(row)" data-on-close="(editing = false)" data-on-saved="editing = false;
340
+ selectedVersion = 0;
341
+ tab = 'evidence';"></template><template data-component="ReleaseActionDialog" data-if="(action)" data-bind-row="(row)" data-bind-action="(action)" data-bind-outcome="(action === 'advance' ? outcome : 'pass')" data-on-close="(action = undefined)" data-on-saved="(saved)"></template></template>
342
+
343
+ </template>
344
+ <template data-source="reference/src/releases/ReleaseEditor.html">
345
+ <!-- 来源:src/releases/ReleaseEditor.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
346
+ <template data-component="Drawer" data-bind-open="(true)" data-bind-title="(row ? '修改发布单 · 生成新修订版' : '准备发布')" data-bind-size="(760)" data-bind-mask="({ closable: false })" data-on-close="(emit('close'))"><template data-component="Alert" data-if="(restored)" class="page-alert" type="info" show-icon="" title="已恢复本账号上次未提交的输入"></template><template data-component="Alert" data-if="(stale)" class="page-alert" type="warning" show-icon="" title="当前记录已更新,输入仍保留" description="请对照当前来源和发布详情,核对后再提交。"><template data-slot="action"><template data-component="Button" data-on-click="(rebase)">已核对,采用当前版本</template></template></template><template data-component="Alert" data-if="(error)" class="page-alert" type="error" show-icon="" data-bind-title="(error)"></template><template data-component="ProForm" name="release-editor" data-bind-form="(form)" layout="vertical" data-bind-disabled="(busy)"></template><div data-if="(task)" class="release-note"><strong>{{ (task.binding.project) }} · 规格 v{{ (task.binding.spec.number) }} · 流程 v{{ (task.binding.flow.number) }}</strong><p>{{ (task.releaseMaterials ? '此任务提供独立发布材料,保存后仍需检查和人工授权。' : '此任务没有独立发布材料,可保存草稿;缺失证据会阻止提交。') }}</p><p>{{ (task.releaseMaterials?.rollback ? '已有稳定版本 ' + task.releaseMaterials.rollback.version + ';回滚不自动还原数据库。' : '首次发布暂无稳定版本可回滚;异常时停止并撤流。') }}</p></div><p class="muted">关闭会保留本账号未提交的输入。保存草稿不产生部署或流量。</p><p data-if="(!allowed)" class="muted">当前账号缺少来源 PBC 或目标环境的发布编辑权限,请在权限管理中配置。</p><template data-slot="footer"><template data-component="Space" wrap=""><template data-component="Button" data-on-click="(emit('close'))">关闭并保留输入</template><template data-component="Button" type="primary" data-bind-disabled="(!allowed || stale)" data-bind-loading="(busy)" data-on-click="(save)">保存发布草稿</template></template></template></template>
347
+
348
+ </template>
349
+ <template data-source="reference/src/releases/ReleaseExecution.html">
350
+ <!-- 来源:src/releases/ReleaseExecution.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
351
+ <template data-component="ReleaseDetail" execution=""></template>
352
+
353
+ </template>
354
+ <template data-source="reference/src/releases/ReleasesPage.html">
355
+ <!-- 来源:src/releases/ReleasesPage.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
356
+ <div class="page-heading"><div><h1>门禁与发布</h1><p>从交付产物准备发布,核对证据后人工放行,跟踪灰度与恢复结果。</p></div><template data-component="Button" type="primary" data-bind-disabled="(!store.session.can('release:edit'))" data-on-click="(creating = true)">准备发布</template></div><div class="task-metrics"><article><span>待准备 / 修订</span><strong>{{ (store.rows.filter(r =&gt; !r.release.unconfirmed &amp;&amp; ['draft', 'returned'].includes(r.release.state)).length) }}</strong></article><article><span>待人工授权</span><strong>{{ (store.rows.filter(r =&gt; !r.release.unconfirmed &amp;&amp; r.release.state === 'pending').length) }}</strong></article><article><span>执行 / 待处理</span><strong>{{ (store.rows.filter(r =&gt; r.release.unconfirmed || ['approved', 'deploying', 'canary', 'observing', 'failed', 'paused', 'rollingBack'].includes(r.release.state)).length) }}</strong></article><article><span>已结束</span><strong>{{ (store.rows.filter(r =&gt; !r.release.unconfirmed &amp;&amp; ['succeeded', 'rolledBack', 'stopped'].includes(r.release.state)).length) }}</strong></article></div><template data-component="Alert" data-if="(route.query.task)" type="info" show-icon="" class="page-alert" title="正在查看来源任务的发布单"><template data-slot="action"><template data-component="Button" data-on-click="(router.replace('/releases'))">查看全部发布</template></template></template><template data-component="Alert" data-if="(!store.session.can('release:edit'))" type="info" show-icon="" class="page-alert" title="当前账号尚未配置发布操作权限" description="既有账号的授权保持原样。管理员可在权限管理中配置发布动作及租户、PBC、目标环境范围。"></template><section class="auth-list"><div class="auth-filters"><template data-component="Input" data-model-value="(query)" aria-label="搜索发布单" placeholder="搜索发布名称、编号或任务" allow-clear=""></template><template data-component="Select" data-model-value="(state)" aria-label="发布状态筛选" data-bind-options="([{ value: 'all', label: '全部状态' }, ...Object.entries(releaseLabels).map(([value, label]) =&gt; ({ value, label }))])"></template><template data-component="Select" data-model-value="(env)" aria-label="发布环境筛选" data-bind-options="([{ value: 'all', label: '全部环境' }, ...environments])"></template><template data-component="Select" data-model-value="(project)" aria-label="发布 PBC 筛选" data-bind-options="([{ value: 'all', label: '全部可见 PBC' }, ...Array.from(new Map(store.rows.map(r =&gt; [r.task.binding.pbcId, { value: r.task.binding.pbcId, label: r.project }])).values())])"></template><template data-component="Button" data-on-click="(reset)">重置</template></div><div class="auth-tools"><template data-component="ListBatchBar" data-bind-count="(selection.selected.value.length)" data-bind-allowed="(store.session.can('release:delete'))" data-on-remove="(selectRows(selection.selected.value))" data-on-clear="(selection.clear)"></template><template data-component="Space" wrap=""><template data-component="Select" data-model-value="(sort)" aria-label="发布排序" data-bind-options="([{ value: 'newest', label: '更新时间倒序' }, { value: 'oldest', label: '更新时间正序' }])"></template><template data-component="Button" data-bind-loading="(loading)" data-on-click="(refresh)">刷新</template><template data-component="ColumnSettings" data-bind-preferences="(prefs)"></template></template></div><template data-component="Alert" data-if="(error || store.notice)" type="error" show-icon="" data-bind-title="(error || store.notice)"></template><template data-component="Alert" data-if="(store.scene === 'error')" type="error" show-icon="" title="发布列表加载失败" description="已有记录保留,重试不会创建新发布单。"><template data-slot="action"><template data-component="Button" data-on-click="(refresh)">重试</template></template></template><template data-component="ProTable" data-else="" data-bind-table="(table)" data-bind-control="(false)" data-bind-table-container="(false)" data-bind-search="(async () =&gt; { })" row-key="id" data-bind-row-selection="(selection.rowSelection.value)" data-bind-loading="(loading)" data-bind-scroll="({ x: 'max-content' })" data-bind-pagination="({ showTotal: (n) =&gt; '共 ' + n + ' 项', showSizeChanger: true, pageSizeOptions: [5, 10, 20] })"></template><div data-if="(!filtered.length &amp;&amp; store.scene === 'normal')" class="release-empty"><p>{{ (store.rows.length ? '当前筛选没有发布单,可重置筛选。' : '还没有发布单。从已完成质量检查的任务开始准备。') }}</p><template data-component="Button" data-if="(store.rows.length)" data-on-click="(reset)">重置筛选</template><template data-component="Button" data-else="" data-on-click="(addExamples)">载入发布演示样例</template><p class="muted">样例使用独立模拟材料,不补写已有任务的缺失证据。</p></div></section><p class="review-footnote">只允许删除未提交的发布草稿;授权、执行、失败和恢复记录须保留。材料检查与灰度观测为两个阶段,首次生产流量前必须人工授权。</p><template data-component="ReleaseEditor" data-if="(creating || editing)" data-bind-row="(editing)" data-bind-task-id="(String(route.query.task || ''))" data-on-close="creating = false;
357
+ editing = undefined;" data-on-saved="(saved)"></template><template data-component="ListDeleteDialog" data-if="(targets.length)" data-model-targets="(targets)" label="发布草稿" data-bind-check="(store.checkDelete)" data-bind-submit="(store.removeMany)" data-on-close="(targets = [])" data-on-deleted="targets = [];
358
+ selection.clear();"></template>
359
+
360
+ </template>
361
+ <template data-source="reference/src/reviews/ReviewDetail.html">
362
+ <!-- 来源:src/reviews/ReviewDetail.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
363
+ <template data-component="Result" data-if="(!row)" status="403" title="评审记录不存在或无权访问"><template data-slot="extra"><template data-component="Button" data-on-click="(router.push('/reviews'))">返回评审列表</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('/reviews'))">← 返回评审列表</template><div class="agent-title"><h1>{{ (row.review.title) }}</h1><template data-component="Tag" data-bind-color="(stateColors[row.status])">{{ (stateLabels[row.status]) }}</template></div><p>{{ (row.task.name) }} · {{ (row.review.code) }}</p></div><template data-component="Space" wrap=""><template data-component="Button" data-on-click="(router.push('/tasks/' + row.task.id))">交付任务</template><template data-component="Button" data-bind-disabled="(!store.session.can('pbc:view', row.task.tenantId, row.task.binding.pbcId))" data-on-click="(router.push('/pbcs/' + row.task.binding.pbcId + '/workspace'))">PBC 工作区</template></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" data-if="(row.status === 'superseded')" type="warning" show-icon="" title="此记录依据的版本已经更新" description="历史证据保留,继续处理请进入当前评审。" class="page-alert"><template data-slot="action"><template data-component="Button" data-if="(current)" data-on-click="(router.push(reviewUrl(row.task.id, current.id)))">打开当前评审</template></template></template><template data-component="Alert" data-if="(row.status === 'automatic')" type="success" show-icon="" title="当前质量点按已登记策略由机器检查通过" description="没有增加额外人工批准。生产发布仍需人工授权,当前尚未发布。" class="page-alert"></template><div class="review-detail-grid"><section class="agent-panel"><template data-component="Tabs" data-model-active-key="(tab)" data-bind-items="([{ key: 'evidence', label: '检查与版本证据' }, { key: 'history', label: '处理记录' }, { key: 'metadata', label: '基础信息' }])"></template><template data-component="ReviewEvidence" data-if="(tab === 'evidence')" data-bind-row="(row)"></template><template data-else-if="(tab === 'history')"><h2>本次处理结果</h2><template data-if="(row.review.decision)"><template data-component="Tag" data-bind-color="(stateColors[row.status])">{{ (stateLabels[row.status]) }}</template><p>{{ (row.review.decision.actor) }} · {{ (formatDate(row.review.decision.at)) }}</p><p class="review-text">{{ (row.review.decision.note) }}</p><p data-if="(row.review.decision.impact)" class="review-text">影响说明:{{ (row.review.decision.impact) }}</p><template data-component="Button" data-if="(row.review.decision.nextReviewId)" type="primary" data-on-click="(router.push(reviewUrl(row.task.id, row.review.decision.nextReviewId)))">查看新设计 v{{ (row.review.decision.newVersion) }}</template></template><p data-else="" class="muted">本记录尚无人工作出处理;不会用 Agent 的文字代替人工批准。</p><h3>同一任务的评审历史</h3><ol class="review-history"><li data-each="r in (store.rows.filter(r =&gt; r.task.id === row.task.id))" data-bind-key="(r.id)"><template data-component="Button" type="link" data-on-click="router.push(reviewUrl(r.task.id, r.review.id));
364
+ tab = 'history';">{{ (r.review.code) }} · {{ (r.review.title) }}</template><template data-component="Tag" data-bind-color="(stateColors[r.status])">{{ (stateLabels[r.status]) }}</template><small>{{ (formatDate(r.review.updatedAt)) }} · {{ (r.review.decision?.actor || r.review.verifier) }}</small></li></ol><p class="muted">审批和验证历史只读保留,不适用删除。</p></template><template data-else=""><template data-component="RecordMetadata" data-bind-record="(row.review)"></template><p>所属 PBC:{{ (row.project) }} · {{ (tenantLabel(row.task.tenantId)) }}</p><p>实际处理人:{{ (row.review.decision?.actor || '尚未处理') }} · {{ (formatDate(row.review.decision?.at || '')) }}</p></template></section><aside class="review-aside"><section data-if="(!closed)" class="agent-panel quality-review-actions"><h2>处理当前评审</h2><div data-each="a in ['confirm', 'edit', 'replan']" data-bind-key="(a)"><template data-component="Tooltip" data-bind-title="(store.reason(row, a))"><span><template data-component="Button" block="" data-bind-type="(a === 'confirm' ? 'primary' : 'default')" data-bind-disabled="(!!store.reason(row, a))" data-on-click="(process(a))">{{ (names[a]) }}</template></span></template><small data-if="(store.reason(row, a))" class="muted">{{ (store.reason(row, a)) }}</small></div><p class="review-footnote">处理只作用于本记录的版本。质量确认完成后,仍须进入后续发布授权。</p></section><section class="agent-panel"><h2>本次评审依据</h2><dl class="task-trace"><dt>PBC</dt><dd>{{ (row.project) }}</dd><dt>交付任务</dt><dd>{{ (row.task.code) }}</dd><dt>来源规格</dt><dd>{{ (row.task.binding.spec.source.code) }} · 规格 v{{ (row.task.binding.spec.number) }}<br>{{ (row.task.binding.spec.confirmedBy) }} · {{ (formatDate(row.task.binding.spec.confirmedAt || '')) }}</dd><dt>流程版本</dt><dd>{{ (row.task.binding.flow.body.name) }} · v{{ (row.task.binding.flow.number) }}</dd><dt>独立验证者</dt><dd>{{ (row.review.verifier) }}</dd><dt>验证时间</dt><dd>{{ (formatDate(row.review.verificationAt || '')) }}</dd><dt>分级与适用确认点</dt><dd><template data-component="Tag">{{ (row.review.grade ? row.review.grade + ' 档(已登记样例)' : '任务未登记分级') }}</template><p>{{ (row.review.policyReason) }}</p></dd><dt>处理轮次</dt><dd>第 {{ (row.review.iteration + 1) }} 轮 · 当前已处理 {{ (row.task.reworks) }} / {{ (reviewBudget(row.task)) }} 次(原型上限)</dd></dl><template data-component="Button" data-bind-disabled="(!store.session.can('spec:view', row.task.tenantId))" data-on-click="(router.push('/intents/' + row.task.binding.intentId + '/spec'))">查看当前需求规格</template><p class="muted">当前规格可能有新版本;本记录始终引用上述绑定版本。</p></section><section data-if="(row.review.kind === 'design' &amp;&amp; ['checking', 'blocked'].includes(row.status))" class="agent-panel review-demo"><h2>模拟设计复核</h2><p>仅用于演示针对新设计版本的检查响应。</p><template data-component="Select" data-model-value="(outcome)" aria-label="设计复核演示结果" data-bind-options="([{ value: 'pass', label: '本次复核通过' }, { value: 'fail', label: '本次复核未通过' }])"></template><template data-component="Button" data-bind-disabled="(!store.session.can('task:operate', row.task.tenantId, row.task.binding.pbcId))" data-on-click="(validate)">接收一次模拟复核结果</template></section></aside></div></template>
365
+
366
+ </template>
367
+ <template data-source="reference/src/reviews/ReviewEvidence.html">
368
+ <!-- 来源:src/reviews/ReviewEvidence.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
369
+ <section class="review-section"><div class="section-heading"><div><h2>检查结果</h2><p>查看汇总与独立验证;未提供的分项证据明确列出。</p></div><template data-component="Tag">绑定当前评审版本</template></div><div class="review-checks"><details data-each="c in (row.review.checks)" data-bind-key="(c.id)" data-bind-open="(c.status === 'fail')"><summary><template data-component="Tag" data-bind-color="(c.status === 'pass' ? 'green' : c.status === 'fail' ? 'red' : c.status === 'pending' ? 'blue' : 'default')">{{ ({ pass: '通过(模拟)', fail: '未通过', pending: '待验证', unavailable: '未提供' }[c.status]) }}</template><strong>{{ (c.name) }}</strong><span data-if="(c.required)" class="muted">本次必需</span></summary><pre>{{ (c.detail) }}</pre></details></div></section><section class="review-section"><div class="section-heading"><div><h2>评审发现</h2><p>每项问题保留检查项编号、严重度、位置和依据。</p></div><template data-component="Select" data-model-value="(dimension)" aria-label="评审发现维度" data-bind-options="([{ value: 'all', label: '全部维度' }, ...dimensions.map(d =&gt; ({ value: d.id, label: d.id + ' · ' + d.label }))])"></template></div><div class="review-dimensions"><button data-each="d in (dimensions)" data-bind-key="(d.id)" data-bind-aria-pressed="(dimension === d.id)" data-on-click="(dimension = dimension === d.id ? 'all' : d.id)"><strong>{{ (d.id) }} <span>{{ (d.label) }}</span></strong><small>{{ (row.review.findings.filter(f =&gt; f.dimension === d.id).length) }} 项登记发现</small></button></div><template data-component="Alert" class="page-alert" type="info" show-icon="" title="维度计数仅表示报告中登记的问题" description="未登记问题不等于该维度已经完成检查。ARC 包含数据结构、迁移安全、租户与审计字段及索引;本地样例没有真实数据库验证。"></template><article data-each="f in (findings)" data-bind-key="(f.id)" class="review-finding"><div><template data-component="Tag" color="red">{{ (f.severity === 'high' ? '严重' : f.severity === 'medium' ? '重要' : '建议') }}</template><span class="mono">{{ (f.id) }}</span><h3>{{ (f.title) }}</h3></div><pre>{{ (f.detail) }}</pre><template data-component="Button" type="link" data-on-click="(router.push('/tasks/' + row.task.id + '/artifacts/' + f.artifactId + '?version=' + f.version))">查看依据:{{ (row.task.artifacts.find(a =&gt; a.id === f.artifactId)?.name) }} v{{ (f.version) }}</template></article><p data-if="(!findings.length)" class="muted">{{ (dimension === 'all' ? '本报告没有登记具体发现,请同时核对上方必需检查。' : '该维度没有登记发现。') }}</p></section><section class="review-section"><div class="section-heading"><div><h2>依据产物与版本差异</h2><p>所有引用指向本次评审的固定版本。</p></div><template data-component="Select" data-model-value="(selected)" aria-label="选择评审依据产物" data-bind-options="(row.review.refs.map(r =&gt; ({ value: r.id, label: r.name + ' · v' + r.version })))" data-bind-placeholder="(refItem?.name)"></template></div><template data-component="Space" wrap="" class="review-ref-links"><template data-component="Button" data-each="r in (row.review.refs)" data-bind-key="(r.id)" size="small" data-on-click="(router.push(artifactUrl(r)))">{{ (r.name) }} v{{ (r.version) }}</template></template><template data-if="(version)"><h3>{{ (refItem?.name) }} · v{{ (version.number) }}</h3><pre class="review-document">{{ (version.content) }}</pre><details data-if="(previous)" class="review-diff"><summary>与 v{{ (previous.number) }} 对比 · 新增/移除内容</summary><pre data-each="(line,i) in (diff)" data-bind-key="(i)" class="task-diff-line" data-bind-class="(line.kind)">{{ (line.kind === 'added' ? '+ ' : '− ') }}{{ (line.text) }}</pre><p data-if="(!diff.length)">正文相同,版本与执行记录仍分别保留。</p></details></template><template data-component="Alert" data-else="" type="warning" show-icon="" title="该版本内容已不可访问,请核对来源,不可据此确认。"></template></section>
370
+
371
+ </template>
372
+ <template data-source="reference/src/reviews/ReviewProcess.html">
373
+ <!-- 来源:src/reviews/ReviewProcess.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
374
+ <template data-component="Result" data-if="(!row)" status="403" title="评审记录不存在或无权访问"><template data-slot="extra"><template data-component="Button" data-on-click="(router.push('/reviews'))">返回评审列表</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(reviewUrl(row.task.id, row.review.id)))">← 返回评审证据</template><h1>{{ (result ? '处理结果' : names[action]) }}</h1><p>{{ (row.task.name) }} · {{ (row.review.code) }}</p></div><template data-component="Tag">本地交互原型</template></div><section data-if="(result)" class="agent-panel review-result"><template data-component="Result" status="success" data-bind-title="({ confirm: '本版本评审已确认', edit: '修改已保存,等待重新验证', replan: '规划意见已保存,等待重新验证' }[result.action])" data-bind-sub-title="(result.action === 'confirm' ? (row.review.kind === 'quality' ? '质量确认已记录。生产发布尚未授权,也尚未执行。' : '确认已写入原任务,可以继续后续实现与检查。') : '新设计尚未获得批准。复核与人工确认后,才继续生成代码和新的测试、验证证据。')"></template><dl class="task-trace"><dt>处理人 / 时间</dt><dd>{{ (result.actor) }} · {{ (formatDate(result.at)) }}</dd><dt>本次说明</dt><dd class="review-text">{{ (result.note) }}</dd><template data-if="(result.impact)"><dt>影响说明</dt><dd class="review-text">{{ (result.impact) }}</dd></template><dt>提交编号</dt><dd class="mono">{{ (result.requestId) }}</dd><dt>版本依据</dt><dd>{{ (row.review.refs.map(r =&gt; r.name + ' v' + r.version).join(' · ')) }}</dd></dl><template data-component="Space" wrap=""><template data-component="Button" data-if="(result.nextReviewId)" type="primary" data-on-click="(router.push(reviewUrl(row.task.id, result.nextReviewId)))">查看新设计 v{{ (result.newVersion) }} 的评审</template><template data-component="Button" data-bind-type="(result.nextReviewId ? 'default' : 'primary')" data-on-click="(router.push('/tasks/' + row.task.id))">返回交付任务</template><template data-component="Button" data-on-click="(router.push('/workbench'))">回到工作台</template><template data-component="Button" data-on-click="(router.push(reviewUrl(row.task.id, row.review.id) + '?tab=history'))">查看处理记录</template></template></section><div data-else="" class="review-process-grid"><section class="agent-panel"><template data-component="Alert" data-if="(unknown)" class="page-alert" type="warning" show-icon="" title="提交结果待核实" description="提交响应未能确认。请先查询同一提交编号的结果,避免重复处理。输入和编号已保留。"><template data-slot="action"><template data-component="Button" data-on-click="(verify)">核实本次提交</template></template></template><template data-component="Alert" data-if="(draftNotice)" class="page-alert" type="info" show-icon="" data-bind-title="(draftNotice)"></template><div data-if="(error)" id="review-errors" role="alert" tabindex="-1" class="review-error"><strong>未完成提交</strong><p>{{ (error) }}</p></div><template data-component="Alert" data-if="(reason &amp;&amp; !unknown)" type="warning" show-icon="" data-bind-title="(reason)" class="page-alert"></template><template data-component="Alert" data-if="(row.task.recordVersion !== expected &amp;&amp; !unknown)" type="warning" show-icon="" title="任务记录已有更新" description="已保留输入;请先核对最新证据,旧记录版本不能直接提交。" class="page-alert"><template data-slot="action"><template data-component="Button" data-bind-disabled="(!!reason)" data-on-click="(recheck)">载入当前记录并重新核对</template></template></template><form data-on-submit.prevent="(submit)"><div data-if="(action === 'edit')" class="review-field"><label for="review-content">修改后的设计内容 <span>*</span></label><p id="review-content-help" class="muted">只生成新的设计版本;原设计、代码、报告与验证证据均保留。</p><template data-component="Input.TextArea" id="review-content" data-model-value="(content)" aria-describedby="review-content-help" data-bind-rows="(14)" data-bind-maxlength="(20000)" show-count="" data-bind-disabled="(unknown)"></template></div><div data-if="(action === 'replan')" class="review-field"><label for="review-impact">调整范围与影响 <span>*</span></label><p class="muted">说明要调整的步骤、影响的产物和需要再次验证的内容。原任务绑定的需求规格与流程版本保持可追溯。</p><template data-component="Input.TextArea" id="review-impact" data-model-value="(impact)" data-bind-rows="(5)" data-bind-maxlength="(2000)" show-count="" data-bind-disabled="(unknown)" placeholder="例如:补充重复确认的幂等设计,重新实现派单逻辑并覆盖并发重试测试。"></template></div><div class="review-field"><label for="review-note">{{ (action === 'confirm' ? '确认说明' : action === 'edit' ? '本次修改原因' : '重新规划意见') }} <span>*</span></label><template data-component="Input.TextArea" id="review-note" data-model-value="(note)" data-bind-rows="(4)" data-bind-maxlength="(1000)" show-count="" data-bind-disabled="(unknown)" placeholder="请说明判断依据、处理原因或仍需关注的事项。"></template></div><div data-if="(action === 'confirm')" class="review-field"><template data-component="Checkbox" id="review-checked" data-model-checked="(checked)" data-bind-disabled="(unknown)">我已核对本记录引用的版本、检查结论及适用确认点。</template></div><p class="review-footnote">{{ (action === 'confirm' ? '确认只对本次引用的版本有效;不代替后续生产发布授权。' : '提交后形成新的设计与评审记录,重新验证及确认后才继续实现。') }} 输入暂存在此身份使用的本浏览器。</p><div class="review-submit"><template data-component="Button" data-on-click="(router.push(reviewUrl(row.task.id, row.review.id)))">返回并保留输入</template><template data-component="Button" type="primary" html-type="submit" data-bind-loading="(busy)" data-bind-disabled="(!!reason || unknown || row.task.recordVersion !== expected)">{{ (action === 'confirm' ? '提交确认' : action === 'edit' ? '保存为新设计版本' : '提交规划意见并生成设计建议') }}</template></div></form></section><aside class="agent-panel review-aside"><h2>本次处理对象</h2><p>{{ (row.review.title) }}</p><p>{{ (row.project) }}</p><dl class="task-trace"><dt>绑定需求与流程</dt><dd>{{ (row.task.binding.spec.source.code) }} · 规格 v{{ (row.task.binding.spec.number) }}<br>{{ (row.task.binding.flow.body.name) }} · v{{ (row.task.binding.flow.number) }}</dd><dt>引用产物</dt><dd><p data-each="r in (row.review.refs)" data-bind-key="(r.id)">{{ (r.name) }} · v{{ (r.version) }}</p></dd><dt>处理对象的记录版本</dt><dd>v{{ (expected) }}</dd><dt>提交编号</dt><dd class="mono">{{ (requestId) }}</dd></dl><template data-component="Button" data-on-click="(router.push(reviewUrl(row.task.id, row.review.id)))">重新阅读版本证据</template><p class="muted">返回证据再进入此页,输入会保留。</p></aside></div></template>
375
+
376
+ </template>
377
+ <template data-source="reference/src/reviews/ReviewsPage.html">
378
+ <!-- 来源:src/reviews/ReviewsPage.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
379
+ <div class="page-heading"><div><h1>质量与评审</h1><p>核对问题和版本证据,处理当前交付中的确认事项。</p></div><template data-component="Button" data-on-click="(router.push('/tasks'))">查看交付任务</template></div><div class="task-metrics review-metrics"><article><span>待人工确认</span><strong>{{ (store.rows.filter(r =&gt; r.status === 'pending').length) }}</strong></article><article><span>问题待处理</span><strong>{{ (store.rows.filter(r =&gt; r.status === 'blocked').length) }}</strong></article><article><span>等待复核或恢复</span><strong>{{ (store.rows.filter(r =&gt; ['checking', 'suspended'].includes(r.status)).length) }}</strong></article><article><span>已确认或机器通过</span><strong>{{ (store.rows.filter(r =&gt; ['approved', 'automatic'].includes(r.status)).length) }}</strong></article></div><template data-component="Alert" data-if="(route.query.task)" class="page-alert" type="info" show-icon="" title="正在查看指定任务的全部评审"><template data-slot="action"><template data-component="Button" data-on-click="(router.replace('/reviews'))">查看所有任务</template></template></template><section class="auth-list review-list-panel"><template data-component="Tabs" data-model-active-key="(scope)" data-bind-items="([{ key: 'pending', label: '待处理 (' + pending.length + ')' }, { key: 'done', label: '历史与已处理 (' + (store.rows.length - pending.length) + ')' }, { key: 'all', label: '全部记录' }])"></template><div class="auth-filters review-filters"><template data-component="Input" data-model-value="(query)" placeholder="搜索任务、编号或问题" aria-label="搜索评审事项" allow-clear=""></template><template data-component="Select" data-model-value="(project)" aria-label="评审 PBC 筛选" data-bind-options="([{ value: 'all', label: '全部可见 PBC' }, ...Array.from(new Map(store.rows.map(r =&gt; [r.task.binding.pbcId, { value: r.task.binding.pbcId, label: r.project }])).values())])"></template><template data-component="Select" data-model-value="(kind)" aria-label="评审类型筛选" data-bind-options="([{ value: 'all', label: '全部评审类型' }, ...Object.entries(kindLabels).map(([value, label]) =&gt; ({ value, label }))])"></template><template data-component="Select" data-model-value="(severity)" aria-label="问题严重度筛选" data-bind-options="([{ value: 'all', label: '全部严重度' }, { value: 'high', label: '严重问题' }, { value: 'medium', label: '重要问题' }, { value: 'suggestion', label: '建议' }, { value: 'none', label: '无登记问题' }])"></template><template data-component="Select" data-model-value="(resultState)" aria-label="评审状态筛选" data-bind-options="([{ value: 'all', label: '全部评审状态' }, ...Object.entries(stateLabels).map(([value, label]) =&gt; ({ value, label }))])"></template><template data-component="Button" data-on-click="(reset)">重置</template></div><div class="auth-tools"><template data-component="Space" wrap=""><span>已选择 {{ (selection.selected.value.length) }} 项</span><template data-component="Button" size="small" data-bind-disabled="(!selection.selected.value.length)" data-on-click="(selection.clear)">清空</template><template data-component="Tooltip" title="评审与批准记录属于审计证据,不能删除。"><span><template data-component="Button" size="small" disabled="">批量删除</template></span></template></template><template data-component="Space" wrap=""><template data-component="Select" data-model-value="(sort)" aria-label="评审排序" data-bind-options="([{ value: 'newest', label: '更新时间倒序' }, { value: 'oldest', label: '更新时间正序' }])"></template><template data-component="Button" data-bind-loading="(loading)" data-on-click="(refresh)">刷新</template><template data-component="ColumnSettings" data-bind-preferences="(prefs)"></template></template></div><template data-component="Alert" data-if="(store.notice)" type="warning" show-icon="" data-bind-title="(store.notice)"></template><template data-component="Alert" data-if="(store.scene === 'error')" type="error" show-icon="" title="评审列表加载失败" description="已有记录保留,重试不会生成新评审。"><template data-slot="action"><template data-component="Button" data-on-click="(refresh)">重试</template></template></template><template data-component="ProTable" data-else="" data-bind-table="(table)" data-bind-control="(false)" data-bind-table-container="(false)" data-bind-search="(async () =&gt; { })" row-key="id" data-bind-loading="(loading)" data-bind-row-selection="(selection.rowSelection.value)" data-bind-scroll="({ x: 'max-content' })" data-bind-pagination="({ showTotal: (n) =&gt; '共 ' + n + ' 项', showSizeChanger: true, pageSizeOptions: [5, 10, 20] })"></template><template data-component="Empty" data-if="(!filtered.length &amp;&amp; store.scene !== 'error')" data-bind-description="(store.rows.length ? '当前筛选范围暂无评审事项' : '当前授权范围暂无评审记录')"><template data-component="Button" data-if="(store.rows.length)" data-on-click="reset();
380
+ scope = 'all';">查看全部记录</template></template><p class="review-footnote">评审由交付流程生成,审批记录和证据保留,不适用手工新增或删除。修改与重新规划形成新版本,生产发布另行授权。</p></section>
381
+
382
+ </template>
383
+ <template data-source="reference/src/shared/ColumnSettings.html">
384
+ <!-- 来源:src/shared/ColumnSettings.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
385
+ <template data-component="Button" aria-label="列设置" data-on-click="(open = true)"><template data-component="SettingOutlined"></template>列设置</template><template data-component="Drawer" data-bind-open="(open)" title="列设置" data-bind-size="(400)" data-on-close="(open = false)"><p class="muted">选择显示字段并调整顺序。设置按当前用户、范围和页面分别保存。</p><div data-each="(key, index) in (preferences.order.value)" data-bind-key="(key)" class="column-choice"><template data-component="Checkbox" data-bind-checked="(preferences.visible.value.includes(key))" data-bind-disabled="(preferences.choices.find(c =&gt; c.key === key)?.locked)" data-on-change="((e) =&gt; preferences.toggle(key, e.target.checked))">{{ (preferences.choices.find(c =&gt; c.key === key)?.label) }}</template><template data-component="Space" data-bind-size="(0)"><template data-component="Button" type="text" data-bind-aria-label="('上移' + preferences.choices.find(c =&gt; c.key === key)?.label)" data-bind-disabled="(index &lt;= 1 || preferences.choices.find(c =&gt; c.key === key)?.locked)" data-on-click="(preferences.move(key, -1))"><template data-component="ArrowUpOutlined"></template></template><template data-component="Button" type="text" data-bind-aria-label="('下移' + preferences.choices.find(c =&gt; c.key === key)?.label)" data-bind-disabled="(index &gt;= preferences.order.value.length - 2 || preferences.choices.find(c =&gt; c.key === key)?.locked)" data-on-click="(preferences.move(key, 1))"><template data-component="ArrowDownOutlined"></template></template></template></div><template data-component="Alert" data-if="(preferences.error.value)" type="warning" data-bind-title="(preferences.error.value)"></template><template data-slot="footer"><div class="drawer-footer"><template data-component="Button" data-on-click="(preferences.reset)">恢复默认</template><template data-component="Button" type="primary" data-on-click="(open = false)">完成</template></div></template></template>
386
+
387
+ </template>
388
+ <template data-source="reference/src/shared/ListBatchBar.html">
389
+ <!-- 来源:src/shared/ListBatchBar.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
390
+ <div class="list-batch-bar"><template data-component="Tooltip" data-bind-title="(!allowed ? '当前身份没有删除权限' : !count ? '请先勾选记录' : '')"><span><template data-component="Button" danger="" aria-label="批量删除" data-bind-disabled="(!allowed || !count)" data-on-click="($emit('remove'))"><template data-component="DeleteOutlined"></template>批量删除</template></span></template><span class="selection-count" role="status">已选 <strong>{{ (count) }}</strong> 项</span><template data-component="Button" data-if="(count)" type="text" class="link-button" data-on-click="($emit('clear'))">清空选择</template><span class="muted selection-hint">仅选择当前页</span><span class="mobile-table-hint muted">左右滑动表格,查看全部字段与操作</span></div>
391
+
392
+ </template>
393
+ <template data-source="reference/src/shared/ListDeleteDialog.html">
394
+ <!-- 来源:src/shared/ListDeleteDialog.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
395
+ <template data-component="Modal" data-bind-open="(true)" data-bind-title="('删除' + label + '确认')" data-bind-width="(640)" data-bind-mask-closable="(false)" data-on-cancel="(!busy &amp;&amp; emit('close'))"><template data-component="Alert" show-icon="" data-bind-type="(blocked.length ? 'warning' : 'info')" data-bind-title="('已选 ' + targets.length + ' 项,可删除 ' + (targets.length - blocked.length) + ' 项,不可删除 ' + blocked.length + ' 项')" description="删除后从管理列表移除,保留记录与操作痕迹。请核对对象,本次提交将整批成功或整批不变。"></template><ul class="delete-preview" aria-label="删除对象"><li data-each="item in (checked)" data-bind-key="(item.target.id)"><div><strong>{{ (item.target.name) }}</strong><template data-component="Tag" data-bind-color="(item.reason ? 'orange' : 'green')">{{ (item.reason ? '不可删除' : '可删除') }}</template></div><p data-if="(item.reason)">{{ (item.reason) }}</p></li></ul><template data-component="Alert" data-if="(error)" type="error" show-icon="" data-bind-title="(error)" description="本次未删除任何记录。选择已保留;版本冲突时请关闭后重新核对。"></template><template data-slot="footer"><div class="delete-footer"><template data-component="Button" data-if="(blocked.length)" data-bind-disabled="(blocked.length === targets.length)" data-on-click="(keepEligible)">移除不可删除项</template><span class="footer-spacer"></span><template data-component="Button" data-bind-disabled="(busy)" data-on-click="(emit('close'))">取消</template><template data-component="Button" danger="" type="primary" data-bind-loading="(busy)" data-bind-disabled="(!!blocked.length || !targets.length)" data-on-click="(remove)">确认删除 {{ (targets.length) }} 项</template></div></template></template>
396
+
397
+ </template>
398
+ <template data-source="reference/src/shared/ListMore.html">
399
+ <!-- 来源:src/shared/ListMore.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
400
+ <template data-component="Dropdown" data-bind-menu="({ items, onClick: ({ key }) =&gt; emit('action', key) })" data-bind-trigger="(['click'])"><template data-component="Button" type="text" class="link-button" data-bind-aria-label="(name + '更多操作')">更多<template data-component="DownOutlined"></template></template></template>
401
+
402
+ </template>
403
+ <template data-source="reference/src/shared/RecordMetadata.html">
404
+ <!-- 来源:src/shared/RecordMetadata.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
405
+ <section data-bind-class="(compact ? 'metadata-compact' : 'drawer-section')"><h2>基础信息</h2><template data-component="Descriptions" data-bind-items="(items)" data-bind-column="(compact ? 1 : { xs: 1, sm: 2, md: 2, lg: 2, xl: 2, xxl: 2 })" bordered="" size="small"></template><p class="muted metadata-note">创建与修改信息由系统记录,列设置只影响列表展示。</p></section>
406
+
407
+ </template>
408
+ <template data-source="reference/src/shell/ConfirmationDialog.html">
409
+ <!-- 来源:src/shell/ConfirmationDialog.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
410
+ <template data-component="Modal" data-bind-open="(!!confirmation)" data-bind-title="(confirmation?.title)" data-bind-width="(480)" data-bind-mask="({ closable: false })" data-bind-closable="(false)" data-on-cancel="(cancel)"><p>{{ (confirmation?.content) }}</p><template data-slot="footer"><template data-component="Space"><template data-component="Button" data-bind-disabled="(busy)" data-on-click="(cancel)">{{ (confirmation?.cancelText) }}</template><template data-component="Button" type="primary" data-bind-danger="(confirmation?.okButtonProps?.danger)" data-bind-loading="(busy)" data-on-click="(accept)">{{ (confirmation?.okText) }}</template></template></template></template>
411
+
412
+ </template>
413
+ <template data-source="reference/src/shell/ConsoleShell.html">
414
+ <!-- 来源:src/shell/ConsoleShell.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
415
+ <div class="console-shell" data-bind-class="({ collapsed, 'mobile-open': mobileOpen })" data-on-keydown.esc="(closeNav)"><a class="skip-link" href="#main-content" data-on-click.prevent="(focusMain)">跳到页面内容</a><button data-if="(mobileOpen)" class="nav-scrim" aria-label="关闭导航" data-on-click="(mobileOpen = false)"></button><aside class="sidebar" aria-label="平台导航" data-bind-inert="(navHidden)" data-bind-aria-hidden="(navHidden)"><template data-component="RouterLink" to="/workbench" class="brand" data-on-click="(mobileOpen = false)"><strong>i3-Composer</strong><span>企业级 AI 软件工程平台</span></template><nav class="navigation"><template data-each="item in (visibleNavigation)" data-bind-key="(item.id)"><button data-if="(item.children)" class="nav-row" data-bind-class="({ 'nav-parent-active': item.children.some(c =&gt; c.id === current) })" data-bind-aria-expanded="(expanded[item.id])" data-on-click="(expanded[item.id] = !expanded[item.id])"><template data-component="$dynamic" data-bind-is="(item.icon)"></template><span>{{ (item.label) }}</span><template data-component="UpOutlined" data-if="(expanded[item.id])" class="nav-arrow"></template><template data-component="DownOutlined" data-else="" class="nav-arrow"></template></button><template data-component="RouterLink" data-else="" data-bind-to="(item.id === 'workbench' ? '/workbench' : item.id === 'projects' ? '/pbcs' : item.id === 'tasks' ? '/tasks' : item.id === 'operations' ? '/operations' : item.id === 'release' ? '/releases' : item.id === 'quality' ? '/reviews' : item.id === 'requirements' ? '/intents' : `/module/${item.id}`)" class="nav-row" data-bind-class="({ selected: current === item.id })" data-bind-aria-current="(current === item.id ? 'page' : undefined)" data-on-click="(mobileOpen = false)"><template data-component="$dynamic" data-bind-is="(item.icon)"></template><span>{{ (item.label) }}</span><template data-component="RightOutlined" data-if="(item.id !== 'workbench')" class="nav-arrow"></template></template><template data-if="(item.children &amp;&amp; expanded[item.id])"><template data-component="RouterLink" data-each="child in (item.children)" data-bind-key="(child.id)" data-bind-to="(child.id.startsWith('permission-') ? '/permissions/' + child.id.replace('permission-', '') : child.id === 'workflows' ? '/workflows' : child.id === 'agents' ? '/agents' : child.id === 'models' ? '/models' : `/module/${child.id}`)" class="nav-row nav-child" data-bind-class="({ selected: current === child.id })" data-bind-aria-current="(current === child.id ? 'page' : undefined)" data-on-click="(mobileOpen = false)">{{ (child.label) }}</template></template></template></nav><div class="sidebar-footer"><button class="text-button guide-button" data-on-click="(guide = true)"><template data-component="InfoCircleOutlined"></template> 原型说明</button><span>v0.14</span></div></aside><div class="workspace" data-bind-inert="(narrow &amp;&amp; mobileOpen)"><header class="topbar"><template data-component="Button" type="text" data-nav-toggle="" data-bind-aria-label="(navHidden ? '展开导航' : '收起导航')" data-bind-aria-expanded="(!navHidden)" data-on-click="(toggleMenu)"><template data-component="MenuUnfoldOutlined" data-if="(collapsed)"></template><template data-component="MenuFoldOutlined" data-else=""></template></template><div class="breadcrumb"><span data-if="(isAi)">AI 编排 <span class="crumb-slash">/</span></span><span>{{ (label) }}</span><span data-if="(subLabel)"><span class="crumb-slash">/</span>{{ (subLabel) }}</span></div><div class="topbar-right"><template data-component="Button" type="text" class="demo-settings-button" data-on-click="(guide = true)">演示设置</template><span class="demo-label">{{ (tenantLabel(session.actor.tenantId)) }} · 演示</span><template data-component="Dropdown" data-bind-menu="(roleMenu)" data-bind-trigger="(['click'])"><button class="profile-button" aria-label="切换演示身份"><template data-component="Avatar" data-bind-size="(30)">{{ (session.actor.name.slice(0, 1)) }}</template><span>{{ (session.actor.name) }} · {{ (session.actor.label) }}</span><template data-component="DownOutlined"></template></button></template></div></header><main id="main-content" tabindex="-1"><div data-show="(canView)" data-bind-inert="(!canView)" data-bind-key="(session.key)"><slot></slot></div><template data-component="Result" data-if="(!canView &amp;&amp; session.state === 'active')" status="403" title="没有业务访问权限" sub-title="已登录不代表拥有业务权限。请联系业务管理员分配相应权限;账号和登录设置由 MaxKey 管理。"><template data-slot="extra"><template data-component="Button" data-on-click="(guide = true)">查看权限演示</template></template></template></main><footer class="page-footer"><template data-component="InfoCircleOutlined"></template> 当前为演示环境,配置与测试仅用于交互评审。<button class="text-button" data-on-click="(guide = true)">评审指南</button></footer></div><template data-component="PrototypeGuide" data-bind-open="(guide)" data-on-close="(guide = false)"></template><template data-component="ConfirmationDialog"></template><template data-component="SessionDialog"></template></div>
416
+
417
+ </template>
418
+ <template data-source="reference/src/shell/PrototypeGuide.html">
419
+ <!-- 来源:src/shell/PrototypeGuide.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
420
+ <template data-component="Drawer" data-bind-open="(open)" title="原型说明与评审指南" data-bind-size="(640)" data-on-close="(emit('close'))"><template data-component="Alert" type="info" show-icon="" title="v0.14 · 运行验收与异常反馈" description="运行验收、异常调查分诊与修复跟踪已接回发布、工作台、任务和 PBC。身份、授权、观测与工程交付均为本地模拟,真实服务尚未接入。"></template><section class="drawer-section"><h2>运行验收与异常反馈 · v0.14</h2><p>运行记录 → 业务证据与人工验收 → 异常调查/分诊 → 关联或创建修复需求 → 新发布版本的回归与验收 → 关闭原异常。</p><p>在运行管理页底部载入独立模拟样例;新功能权限通过权限管理配置。旧版数据和端口保留,新版4187的数据按浏览器独立保存。</p><template data-component="Button" data-on-click="router.push('/operations');
421
+ emit('close');">打开运行管理</template></section><section class="drawer-section"><h2>发布准备与人工放行</h2><p>创建发布草稿 → 核对固定版本证据 → 人工授权 → 部署 → 首次灰度 → 观测与全量;失败时有限重试、暂停或恢复。所有执行与材料均为模拟。</p><p>历史任务保留材料缺失;独立样例提供完整模拟证据。既有用户新增发布权限需在权限管理配置,可限定目标环境。</p><template data-component="Button" data-on-click="router.push('/releases');
422
+ emit('close');">打开门禁与发布</template><h3>发布列表状态</h3><template data-component="RadioGroup" data-model-value="(releases.scene)" data-bind-options="(listOutcomes)"></template><h3>下一次发布提交结果</h3><template data-component="RadioGroup" data-model-value="(releases.response)" data-bind-options="(outcomes)"></template></section><section class="drawer-section"><h2>质量与人工确认走读</h2><ol><li>打开评审列表,按PBC和状态筛选;查看更多、显示字段与审批记录删除说明。</li><li>进入有问题的质量评审,查看固定版本,再修改设计或填写重新规划意见。</li><li>提交后进入新设计评审,接收模拟复核结果并确认;回到任务重新实现、检查、独立验证。</li><li>回到工作台查看同一任务待办更新;打开历史评审核对旧报告与处理人。</li></ol><p>既有用户的授权保持。新增“修改评审设计”和“重新规划交付”由权限管理员在独立权限菜单配置;新动作未授权时仍可查看原因。</p><template data-component="Button" type="primary" data-on-click="router.push('/reviews');
423
+ emit('close');">打开质量与评审</template><h3>评审列表状态</h3><template data-component="RadioGroup" data-model-value="(reviews.scene)" data-bind-options="(listOutcomes)"></template><h3>下一次评审提交结果</h3><template data-component="RadioGroup" data-model-value="(session.confirmResult)" data-bind-options="(outcomes)"></template></section><section class="drawer-section"><h2>工作台首版走读</h2><ol><li>切换“与我相关”和“全部授权范围”,核对待办、PBC及交付数量。</li><li>从待办进入规格或任务处理,返回首页查看状态变化。</li><li>新建PBC可查看所有可见需求的前置原因;已归属记录进入原结果。</li><li>查看只读公告与规范提醒;质量评审已接入,发布待办已接入,运行验收与异常待办已接入。</li></ol><p>个人关系按创建人、负责人和可见关联记录识别;演示林晓的两种授权配置属于同一人员,权限仍单独计算。本版使用 4187 独立预览,其他端口保留各自版本与数据。</p><h2>PBC 与项目走读</h2><ol class="review-steps"><li>从 PBC 列表编辑资料,查看基础字段、更多与批量删除预检。</li><li>进入服务管理,新增并修改服务方案,核对已建工程的保护。</li><li>打开交付工作区,从需求规格进入任务与版本产物。</li><li>新建 PBC 选择已确认规格,沿用三步创建向导及失败续接。</li></ol><p class="muted">本版以 PBC 聚合交付工作区;独立项目实体尚待确认。更名保留历史和原型兼容的资源授权引用;正式接口按稳定ID治理。</p><template data-component="Button" type="primary" data-on-click="router.push('/pbcs');
424
+ emit('close');">打开 PBC 管理</template></section><section class="drawer-section"><h2>交付任务走读</h2><ol class="review-steps"><li>发起交付,核对已确认规格、PBC、流程与资源版本。</li><li>打开任务,用阶段详情中的演示控件推进;确认原型后查看产物。</li><li>模拟失败,尝试返工、暂停与人工接管,再刷新查看保留的状态。</li></ol><p class="muted">预置确认与产物均为样例;可继续查看发布、运行验收和修复反馈。</p><template data-component="Button" data-on-click="router.push('/tasks');
425
+ emit('close');">打开交付任务</template><h3>任务列表状态</h3><template data-component="RadioGroup" data-model-value="(tasks.scene)" data-bind-options="(listOutcomes)"></template></section><section class="drawer-section"><h2>研发交付流程走读</h2><ol class="review-steps"><li>查看标准交付模板,选择节点核对 Agent 和产物。</li><li>编辑草稿并修改节点,检查流程后提交审核。</li><li>切换到有发布权限的王睿,审核配置;再核对版本差异与固定版本选择。</li></ol><p class="muted">本地原型不运行 CI、Agent 或 Dapr。预置质量评审 Agent 在本版示例中已启用并取得模型授权。独立审核为待评审交互提案。</p><template data-component="Button" type="primary" data-bind-disabled="(!session.can('workflow:view'))" data-on-click="router.push('/workflows');
426
+ emit('close');">打开流程模板</template><h3>流程列表状态</h3><template data-component="RadioGroup" data-model-value="(workflows.scene)" data-bind-options="(listOutcomes)"></template></section><section class="drawer-section"><h2>Agent 原型走读</h2><ol class="review-steps"><li>在 Agent 注册表查看四要素配置、所属项目与基础字段。</li><li>注册一个 Agent 并保存草稿,检查引用与模型使用授权;通过模型管理补齐授权后启用。</li><li>停用后编辑,再核对批量删除、引用保护及操作记录。</li></ol><template data-component="Button" type="primary" data-bind-disabled="(!session.can('agent:view'))" data-on-click="router.push('/agents');
427
+ emit('close');">打开 Agent 注册表</template><p class="muted">提示词、技能、工具与模板为示例资源,本包没有连接真实 Agent 运行时。</p><h3>Agent 列表状态</h3><template data-component="RadioGroup" data-model-value="(agents.scene)" data-bind-options="(listOutcomes)"></template></section><section class="drawer-section"><h2>权限管理走读</h2><ol class="review-steps"><li>使用陈敏进入独立的「权限管理」,新增角色并配置功能和资源范围。</li><li>在成员授权中,将角色关联给周晨;查看成员的有效权限与来源。</li><li>切换到周晨,进入原有意图/规格页面核对权限;切回陈敏撤权并查看授权记录。</li></ol><template data-component="Button" type="primary" data-bind-disabled="(!session.can('permission:view'))" data-on-click="router.push('/permissions/roles');
428
+ emit('close');">打开权限管理</template><p class="muted">以下身份切换和故障选项仅供原型评审,正式产品不包含这些控件。</p></section><section class="drawer-section"><h2>身份与权限</h2><template data-component="Select" data-model-value="(session.actorId)" aria-label="评审身份" class="full-width" data-bind-options="(actors.map(a =&gt; ({ label: a.name + ' · ' + a.label, value: a.id })))"></template><p class="muted">预置角色只是演示配置;动作与范围决定功能,角色名称不参与授权判断。</p><template data-component="Space" wrap=""><template data-component="Button" data-on-click="(session.state = 'expired')">模拟登录失效</template><template data-component="Button" data-on-click="(session.state = 'anonymous')">模拟未登录</template></template></section><section class="drawer-section"><h2>规格生成与资源</h2><template data-component="RadioGroup" data-model-value="(specs.generation)" data-bind-options="(outcomes.slice(0, 2))"></template><p><template data-component="Switch" data-model-checked="(specs.resource)" aria-label="规格生成资源可用"></template> 规格生成资源可用(模拟)</p><h3>规格确认结果</h3><template data-component="RadioGroup" data-model-value="(specs.confirmation)" data-bind-options="(outcomes)"></template></section><section class="drawer-section"><h2>下一次 PBC 关联 / 创建</h2><template data-component="RadioGroup" data-model-value="(pbcs.mode)" data-bind-options="(outcomes)"></template><p class="muted">创建失败发生在第 3 步;未知结果发生在第 1 步。核实 / 续接沿用原操作编号,已完成步骤保留。</p><h3>PBC 目录</h3><template data-component="RadioGroup" data-model-value="(pbcs.scene)" data-bind-options="(listOutcomes)"></template></section><section class="drawer-section"><h2>权限管理列表</h2><template data-component="RadioGroup" data-model-value="(authority.scene)" data-bind-options="(listOutcomes)"></template></section><section class="drawer-section"><h2>下一次保存 / 提交</h2><template data-component="RadioGroup" data-model-value="(session.nextWrite)" data-bind-options="([{ label: '成功', value: 'success' }, { label: '服务失败', value: 'failure' }, { label: '版本冲突', value: 'conflict' }])"></template><p class="muted">失败或冲突仅作用一次,便于继续重试。</p></section><section class="drawer-section"><h2>原有模型 / 意图列表状态</h2><template data-component="RadioGroup" data-model-value="(scene)" data-bind-options="(listOutcomes)"></template><h3>模型发布结果</h3><template data-component="RadioGroup" data-model-value="(session.publishResult)" data-bind-options="(outcomes.slice(0, 2))"></template><h3>意图确认结果</h3><template data-component="RadioGroup" data-model-value="(session.confirmResult)" data-bind-options="(outcomes)"></template><h3>意图整理结果</h3><template data-component="RadioGroup" data-model-value="(intents.resultMode)" data-bind-options="(outcomes.slice(0, 2))"></template></section><template data-slot="footer"><template data-component="Space"><template data-component="Button" danger="" data-on-click="(reset)">重置演示数据</template><template data-component="Button" type="primary" data-on-click="(emit('close'))">开始体验</template></template></template></template>
429
+
430
+ </template>
431
+ <template data-source="reference/src/shell/ScopePage.html">
432
+ <!-- 来源:src/shell/ScopePage.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
433
+ <div class="page-heading"><div><h1>{{ (label) }}</h1><p>Console 导航结构预览</p></div></div><section class="panel scope-panel"><template data-component="Empty" data-bind-description="(`${label}将在后续逐功能设计中展开`)"><p class="muted">当前可体验意图发起与澄清,以及模型管理。</p><template data-component="Button" type="primary" data-on-click="(router.push('/intents'))">进入意图池</template></template></section>
434
+
435
+ </template>
436
+ <template data-source="reference/src/shell/SessionDialog.html">
437
+ <!-- 来源:src/shell/SessionDialog.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
438
+ <template data-component="Modal" data-bind-open="(session.state !== 'active')" data-bind-z-index="(4000)" data-bind-title="(redirected ? 'MaxKey 统一认证 · 演示' : session.state === 'expired' ? '登录状态已失效' : '请先登录')" data-bind-closable="(false)" data-bind-keyboard="(false)" data-bind-mask="({ closable: false })"><p>{{ (redirected ? '实际应用会跳转 MaxKey 完成认证。这里仅模拟登录结果,不收集密码或生成令牌。' : '继续操作前需要通过统一认证。当前页面的未提交输入暂时保留,重新登录后可核对并继续。') }}</p><template data-component="Alert" data-if="(redirected)" type="info" data-bind-title="('模拟以 ' + session.actor.name + ' 登录')"></template><template data-slot="footer"><template data-component="Button" data-if="(!redirected)" type="primary" data-on-click="(redirected = true)">前往 MaxKey 登录</template><template data-component="Button" data-else="" type="primary" data-on-click="(session.state = 'active')">模拟登录成功并返回</template></template></template>
439
+
440
+ </template>
441
+ <template data-source="reference/src/specs/SpecDocument.html">
442
+ <!-- 来源:src/specs/SpecDocument.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
443
+ <article class="spec-document" aria-label="需求规格正文"><section data-each="section in (sections)" data-bind-id="('spec-' + section.key)" data-bind-key="(section.key)"><h2>{{ (section.label) }}</h2><p>{{ (version.content[section.key]) }}</p></section><section><h2>决策登记</h2><div data-each="d in (version.decisions)" data-bind-key="(d.id)" class="decision-row"><div class="section-heading"><strong>{{ (d.question) }}</strong><template data-component="Tag" data-bind-color="(d.answer &amp;&amp; d.reason ? 'green' : 'orange')">{{ (d.answer &amp;&amp; d.reason ? '已明确' : '待处理') }}</template></div><p>结论:{{ (d.answer || '尚未明确') }}<br>理由:{{ (d.reason || '待补充') }}</p><small class="muted">责任方:{{ (d.owner) }}<template data-if="(d.resolvedAt)"> · {{ (d.resolvedBy) }} · {{ (formatDate(d.resolvedAt)) }}</template></small></div></section></article>
444
+
445
+ </template>
446
+ <template data-source="reference/src/specs/SpecEdit.html">
447
+ <!-- 来源:src/specs/SpecEdit.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
448
+ <template data-component="Drawer" data-bind-open="(true)" data-bind-title="(mode === 'content' ? '修改需求规格' : '处理未决事项')" data-bind-size="(860)" data-bind-mask="({ closable: false })" data-on-close="(close)"><template data-component="Alert" type="info" show-icon="" data-bind-title="('保存为规格 v' + (version.number + 1) + ',需重新确认')" description="原版本及其签署记录继续保留。请分别填写每项决策理由,以及表单底部必填的“本次修改原因”;前者解释决策,后者记录本次版本变化。" 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-if="(mode === 'decisions')"><fieldset data-each="(d,index) in (decisions)" data-bind-key="(d.id)" class="spec-decision-form" data-bind-disabled="(!editable)"><legend>{{ (index + 1) }}. {{ (d.question) }}</legend><p class="muted">责任方:{{ (d.owner) }}</p><template data-component="RadioGroup" data-model-value="(d.answer)" data-bind-aria-label="(d.question)" class="vertical-options" data-bind-options="(d.options.map(value =&gt; ({ label: value, value })))"></template><label data-bind-for="('reason-' + d.id)">决策理由</label><template data-component="Input.TextArea" data-bind-id="('reason-' + d.id)" data-model-value="(d.reason)" data-bind-rows="(2)" data-bind-maxlength="(1500)" placeholder="说明依据、影响与后续处理。"></template></fieldset></template><template data-component="ProForm" data-bind-form="(form)" name="spec-revision" layout="vertical" data-bind-disabled="(!editable)"></template><template data-slot="footer"><template data-component="Alert" data-if="(error)" type="error" show-icon="" data-bind-title="(error)" class="page-alert" role="alert"><template data-slot="action"><template data-component="Button" data-if="(error.startsWith('尚未保存'))" data-on-click="(locateInvalid)">定位缺项</template></template></template><div class="drawer-footer"><span class="muted">保存后保留版本与操作人</span><template data-component="Space"><template data-component="Button" data-on-click="(close)">取消</template><template data-component="Button" type="primary" data-bind-disabled="(!editable)" data-on-click="(save)">保存新版本</template></template></div></template></template>
449
+
450
+ </template>
451
+ <template data-source="reference/src/specs/SpecHeader.html">
452
+ <!-- 来源:src/specs/SpecHeader.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
453
+ <template data-component="Button" type="link" class="intent-back" data-on-click="(router.push('/intents/' + intent.id))">← 返回来源意图</template><div class="page-heading intent-heading"><div><h1>{{ (['需求规格工作区', '规格版本评审', 'PBC 归属'][step]) }}</h1><p class="muted">{{ (intent.title) }}</p><template data-component="Space" wrap=""><template data-component="Tag">{{ (intent.code) }}</template><template data-component="Tag" data-if="(version)" data-bind-color="(version.confirmedAt ? 'green' : 'blue')">规格 v{{ (version.number) }} · {{ (version.confirmedAt ? '已确认' : '待确认') }}</template><span class="muted">来源意图 v{{ (version?.source.version || intent.versions.at(-1)?.number) }}</span></template></div><template data-component="Space" wrap=""><slot></slot></template></div><template data-component="Steps" class="delivery-steps" data-bind-current="(step)" size="small" data-on-change="(navigate)" data-bind-items="([{ title: '生成与完善规格' }, { title: '核对版本并确认', disabled: !version }, { title: '关联或创建 PBC', disabled: !version?.confirmedAt || !session.can('pbc:view', intent.tenantId) }])"></template>
454
+
455
+ </template>
456
+ <template data-source="reference/src/specs/SpecHistory.html">
457
+ <!-- 来源:src/specs/SpecHistory.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
458
+ <template data-component="Drawer" data-bind-open="(true)" title="规格版本与操作记录" data-bind-size="(860)" data-on-close="(emit('close'))"><template data-component="Alert" type="info" show-icon="" title="版本与签署记录只读保存,不适用删除或批量删除。"></template><template data-component="Tabs" data-model-active-key="(tab)" data-bind-items="([{ key: 'versions', label: '历史版本' }, { key: 'events', label: '操作记录' }])"></template><template data-if="(tab === 'versions')"><template data-component="Select" data-model-value="(selected)" aria-label="历史规格版本" class="full-width" data-bind-options="(spec.versions.map(v =&gt; ({ label: '规格 v' + v.number + ' · ' + (v.confirmedAt ? '已确认' : '未确认'), value: v.number })))"></template><template data-if="(version)"><p>{{ (version.reason) }} · {{ (version.createdBy) }} · {{ (formatDate(version.createdAt)) }}</p><p data-if="(version.confirmedAt)" class="version-confirmed">{{ (version.confirmedBy) }} · {{ (formatDate(version.confirmedAt)) }} 确认此版本</p><p data-if="(version.resource)" class="muted">生成来源:{{ (version.resource.agent) }} v{{ (version.resource.agentVersion) }} · {{ (version.resource.name) }} v{{ (version.resource.version) }}</p><template data-component="SpecDocument" data-bind-version="(version)"></template></template></template><ol data-else="" class="intent-events"><li data-each="event in ([...spec.events].reverse())" data-bind-key="(event.id)"><strong>{{ (event.action) }} · v{{ (event.version) }}</strong><p>{{ (event.result) }}</p><small>{{ (event.actor) }} · {{ (formatDate(event.at)) }}</small></li></ol></template>
459
+
460
+ </template>
461
+ <template data-source="reference/src/specs/SpecReview.html">
462
+ <!-- 来源:src/specs/SpecReview.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
463
+ <template data-component="Result" data-if="(!intent || !spec || !version || !viewed)" title="尚无可评审的规格或无权访问"><template data-slot="extra"><template data-component="Button" data-on-click="(router.push('/intents/' + id + '/spec'))">返回规格工作区</template></template></template><template data-else=""><template data-component="SpecHeader" data-bind-intent="(intent)" data-bind-version="(version)" data-bind-step="(1)"><template data-component="Button" data-on-click="(history = true)">版本与记录</template><template data-component="Button" data-on-click="(router.push('/intents/' + id + '/spec'))">返回工作区</template></template><template data-component="Alert" data-if="(error || spec.error || sourceError)" type="error" show-icon="" data-bind-title="(error || spec.error || sourceError)" class="page-alert"></template><template data-component="Alert" data-if="(spec.confirmation === 'pending')" type="info" show-icon="" title="正在提交确认,请稍候…" class="page-alert"></template><template data-component="Alert" data-if="(spec.confirmation === 'unknown')" type="warning" show-icon="" title="确认响应未收到,请核实原请求结果" data-bind-description="('请求 ' + spec.pending?.id + ';规格 v' + spec.pending?.version)" class="page-alert"><template data-slot="action"><template data-component="Button" data-on-click="(reconcile)">核实确认结果</template></template></template><template data-component="Alert" data-if="(version.confirmedAt)" type="success" show-icon="" data-bind-title="('规格 v' + version.number + ' 已确认')" data-bind-description="(version.confirmedBy + ' · ' + formatDate(version.confirmedAt) + ';确认基线只读保留,修改会形成新版本。')" class="page-alert"></template><template data-component="Alert" data-else-if="(pendingDecisions(version).length)" type="warning" show-icon="" data-bind-title="('还有 ' + pendingDecisions(version).length + ' 项决策需要结论和理由,暂不能确认。')" class="page-alert"><template data-slot="action"><template data-component="Button" data-on-click="(router.push('/intents/' + id + '/spec'))">返回处理</template></template></template><section class="panel delivery-main"><div class="review-toolbar"><div class="version-toolbar"><label for="review-after">查看版本</label><template data-component="Select" id="review-after" data-model-value="(after)" data-bind-options="(spec.versions.map(v =&gt; ({ label: '规格 v' + v.number, value: v.number })))"></template><template data-component="Button" data-bind-disabled="(spec.versions.length &lt; 2)" data-on-click="(compare = !compare)">{{ (compare ? '阅读完整规格' : '对比版本变化') }}</template><template data-if="(compare)"><label for="review-before">对比来源</label><template data-component="Select" id="review-before" data-model-value="(before)" data-bind-options="(spec.versions.filter(v =&gt; v.number !== after).map(v =&gt; ({ label: '规格 v' + v.number, value: v.number })))"></template></template></div><template data-component="Tag" data-if="(after !== version.number)">历史版本 · 只读</template></div><p class="muted">{{ (viewed.reason) }} · {{ (viewed.createdBy) }} · {{ (formatDate(viewed.createdAt)) }} · 来源意图 v{{ (viewed.source.version) }}</p><template data-if="(compare)"><div data-each="d in (diff)" data-bind-key="(d.key)" class="spec-diff"><div class="section-heading"><h2>{{ (d.label) }}</h2><template data-component="Tag" data-bind-color="(d.changed ? 'blue' : 'default')">{{ (d.changed ? '有变化' : '内容相同') }}</template></div><div class="diff-columns"><section><h3>原内容 · v{{ (before) }}</h3><p>{{ (d.before || '无内容') }}</p></section><section data-bind-class="({ 'diff-changed': d.changed })"><h3>当前查看 · v{{ (after) }}</h3><p>{{ (d.after) }}</p></section></div></div><section class="decision-row"><h2>决策变化</h2><div data-each="d in (viewed.decisions)" data-bind-key="(d.id)"><strong>{{ (d.question) }}</strong><p>原结论:{{ (previous?.decisions.find(x =&gt; x.id === d.id)?.answer || '未明确') }} → 新结论:{{ (d.answer || '未明确') }}</p><p>新理由:{{ (d.reason || '待补充') }}</p></div></section></template><template data-component="SpecDocument" data-else="" data-bind-version="(viewed)"></template></section><template data-component="Alert" data-if="(!version.confirmedAt &amp;&amp; blockReason)" type="info" show-icon="" data-bind-title="(blockReason)" class="page-alert"></template><template data-component="Alert" data-if="(version.confirmedAt &amp;&amp; !session.can('pbc:view', spec.tenantId))" type="info" show-icon="" title="规格已确认;继续归属需要当前租户的 PBC 查看及相应创建/关联权限。" class="page-alert"></template><section class="panel review-actions" aria-label="规格评审操作"><span class="muted">当前操作:规格 v{{ (version.number) }} · {{ (session.actor.name) }}</span><template data-component="Space" wrap=""><template data-component="Button" data-bind-disabled="(busy || !!sourceError || !session.can('spec:edit', spec.tenantId))" data-on-click="(edit = true)">修改规格</template><template data-component="Button" data-bind-disabled="(busy || !!sourceError || !session.can('spec:generate', spec.tenantId) || !session.can('spec:edit', spec.tenantId))" data-on-click="(replan = true)">重新规划</template><template data-component="Button" data-if="(!version.confirmedAt)" type="primary" data-bind-disabled="(blocked)" data-bind-loading="(spec.confirmation === 'pending')" data-on-click="(confirm)">确认规格 v{{ (version.number) }}</template><template data-component="Button" data-else="" type="primary" data-bind-disabled="(!!sourceError || !session.can('pbc:view', spec.tenantId))" data-on-click="(router.push('/intents/' + id + '/pbc'))">确定 PBC 归属</template></template></section><template data-component="SpecEdit" data-if="(edit)" data-bind-spec="(spec)" mode="content" data-on-close="(edit = false)"></template><template data-component="SpecHistory" data-if="(history)" data-bind-spec="(spec)" data-on-close="(history = false)"></template><template data-component="Modal" data-model-open="(replan)" title="重新规划规格" ok-text="生成新版本" cancel-text="取消" data-bind-confirm-loading="(spec.generating)" data-on-ok="(regenerate)"><p>重新读取已确认意图,保留旧版本与签署记录。</p><label for="spec-replan-reason">重新规划原因</label><template data-component="Input.TextArea" id="spec-replan-reason" data-model-value="(reason)" data-bind-rows="(4)"></template><template data-component="Alert" data-if="(error)" type="error" data-bind-title="(error)"></template></template></template>
464
+
465
+ </template>
466
+ <template data-source="reference/src/specs/SpecWorkspace.html">
467
+ <!-- 来源:src/specs/SpecWorkspace.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
468
+ <template data-component="Result" data-if="(!intent || !session.readable('spec:view', intent.tenantId))" status="403" title="规格不存在或当前没有查看权限"><template data-slot="extra"><template data-component="Button" data-on-click="(router.push('/intents'))">返回意图池</template></template></template><template data-else=""><template data-component="SpecHeader" data-bind-intent="(intent)" data-bind-version="(version)" data-bind-step="(0)"><template data-component="Button" data-if="(spec?.versions.length)" data-on-click="(history = true)">版本与记录</template><template data-component="Button" data-if="(version)" type="primary" data-on-click="(router.push('/intents/' + id + '/spec/review'))">进入规格评审</template><template data-component="TaskLaunch" data-if="(version?.confirmedAt)" data-bind-intent-id="(id)"></template></template><template data-component="Alert" data-if="(error || spec?.error || store.notice)" type="error" show-icon="" class="page-alert" data-bind-title="(error || spec?.error || store.notice)"></template><template data-component="Alert" data-if="(sourceError || stale)" type="warning" show-icon="" class="page-alert" data-bind-title="(sourceError || '来源意图已有新版本,请重新生成规格后评审。')"></template><template data-component="Alert" data-if="(spec?.confirmation === 'unknown')" type="warning" show-icon="" class="page-alert" title="确认结果待核实,修改暂不可用"><template data-slot="action"><template data-component="Button" data-on-click="(router.push('/intents/' + id + '/spec/review'))">核实原请求</template></template></template><template data-component="Alert" data-if="(generationReason)" type="info" show-icon="" class="page-alert" data-bind-title="(generationReason)"></template><template data-component="Alert" data-if="(version &amp;&amp; !session.can('spec:edit', intent.tenantId))" type="info" show-icon="" class="page-alert" title="当前可查看规格,但缺少修改权限;需由有权人员处理未决事项。"></template><div class="delivery-grid"><section class="panel delivery-main"><template data-if="(spec?.generating)"><div role="status" aria-live="polite" class="intent-generating"><h2>正在整理需求规格…</h2><p class="muted">读取已确认意图 → 整理需求与验收 → 登记待决策事项</p><template data-component="Skeleton" active="" data-bind-paragraph="({ rows: 9 })"></template></div></template><template data-else-if="(version)"><div class="section-heading"><h2>需求规格 · v{{ (version.number) }}</h2><template data-component="Button" data-bind-disabled="(!session.can('spec:edit', intent.tenantId) || busy || !!sourceError || stale)" data-on-click="(edit = 'content')">修改规格</template></div><template data-component="SpecDocument" data-bind-version="(version)"></template></template><template data-else=""><template data-component="Empty" description="从已确认的意图生成第一版规格"><template data-slot="image"><span class="empty-spec-mark">Aa</span></template><p class="muted">包含需求、验收标准、成功标准、实体和页面清单。<br>生成后先完善未决事项,再人工确认。</p><template data-component="Button" type="primary" data-bind-disabled="(!session.can('spec:generate', intent.tenantId) || !!sourceError || !store.generationResource(intent.tenantId))" data-on-click="(generate)">生成需求规格</template></template></template></section><aside class="panel delivery-aside"><h2>本次规格</h2><p>来源:意图 v{{ (version?.source.version || intent.versions.at(-1)?.number) }}</p><p class="muted">{{ (intent.code) }}</p><template data-if="(version)"><div class="summary-context"><div class="section-heading"><h2>待处理事项</h2><template data-component="Tag" data-bind-color="(pendingDecisions(version).length ? 'orange' : 'green')">{{ (pendingDecisions(version).length) }} 项</template></div><p class="muted">补充决策结论与理由,记录实际操作人。</p><template data-component="Button" block="" data-bind-disabled="(!session.can('spec:edit', intent.tenantId) || busy || !!sourceError || stale)" data-on-click="(edit = 'decisions')">处理未决事项</template></div><nav class="spec-outline" aria-label="规格目录"><a data-each="s in (sections)" data-bind-key="(s.key)" data-bind-href="('#spec-' + s.key)" data-on-click.prevent="($el.ownerDocument.getElementById('spec-' + s.key)?.scrollIntoView({ block: 'start' }))">{{ (s.label) }}</a></nav></template><div class="summary-context"><h2>生成资源</h2><p>需求规划 Agent · v1.0(模拟)<br>{{ (store.generationResource(intent.tenantId)?.name || '配置引用失效') }} · v{{ (store.generationResource(intent.tenantId)?.version || '—') }}</p><template data-component="Tag" data-bind-color="(store.generationResource(intent.tenantId) ? 'green' : 'red')">{{ (store.generationResource(intent.tenantId) ? '资源可用(模拟)' : '资源不可用') }}</template><p class="muted">正式运行需由调用入口校验模型、Agent 与数据权限。</p><template data-component="Button" data-if="(version &amp;&amp; !sourceError)" block="" data-bind-disabled="(busy || !session.can('spec:generate', intent.tenantId) || !session.can('spec:edit', intent.tenantId) || !store.generationResource(intent.tenantId))" data-on-click="(generate)">{{ (stale ? '按最新意图生成' : '重新生成规格') }}</template><template data-component="Button" data-if="(!version &amp;&amp; spec?.error)" block="" data-bind-disabled="(busy || !session.can('spec:generate', intent.tenantId) || !!sourceError || !store.generationResource(intent.tenantId))" data-on-click="(generate)">重试生成</template></div><template data-component="RecordMetadata" data-if="(spec)" data-bind-record="(spec)" compact=""></template></aside></div><template data-component="SpecEdit" data-if="(edit &amp;&amp; spec)" data-bind-spec="(spec)" data-bind-mode="(edit)" data-on-close="(edit = '')"></template><template data-component="SpecHistory" data-if="(history &amp;&amp; spec)" data-bind-spec="(spec)" data-on-close="(history = false)"></template></template>
469
+
470
+ </template>
471
+ <template data-source="reference/src/tasks/ArtifactDetail.html">
472
+ <!-- 来源:src/tasks/ArtifactDetail.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
473
+ <template data-component="Result" data-if="(!task || !artifact || !version)" status="403" title="产物不存在或无权访问"><template data-slot="extra"><template data-component="Button" data-on-click="(router.push('/tasks'))">返回交付任务</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('/tasks/' + task.id + '?tab=artifacts'))">← 返回任务产物</template><div class="agent-title"><h1>{{ (artifact.name) }}</h1><template data-component="Tag">只读快照</template><template data-component="Tag" data-bind-color="(version.result === 'fail' ? 'red' : version.result === 'pass' ? 'green' : 'blue')">{{ (version.result === 'fail' ? '示例问题' : version.result === 'pass' ? '示例通过' : '示例产物') }}</template></div><p>{{ (task.name) }} · {{ (task.code) }}</p></div><template data-component="Space" wrap=""><template data-component="Select" data-bind-value="(version.number)" aria-label="查看产物版本" style="width:210px" data-bind-options="(artifact.versions.slice().reverse().map(v =&gt; ({ value: v.number, label: 'v' + v.number + ' · 第 ' + (v.iteration + 1) + ' 轮' })))" data-on-change="(v =&gt; router.replace({ query: { ...route.query, version: String(v) } }))"></template><template data-component="Select" data-model-value="(compare)" aria-label="产物对比方式" style="width:155px" data-bind-options="([{ value: 'none', label: '阅读全文' }, { value: 'previous', label: '与上一版对比', disabled: !previous }])"></template></template></div><template data-component="Alert" class="page-alert" type="info" show-icon="" title="用于交互评审的产物样例" description="内容没有经过真实 Agent、代码仓库或 CI 生成。产物及历史版本只读保留,支持回溯,不适用删除。"></template><div class="task-artifact-layout"><section class="agent-panel task-artifact-content"><h2>{{ (compare === 'previous' &amp;&amp; previous ? '版本差异 · v' + previous.number + ' → v' + version.number : '内容 · v' + version.number) }}</h2><template data-if="(compare === 'previous' &amp;&amp; previous)"><p class="muted">按内容行展示新增与移除,用于样例版本核对。</p><pre data-each="(line,i) in (diff)" data-bind-key="(i)" class="task-diff-line" data-bind-class="(line.kind)">{{ (line.kind === 'added' ? '+ ' : '− ') }}{{ (line.text) }}</pre><p data-if="(!diff.length)">两个版本的正文内容相同,请对照生成轮次与来源。</p></template><pre data-else="" class="task-artifact-text">{{ (version.content) }}</pre></section><aside class="agent-panel"><h2>引用此版本的发布单</h2><p data-if="(!releases.length)" class="muted">暂无发布引用此版本。</p><p data-each="item in (releases)" data-bind-key="(item.r.id + item.v.number)"><template data-component="RouterLink" data-bind-to="(releaseUrl(item.r) + '?tab=versions&amp;version=' + item.v.number)">{{ (item.r.code) }} · 修订 v{{ (item.v.number) }} →</template></p><h2>引用此版本的评审</h2><p data-if="(!reviews.length)" class="muted">暂无评审引用此版本。</p><p data-each="r in (reviews)" data-bind-key="(r.id)"><template data-component="Button" type="link" data-on-click="(router.push(reviewUrl(task.id, r.id)))">{{ (r.title) }}</template></p><h2>来源与版本</h2><dl class="task-trace"><dt>交付任务</dt><dd><template data-component="Button" type="link" data-on-click="(router.push('/tasks/' + task.id))">{{ (task.code) }}</template></dd><dt>生成阶段</dt><dd>{{ (task.binding.flow.body.nodes.find(n =&gt; n.id === version.stageId)?.name || '任务启动时固定的输入') }}</dd><dt>依据规格</dt><dd>v{{ (task.binding.spec.number) }} / 意图 v{{ (task.binding.spec.source.version) }}</dd><dt>流程版本</dt><dd>{{ (task.binding.flow.body.name) }} · v{{ (task.binding.flow.number) }}</dd><dt>生成者</dt><dd>{{ (version.by) }}</dd><dt>生成时间</dt><dd>{{ (formatDate(version.at)) }}</dd><dt>本次输入版本</dt><dd><div data-each="i in (version.inputs)" data-bind-key="(i.id)"><template data-component="Button" type="link" data-on-click="router.push('/tasks/' + task.id + '/artifacts/' + i.id + '?version=' + i.version);
474
+ selected = i.version;">{{ (task.artifacts.find(a =&gt; a.id === i.id)?.name) }} v{{ (i.version) }}</template></div><span data-if="(!version.inputs.length)">已确认规格与交付配置快照</span></dd></dl></aside></div></template>
475
+
476
+ </template>
477
+ <template data-source="reference/src/tasks/TaskCreate.html">
478
+ <!-- 来源:src/tasks/TaskCreate.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
479
+ <template data-component="Result" data-if="(editId &amp;&amp; (!old || old.startedAt))" status="403" title="草稿不存在、已经启动或无权访问"><template data-slot="extra"><template data-component="Button" data-on-click="(router.push('/tasks'))">返回任务</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('/tasks'))">← 返回交付任务</template><h1>{{ (editId ? '修改交付草稿' : '发起交付') }}</h1><p>为已确认的需求组织一次研发交付,先核对输入和采用的流程。</p></div><template data-component="Tag" color="blue">{{ (editId ? '草稿可修改' : '1 核对输入 → 2 选择流程 → 3 启动任务') }}</template></div><template data-component="Alert" data-if="(source?.spec.id === 'example-spec-heating')" class="page-alert" type="info" show-icon="" title="当前为预置供热工单示例" description="规格确认与 PBC 归属已预置,供你直接体验完整路径;不代表真实需求已被确认。"></template><div class="task-create-layout"><section class="agent-panel task-form"><h2>交付输入</h2><label for="task-name">任务名称 <span class="required">*</span></label><template data-component="Input" id="task-name" data-model-value="(name)" data-bind-maxlength="(80)" placeholder="描述这次要交付的功能"></template><label>来源需求与规格 <span class="required">*</span></label><template data-component="Select" data-model-value="(intent)" aria-label="来源需求与规格" class="full-width" data-bind-disabled="(!!editId)" data-bind-options="(store.sources.map(s =&gt; ({ value: s.id, label: s.title + (s.reason ? ' · ' + s.reason : ''), disabled: !!s.reason })))"></template><p data-if="(!store.sources.length)" class="muted">尚无可见规格。请到意图与需求生成、确认规格并完成 PBC 归属。</p><div data-if="(source?.version)" class="task-source-box"><strong>{{ (source.job?.pbc.name || '尚未归属 PBC') }}</strong><p>{{ (tenantLabel(source.spec.tenantId)) }} · {{ (source.version.source.code) }} v{{ (source.version.source.version) }}</p><p>规格 v{{ (source.version.number) }} · {{ (source.version.confirmedBy || '尚未确认') }}</p><template data-component="Space" wrap=""><template data-component="Button" type="link" data-on-click="(router.push('/intents/' + intent + '/spec'))">查看需求规格</template><template data-component="Button" type="link" data-on-click="(router.push('/intents/' + intent + '/pbc'))">查看 PBC 归属</template></template></div><label>研发交付流程 <span class="required">*</span></label><template data-component="Select" data-model-value="(flow)" aria-label="研发交付流程" class="full-width" placeholder="选择同一 PBC 的已发布流程" data-bind-options="(flows.map(f =&gt; ({ value: f.id, label: f.body.name })))"></template><p data-if="(!flows.length)" class="muted">当前没有可用流程。需要同一 PBC 的已启用发布版本,以及对应的流程使用权限。</p><label>使用版本 <span class="required">*</span></label><template data-component="Select" data-model-value="(number)" aria-label="交付流程版本" class="full-width" data-bind-options="(versions)"></template><label for="task-note">交付说明</label><template data-component="Input.TextArea" id="task-note" data-model-value="(note)" data-bind-rows="(3)" data-bind-maxlength="(1000)" placeholder="本次范围、关注点或补充说明"></template></section><aside class="agent-panel task-launch-summary"><h2>本次交付将如何进行</h2><p>{{ (chosen?.versions.find(v =&gt; v.number === number)?.body.description || '选择流程后可查看阶段和绑定资源。') }}</p><ol class="task-outline"><li data-each="n in (bindingResult.value?.flow.body.nodes)" data-bind-key="(n.id)"><span>{{ (n.name) }}</span><small>{{ (n.gate === 'production' || ['publish', 'archive'].includes(n.kind) ? '后续原型范围' : n.kind === 'human' ? '等待获授权的人确认' : n.agentId ? bindingResult.value?.agents.find(a =&gt; a.config.id === n.agentId)?.config.name : '交付阶段') }}</small></li></ol><h3>固定的资源版本</h3><div data-each="a in (bindingResult.value?.agents)" data-bind-key="(a.config.id)" class="task-resource"><strong>{{ (a.config.name) }} · 记录 v{{ (a.config.recordVersion) }}</strong><small>{{ (a.model.name) }} · 发布 v{{ (a.model.version) }}</small></div><p class="muted">启动后保留绑定版本;本地原型模拟阶段推进和产物,不执行实际研发或生产发布。</p></aside></div><div class="agent-panel task-submit"><template data-component="Alert" data-if="(bindingResult.error || error)" type="error" show-icon="" data-bind-title="(error || bindingResult.error)"></template><template data-component="Checkbox" data-model-checked="(reviewed)" data-bind-disabled="(!bindingResult.value)">已核对来源规格、PBC 和交付流程版本</template><template data-component="Space" wrap=""><template data-component="Button" data-on-click="(router.push('/tasks'))">取消</template><template data-component="Button" data-bind-loading="(busy)" data-bind-disabled="(!reviewed || !session.can(editId ? 'task:edit' : 'task:create', source?.spec.tenantId, source?.job?.pbc.id))" data-on-click="(submit(false))">{{ (editId ? '保存修改' : '保存草稿') }}</template><template data-component="Button" data-if="(!editId)" type="primary" data-bind-loading="(busy)" data-bind-disabled="(!reviewed || !session.can('task:operate', source?.spec.tenantId, source?.job?.pbc.id))" data-on-click="(submit(true))">确认并启动交付</template></template></div></template>
480
+
481
+ </template>
482
+ <template data-source="reference/src/tasks/TaskDetail.html">
483
+ <!-- 来源:src/tasks/TaskDetail.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
484
+ <template data-component="Result" data-if="(!task)" status="404" title="任务不存在或无权访问"><template data-slot="extra"><template data-component="Button" data-on-click="(router.push('/tasks'))">返回交付任务</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('/tasks'))">← 返回交付任务</template><template data-component="Button" data-if="(can('pbc:view'))" type="link" data-on-click="(router.push('/pbcs/' + task.binding.pbcId + '/workspace?tab=tasks'))">PBC 交付工作区</template><div class="agent-title"><h1>{{ (task.name) }}</h1><template data-component="Tag" data-bind-color="(statusColors[task.status])">{{ (release ? taskReleaseLabel(task, session.actor) : review ? stateLabels[reviewStatus(task, review)] : statusLabels[task.status]) }}</template></div><p>{{ (task.code) }} · {{ (task.binding.project) }} · 负责人 {{ (task.owner) }}</p></div><template data-component="Space" wrap=""><template data-component="Button" data-if="(can('artifact:view'))" data-on-click="(router.push('/reviews?task=' + task.id))">评审与处理记录</template><template data-component="Button" data-if="(task.status === 'draft')" data-bind-disabled="(!can('task:edit'))" data-on-click="(router.push('/tasks/' + task.id + '/edit'))">修改草稿</template><template data-component="Button" data-if="(task.status === 'draft')" type="primary" data-bind-disabled="(!can('task:operate'))" data-on-click="(open('start'))">启动交付</template><template data-component="Button" data-if="(['running', 'waiting'].includes(task.status))" data-bind-disabled="(!can('task:operate'))" data-on-click="(open('pause'))">暂停任务</template><template data-component="Button" data-if="(['paused', 'manual'].includes(task.status))" data-bind-disabled="(!can('task:operate'))" data-on-click="(open('resume'))">恢复任务</template><template data-component="Button" data-if="(!['draft', 'manual'].includes(task.status) &amp;&amp; (task.status !== 'ready' || !!review))" data-bind-disabled="(!can('task:takeover'))" data-on-click="(open('takeover'))">人工接管</template></template></div><template data-component="Alert" data-if="(error &amp;&amp; !modal)" class="page-alert" type="error" show-icon="" data-bind-title="(error)" closable="" data-on-close="(error = '')"></template><template data-component="Alert" data-if="(task.example)" class="page-alert" type="info" show-icon="" title="预置任务样例" description="已有确认、阶段执行与产物都是演示数据,可以继续操作或新建一项交付。"></template><div class="task-status-banner" data-bind-class="('task-status-' + task.status)"><div><span class="task-eyebrow">{{ (task.status === 'draft' ? '尚未启动' : '当前阶段') }}</span><h2>{{ (node?.name || '准备交付输入') }}</h2><p>{{ (taskReason) }}</p></div><div class="task-progress-summary"><strong>{{ (taskProgress(task)) }}<small>%</small></strong><span>{{ (release ? '交付与发布阶段' : '研发阶段进度') }}</span><div class="task-progress-bar"><i data-bind-style="({ width: taskProgress(task) + '%' })"></i></div></div></div><template data-component="OperationEntry" data-bind-task="(task)"></template><template data-component="Alert" data-if="(can('artifact:view') &amp;&amp; task.status === 'ready' &amp;&amp; !review)" class="page-alert" type="info" show-icon="" data-bind-title="(release ? taskReleaseLabel(task, session.actor) : '可以准备发布')" data-bind-description="((release ? taskReason : '') || qualityReason(task) || '质量点处理结束;发布前仍需独立材料及人工授权。')"><template data-slot="action"><template data-component="Button" type="primary" data-on-click="(router.push(releasePath))">{{ (release ? '查看发布单' : '准备发布') }}</template><template data-component="Button" data-if="(hasPendingRelease(task) &amp;&amp; release &amp;&amp; !activeRelease(task))" data-on-click="(router.push('/releases?task=' + task.id + '&amp;prepare=1'))">准备生产发布</template></template></template><template data-component="Alert" data-if="(review)" class="page-alert" data-bind-type="(reviewStatus(task, review) === 'blocked' ? 'warning' : 'info')" show-icon="" data-bind-title="(review.title + ' · ' + stateLabels[reviewStatus(task, review)])" data-bind-description="(task.pendingDesignReview ? '新设计需重新验证与确认,之后才恢复实现。' : '在质量与评审中核对本次版本,处理结果直接写回此任务。')"><template data-slot="action"><template data-component="Button" type="primary" data-on-click="(router.push(reviewUrl(task.id, review.id)))">打开当前评审</template></template></template><section class="agent-panel"><template data-component="Tabs" data-model-active-key="(tab)" data-bind-items="(tabs)"></template><div data-if="(tab === 'progress')" class="task-detail-layout"><nav class="task-stage-nav" aria-label="交付阶段"><button data-each="(s,index) in (task.stages)" data-bind-key="(s.nodeId)" data-bind-class="({ active: selected === s.nodeId })" data-bind-aria-current="(selected === s.nodeId ? 'step' : undefined)" data-on-click="(selected = s.nodeId)"><span class="task-stage-dot" data-bind-class="(s.state)">{{ (s.state === 'done' ? '✓' : s.state === 'failed' ? '!' : index + 1) }}</span><span><strong>{{ (task.binding.flow.body.nodes.find(n =&gt; n.id === s.nodeId)?.name) }}</strong><small>{{ ({ pending: '待执行', active: '当前阶段', done: '已完成', failed: '执行失败', skipped: '分支未命中' }[s.state]) }}</small></span></button></nav><section class="task-stage-detail"><template data-if="(selectedNode &amp;&amp; selectedStage)"><div class="section-heading"><div><h2>{{ (selectedNode.name) }}</h2><p>{{ (kindLabel(selectedNode)) }} · {{ (selectedStage.attempts) }} 次执行</p></div><template data-component="Tag" data-if="(selected === task.currentId)" color="blue">当前阶段</template></div><p class="task-stage-message">{{ (selectedStage.detail) }}</p><dl class="task-info-grid"><div><dt>执行者</dt><dd>{{ (selectedNode.agentId ? task.binding.agents.find(a =&gt; a.config.id === selectedNode.agentId)?.config.name : selectedNode.kind === 'human' ? '获得此动作与范围授权的成员' : selectedNode.kind === 'tool' ? '项目工具(模拟)' : '交付引擎(模拟)') }}</dd></div><div><dt>输入</dt><dd>{{ (selectedNode.input || '绑定需求、规格与当前阶段上下文') }}</dd></div><div><dt>预期输出</dt><dd>{{ (selectedNode.output || (selectedNode.kind === 'human' ? '绑定版本的确认记录' : '阶段状态与事件记录')) }}</dd></div><div><dt>开始 / 完成</dt><dd>{{ (formatDate(selectedStage.startedAt || '')) }}<br>{{ (formatDate(selectedStage.finishedAt || '')) }}</dd></div></dl><div data-if="(selected === task.currentId &amp;&amp; task.status === 'waiting' &amp;&amp; !task.pendingDesignReview)" class="task-gate"><h3>核对当前交互原型与规格</h3><p>原型描述包含报修受理、分诊建议、依据和人工确认。确认只对当前任务中的规格与原型版本有效。</p><template data-component="Space" wrap=""><template data-component="Button" data-bind-disabled="(!can('artifact:view'))" data-on-click="(router.push(artifactUrl('spec')))">阅读规格快照</template><template data-component="Button" data-bind-disabled="(!can('artifact:view'))" data-on-click="(router.push(artifactUrl('prototype')))">阅读原型评审包</template><template data-component="Button" type="primary" data-bind-disabled="(!can('workflow:approve'))" data-on-click="(review ? router.push(reviewUrl(task.id, review.id)) : open('approve'))">核对并确认阶段</template></template><p data-if="(!can('workflow:approve'))" class="muted">你可以查看进度;当前未获此项目的交付人工确认权限。</p></div><div data-if="(selected === task.currentId &amp;&amp; task.status === 'failed')" class="task-gate task-failed"><h3>保留本次证据,处理后继续</h3><p>{{ (node?.kind === 'verify' ? '返工将回到实现阶段,生成新代码,再执行质量检查与独立验证。' : '重试沿用同一任务与输入,已完成的前序阶段不重复执行。') }}已处理 {{ (task.reworks) }} / {{ (retryBudget(task)) }} 次(本原型示例上限)。</p><template data-component="Space" wrap=""><template data-component="Button" type="primary" data-bind-disabled="(!can('task:operate') || task.reworks &gt;= retryBudget(task))" data-on-click="(open('retry'))">{{ (node?.kind === 'verify' ? '发起返工' : '重试阶段') }}</template><template data-component="Button" data-bind-disabled="(!can('task:takeover'))" data-on-click="(open('takeover'))">人工接管</template></template><p data-if="(task.reworks &gt;= retryBudget(task))" class="muted">处理次数已耗尽,请人工接管;接管后仍须处理问题,不能直接通过。</p></div><template data-component="Alert" data-if="(selected === task.currentId &amp;&amp; task.status === 'ready')" type="info" show-icon="" data-bind-title="(release ? taskReleaseLabel(task, session.actor) : '研发产物等待后续确认')" data-bind-description="(review ? '当前质量评审尚待处理,请从上方进入并核对版本。' : (release ? taskReason : '') || '质量点处理结束,请从发布入口准备本版材料并申请人工授权。')"></template><section data-if="(outputs.length &amp;&amp; can('artifact:view'))" class="task-stage-outputs"><h3>本阶段产物</h3><div data-each="o in (outputs.slice().reverse())" data-bind-key="(o.a.id + o.v.number)"><template data-component="Button" type="link" data-on-click="(router.push(artifactUrl(o.a.id, o.v.number)))">{{ (o.a.name) }} · v{{ (o.v.number) }}</template><template data-component="Tag" data-bind-color="(o.v.result === 'fail' ? 'red' : o.v.result === 'pass' ? 'green' : 'default')">{{ (o.v.result === 'fail' ? '有问题' : o.v.result === 'pass' ? '示例通过' : '示例产物') }}</template><span>第 {{ (o.v.iteration + 1) }} 轮</span></div></section><div data-if="(selected === task.currentId &amp;&amp; task.status === 'running')" class="task-demo-panel"><strong>原型演示控件</strong><p>模拟收到一次执行结果,以体验任务状态和产物。正式产品由执行服务上报进度。</p><template data-component="Space" wrap=""><template data-component="Select" data-model-value="(outcome)" aria-label="阶段演示结果" data-bind-options="([{ value: 'pass', label: '本阶段成功' }, ...(['agent', 'tool', 'loop', 'verify'].includes(node?.kind || '') ? [{ value: 'fail', label: '本阶段失败' }] : [])])" style="width:180px"></template><template data-component="Button" data-bind-disabled="(!can('task:operate'))" data-on-click="(advance)">演示推进一步</template></template></div></template></section></div><template data-else-if="(tab === 'artifacts' &amp;&amp; can('artifact:view'))"><div class="section-heading"><div><h2>交付产物</h2><p>保留各轮版本与证据,产物只读,不适用删除。</p></div><template data-component="Tag">{{ (task.artifacts.length) }} 类产物</template></div><div class="task-artifact-grid"><article data-each="a in (task.artifacts)" data-bind-key="(a.id)" class="task-artifact-card"><div><span class="task-file-icon">{{ (a.kind === 'code' ? '&lt;/&gt;' : '文') }}</span><template data-component="ListMore" data-bind-name="(a.name)" data-bind-items="([{ key: 'latest', label: '查看最新版本' }, { key: 'history', label: '版本与差异' }])" data-on-action="(router.push(artifactUrl(a.id) + ($event === 'history' ? '?compare=1' : '')))"></template></div><h3>{{ (a.name) }}</h3><p>{{ (a.versions.length) }} 个版本 · 最新 v{{ (a.versions.at(-1)?.number) }}</p><p class="muted">{{ (a.versions.at(-1)?.by) }}<br>{{ (formatDate(a.versions.at(-1)?.at || '')) }}</p><template data-component="Button" type="link" data-on-click="(router.push(artifactUrl(a.id)))">查看产物 →</template></article></div><p data-if="(!task.artifacts.length)" class="muted">任务尚未启动,还没有产物。</p></template><template data-else-if="(tab === 'bindings')"><h2>启动时固定的交付输入</h2><dl class="task-info-grid"><div><dt>来源意图</dt><dd>{{ (task.binding.spec.source.title) }}<br>{{ (task.binding.spec.source.code) }} v{{ (task.binding.spec.source.version) }}</dd></div><div><dt>确认规格</dt><dd>v{{ (task.binding.spec.number) }} · {{ (task.binding.spec.confirmedBy) }}<br>{{ (formatDate(task.binding.spec.confirmedAt || '')) }}</dd></div><div><dt>PBC / 租户</dt><dd>{{ (task.binding.project) }} / {{ (tenantLabel(task.tenantId)) }}</dd></div><div><dt>研发交付流程</dt><dd>{{ (task.binding.flow.body.name) }} · 发布 v{{ (task.binding.flow.number) }}</dd></div></dl><template data-component="Space" wrap=""><template data-component="Button" data-bind-disabled="(!session.can('spec:view', task.tenantId))" data-on-click="(router.push('/intents/' + task.binding.intentId + '/spec'))">查看当前规格</template><template data-component="Button" data-bind-disabled="(!can('workflow:view'))" data-on-click="(router.push('/workflows/' + task.binding.flowId))">查看当前流程</template></template><p class="muted">当前规格和流程可能已有新版本;本任务使用上面保留的快照。</p><h3>绑定的 Agent 与模型</h3><div data-each="a in (task.binding.agents)" data-bind-key="(a.config.id)" class="task-resource"><strong>{{ (a.config.name) }} · 记录 v{{ (a.config.recordVersion) }}</strong><span>{{ (a.model.name) }} · 发布 v{{ (a.model.version) }}</span><small>提示词 {{ (a.config.promptRef) }} · 技能 {{ (a.config.skillRefs.join('、') || '无') }}</small></div><p class="muted">交付说明:{{ (task.note || '无补充说明') }}</p></template><template data-else-if="(tab === 'metadata')"><template data-component="RecordMetadata" data-bind-record="(task)"></template><p class="muted">记录版本 {{ (task.recordVersion) }} · 逻辑删除 {{ (task.isDeleted ? '是' : '否') }} · 启动时间 {{ (formatDate(task.startedAt || '')) }}</p></template><template data-else-if="(tab === 'records' &amp;&amp; can('task:audit'))"><h2>操作与阶段记录</h2><p class="muted">只读历史。每次确认、失败、返工、暂停和接管都保留操作者与阶段。</p><ol class="agent-audit"><li data-each="e in (task.events.slice().reverse())" data-bind-key="(e.id)"><strong>{{ (e.action) }}</strong><span>{{ (e.actor) }} · {{ (formatDate(e.at)) }} · 第 {{ (e.iteration + 1) }} 轮</span><p>{{ (e.detail) }}</p><small>{{ (task.binding.flow.body.nodes.find(n =&gt; n.id === e.stageId)?.name || '来源与任务') }}</small></li></ol></template><template data-component="Result" data-else="" status="403" title="没有此页签的访问权限"></template></section><template data-component="Modal" data-bind-open="(!!modal)" data-bind-title="(actionNames[modal] || '处理任务')" data-bind-footer="(null)" data-on-cancel="(modal = '')"><p>{{ (task.name) }}</p><p class="muted">规格 v{{ (task.binding.spec.number) }} · 交付流程 v{{ (task.binding.flow.number) }} · 当前记录 v{{ (expected) }}</p><template data-component="Alert" data-if="(modal === 'takeover')" type="info" show-icon="" title="接管会暂停自动推进并记录负责人" description="接管不绕过确认、验证或发布门禁;恢复后回到原阶段和状态。"></template><template data-component="Checkbox" data-if="(modal === 'approve')" data-model-checked="(checked)">已查看绑定规格和原型评审包 v{{ (artifactVersion) }}</template><p data-if="(modal === 'start')">启动后固定版本;任务、产物与记录须保留,不能再删除。</p><template data-component="Input.TextArea" data-if="(modal !== 'start')" data-model-value="(note)" aria-label="任务处理说明" data-bind-rows="(3)" data-bind-maxlength="(1000)" placeholder="填写核对结果或操作原因"></template><template data-component="Alert" data-if="(error)" type="error" show-icon="" data-bind-title="(error)"></template><template data-component="Space" class="flow-modal-actions"><template data-component="Button" data-on-click="(modal = '')">取消</template><template data-component="Button" type="primary" data-on-click="(submit)">确认{{ (modal === 'approve' ? '阶段' : modal === 'retry' ? '处理' : modal === 'start' ? '启动' : modal === 'takeover' ? '接管' : modal === 'pause' ? '暂停' : '恢复') }}</template></template></template></template>
485
+
486
+ </template>
487
+ <template data-source="reference/src/tasks/TaskLaunch.html">
488
+ <!-- 来源:src/tasks/TaskLaunch.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
489
+ <template data-component="Button" type="primary" data-bind-disabled="(!session.can('task:create'))" data-on-click="(router.push({ path: '/tasks/new', query: { intent: intentId } }))">发起交付</template>
490
+
491
+ </template>
492
+ <template data-source="reference/src/tasks/TasksPage.html">
493
+ <!-- 来源:src/tasks/TasksPage.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
494
+ <div class="page-heading"><div><h1>交付任务</h1><p>从一份已确认的需求,追踪到研发阶段、产物和待处理事项。</p></div><template data-component="Space" wrap=""><template data-component="Segmented" data-model-value="(view)" data-bind-options="(['列表', '看板'])" aria-label="任务展示方式"></template><template data-component="Button" type="primary" data-bind-disabled="(!session.can('task:create'))" data-on-click="(router.push('/tasks/new'))">发起交付</template></template></div><div class="task-metrics"><article><span>全部任务</span><strong>{{ (store.records.length) }}</strong></article><article><span>正在执行</span><strong>{{ (store.records.filter(t =&gt; t.status === 'running').length) }}</strong></article><article><span>等待或需处理</span><strong>{{ (store.records.filter(t =&gt; ['waiting', 'failed', 'paused', 'manual'].includes(t.status)).length) }}</strong></article><article><span>待质量 / 发布处理</span><strong>{{ (store.records.filter(t =&gt; t.status === 'ready' &amp;&amp; hasPendingRelease(t)).length) }}</strong></article></div><section class="auth-list"><div class="auth-filters"><template data-component="Input" data-model-value="(query)" aria-label="搜索交付任务" placeholder="搜索任务、需求或阻塞原因" allow-clear=""></template><template data-component="Select" data-model-value="(project)" aria-label="任务 PBC 筛选" data-bind-options="([{ value: 'all', label: '全部可见 PBC' }, ...[...new Set(store.records.map(r =&gt; r.binding.project))].map(v =&gt; ({ value: v, label: v }))])"></template><template data-component="Select" data-model-value="(state)" aria-label="任务状态筛选" data-bind-options="([{ value: 'all', label: '全部任务状态' }, ...Object.entries(statusLabels).map(([value, label]) =&gt; ({ value, label }))])"></template><template data-component="Button" data-on-click="query = '';
495
+ state = 'all';
496
+ project = 'all';">重置</template></div><div class="auth-tools"><template data-component="ListBatchBar" data-if="(view === '列表')" data-bind-count="(selection.selected.value.length)" data-bind-allowed="(canDelete)" data-on-remove="(targets = selection.selected.value)" data-on-clear="(selection.clear)"></template><p data-else="" class="muted">{{ (filtered.length) }} 项任务 · 切换列表可选择并批量处理</p><template data-component="Space" wrap=""><template data-component="Button" data-on-click="(desc = !desc)">时间{{ (desc ? '倒序' : '正序') }}</template><template data-component="Button" data-bind-loading="(refreshing)" data-on-click="(refresh)">刷新</template><template data-component="ColumnSettings" data-if="(view === '列表')" data-bind-preferences="(prefs)"></template></template></div><template data-component="Alert" data-if="(store.notice)" type="warning" show-icon="" data-bind-title="(store.notice)"></template><template data-component="Alert" data-if="(store.scene === 'error')" type="error" show-icon="" title="交付任务加载失败" description="任务记录保留,重试不会重新创建任务。"><template data-slot="action"><template data-component="Button" data-on-click="(refresh)">重试</template></template></template><template data-else=""><template data-component="ProTable" data-if="(view === '列表')" data-bind-table="(table)" data-bind-search="(async () =&gt; { })" data-bind-control="(false)" data-bind-table-container="(false)" row-key="id" data-bind-loading="(refreshing)" 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><div data-else="" class="task-board"><section data-each="lane in (lanes)" data-bind-key="(lane.name)" class="task-lane"><h2>{{ (lane.name) }} <small>{{ (filtered.filter(t =&gt; lane.states.includes(t.status)).length) }}</small></h2><article data-each="t in (filtered.filter(t =&gt; lane.states.includes(t.status)))" data-bind-key="(t.id)" class="task-card"><div><template data-component="Tag" data-bind-color="(statusColors[t.status])">{{ (taskLabel(t)) }}</template><template data-component="ListMore" data-bind-name="(t.name)" data-bind-items="(more(t))" data-on-action="(action($event, t))"></template></div><template data-component="Button" type="link" class="task-card-name" data-on-click="(router.push('/tasks/' + t.id))">{{ (t.name) }}</template><small>{{ (t.binding.project) }} · {{ (t.code) }}</small><p>{{ (currentNode(t)?.name || '尚未启动') }} · {{ (taskProgress(t)) }}%</p><div class="task-progress-bar"><i data-bind-style="({ width: taskProgress(t) + '%' })"></i></div><p class="task-card-reason">{{ (t.reason) }}</p><small>{{ (t.owner) }} · {{ (formatDate(t.updatedAt)) }}</small></article><p data-if="(!filtered.some(t =&gt; lane.states.includes(t.status)))" class="muted">暂无任务</p></section></div><p data-if="(!filtered.length)" class="muted">没有符合条件的交付任务,可调整筛选或发起交付。</p></template><p class="muted task-list-note">仅未启动的草稿可以删除。已启动任务保留阶段与产物;发布状态由对应发布单汇总,真实运行验收仍待后续设计。</p></section><template data-component="ListDeleteDialog" data-if="(targets.length)" data-model-targets="(targets)" label="交付任务" data-bind-check="(store.checkRemove)" data-bind-submit="(store.removeMany)" data-on-close="(targets = [])" data-on-deleted="targets = [];
497
+ selection.clear();"></template>
498
+
499
+ </template>
500
+ <template data-source="reference/src/workbench/WorkbenchPage.html">
501
+ <!-- 来源:src/workbench/WorkbenchPage.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
502
+ <div class="page-heading wb-heading"><div><h1>工作台</h1><p>{{ (session.actor.name) }},从待办继续推进你的需求与交付。</p></div><template data-component="Space" wrap=""><template data-component="Select" data-model-value="(store.range)" aria-label="工作台查看范围" data-bind-options="([{ label: '与我相关', value: 'mine' }, { label: '全部授权范围', value: 'all' }])"></template><template data-component="Button" aria-label="刷新工作台" data-on-click="(refresh)"><template data-component="ReloadOutlined"></template></template><template data-component="Button" type="primary" data-bind-disabled="(!session.can('intent:view', session.actor.tenantId) || !session.can('intent:edit', session.actor.tenantId))" data-on-click="(router.push('/intents/new'))"><template data-component="PlusOutlined"></template>发起意图</template></template></div><template data-component="Alert" data-if="(!session.can('intent:view') &amp;&amp; !session.can('pbc:view') &amp;&amp; !session.can('task:view'))" type="info" show-icon="" title="当前身份尚无业务查看权限" description="首页只统计有权查看的记录。请联系业务管理员在权限管理中配置功能及数据范围。" class="page-alert"></template><template data-component="Alert" data-if="(store.notices.length)" class="page-alert" type="error" show-icon="" title="部分本地记录读取失败,请先重新加载核对" data-bind-description="(store.notices.join(';'))"><template data-slot="action"><template data-component="Button" data-on-click="(refresh)">重新加载</template></template></template><p class="wb-scope-note">{{ (store.range === 'mine' ? '与我相关:我创建或负责的需求、任务,以及关联的 PBC。' : '全部授权范围:仅显示当前身份获准查看的业务记录。') }} 数据来自本浏览器的演示记录。</p><div class="wb-metrics" aria-label="工作概览"><button class="panel wb-metric" data-on-click="(focusSection('wb-todos'))"><span class="wb-metric-icon"><template data-component="CheckSquareOutlined"></template></span><span><span class="wb-metric-label">待处理事项</span><strong>{{ (store.data.todos.length) }}</strong><small>其中 {{ (store.data.actionable) }} 项具备下一步处理权限</small></span><template data-component="ArrowRightOutlined"></template></button><button class="panel wb-metric" data-on-click="(focusSection('wb-deliveries'))"><span class="wb-metric-icon"><template data-component="ProjectOutlined"></template></span><span><span class="wb-metric-label">在途交付</span><strong>{{ (store.data.ongoing) }}</strong><small>执行、人工确认或异常处理中</small></span><template data-component="ArrowRightOutlined"></template></button><button class="panel wb-metric" data-on-click="(focusSection('wb-pbcs'))"><span class="wb-metric-icon"><template data-component="AppstoreOutlined"></template></span><span><span class="wb-metric-label">{{ (store.range === 'mine' ? '相关 PBC' : '可见 PBC') }}</span><strong>{{ (store.data.pbcs.length) }}</strong><small>进入工作区查看需求、任务与产物</small></span><template data-component="ArrowRightOutlined"></template></button></div><div class="wb-grid"><div class="wb-main"><section id="wb-todos" class="panel wb-panel" tabindex="-1" aria-labelledby="wb-todo-title"><div class="section-heading"><h2 id="wb-todo-title">{{ (heading) }}待办</h2><template data-component="Input.Search" data-model-value="(keyword)" aria-label="搜索工作台待办" placeholder="搜索名称或编号" allow-clear="" class="wb-search"></template></div><template data-component="Tabs" data-model-active-key="(group)" data-bind-items="([{ key: 'all', label: '全部' }, { key: '需求与规格', label: '需求与规格' }, { key: 'PBC 归属', label: 'PBC 归属' }, { key: '交付任务', label: '交付任务' }, { key: '质量与评审', label: '质量与评审' }, { key: '门禁与发布', label: '门禁与发布' }, { key: '运行管理', label: '运行管理' }])"></template><template data-component="ProTable" data-if="(filtered.length)" class="wb-todo-table" data-bind-table="(table)" data-bind-search="(async () =&gt; { })" data-bind-control="(false)" data-bind-table-container="(false)" row-key="id" data-bind-scroll="({ x: 690 })" size="small" data-bind-pagination="({ showSizeChanger: false, showTotal: (n) =&gt; '共 ' + n + ' 项' })"></template><div data-if="(filtered.length)" class="wb-todo-mobile"><article data-each="t in (table.dataSource.value)" data-bind-key="(t.id)"><template data-component="RouterLink" data-bind-to="(t.path)" class="model-link">{{ (t.title) }}</template><span class="mono muted">{{ (t.code) }}</span><template data-component="Tag" data-bind-color="(t.allowed ? 'blue' : 'default')">{{ (t.status) }}</template><p>{{ (t.reason) }}</p><small class="muted">{{ (t.affiliation) }} · {{ (tenantLabel(t.tenantId)) }}<br>创建人 {{ (t.createdBy) }}<br>更新 {{ (formatDate(t.updatedAt)) }}</small><template data-component="Button" size="small" data-on-click="(router.push(t.path))">{{ (t.action) }}</template></article><template data-component="Pagination" data-model-current="(table.pageParam.current)" data-bind-page-size="(5)" data-bind-total="(filtered.length)" size="small" data-bind-show-size-changer="(false)"></template></div><template data-component="Empty" data-if="(!filtered.length)" data-bind-description="(keyword || group !== 'all' ? '没有符合筛选条件的待办' : '当前范围暂无待办')" class="wb-empty"><template data-component="Button" data-if="(keyword || group !== 'all')" data-on-click="keyword = '';
503
+ group = 'all';">清除筛选</template><template data-component="Button" data-else-if="(store.range === 'mine')" data-on-click="(store.range = 'all')">查看全部授权范围</template><p class="muted">汇总意图、规格、PBC、交付、评审、发布与运行待办。</p></template><p class="wb-footnote">待办是业务记录的汇总入口;修改与删除请进入相应管理页面。</p></section><section id="wb-pbcs" class="panel wb-panel" tabindex="-1" aria-labelledby="wb-pbc-title"><div class="section-heading"><h2 id="wb-pbc-title">{{ (heading) }}PBC</h2><template data-component="Button" type="link" data-bind-disabled="(!session.can('pbc:view'))" data-on-click="(router.push('/pbcs'))">PBC 管理 <template data-component="ArrowRightOutlined"></template></template></div><div data-if="(store.data.pbcs.length)" class="wb-pbcs"><button data-each="p in (store.data.pbcs.slice(0, 4))" data-bind-key="(p.id)" class="wb-pbc" data-on-click="(router.push('/pbcs/' + p.id + '/workspace'))"><span class="wb-pbc-top"><strong>{{ (p.name) }}</strong><template data-component="Tag" data-bind-color="(p.state === 'archived' ? 'default' : 'green')">{{ (p.state === 'archived' ? '已归档' : '正常') }}</template></span><span>{{ (p.ebc) }} · {{ (tenantLabel(p.tenantId)) }}</span><span class="muted">负责人 {{ (p.owner) }} · {{ (p.services.filter(s =&gt; !s.isDeleted).length) }} 项服务方案</span><span class="wb-pbc-bottom">进入交付工作区 <template data-component="ArrowRightOutlined"></template></span></button></div><template data-component="Empty" data-else="" description="当前范围暂无 PBC" class="wb-empty"><p class="muted">需求完成规格确认后,可以关联已有 PBC 或创建新 PBC。</p></template><p data-if="(store.data.pbcs.length &gt; 4)" class="wb-footnote">这里显示前 4 个 PBC,完整记录可进入 PBC 管理查看。</p></section><section id="wb-deliveries" class="panel wb-panel" tabindex="-1" aria-labelledby="wb-delivery-title"><div class="section-heading"><h2 id="wb-delivery-title">{{ (heading) }}交付</h2><template data-component="Button" type="link" data-bind-disabled="(!session.can('task:view'))" data-on-click="(router.push('/tasks'))">交付任务 <template data-component="ArrowRightOutlined"></template></template></div><div data-if="(store.data.deliveries.length)" class="wb-deliveries"><article data-each="t in (store.data.deliveries.slice(0, 4))" data-bind-key="(t.id)" class="wb-delivery"><div class="wb-delivery-info"><template data-component="RouterLink" data-bind-to="('/tasks/' + t.id)" class="model-link">{{ (t.name) }}</template><span class="muted">{{ (t.code) }} · {{ (t.project) }} · {{ (t.owner) }}</span><span>{{ (t.stage) }} <template data-component="Tag" data-bind-color="(t.status === 'failed' ? 'red' : t.status === 'waiting' ? 'orange' : 'blue')">{{ (t.label) }}</template></span></div><div class="wb-progress"><template data-component="Progress" data-bind-percent="(t.progress)" data-bind-status="(t.status === 'failed' ? 'exception' : 'normal')" size="small"></template><small class="muted">研发阶段进度 · {{ (formatDate(t.updatedAt)) }}</small></div></article></div><template data-component="Empty" data-else="" description="当前范围暂无交付任务" class="wb-empty"></template><p data-if="(store.data.deliveries.length &gt; 4)" class="wb-footnote">最近更新的 4 个任务;完整记录请进入交付任务。</p></section></div><aside class="wb-side"><section class="panel wb-panel" aria-label="快捷入口"><h2>快捷入口</h2><div class="wb-shortcuts"><template data-component="Button" data-bind-disabled="(!session.can('pbc:view') || !session.can('intent:view') || !session.can('pbc:create'))" data-on-click="(create = true)"><template data-component="AppstoreOutlined"></template>新建 PBC <template data-component="ArrowRightOutlined"></template></template><small class="muted">需有已确认规格及对应租户创建权限。</small><template data-component="Button" data-bind-disabled="(!session.can('task:view') || !session.can('task:create'))" data-on-click="(router.push('/tasks/new'))"><template data-component="ProjectOutlined"></template>发起交付 <template data-component="ArrowRightOutlined"></template></template><small class="muted">需完成 PBC 归属并选择可用交付流程。</small><template data-component="Button" data-bind-disabled="(!session.can('intent:view'))" data-on-click="(router.push('/intents'))">意图与需求 <template data-component="ArrowRightOutlined"></template></template><template data-component="Button" data-bind-disabled="(!session.can('task:view') || !session.can('artifact:view'))" data-on-click="(router.push('/reviews'))">质量与评审 <template data-component="ArrowRightOutlined"></template></template><template data-component="Button" data-bind-disabled="(!session.can('task:view') || !session.can('artifact:view'))" data-on-click="(router.push('/releases'))">门禁与发布 <template data-component="ArrowRightOutlined"></template></template><template data-component="Button" data-bind-disabled="(!session.can('operation:view'))" data-on-click="(router.push('/operations'))">运行管理 <template data-component="ArrowRightOutlined"></template></template><template data-component="Button" data-bind-disabled="(!session.can('model:view'))" data-on-click="(router.push('/models'))">模型管理 <template data-component="ArrowRightOutlined"></template></template></div><p class="wb-footnote">入口按授权显示可用状态。无权限时请联系业务管理员。</p></section><section class="panel wb-panel" aria-label="公告与规范提醒"><div class="section-heading"><h2><template data-component="NotificationOutlined"></template> 公告与规范</h2><template data-component="Tag">演示</template></div><ul class="wb-notices"><li data-each="n in (alerts)" data-bind-key="(n.id)"><button data-on-click="(notice = n.id)"><span class="wb-notice-meta">{{ (n.category) }} · {{ (n.date) }}</span><strong>{{ (n.title) }}</strong><span class="muted">查看详情 <template data-component="ArrowRightOutlined"></template></span></button></li></ul><p class="wb-footnote">只读内容样例,未发送真实通知。</p></section><section class="panel wb-panel wb-coming"><h2>运行反馈已接入</h2><p>运行验收与异常按原记录汇总;处理后待办同步更新,历史证据保留。</p></section></aside></div><template data-component="PbcCreateEntry" data-bind-open="(create)" data-on-close="(create = false)"></template><template data-component="Modal" data-bind-open="(!!selectedNotice)" data-bind-title="(selectedNotice?.title)" data-on-cancel="(notice = '')" data-bind-footer="(null)"><template data-if="(selectedNotice)"><p class="muted">{{ (selectedNotice.category) }} · {{ (selectedNotice.date) }} · 演示内容</p><p class="wb-notice-content">{{ (selectedNotice.body) }}</p><template data-component="Button" data-on-click="(notice = '')">关闭</template></template></template>
504
+
505
+ </template>
506
+ <template data-source="reference/src/workflows/FlowCanvas.html">
507
+ <!-- 来源:src/workflows/FlowCanvas.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
508
+ <section class="flow-canvas" aria-label="流程画布"><div class="flow-canvas-tools"><span>{{ (body.nodes.length) }} 个节点 · {{ (body.edges.length) }} 条连线</span><template data-component="Space"><template data-component="Button" aria-label="缩小画布" data-bind-disabled="(zoom &lt;= .25)" data-on-click="(zoom = Math.max(.25, zoom - .1))">−</template><span class="flow-zoom">{{ (Math.round(zoom * 100)) }}%</span><template data-component="Button" aria-label="放大画布" data-bind-disabled="(zoom &gt;= 1.5)" data-on-click="(zoom = Math.min(1.5, zoom + .1))">+</template><template data-component="Button" data-on-click="(fit)">适合画布</template></template></div><div ref="viewport" class="flow-viewport" tabindex="0" aria-label="可滚动流程画布"><div data-bind-style="({ width: size.width * zoom + 'px', height: size.height * zoom + 'px' })"><div class="flow-board" data-bind-style="({ width: size.width + 'px', height: size.height + 'px', transform: `scale(${zoom})` })"><svg class="flow-edges" data-bind-width="(size.width)" data-bind-height="(size.height)" aria-hidden="true"><defs><marker id="flow-arrow" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="6" markerHeight="6" orient="auto-start-reverse"><path d="M 0 0 L 10 5 L 0 10 z" fill="#8291aa"></path></marker></defs><g data-each="edge in (edges)" data-bind-key="(edge.id)"><path data-bind-d="(edge.path)" fill="none" stroke="#8291aa" stroke-width="2" marker-end="url(#flow-arrow)"></path><text data-if="(edge.label)" data-bind-x="(edge.x)" data-bind-y="(edge.y)" text-anchor="middle">{{ (edge.label) }}</text></g></svg><div data-each="n in (body.nodes)" data-bind-key="(n.id)" class="flow-node" data-bind-class="(['kind-' + n.kind, { selected: selected === n.id }])" role="button" tabindex="0" data-bind-aria-label="('节点 ' + n.name)" data-bind-aria-pressed="(selected === n.id)" data-bind-style="({ left: n.x + 'px', top: n.y + 'px' })" data-on-pointerdown="(down($event, n))" data-on-pointermove="(move)" data-on-pointerup="(drag = undefined)" data-on-pointercancel="(drag = undefined)" data-on-keydown="(key($event, n))"><div class="flow-node-top"><span class="flow-node-kind">{{ (kindLabel(n)) }}</span><span data-if="(protectedNode(n))" class="flow-lock">保护</span></div><strong>{{ (n.name) }}</strong><small>{{ (n.kind === 'loop' ? '最多 ' + (n.limit || '未设置') + ' 次 · 耗尽转人工' : n.gate === 'production' ? '人工授权后方可发布' : n.kind === 'verify' ? '与实现 Agent 独立' : n.output || '流程控制节点') }}</small></div></div></div></div><div class="flow-canvas-hint"><template data-component="Tag" color="blue">{{ (readonly ? '版本预览' : '可编辑草稿') }}</template>{{ (readonly ? '选择节点查看属性' : '拖动节点调整布局;选中后用方向键微调,右侧配置连线。') }}</div></section>
509
+
510
+ </template>
511
+ <template data-source="reference/src/workflows/FlowDetail.html">
512
+ <!-- 来源:src/workflows/FlowDetail.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
513
+ <template data-component="Result" data-if="(!record || !body)" status="404" title="模板不存在或无权访问"><template data-slot="extra"><template data-component="Button" data-on-click="(router.push('/workflows'))">返回列表</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('/workflows'))">← 返回模板列表</template><div class="agent-title"><h1>{{ (record.body.name) }}</h1><template data-component="Tag" data-bind-color="(record.enabled ? 'green' : 'default')">{{ (record.enabled ? '已启用' : '已停用') }}</template></div><p>{{ (record.body.description) }}</p></div><template data-component="Space" wrap=""><template data-component="Button" data-bind-disabled="(!can('workflow:status') || (!record.enabled &amp;&amp; !record.versions.length))" data-on-click="(toggle)">{{ (record.enabled ? '停用模板' : '启用模板') }}</template><template data-component="Button" data-bind-disabled="(!can('workflow:edit') || record.state === 'review')" data-on-click="(router.push('/workflows/' + record.id + '/edit'))">编辑草稿</template><template data-component="Button" type="primary" data-bind-disabled="(!can('workflow:use') || !record.enabled)" data-on-click="useVersion = record.versions.at(-1)?.number;
514
+ useOpen = true;">保存版本选择</template><template data-component="Button" type="primary" data-bind-disabled="(!can('workflow:use') || !can('task:create') || !record.enabled)" data-on-click="(router.push({ path: '/tasks/new', query: { flow: record.id, version: record.versions.at(-1)?.number } }))">用于发起交付</template></template></div><template data-component="Alert" data-if="(error)" class="page-alert" type="error" show-icon="" data-bind-title="(error)" closable="" data-on-close="(error = '')"></template><template data-component="Alert" data-if="(record.state === 'review')" class="page-alert" type="info" show-icon="" title="草稿等待配置审核" data-bind-description="('提交人:' + record.requestName + ';变更说明:' + record.reviewNote)"><template data-slot="action"><template data-component="Space" wrap=""><template data-component="Button" data-if="(can('workflow:edit'))" data-on-click="(run(() =&gt; store.withdraw(record.id, record.recordVersion)))">撤回审核</template><template data-component="Button" type="primary" data-bind-disabled="(!can('workflow:publish') || record.requestBy === session.actor.id)" data-on-click="note = '';
515
+ reviewOpen = true;">审核配置</template></template></template></template><template data-component="Alert" data-else-if="(record.state === 'draft' &amp;&amp; record.reviewNote)" class="page-alert" type="warning" title="配置已退回" data-bind-description="(record.reviewNote)" show-icon=""></template><div class="agent-meta-strip"><span>项目 <strong>{{ (record.project) }}</strong></span><span>标识 <strong>{{ (record.body.code) }}</strong></span><span>最新发布 <strong>{{ (record.versions.length ? 'v' + record.versions.at(-1).number : '尚未发布') }}</strong></span><span>草稿 <strong>{{ ({ draft: '编辑中', review: '待审核', published: '与最新发布一致' }[record.state]) }}</strong></span></div><section class="agent-panel"><template data-component="Tabs" data-model-active-key="(active)" data-bind-items="([{ key: 'flow', label: '流程配置' }, { key: 'versions', label: '版本与差异' }, { key: 'handoff', label: '版本选择记录' }, { key: 'metadata', label: '基础信息' }, ...(can('workflow:audit') ? [{ key: 'records', label: '操作记录' }] : [])])"></template><template data-if="(active === 'flow' || active === 'versions')"><div class="flow-version-tools"><template data-component="Space" wrap=""><span>查看</span><template data-component="Select" data-model-value="(version)" aria-label="查看流程版本" data-bind-options="(versions)" style="width:190px"></template><template data-if="(active === 'versions' &amp;&amp; record.versions.length)"><span>对比</span><template data-component="Select" data-bind-value="(compare || String(record.versions.at(-1)?.number))" aria-label="对比基准版本" data-bind-options="(versions.filter(v =&gt; v.value !== 'draft'))" style="width:160px" data-on-change="(v =&gt; compare = String(v))"></template></template></template><template data-component="Button" data-if="(version !== 'draft')" data-bind-disabled="(!can('workflow:edit') || record.state === 'review')" data-on-click="(restore)">基于此版本编辑</template></div><template data-if="(active === 'versions')"><template data-component="Alert" type="info" show-icon="" title="发布版本只读保留" description="草稿保存和新版本发布都不会改写历史版本。版本历史不适用批量删除。"></template><div class="flow-version-history"><article data-each="v in (record.versions.slice().reverse())" data-bind-key="(v.number)"><template data-component="Tag" color="blue">v{{ (v.number) }}</template><strong>{{ (v.note) }}</strong><span>{{ (v.by) }} · {{ (formatDate(v.at)) }}</span><template data-component="Button" type="link" data-on-click="(version = String(v.number))">查看此版</template></article><p data-if="(!record.versions.length)" class="muted">尚无发布版本。保存并提交草稿后可审核发布。</p></div><h2>差异明细</h2><ul data-if="(changes.length)" class="flow-diff"><li data-each="(change,i) in (changes)" data-bind-key="(i)">{{ (change) }}</li></ul><p data-else="" class="muted">{{ (record.versions.length ? '与所选基准版本没有差异。' : '发布首版后可对比差异。') }}</p></template><template data-component="Alert" data-if="(issues.length)" class="page-alert" type="warning" show-icon="" data-bind-title="(issues.length + ' 项配置或资源待处理')" description="下方检查包含当前资源状态,可能与历史发布时不同。"></template><div class="flow-editor-layout"><template data-component="FlowCanvas" data-bind-body="(body)" readonly="" data-bind-selected="(selected)" data-on-select="(selected = $event)"></template><aside class="flow-properties"><template data-if="(node)"><h2>{{ (node.name) }}</h2><template data-component="Tag">{{ (kindLabel(node)) }}</template><dl class="flow-node-details"><dt data-if="(node.agentId)">执行 Agent</dt><dd data-if="(node.agentId)">{{ (store.choices(record).find(a =&gt; a.id === node.agentId)?.name || '引用不可用或无权查看') }}</dd><dt data-if="(node.input)">输入产物</dt><dd data-if="(node.input)">{{ (node.input) }}</dd><dt data-if="(node.output)">输出产物</dt><dd data-if="(node.output)">{{ (node.output) }}</dd><dt data-if="(node.permission)">确认权限</dt><dd data-if="(node.permission)">交付人工确认</dd><dt data-if="(node.tool)">登记工具</dt><dd data-if="(node.tool)">{{ (node.tool === 'ci-check' ? '项目 CI · 质量检查' : '契约查询') }}(示例)</dd><dt data-if="(node.limit)">修复上限</dt><dd data-if="(node.limit)">{{ (node.limit) }} 次,耗尽转人工</dd><dt data-if="(node.condition)">判断条件</dt><dd data-if="(node.condition)">{{ (node.condition === 'checks.passed' ? '质量检查通过' : '人工评审通过') }}</dd></dl></template><p class="muted">配置预览不触发执行。</p></aside></div><div data-if="(issues.length)" class="flow-checks"><div data-each="c in (issues)" data-bind-key="(c.id)" class="flow-check"><template data-component="Tag" color="orange">待处理</template><div><strong>{{ (c.title) }}</strong><p>{{ (c.detail) }}</p></div></div></div></template><template data-else-if="(active === 'handoff')"><template data-component="Alert" type="info" show-icon="" title="已固定版本,尚未创建任务" description="这些是本地原型的交接凭据,可通过右上角“用于发起交付”选择需求并创建任务。选择记录只读,不适用删除。"></template><article data-each="u in (store.uses(record))" data-bind-key="(u.id)" class="flow-use" data-bind-class="({ selected: u.id === useId })"><div><template data-component="Tag" color="blue">v{{ (u.version.number) }}</template><strong>{{ (u.version.body.name) }}</strong></div><p>{{ (u.project) }} · {{ (u.by) }} · {{ (formatDate(u.at)) }}</p><p class="muted">所选版本:{{ (u.version.note) }};{{ (u.version.body.nodes.length) }} 个节点,快照保留。</p><p data-each="a in (u.agentVersions)" data-bind-key="(a.id)" class="muted">{{ (a.name) }} · 选择时记录 v{{ (a.recordVersion) }}</p><small class="agent-code">{{ (u.id) }}</small></article><p data-if="(!store.uses(record).length)" class="muted">尚未选择版本。启用模板后可从右上角“使用模板”体验。</p></template><template data-component="RecordMetadata" data-else-if="(active === 'metadata')" data-bind-record="(record)"></template><section data-else-if="(active === 'records' &amp;&amp; can('workflow:audit'))"><p class="muted">操作记录只读保留,不适用删除。</p><ol class="agent-audit"><li data-each="a in (store.audits(record))" data-bind-key="(a.id)"><strong>{{ (a.action) }}</strong><span>{{ (a.actor) }} · {{ (formatDate(a.at)) }}</span><p>{{ (a.detail) }}</p></li></ol><p data-if="(!store.audits(record).length)" class="muted">暂无操作记录。</p></section></section><template data-component="Modal" data-bind-open="(reviewOpen)" title="审核流程配置" data-bind-footer="(null)" data-on-cancel="(reviewOpen = false)"><p>提交人:{{ (record.requestName) }};拟发布版本:v{{ ((record.versions.at(-1)?.number || 0) + 1) }}</p><p>{{ (record.reviewNote) }}</p><p class="muted">审核当前草稿、版本差异和检查结果;确认后生成不可变发布快照。</p><template data-component="Input.TextArea" data-model-value="(note)" aria-label="审核意见" placeholder="退回时请填写原因"></template><template data-component="Alert" data-if="(error)" type="error" data-bind-title="(error)"></template><template data-component="Space" class="flow-modal-actions"><template data-component="Button" data-on-click="(reviewOpen = false)">取消</template><template data-component="Button" danger="" data-on-click="(review(false))">退回修改</template><template data-component="Button" type="primary" data-on-click="(review(true))">确认审核发布</template></template></template><template data-component="Modal" data-bind-open="(useOpen)" title="选择交付模板版本" data-bind-footer="(null)" data-on-cancel="(useOpen = false)"><p>项目:{{ (record.project) }}</p><template data-component="Select" data-model-value="(useVersion)" aria-label="使用模板版本" class="full-width" data-bind-options="(record.versions.map(v =&gt; ({ value: v.number, label: 'v' + v.number + ' · ' + v.note })).reverse())"></template><p class="muted">确认后保存此版本的交接快照。后续模板更新不会改写此选择,当前不会启动实际任务。</p><template data-component="Alert" data-if="(error)" type="error" data-bind-title="(error)"></template><template data-component="Space" class="flow-modal-actions"><template data-component="Button" data-on-click="(useOpen = false)">取消</template><template data-component="Button" type="primary" data-on-click="(use)">确认选择版本</template></template></template></template>
516
+
517
+ </template>
518
+ <template data-source="reference/src/workflows/FlowEditor.html">
519
+ <!-- 来源:src/workflows/FlowEditor.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
520
+ <template data-component="Result" data-if="(!draft)" status="404" title="模板不存在或无权访问"></template><template data-else=""><div class="page-heading flow-heading"><div><template data-component="Button" type="link" class="agent-back" data-on-click="(router.push('/workflows'))">← 返回模板列表</template><h1>{{ (isNew ? '创建流程模板' : '编辑流程草稿') }}</h1><p>组合交付步骤,明确每一步的执行资源与产物。</p></div><template data-component="Space" wrap=""><template data-component="Tag" data-if="(dirty)" color="orange">有未保存修改</template><template data-component="Button" data-on-click="(showChecks = !showChecks)">检查流程</template><template data-component="Button" type="primary" data-bind-disabled="(!allowed)" data-bind-loading="(busy)" data-on-click="(save())">保存草稿</template></template></div><template data-component="Alert" data-if="(!allowed)" type="warning" show-icon="" title="当前草稿只读" description="需要编辑权限;审核中的配置须先撤回。"></template><template data-component="Alert" data-if="(error)" class="page-alert" type="error" show-icon="" data-bind-title="(error)" closable="" data-on-close="(error = '')"></template><template data-component="Form" layout="vertical" class="flow-basics" data-bind-disabled="(!allowed)"><template data-component="FormItem" label="模板名称" required=""><template data-component="Input" data-model-value="(draft.body.name)" aria-label="模板名称" placeholder="例如:供热工单 AI 应用交付" data-bind-maxlength="(80)"></template></template><template data-component="FormItem" label="模板标识" required=""><template data-component="Input" data-model-value="(draft.body.code)" aria-label="模板标识" placeholder="heating-ai-delivery" data-bind-disabled="(!isNew)" data-bind-maxlength="(50)"></template></template><template data-component="FormItem" label="所属项目" required=""><template data-component="Select" data-bind-value="(draft.pbcId)" aria-label="模板所属项目" data-bind-disabled="(!isNew)" data-bind-options="(store.projects.map(p =&gt; ({ value: p.id, label: p.name })))" data-on-change="(v =&gt; project(String(v)))"></template></template><template data-component="FormItem" label="用途说明"><template data-component="Input" data-model-value="(draft.body.description)" aria-label="模板用途" data-bind-maxlength="(300)"></template></template></template><div class="flow-palette"><span>添加节点</span><template data-component="Button" data-each="k in (kinds)" data-bind-key="(k.value)" data-bind-disabled="(!allowed)" data-on-click="(add(k.value))">{{ (k.mark) }} {{ (k.label) }}</template><template data-component="Button" data-bind-disabled="(!allowed)" data-on-click="(arrange)">自动整理</template></div><div class="flow-editor-layout"><template data-component="FlowCanvas" data-bind-body="(draft.body)" data-bind-selected="(selected)" data-bind-readonly="(!allowed)" data-on-select="(selected = $event)" data-on-move="(move)"></template><aside class="flow-properties" aria-label="节点属性"><template data-if="(node)"><div class="flow-prop-title"><h2>节点属性</h2><template data-component="Tag" data-bind-color="(protectedNode(node) ? 'blue' : 'default')">{{ (protectedNode(node) ? '治理保护' : kindLabel(node)) }}</template></div><template data-component="Form" layout="vertical" data-bind-disabled="(!allowed)"><template data-component="FormItem" label="节点名称"><template data-component="Input" data-model-value="(node.name)" aria-label="节点名称" data-bind-maxlength="(50)"></template></template><template data-component="FormItem" data-if="(['agent', 'verify', 'loop'].includes(node.kind))" label="执行 Agent" required=""><template data-component="Select" data-model-value="(node.agentId)" aria-label="节点执行 Agent" data-bind-options="(agentOptions)" placeholder="选择可用 Agent" allow-clear=""></template><p class="muted">仅显示同一项目内有权查看的配置。</p></template><template data-component="FormItem" data-if="(node.kind === 'tool')" label="登记工具 / CI" required=""><template data-component="Select" data-model-value="(node.tool)" aria-label="节点工具" data-bind-options="([{ value: 'ci-check', label: '项目 CI · 质量检查(示例)' }, { value: 'contract-read', label: '契约查询(示例)' }])"></template></template><template data-if="(['agent', 'verify', 'loop', 'tool'].includes(node.kind))"><template data-component="FormItem" label="输入产物" required=""><template data-component="Input" data-model-value="(node.input)" aria-label="输入产物" placeholder="例如:规格与代码"></template></template><template data-component="FormItem" label="输出产物" required=""><template data-component="Input" data-model-value="(node.output)" aria-label="输出产物" placeholder="例如:检查报告"></template></template></template><template data-component="FormItem" data-if="(node.kind === 'human')" label="确认所需权限"><template data-component="Select" data-model-value="(node.permission)" aria-label="确认权限" data-bind-disabled="(!!node.gate)" data-bind-options="([{ value: 'workflow:approve', label: '交付人工确认' }])"></template><p class="muted">按权限分配给成员,不限定岗位名称。</p></template><template data-component="FormItem" data-if="(node.kind === 'branch')" label="判断条件"><template data-component="Select" data-model-value="(node.condition)" aria-label="分支条件" data-bind-options="([{ value: 'checks.passed', label: '质量检查通过' }, { value: 'review.approved', label: '人工评审通过' }])"></template></template><template data-component="FormItem" data-if="(node.kind === 'loop')" label="最多修复次数"><template data-component="InputNumber" data-model-value="(node.limit)" aria-label="最多修复次数" data-bind-min="(1)" data-bind-max="(10)" data-bind-precision="(0)"></template><p class="muted">耗尽后转人工处理;修复后仍需独立验证。范围为原型示例。</p></template></template><h3>后续连线</h3><div data-each="edge in (draft.body.edges.filter(e =&gt; e.from === node?.id))" data-bind-key="(edge.id)" class="flow-connection"><span>{{ (edge.label ? edge.label + ' → ' : '') }}{{ (draft.body.nodes.find(n =&gt; n.id === edge.to)?.name) }}</span><template data-component="Button" type="text" danger="" data-bind-disabled="(!allowed)" data-bind-aria-label="('移除连线至 ' + draft.body.nodes.find(n =&gt; n.id === edge.to)?.name)" data-on-click="(draft.body.edges = draft.body.edges.filter(e =&gt; e.id !== edge.id))">×</template></div><template data-if="(node.kind !== 'archive')"><template data-component="Select" data-if="(node.kind === 'branch')" data-model-value="(branchLabel)" aria-label="分支出口" data-bind-disabled="(!allowed)" data-bind-options="(['满足', '不满足'].map(v =&gt; ({ value: v, label: v })))"></template><template data-component="Select" data-model-value="(connectTo)" aria-label="连接到节点" data-bind-disabled="(!allowed)" placeholder="选择后续节点" data-bind-options="(draft.body.nodes.filter(n =&gt; n.id !== node?.id &amp;&amp; n.kind !== 'start').map(n =&gt; ({ value: n.id, label: n.name })))"></template><template data-component="Button" block="" data-bind-disabled="(!allowed || !connectTo)" data-on-click="(connect)">添加连线</template></template><p data-if="(protectedNode(node))" class="muted">必要治理节点不可删除。连接变化仍需通过全路径检查。</p><template data-component="Button" danger="" block="" data-bind-disabled="(!allowed || protectedNode(node))" data-on-click="(removeNode)">删除节点</template></template></aside></div><section data-if="(showChecks)" class="agent-panel flow-checks" aria-label="流程检查结果"><h2>{{ (issues.length ? '检查发现 ' + issues.length + ' 项待处理' : '流程检查通过') }}</h2><p class="muted">本地结构、引用与治理检查;真实 CI、产物类型和 Dapr 执行未接入。</p><div data-each="c in (issues.length ? issues : checks.filter(c =&gt; ['gates', 'release', 'independent', 'cycle'].includes(c.id)))" data-bind-key="(c.id)" class="flow-check"><template data-component="Tag" data-bind-color="(c.ok ? 'green' : 'orange')">{{ (c.ok ? '通过' : '待处理') }}</template><div><strong>{{ (c.title) }}</strong><p>{{ (c.detail) }}</p></div><template data-component="Button" data-if="(c.nodeId)" data-on-click="(selected = c.nodeId)">定位节点</template></div></section><section class="flow-submit"><div><h2>提交配置审核</h2><p class="muted">草稿通过检查后提交,由有发布权限的其他成员审核。现有发布版继续保留。</p><template data-component="Input.TextArea" data-model-value="(note)" aria-label="版本变更说明" placeholder="说明本次节点、资源或流程调整" data-bind-rows="(2)" data-bind-maxlength="(500)"></template></div><template data-component="Button" data-bind-disabled="(!allowed)" data-bind-loading="(busy)" data-on-click="(save(true))">保存并提交审核</template></section></template>
521
+
522
+ </template>
523
+ <template data-source="reference/src/workflows/WorkflowsPage.html">
524
+ <!-- 来源:src/workflows/WorkflowsPage.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
525
+ <div class="page-heading"><div><h1>研发交付流程</h1><p>定义一次研发交付经过哪些步骤、由谁执行,以及何时需要人工确认。</p></div><template data-component="Button" type="primary" data-bind-disabled="(!session.can('workflow:edit'))" data-on-click="(router.push('/workflows/new'))">创建模板</template></div><div class="workflow-purpose"><article><strong>什么时候用</strong><p>需求规格与 PBC 归属完成后,发起交付时选择。</p></article><article><strong>输入什么</strong><p>确认的规格、交互原型,以及项目和资源权限。</p></article><article><strong>得到什么</strong><p>一项交付任务,持续记录阶段进度、产物与待处理事项。</p></article><template data-component="Button" type="primary" data-bind-disabled="(!session.can('task:create'))" data-on-click="(router.push('/tasks/new'))">发起一次交付</template></div><div class="agent-overview"><span>全部模板 <strong>{{ (store.records.length) }}</strong></span><span>可供选择 <strong>{{ (store.records.filter(r =&gt; r.enabled).length) }}</strong></span><span>待审核 <strong>{{ (store.records.filter(r =&gt; r.state === 'review').length) }}</strong></span><span class="muted">草稿修改不影响已发布版本</span></div><section class="auth-list"><div class="auth-filters"><template data-component="Input" data-model-value="(query)" aria-label="搜索流程模板" placeholder="搜索模板名称、标识或用途" allow-clear=""></template><template data-component="Select" data-model-value="(project)" aria-label="流程项目筛选" data-bind-options="([{ value: 'all', label: '全部可见项目' }, ...[...new Set(store.records.map(r =&gt; r.project))].map(v =&gt; ({ value: v, label: v }))])"></template><template data-component="Select" data-model-value="(state)" aria-label="流程状态筛选" data-bind-options="([{ value: 'all', label: '全部配置状态' }, ...Object.entries(labels).map(([value, label]) =&gt; ({ value, label }))])"></template><template data-component="Button" data-on-click="query = '';
526
+ state = 'all';
527
+ project = 'all';">重置</template></div><div class="auth-tools"><template data-component="ListBatchBar" data-bind-count="(selection.selected.value.length)" data-bind-allowed="(canDelete)" data-on-remove="(targets = selection.selected.value)" data-on-clear="(selection.clear)"></template><template data-component="Space" wrap=""><template data-component="Button" data-on-click="(desc = !desc)">时间{{ (desc ? '倒序' : '正序') }}</template><template data-component="Button" data-bind-loading="(refreshing)" data-on-click="(refresh)">刷新</template><template data-component="ColumnSettings" data-bind-preferences="(prefs)"></template></template></div><template data-component="Alert" data-if="(error)" type="error" show-icon="" data-bind-title="(error)" closable="" data-on-close="(error = '')"></template><template data-component="Alert" data-if="(store.scene === 'error')" type="error" show-icon="" title="流程模板加载失败" description="请重试,现有草稿保持不变。"><template data-slot="action"><template data-component="Button" data-on-click="(refresh)">重试</template></template></template><template data-else=""><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-loading="(refreshing)" 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><p data-if="(!filtered.length)" class="muted">没有符合条件的流程模板。可调整筛选,或创建模板。</p></template></section><template data-component="ListDeleteDialog" data-if="(targets.length)" data-model-targets="(targets)" label="流程模板" data-bind-check="(store.checkRemove)" data-bind-submit="(store.removeMany)" data-on-close="(targets = [])" data-on-deleted="targets = [];
528
+ selection.clear();"></template>
529
+
530
+ </template>
531
+ <script type="application/json" id="prototype-offline-routes">[{"path":"/","redirect":"/workbench"},{"path":"/workbench","component":"./src/workbench/WorkbenchPage.js"},{"path":"/module/workbench","redirect":"/workbench"},{"path":"/pbcs","component":"./src/pbc/PbcsPage.js"},{"path":"/pbcs/:id/workspace","component":"./src/pbc/PbcWorkspace.js"},{"path":"/pbcs/:id","component":"./src/pbc/PbcDetail.js"},{"path":"/operations","component":"./src/operations/OperationsPage.js"},{"path":"/operations/:taskId/:runId/incidents/:incidentId/repair","component":"./src/operations/RepairTrack.js"},{"path":"/operations/:taskId/:runId/incidents/:incidentId","component":"./src/operations/IncidentDetail.js"},{"path":"/module/operations","redirect":"/operations"},{"path":"/releases","component":"./src/releases/ReleasesPage.js"},{"path":"/releases/:taskId/:releaseId/execution","component":"./src/releases/ReleaseExecution.js"},{"path":"/releases/:taskId/:releaseId","component":"./src/releases/ReleaseDetail.js"},{"path":"/module/release","redirect":"/releases"},{"path":"/reviews","component":"./src/reviews/ReviewsPage.js"},{"path":"/reviews/:taskId/:reviewId/process","component":"./src/reviews/ReviewProcess.js"},{"path":"/reviews/:taskId/:reviewId","component":"./src/reviews/ReviewDetail.js"},{"path":"/module/quality","redirect":"/reviews"},{"path":"/tasks","component":"./src/tasks/TasksPage.js"},{"path":"/tasks/new","component":"./src/tasks/TaskCreate.js"},{"path":"/tasks/:id/edit","component":"./src/tasks/TaskCreate.js"},{"path":"/tasks/:id/artifacts/:artifact","component":"./src/tasks/ArtifactDetail.js"},{"path":"/tasks/:id","component":"./src/tasks/TaskDetail.js"},{"path":"/workflows","component":"./src/workflows/WorkflowsPage.js"},{"path":"/workflows/new","component":"./src/workflows/FlowEditor.js"},{"path":"/workflows/:id/edit","component":"./src/workflows/FlowEditor.js"},{"path":"/workflows/:id","component":"./src/workflows/FlowDetail.js"},{"path":"/agents","component":"./src/agents/AgentsPage.js"},{"path":"/agents/new","component":"./src/agents/AgentEditor.js"},{"path":"/agents/:id/edit","component":"./src/agents/AgentEditor.js"},{"path":"/agents/:id","component":"./src/agents/AgentDetail.js"},{"path":"/permissions/roles","component":"./src/permissions/RolesPage.js"},{"path":"/permissions/members","component":"./src/permissions/MembersPage.js"},{"path":"/permissions/records","component":"./src/permissions/RecordsPage.js"},{"path":"/intents","component":"./src/intents/IntentList.js"},{"path":"/intents/new","component":"./src/intents/IntentCreate.js"},{"path":"/intents/:id/spec","component":"./src/specs/SpecWorkspace.js"},{"path":"/intents/:id/spec/review","component":"./src/specs/SpecReview.js"},{"path":"/intents/:id/pbc","component":"./src/pbc/PbcPage.js"},{"path":"/intents/:id/workspace","component":"./src/intents/IntentWorkspace.js"},{"path":"/intents/:id","component":"./src/intents/IntentDetail.js"},{"path":"/models","component":"./src/models/ModelsPage.js"},{"path":"/module/:id","component":"./src/shell/ScopePage.js"},{"path":"/:pathMatch(.*)*","redirect":"/intents"}]</script>
532
+ <script type="application/json" id="prototype-offline-config">{"title":"i3-Composer · 企业管理后台原型"}</script>
533
+ <script src="offline.js"></script></body>
534
+ </html>