@givolt/i3-composer-agent 2.2.3 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (436) hide show
  1. package/.agents/plugins/marketplace.json +1 -1
  2. package/.claude/commands/i3-prototype.md +23 -0
  3. package/.claude/commands/i3-review.md +1 -1
  4. package/.claude/commands/i3-ship.md +1 -1
  5. package/.claude-plugin/marketplace.json +1 -1
  6. package/.claude-plugin/plugin.json +1 -1
  7. package/.codex-plugin/plugin.json +2 -2
  8. package/.gemini/commands/i3-prototype.toml +23 -0
  9. package/.gemini/commands/i3-review.toml +1 -1
  10. package/.gemini/commands/i3-ship.toml +1 -1
  11. package/README.md +15 -5
  12. package/agents/code-reviewer.md +1 -1
  13. package/agents/test-engineer.md +1 -1
  14. package/bin/native-layout.cjs +2 -0
  15. package/commands/i3-prototype.toml +23 -0
  16. package/commands/i3-review.toml +1 -1
  17. package/commands/i3-ship.toml +1 -1
  18. package/docs/agents.md +2 -2
  19. package/docs/codebuddy-setup.md +2 -2
  20. package/docs/codex-setup.md +1 -1
  21. package/docs/copilot-setup.md +4 -0
  22. package/docs/cursor-setup.md +3 -0
  23. package/docs/other-hosts.md +44 -9
  24. package/docs/workbuddy-setup.md +2 -2
  25. package/evals/README.md +2 -0
  26. package/evals/cases/i3-documentation-and-adrs.json +18 -0
  27. package/evals/cases/i3-test-driven-development.json +8 -0
  28. package/evals/cases/i3-ui-prototype.json +49 -0
  29. package/evals/fixtures/i3-documentation-and-adrs/prose-review/README.md +19 -0
  30. package/evals/fixtures/i3-documentation-and-adrs/prose-review/queue.js +32 -0
  31. package/evals/fixtures/i3-ui-prototype/business-brief.md +7 -0
  32. package/evals/plugin/tdd-fires-on-pasted-bug/graders/failing-test-first.md +7 -0
  33. package/evals/plugin/tdd-fires-on-pasted-bug/graders/skill-fired.md +5 -0
  34. package/evals/plugin/tdd-fires-on-pasted-bug/prompt.md +15 -0
  35. package/evals/plugin/tdd-stays-quiet-on-debug/graders/not-fired.md +8 -0
  36. package/evals/plugin/tdd-stays-quiet-on-debug/prompt.md +25 -0
  37. package/evals/zh-CN/cases/i3-documentation-and-adrs.json +19 -0
  38. package/evals/zh-CN/cases/i3-test-driven-development.json +4 -0
  39. package/evals/zh-CN/cases/i3-ui-prototype.json +50 -0
  40. package/hooks/SIMPLIFY-IGNORE.md +3 -2
  41. package/hooks/simplify-ignore-test.sh +93 -1
  42. package/hooks/simplify-ignore.sh +94 -11
  43. package/package.json +27 -1
  44. package/plugin.json +1 -1
  45. package/references/performance-checklist.md +4 -2
  46. package/scripts/enterprise-template-test.js +139 -0
  47. package/scripts/lib/skill-lint-test.js +113 -1
  48. package/scripts/lib/skill-lint.js +62 -8
  49. package/scripts/run-evals-test.js +207 -0
  50. package/scripts/run-evals.js +47 -9
  51. package/scripts/template-adapter-test.js +155 -0
  52. package/scripts/ui-prototype-test.js +114 -0
  53. package/scripts/validate-commands-test.js +30 -0
  54. package/scripts/validate-commands.js +6 -16
  55. package/scripts/validate-reference-links-test.js +18 -0
  56. package/scripts/validate-reference-links.js +4 -2
  57. package/scripts/validate-skills.js +26 -3
  58. package/skills/i3-documentation-and-adrs/SKILL.md +9 -0
  59. package/skills/i3-frontend-ui-engineering/SKILL.md +5 -1
  60. package/skills/i3-idea-refine/SKILL.md +20 -5
  61. package/skills/i3-incremental-implementation/SKILL.md +4 -0
  62. package/skills/i3-performance-optimization/SKILL.md +10 -10
  63. package/skills/i3-security-and-hardening/references/hardening-patterns.md +1 -1
  64. package/skills/i3-shipping-and-launch/SKILL.md +6 -0
  65. package/skills/i3-test-driven-development/SKILL.md +3 -3
  66. package/skills/i3-ui-prototype/SKILL.md +119 -0
  67. package/skills/i3-ui-prototype/assets/templates/catalog.json +147 -0
  68. package/skills/i3-ui-prototype/assets/templates/classic-admin/manifest.json +9 -0
  69. package/skills/i3-ui-prototype/assets/templates/classic-admin/preset.json +6 -0
  70. package/skills/i3-ui-prototype/assets/templates/common/app/app.mjs +89 -0
  71. package/skills/i3-ui-prototype/assets/templates/common/app/config.json +1 -0
  72. package/skills/i3-ui-prototype/assets/templates/common/app/domain.mjs +20 -0
  73. package/skills/i3-ui-prototype/assets/templates/common/app/index.html +17 -0
  74. package/skills/i3-ui-prototype/assets/templates/common/app/serve.cjs +16 -0
  75. package/skills/i3-ui-prototype/assets/templates/common/app/styles.css +670 -0
  76. package/skills/i3-ui-prototype/assets/templates/common/app/tokens.css +19 -0
  77. package/skills/i3-ui-prototype/assets/templates/common/design-system/master.md +20 -0
  78. package/skills/i3-ui-prototype/assets/templates/common/gallery.html +2 -0
  79. package/skills/i3-ui-prototype/assets/templates/common/mocks/applications.json +5 -0
  80. package/skills/i3-ui-prototype/assets/templates/common/requirements-map.json +8 -0
  81. package/skills/i3-ui-prototype/assets/templates/common/serve-gallery.cjs +16 -0
  82. package/skills/i3-ui-prototype/assets/templates/credits.md +17 -0
  83. package/skills/i3-ui-prototype/assets/templates/data-operations/manifest.json +9 -0
  84. package/skills/i3-ui-prototype/assets/templates/data-operations/preset.json +6 -0
  85. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/design-system.md +32 -0
  86. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/index.html +29 -0
  87. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/manifest.json +9 -0
  88. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/origin.json +344 -0
  89. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/preset.json +928 -0
  90. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/app.js +22 -0
  91. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets/empty.svg +1 -0
  92. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets/reference-styles.json +1 -0
  93. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets/result-403.svg +1 -0
  94. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets/result-404.svg +1 -0
  95. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/assets-manifest.json +334 -0
  96. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/baseline.json +173 -0
  97. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/conversion.md +30 -0
  98. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/credits.md +17 -0
  99. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/design-tokens.json +881 -0
  100. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/index.html +28 -0
  101. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/licenses/@qin-ui-antdv-next-pro.txt +9 -0
  102. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/licenses/ant-design-icons.txt +22 -0
  103. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/licenses/antdv-next.txt +21 -0
  104. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/package.json +12 -0
  105. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/browser-routes.json +298 -0
  106. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/coverage.json +180 -0
  107. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/integrity.json +13 -0
  108. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/keyboard.json +11 -0
  109. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/responsive.json +125 -0
  110. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/review.md +51 -0
  111. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/rules.log +150 -0
  112. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/flow-editor-html.png +0 -0
  113. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/flow-editor-original.png +0 -0
  114. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/intent-create-html.png +0 -0
  115. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/intent-create-original.png +0 -0
  116. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/models-html.png +0 -0
  117. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/models-original.png +0 -0
  118. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/workbench-html.png +0 -0
  119. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/screenshots/workbench-original.png +0 -0
  120. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/selection.json +9 -0
  121. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/qa/visual-comparison.json +342 -0
  122. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/readme.md +73 -0
  123. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/reference.md +59 -0
  124. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/routes.json +178 -0
  125. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/controls.js +99 -0
  126. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/dialogs.js +54 -0
  127. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/dom.js +264 -0
  128. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/forms.js +47 -0
  129. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/icons.js +41 -0
  130. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/layout.js +47 -0
  131. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/router.js +63 -0
  132. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/state.js +90 -0
  133. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/table.js +41 -0
  134. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/runtime/widgets.js +8 -0
  135. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentDetail.html +3 -0
  136. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentDetail.js +36 -0
  137. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentEditor.html +2 -0
  138. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentEditor.js +51 -0
  139. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentsPage.html +3 -0
  140. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/AgentsPage.js +48 -0
  141. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/CheckResults.html +2 -0
  142. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/CheckResults.js +6 -0
  143. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/ResourcePicker.html +2 -0
  144. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/ResourcePicker.js +13 -0
  145. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/data.js +24 -0
  146. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/domain.js +32 -0
  147. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/registry.js +25 -0
  148. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/agents/store.js +85 -0
  149. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentClose.html +2 -0
  150. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentClose.js +17 -0
  151. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentCreate.html +2 -0
  152. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentCreate.js +66 -0
  153. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDecisions.html +3 -0
  154. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDecisions.js +38 -0
  155. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDetail.html +2 -0
  156. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDetail.js +66 -0
  157. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDocument.html +2 -0
  158. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentDocument.js +5 -0
  159. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentHeader.html +2 -0
  160. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentHeader.js +12 -0
  161. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentHistory.html +2 -0
  162. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentHistory.js +11 -0
  163. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentList.html +2 -0
  164. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentList.js +116 -0
  165. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentReplan.html +2 -0
  166. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentReplan.js +32 -0
  167. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentRevision.html +2 -0
  168. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentRevision.js +49 -0
  169. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentSummary.html +2 -0
  170. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentSummary.js +10 -0
  171. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentWorkspace.html +2 -0
  172. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/IntentWorkspace.js +77 -0
  173. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/data.js +60 -0
  174. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/domain.js +105 -0
  175. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/intents/store.js +212 -0
  176. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/AuditPanel.html +2 -0
  177. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/AuditPanel.js +18 -0
  178. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelDetail.html +2 -0
  179. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelDetail.js +23 -0
  180. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelEditor.html +2 -0
  181. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelEditor.js +78 -0
  182. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelGrant.html +2 -0
  183. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelGrant.js +55 -0
  184. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelReferences.html +2 -0
  185. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelReferences.js +26 -0
  186. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelRelease.html +2 -0
  187. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelRelease.js +38 -0
  188. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelStatus.html +2 -0
  189. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelStatus.js +7 -0
  190. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelTable.html +2 -0
  191. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelTable.js +72 -0
  192. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelTester.html +2 -0
  193. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelTester.js +46 -0
  194. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelsPage.html +2 -0
  195. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/ModelsPage.js +52 -0
  196. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/RowActions.html +2 -0
  197. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/RowActions.js +19 -0
  198. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/UsagePanel.html +2 -0
  199. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/UsagePanel.js +30 -0
  200. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/data.js +48 -0
  201. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/domain.js +39 -0
  202. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/models/store.js +129 -0
  203. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/IncidentDetail.html +4 -0
  204. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/IncidentDetail.js +21 -0
  205. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/IntentSource.html +2 -0
  206. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/IntentSource.js +8 -0
  207. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationActionDialog.html +2 -0
  208. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationActionDialog.js +37 -0
  209. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationEntry.html +2 -0
  210. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationEntry.js +10 -0
  211. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationsPage.html +2 -0
  212. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/OperationsPage.js +37 -0
  213. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/RepairTrack.html +2 -0
  214. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/RepairTrack.js +49 -0
  215. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/RunDetail.html +4 -0
  216. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/RunDetail.js +22 -0
  217. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/SourceSummary.html +2 -0
  218. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/SourceSummary.js +9 -0
  219. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/commands.js +82 -0
  220. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/examples.js +47 -0
  221. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/model.js +61 -0
  222. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/repair.js +68 -0
  223. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/store.js +55 -0
  224. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/types.js +1 -0
  225. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/operations/workbench.js +18 -0
  226. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ManagementTable.html +3 -0
  227. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ManagementTable.js +28 -0
  228. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcCreateEntry.html +2 -0
  229. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcCreateEntry.js +18 -0
  230. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcDetail.html +2 -0
  231. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcDetail.js +31 -0
  232. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcEditor.html +2 -0
  233. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcEditor.js +27 -0
  234. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcLifecycle.html +2 -0
  235. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcLifecycle.js +16 -0
  236. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcPage.html +2 -0
  237. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcPage.js +43 -0
  238. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcPicker.html +4 -0
  239. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcPicker.js +34 -0
  240. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcProgress.html +2 -0
  241. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcProgress.js +30 -0
  242. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcWizard.html +3 -0
  243. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcWizard.js +67 -0
  244. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcWorkspace.html +2 -0
  245. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcWorkspace.js +41 -0
  246. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcsPage.html +2 -0
  247. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/PbcsPage.js +31 -0
  248. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ServiceEditor.html +2 -0
  249. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ServiceEditor.js +26 -0
  250. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ServiceList.html +2 -0
  251. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/ServiceList.js +70 -0
  252. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/data.js +8 -0
  253. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/domain.js +62 -0
  254. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/management.js +36 -0
  255. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/managementStore.js +49 -0
  256. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/pbc/store.js +132 -0
  257. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/AdminList.html +2 -0
  258. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/AdminList.js +38 -0
  259. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/EffectiveGrants.html +2 -0
  260. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/EffectiveGrants.js +11 -0
  261. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/GrantEditor.html +2 -0
  262. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/GrantEditor.js +45 -0
  263. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/MemberEditor.html +2 -0
  264. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/MemberEditor.js +54 -0
  265. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/MembersPage.html +3 -0
  266. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/MembersPage.js +27 -0
  267. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RecordsPage.html +2 -0
  268. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RecordsPage.js +12 -0
  269. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RoleEditor.html +2 -0
  270. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RoleEditor.js +45 -0
  271. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RolesPage.html +3 -0
  272. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/RolesPage.js +38 -0
  273. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/domain.js +61 -0
  274. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/state.js +51 -0
  275. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/permissions/store.js +116 -0
  276. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseActionDialog.html +2 -0
  277. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseActionDialog.js +45 -0
  278. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseDetail.html +4 -0
  279. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseDetail.js +30 -0
  280. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseEditor.html +2 -0
  281. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseEditor.js +67 -0
  282. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseExecution.html +2 -0
  283. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleaseExecution.js +5 -0
  284. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleasesPage.html +4 -0
  285. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/ReleasesPage.js +60 -0
  286. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/commands.js +157 -0
  287. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/model.js +136 -0
  288. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/releases/store.js +76 -0
  289. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewDetail.html +3 -0
  290. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewDetail.js +26 -0
  291. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewEvidence.html +2 -0
  292. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewEvidence.js +14 -0
  293. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewProcess.html +2 -0
  294. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewProcess.js +113 -0
  295. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewsPage.html +3 -0
  296. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/ReviewsPage.js +62 -0
  297. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/commands.js +97 -0
  298. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/model.js +147 -0
  299. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/reviews/store.js +13 -0
  300. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ColumnSettings.html +2 -0
  301. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ColumnSettings.js +9 -0
  302. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListBatchBar.html +2 -0
  303. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListBatchBar.js +8 -0
  304. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListDeleteDialog.html +2 -0
  305. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListDeleteDialog.js +37 -0
  306. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListMore.html +2 -0
  307. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/ListMore.js +8 -0
  308. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/RecordMetadata.html +2 -0
  309. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/RecordMetadata.js +17 -0
  310. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/columns.js +32 -0
  311. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/deliveryGuide.js +49 -0
  312. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/deliveryView.js +12 -0
  313. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/listBatch.js +15 -0
  314. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/listSelection.js +37 -0
  315. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/policy.js +68 -0
  316. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shared/session.js +44 -0
  317. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ConfirmationDialog.html +2 -0
  318. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ConfirmationDialog.js +25 -0
  319. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ConsoleShell.html +2 -0
  320. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ConsoleShell.js +53 -0
  321. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/PrototypeGuide.html +10 -0
  322. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/PrototypeGuide.js +30 -0
  323. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ScopePage.html +2 -0
  324. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/ScopePage.js +10 -0
  325. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/SessionDialog.html +2 -0
  326. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/SessionDialog.js +9 -0
  327. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/confirmation.js +3 -0
  328. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/shell/navigation.js +19 -0
  329. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecDocument.html +2 -0
  330. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecDocument.js +8 -0
  331. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecEdit.html +2 -0
  332. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecEdit.js +32 -0
  333. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecHeader.html +2 -0
  334. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecHeader.js +15 -0
  335. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecHistory.html +2 -0
  336. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecHistory.js +11 -0
  337. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecReview.html +2 -0
  338. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecReview.js +57 -0
  339. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecWorkspace.html +2 -0
  340. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/SpecWorkspace.js +37 -0
  341. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/data.js +20 -0
  342. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/domain.js +55 -0
  343. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/specs/store.js +151 -0
  344. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/ArtifactDetail.html +3 -0
  345. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/ArtifactDetail.js +18 -0
  346. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskCreate.html +2 -0
  347. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskCreate.js +40 -0
  348. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskDetail.html +2 -0
  349. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskDetail.js +51 -0
  350. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskLaunch.html +2 -0
  351. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TaskLaunch.js +9 -0
  352. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TasksPage.html +5 -0
  353. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/TasksPage.js +48 -0
  354. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/domain.js +204 -0
  355. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/exampleSource.js +22 -0
  356. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/registry.js +135 -0
  357. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/tasks/store.js +137 -0
  358. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workbench/WorkbenchPage.html +3 -0
  359. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workbench/WorkbenchPage.js +36 -0
  360. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workbench/model.js +56 -0
  361. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workbench/store.js +15 -0
  362. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowCanvas.html +2 -0
  363. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowCanvas.js +27 -0
  364. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowDetail.html +4 -0
  365. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowDetail.js +31 -0
  366. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowEditor.html +2 -0
  367. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/FlowEditor.js +68 -0
  368. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/WorkflowsPage.html +5 -0
  369. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/WorkflowsPage.js +55 -0
  370. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/data.js +16 -0
  371. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/domain.js +83 -0
  372. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/registry.js +18 -0
  373. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/src/workflows/store.js +61 -0
  374. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/admin.css +60 -0
  375. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/agents.css +46 -0
  376. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/antdv.css +295 -0
  377. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/app.css +102 -0
  378. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/delivery.css +4 -0
  379. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/intents.css +37 -0
  380. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/native.css +22 -0
  381. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/operations.css +2 -0
  382. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/pbc.css +3 -0
  383. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/permissions.css +22 -0
  384. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/pro.css +1 -0
  385. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/releases.css +4 -0
  386. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/reset.css +246 -0
  387. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/reviews.css +8 -0
  388. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/tasks.css +6 -0
  389. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/tokens.css +15 -0
  390. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/workbench.css +61 -0
  391. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/styles/workflows.css +1 -0
  392. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/admin-rules.test.js +96 -0
  393. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/agents.test.js +14 -0
  394. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/intent-state.test.js +37 -0
  395. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/list-batch.test.js +44 -0
  396. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/operation-fixtures.js +19 -0
  397. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/operation-repair.test.js +14 -0
  398. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/operations.test.js +25 -0
  399. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/pbc-management.test.js +17 -0
  400. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/pbc-state.test.js +24 -0
  401. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/permission-config.test.js +23 -0
  402. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/permissions.test.js +24 -0
  403. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/releases.test.js +50 -0
  404. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/reviews.test.js +36 -0
  405. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/runtime-forms-router.test.js +28 -0
  406. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/runtime-state.test.js +42 -0
  407. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/runtime-stores.test.js +16 -0
  408. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/spec-state.test.js +11 -0
  409. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/tasks.test.js +27 -0
  410. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/workbench.test.js +34 -0
  411. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tests/workflows.test.js +16 -0
  412. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tools/convert.mjs +168 -0
  413. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tools/serve.mjs +7 -0
  414. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tools/styles.mjs +11 -0
  415. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/reference/tools/verify.mjs +24 -0
  416. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/serve.cjs +16 -0
  417. package/skills/i3-ui-prototype/assets/templates/enterprise-admin/usability.css +44 -0
  418. package/skills/i3-ui-prototype/assets/templates/gallery/index.html +40 -0
  419. package/skills/i3-ui-prototype/assets/templates/modern-workspace/manifest.json +9 -0
  420. package/skills/i3-ui-prototype/assets/templates/modern-workspace/preset.json +6 -0
  421. package/skills/i3-ui-prototype/assets/templates/serve-gallery.cjs +16 -0
  422. package/skills/i3-ui-prototype/references/artifact-contract.md +41 -0
  423. package/skills/i3-ui-prototype/references/enterprise-admin.md +38 -0
  424. package/skills/i3-ui-prototype/references/expert-adapter.md +42 -0
  425. package/skills/i3-ui-prototype/references/template-adapters.md +57 -0
  426. package/skills/i3-ui-prototype/references/workflow-contract.md +19 -0
  427. package/skills/i3-ui-prototype/scripts/adapters/easel-html.cjs +30 -0
  428. package/skills/i3-ui-prototype/scripts/adapters/legacy-html.cjs +28 -0
  429. package/skills/i3-ui-prototype/scripts/check-design-provider.cjs +9 -0
  430. package/skills/i3-ui-prototype/scripts/check-prototype.cjs +14 -0
  431. package/skills/i3-ui-prototype/scripts/enterprise-template.cjs +88 -0
  432. package/skills/i3-ui-prototype/scripts/init-prototype.cjs +8 -0
  433. package/skills/i3-ui-prototype/scripts/manage-baseline.cjs +11 -0
  434. package/skills/i3-ui-prototype/scripts/prototype-lib.cjs +255 -0
  435. package/skills/i3-ui-prototype/scripts/template-adapters.cjs +89 -0
  436. package/skills/i3-using-agent-skills/SKILL.md +5 -0
@@ -0,0 +1,49 @@
1
+ import { useDeliveryView } from "../shared/deliveryView.js";
2
+ import { computed } from '../../runtime/state.js';
3
+ import { defineStore } from "../../runtime/state.js";
4
+ import { usePbcs } from "./store.js";
5
+ import { useSession } from "../shared/session.js";
6
+ import { useSpecs } from "../specs/store.js";
7
+ import { useIntents } from "../intents/store.js";
8
+ import { taskRecords } from "../tasks/registry.js";
9
+ import { agentRecords } from "../agents/registry.js";
10
+ import { flowRecords, flowUses } from "../workflows/registry.js";
11
+ import { assertBatch } from "../shared/listBatch.js";
12
+ import { stateOf, assertPbcRemovable, assertServiceRemovable, revisePbc, reviseService, requireReason } from "./management.js";
13
+ export const usePbcManagement = defineStore('pbc-management', () => {
14
+ const pbcs = usePbcs(), session = useSession(), specs = useSpecs(), intents = useIntents();
15
+ const records = computed(() => pbcs.items), item = (id) => records.value.find(p => p.id === id);
16
+ const { candidates } = useDeliveryView();
17
+ const newSources = computed(() => candidates.value.filter(s => s.guide.create));
18
+ function references(p) {
19
+ return [
20
+ ...pbcs.jobs.filter(j => j.pbc.id === p.id).map(() => '需求归属'),
21
+ ...taskRecords.value.filter(t => !t.isDeleted && t.binding.pbcId === p.id).map(() => '交付任务'),
22
+ ...agentRecords.value.filter(a => !a.isDeleted && a.pbcId === p.id).map(() => 'Agent'),
23
+ ...flowRecords.value.filter(f => !f.isDeleted && f.pbcId === p.id).map(() => '流程模板'),
24
+ ...flowUses.value.filter(f => f.pbcId === p.id).map(() => '模板交接记录'),
25
+ ];
26
+ }
27
+ function current(id, action, version, fresh = false) { if (fresh)
28
+ pbcs.refreshLatest(); const p = item(id); if (!p)
29
+ throw Error('PBC 不存在或无权访问。'); session.require('pbc:view', p.tenantId, p.id); session.require(action, p.tenantId, p.id); if (version !== undefined && version !== p.recordVersion)
30
+ throw Error('PBC 记录已更新,请重新打开核对。'); return p; }
31
+ function event(p, action, reason, before, after) { return { id: crypto.randomUUID(), pbcId: p.id, tenantId: p.tenantId, actor: session.actor.name, at: new Date().toISOString(), action, reason, before: JSON.stringify(before, null, 2), after: JSON.stringify(after, null, 2) }; }
32
+ function persist(next, e) { session.writeCheck(); pbcs.saveManagement(pbcs.catalog.map(p => p.id === next.id ? next : p), [e]); return next; }
33
+ function save(id, version, input, reason) { requireReason(reason); const p = current(id, 'pbc:edit', version, true); if (pbcs.catalog.some(q => !q.isDeleted && q.id !== id && q.tenantId === p.tenantId && q.name === input.name.trim()))
34
+ throw Error('同一租户下 PBC 名称不能重复。'); const n = revisePbc(p, input, session.actor, new Date().toISOString()); const fields = (x) => ({ name: x.name, ebc: x.ebc, owner: x.owner, description: x.description || '', recordVersion: x.recordVersion }); return persist(n, event(p, '修改基础资料', reason, fields(p), fields(n))); }
35
+ function archive(id, version, reason) { requireReason(reason); const p = current(id, 'pbc:archive', version, true), active = stateOf(p) === 'active'; if (active && (taskRecords.value.some(t => !t.isDeleted && t.binding.pbcId === id) || pbcs.jobs.some(j => j.pbc.id === id && j.status !== 'done') || agentRecords.value.some(a => !a.isDeleted && a.pbcId === id && a.enabled) || flowRecords.value.some(f => !f.isDeleted && f.pbcId === id && f.enabled)))
36
+ throw Error('仍有交付任务、在途创建或启用资源,请处理后再归档。'); const n = { ...p, state: active ? 'archived' : 'active', recordVersion: p.recordVersion + 1, updatedAt: new Date().toISOString(), updatedBy: session.actor.name }; return persist(n, event(p, active ? '归档 PBC' : '恢复 PBC', reason, { state: stateOf(p), version: p.recordVersion }, { state: n.state, version: n.recordVersion })); }
37
+ function checkRemove(t) { const p = current(t.id, 'pbc:delete', t.recordVersion); assertPbcRemovable(p, references(p)); }
38
+ function removeMany(targets) { pbcs.refreshLatest(); const selected = assertBatch(pbcs.catalog, targets, p => { session.require('pbc:view', p.tenantId, p.id); session.require('pbc:delete', p.tenantId, p.id); assertPbcRemovable(p, references(p)); }), ids = new Set(selected.map(p => p.id)), at = new Date().toISOString(); session.writeCheck(); pbcs.saveManagement(pbcs.catalog.map(p => ids.has(p.id) ? { ...p, isDeleted: true, recordVersion: p.recordVersion + 1, updatedBy: session.actor.name, updatedAt: at } : p), selected.map(p => event(p, '删除 PBC', '已核对归档状态及无工程/引用;批量 ' + ids.size + ' 项', { deleted: false }, { deleted: true }))); }
39
+ function serviceSave(id, version, serviceId, input, reason) { requireReason(reason); const p = current(id, 'pbc:service', version, true), old = serviceId ? p.services.find(s => s.id === serviceId && !s.isDeleted) : undefined; if (serviceId && !old)
40
+ throw Error('服务记录已不存在。'); if (input.sourceIntentId && !pbcs.jobs.some(j => j.intentId === input.sourceIntentId && j.pbc.id === id && j.status === 'done' && session.can('spec:view', j.tenantId)))
41
+ throw Error('需求依据不可访问或不属于当前 PBC。'); const s = reviseService(p, old, input, session.actor, new Date().toISOString()), n = { ...p, services: old ? p.services.map(x => x.id === s.id ? s : x) : [s, ...p.services], recordVersion: p.recordVersion + 1, updatedBy: session.actor.name, updatedAt: new Date().toISOString() }; return persist(n, event(p, old ? '修改服务资料' : '新增服务方案', reason, old || {}, s)); }
42
+ function serviceCheck(id, t) { const p = current(id, 'pbc:service'), s = p.services.find(s => !s.isDeleted && s.id === t.id); if (!s)
43
+ throw Error('服务已不存在。'); if (s.recordVersion !== t.recordVersion)
44
+ throw Error('服务已更新,请重新核对。'); assertServiceRemovable(p, s); }
45
+ function serviceRemove(id, version, targets) { const p = current(id, 'pbc:service', version, true); const selected = assertBatch(p.services, targets, s => assertServiceRemovable(p, s)); const ids = new Set(selected.map(s => s.id)), at = new Date().toISOString(), n = { ...p, services: p.services.map(s => ids.has(s.id) ? { ...s, isDeleted: true, recordVersion: s.recordVersion + 1, updatedAt: at, updatedBy: session.actor.name } : s), recordVersion: p.recordVersion + 1, updatedAt: at, updatedBy: session.actor.name }; session.writeCheck(); pbcs.saveManagement(pbcs.catalog.map(x => x.id === id ? n : x), selected.map(s => event(p, '删除服务方案', '已核对未登记工程;批量 ' + ids.size + ' 项', s, { id: s.id, isDeleted: true }))); }
46
+ const jobsFor = (id) => pbcs.jobs.filter(j => j.pbc.id === id && item(id) && session.can('intent:view', j.tenantId) && session.can('spec:view', j.tenantId));
47
+ const eventsFor = (id) => { const p = item(id); return p && session.can('pbc:audit', p.tenantId, id) ? pbcs.managementAudit.filter(e => e.pbcId === id && e.tenantId === p.tenantId) : []; };
48
+ return { records, item, newSources, save, archive, checkRemove, removeMany, serviceSave, serviceCheck, serviceRemove, jobsFor, eventsFor };
49
+ });
@@ -0,0 +1,132 @@
1
+ import { computed, ref } from '../../runtime/state.js';
2
+ import { seedTaskJobs } from "../tasks/exampleSource.js";
3
+ import { defineStore } from "../../runtime/state.js";
4
+ import { useSession } from "../shared/session.js";
5
+ import { useIntents } from "../intents/store.js";
6
+ import { useSpecs } from "../specs/store.js";
7
+ import { clone } from "../specs/domain.js";
8
+ import { seedPbcs } from "./data.js";
9
+ import { activeStep, makeJob, newDraft, queryReceipt, validateDraft, assertBinding } from "./domain.js";
10
+ import { assertActive } from "./management.js";
11
+ const key = 'i3-prototype-antdv-pbc-v010', now = () => new Date().toISOString();
12
+ export const usePbcs = defineStore('pbcs', () => {
13
+ const session = useSession(), intents = useIntents(), specs = useSpecs(), catalog = ref(seedPbcs()), drafts = ref([]), jobs = ref(seedTaskJobs()), notice = ref(''), mode = ref('success'), scene = ref('normal');
14
+ const managementAudit = ref([]);
15
+ let epoch = 0;
16
+ try {
17
+ const saved = JSON.parse(localStorage.getItem(key) || 'null');
18
+ if (saved) {
19
+ catalog.value = saved.catalog;
20
+ drafts.value = saved.drafts;
21
+ managementAudit.value = saved.audit || [];
22
+ jobs.value = saved.jobs.map((j) => ({ ...j, status: j.status === 'running' ? 'unknown' : j.status, steps: j.steps.map(s => ({ ...s, state: s.state === 'running' ? 'unknown' : s.state })) }));
23
+ }
24
+ }
25
+ catch {
26
+ notice.value = '本地归属数据无法读取,已加载初始目录。';
27
+ }
28
+ const items = computed(() => catalog.value.filter(p => !p.isDeleted && session.readable('pbc:view', p.tenantId, p.id)));
29
+ const job = (id) => jobs.value.find(j => j.intentId === id && session.readable('pbc:view', j.tenantId, j.pbc.id));
30
+ function persist(nextCatalog = catalog.value, nextDrafts = drafts.value, nextJobs = jobs.value, nextAudit = managementAudit.value) { try {
31
+ localStorage.setItem(key, JSON.stringify({ catalog: nextCatalog, drafts: nextDrafts, jobs: nextJobs, audit: nextAudit }));
32
+ }
33
+ catch {
34
+ throw Error('浏览器保存失败,操作未提交,请重试。');
35
+ } catalog.value = nextCatalog; drafts.value = nextDrafts; jobs.value = nextJobs; managementAudit.value = nextAudit; }
36
+ function update(j, text) { const next = { ...clone(j), recordVersion: j.recordVersion + 1, updatedAt: now(), updatedBy: session.actor.name, events: [...j.events, { at: now(), actor: session.actor.name, text }] }; persist(catalog.value, drafts.value, jobs.value.map(old => old.id === j.id ? next : old)); return next; }
37
+ function draft(id) { const i = intents.get(id); if (!i)
38
+ throw Error('没有来源意图权限。'); session.require('pbc:create', i.tenantId); return clone(drafts.value.find(d => d.intentId === id) || newDraft(i, session.actor, now())); }
39
+ function saveDraft(d) { session.require('pbc:create', d.tenantId); if (jobs.value.some(j => j.intentId === d.intentId))
40
+ throw Error('该意图已提交归属;已提交内容只读。'); session.writeCheck(); const old = drafts.value.find(v => v.id === d.id); if (old && old.recordVersion !== d.recordVersion)
41
+ throw Error('草稿已更新,请重新打开核对。'); const next = { ...clone(d), recordVersion: d.recordVersion + 1, updatedAt: now(), updatedBy: session.actor.name }; persist(catalog.value, [next, ...drafts.value.filter(v => v.id !== d.id)]); return clone(next); }
42
+ function sources(id, binding) { const i = intents.get(id), s = specs.get(id); if (!i || !s)
43
+ throw Error('意图或规格不可访问。'); if (jobs.value.some(j => j.intentId === id))
44
+ throw Error('此意图已有归属请求,请查看原请求结果,避免重复创建。'); assertBinding(i, s, binding); return { i, s }; }
45
+ async function start(id, target, d, binding) { const { i, s } = sources(id, binding); session.require(d ? 'pbc:create' : 'pbc:link', i.tenantId, d ? undefined : target.id); if (d)
46
+ validateDraft(d, catalog.value); session.writeCheck(); const j = makeJob(i, s, session.actor, target, d); persist(catalog.value, drafts.value, [j, ...jobs.value]); await run(j.id); }
47
+ async function link(id, pbcId, binding) { const p = items.value.find(p => p.id === pbcId); if (!p)
48
+ throw Error('PBC 不可访问。'); assertActive(p); await start(id, p, undefined, binding); }
49
+ async function create(id, d, binding) { const p = { ...clone(d), id: 'pbc-' + d.slug, state: 'active', provisioned: true, resourceKey: d.name, services: d.services.filter(s => !s.isDeleted).map(s => ({ ...clone(s), id: d.prefix + '-' + s.name, registered: true })) }; await start(id, p, d, binding); }
50
+ const current = (id) => jobs.value.find(j => j.id === id);
51
+ function complete(j) { const list = j.kind === 'create' && !catalog.value.some(p => p.id === j.pbc.id) ? [j.pbc, ...catalog.value] : catalog.value; persist(list, drafts.value, jobs.value.map(x => x.id === j.id ? { ...j, status: 'done' } : x)); }
52
+ async function run(id) {
53
+ let j = current(id);
54
+ if (j.status === 'done' || j.status === 'unknown')
55
+ return;
56
+ const permission = j.kind === 'create' ? 'pbc:create' : 'pbc:link';
57
+ session.require(permission, j.tenantId, j.kind === 'link' ? j.pbc.id : undefined);
58
+ if (j.steps.some(s => s.state === 'running'))
59
+ throw Error('该请求正在执行。');
60
+ const runEpoch = epoch, result = mode.value, actorId = session.actor.id;
61
+ mode.value = 'success';
62
+ for (let index = activeStep(j); index < j.steps.length && index >= 0; index++) {
63
+ j = current(id);
64
+ const next = clone(j);
65
+ next.status = 'running';
66
+ next.steps[index].state = 'running';
67
+ next.steps[index].detail = '正在处理(模拟)';
68
+ update(next, '开始:' + next.steps[index].name);
69
+ await new Promise(resolve => setTimeout(resolve, 450));
70
+ if (runEpoch !== epoch)
71
+ return;
72
+ j = clone(current(id));
73
+ let allowed = session.actor.id === actorId && session.can(permission, j.tenantId, j.kind === 'link' ? j.pbc.id : undefined);
74
+ const step = j.steps[index];
75
+ if (!allowed) {
76
+ step.state = 'failed';
77
+ step.detail = '身份、权限或登录状态变化;本步尚未执行。';
78
+ j.status = 'paused';
79
+ update(j, '暂停执行:' + step.detail);
80
+ return;
81
+ }
82
+ if (result === 'failure' && index === (j.kind === 'create' ? 2 : 0)) {
83
+ step.state = 'failed';
84
+ step.detail = '模拟服务不可用,已完成步骤保留。';
85
+ j.status = 'failed';
86
+ update(j, '步骤失败:' + step.name);
87
+ return;
88
+ }
89
+ step.receipt = j.id + ':' + index;
90
+ if (result === 'unknown' && index === 0) {
91
+ step.state = 'unknown';
92
+ step.detail = '响应未收到,先核实原操作。';
93
+ j.status = 'unknown';
94
+ update(j, '步骤结果待核实:' + step.name);
95
+ return;
96
+ }
97
+ step.state = 'done';
98
+ step.detail = '已完成(模拟);操作回执 ' + step.receipt;
99
+ j = update(j, '完成:' + step.name);
100
+ }
101
+ complete(current(id));
102
+ }
103
+ async function resume(id) { const j = job(id); if (!j)
104
+ throw Error('没有可访问的归属请求。'); await run(j.id); }
105
+ function reconcile(id) { const j = job(id); if (!j)
106
+ throw Error('没有可访问的归属请求。'); session.require('pbc:view', j.tenantId, j.pbc.id); const next = update(queryReceipt(j), '查询原操作结果'); if (next.status === 'done')
107
+ complete(next); }
108
+ function reset() { epoch++; localStorage.removeItem(key); catalog.value = seedPbcs(); drafts.value = []; jobs.value = seedTaskJobs(); notice.value = ''; mode.value = 'success'; scene.value = 'normal'; managementAudit.value = []; }
109
+ function refreshLatest() { try {
110
+ const raw = JSON.parse(localStorage.getItem(key) || 'null');
111
+ if (raw) {
112
+ catalog.value = raw.catalog;
113
+ drafts.value = raw.drafts;
114
+ jobs.value = raw.jobs;
115
+ managementAudit.value = raw.audit || [];
116
+ }
117
+ }
118
+ catch {
119
+ throw Error('本地数据无法读取,请保留输入并重新加载。');
120
+ } }
121
+ function saveManagement(next, events) { persist(next, drafts.value, jobs.value, [...events, ...managementAudit.value]); }
122
+ if (typeof window !== 'undefined')
123
+ window.addEventListener('storage', e => { if (e.key === key && e.newValue) {
124
+ try {
125
+ refreshLatest();
126
+ }
127
+ catch {
128
+ notice.value = '本地数据刷新失败,请重新加载。';
129
+ }
130
+ } });
131
+ return { catalog, jobs, managementAudit, refreshLatest, saveManagement, items, notice, mode, scene, job, draft, saveDraft, link, create, resume, reconcile, reset };
132
+ });
@@ -0,0 +1,2 @@
1
+ <!-- 来源:src/permissions/AdminList.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
2
+ <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>
@@ -0,0 +1,38 @@
1
+ import { computed, ref, watch } from '../../runtime/state.js';
2
+ import { h } from '../../runtime/dom.js';
3
+ import { Alert, Button, Input, Select, Space, Tag } from "../../runtime/widgets.js";
4
+ import { ProTable, useTable } from "../../runtime/widgets.js";
5
+ import { useSession } from "../shared/session.js";
6
+ import { tenantLabel, tenants, formatDate } from "../shared/policy.js";
7
+ import { useColumns } from "../shared/columns.js";
8
+ import { useListSelection } from "../shared/listSelection.js";
9
+ import ColumnSettings from "../shared/ColumnSettings.js";
10
+ import ListMore from "../shared/ListMore.js";
11
+ import ListBatchBar from "../shared/ListBatchBar.js";
12
+ import { useAuthority } from "./store.js";
13
+ import { createComponent } from '../../runtime/dom.js';
14
+ export default createComponent({ name: 'AdminList', propKeys: ["rows", "kind", "title", "description", "initialQuery"], template: new URL('./AdminList.html', import.meta.url).href, setup(__props, __emit) {
15
+ const props = __props;
16
+ const emit = __emit;
17
+ const session = useSession(), store = useAuthority(), query = ref(props.initialQuery || ''), scope = ref('all'), status = ref('all'), desc = ref(true), refreshing = ref(false);
18
+ const readonly = computed(() => props.kind === 'records'), createAction = computed(() => props.kind === 'roles' ? 'permission:roles' : 'permission:members');
19
+ const canDelete = computed(() => !readonly.value && session.can('permission:delete') && (props.kind !== 'members' || session.can('permission:members')));
20
+ const scopeOptions = computed(() => [{ value: 'all', label: '全部可见范围' }, ...[{ value: 'platform', label: '平台统一管理' }, ...tenants].filter(t => session.can(readonly.value ? 'permission:audit' : 'permission:view', t.value))]);
21
+ const prefs = useColumns('permission-' + props.kind, [{ key: 'name', label: props.kind === 'roles' ? '角色名称' : props.kind === 'members' ? '成员' : '操作对象', locked: true }, { key: 'code', label: props.kind === 'roles' ? '角色编码' : props.kind === 'members' ? '已关联角色' : '操作类型', defaultVisible: true }, { key: 'tenantId', label: '所属范围', defaultVisible: true }, { key: 'status', label: '状态', defaultVisible: true }, { key: 'extra', label: readonly.value ? '变更原因' : '用途 / 说明', defaultVisible: false }, { key: 'createdBy', label: readonly.value ? '操作者' : '创建人', defaultVisible: true }, { key: 'createdAt', label: readonly.value ? '操作时间' : '创建时间', defaultVisible: true }, { key: 'createdDept', label: '创建部门' }, { key: 'updatedBy', label: '修改人' }, { key: 'updatedAt', label: '修改时间' }, { key: 'actions', label: '操作', locked: true }]);
22
+ function actionButtons(r) {
23
+ const disabled = r.protected || !session.can(createAction.value, r.tenantId);
24
+ const items = [{ key: 'detail', label: readonly.value ? '查看变更详情' : '查看详情' }, ...(!readonly.value ? [{ key: 'edit', label: props.kind === 'roles' ? '编辑角色' : '修改成员授权', disabled }, ...(props.kind === 'roles' ? [{ key: 'toggle', label: r.status === '启用' ? '停用角色' : '启用角色', disabled }] : []), { key: 'history', label: '授权记录', disabled: !session.can('permission:audit', r.tenantId) }, { key: 'delete', label: props.kind === 'members' ? '移除业务关联' : '删除角色', danger: true, disabled: !canDelete.value || !session.can('permission:delete', r.tenantId) }] : [])];
25
+ return h('div', { class: 'row-actions' }, [h(Button, { type: 'link', disabled: readonly.value ? false : props.kind === 'roles' ? (!!r.protected || !session.can('permission:grant', r.tenantId)) : disabled, onClick: () => emit('action', readonly.value ? 'detail' : props.kind === 'roles' ? 'grant' : 'edit', r) }, () => readonly.value ? '详情' : props.kind === 'roles' ? '配置权限' : '配置角色'), h(ListMore, { name: r.name, items, onAction: (key) => emit('action', key, r) })]);
26
+ }
27
+ const table = useTable({ pageParam: { current: 1, pageSize: 5, total: 0 }, columns: prefs.choices.map(c => ({ key: c.key, title: c.label, dataIndex: c.key, fixed: c.key === 'actions' ? 'right' : undefined, width: c.key === 'name' ? 180 : c.key === 'code' ? 240 : c.key === 'actions' ? 190 : 160, ...(c.key === 'actions' ? { render: (_, r) => actionButtons(r) } : c.key === 'tenantId' ? { render: (v) => tenantLabel(String(v)) } : c.key.endsWith('At') ? { render: (v) => formatDate(String(v)) } : c.key === 'status' ? { render: (v) => h(Tag, { color: v === '停用' ? 'default' : 'green' }, () => String(v)) } : {}) })) });
28
+ const columns = new Map(table.columns.value.map(c => [c.key, c]));
29
+ watch(prefs.keys, keys => table.columns.value = keys.map(k => columns.get(k)).filter(Boolean), { immediate: true });
30
+ const filtered = computed(() => store.scene === 'empty' ? [] : props.rows.filter(r => (r.name + r.code + r.extra).toLowerCase().includes(query.value.trim().toLowerCase()) && (scope.value === 'all' || r.tenantId === scope.value) && (status.value === 'all' || r.status === status.value)).sort((a, b) => desc.value ? b.createdAt.localeCompare(a.createdAt) : a.createdAt.localeCompare(b.createdAt)));
31
+ watch([filtered, () => table.pageParam.current, () => table.pageParam.pageSize], () => { const size = table.pageParam.pageSize || 5, max = Math.max(1, Math.ceil(filtered.value.length / size)); if ((table.pageParam.current || 1) > max)
32
+ table.setPageParam({ current: max }); const start = ((table.pageParam.current || 1) - 1) * size; table.dataSource.value = filtered.value.slice(start, start + size); table.setPageParam({ total: filtered.value.length }); }, { immediate: true });
33
+ const selection = useListSelection(table.dataSource, computed(() => JSON.stringify([session.key, query.value, scope.value, status.value, desc.value, table.pageParam.current, table.pageParam.pageSize])), canDelete, r => r.name);
34
+ watch([query, scope, status], () => table.setPageParam({ current: 1 }));
35
+ async function refresh() { selection.clear(); refreshing.value = true; await new Promise(r => setTimeout(r, 250)); store.scene = 'normal'; refreshing.value = false; }
36
+ function reset() { query.value = ''; scope.value = 'all'; status.value = 'all'; }
37
+ return { computed, ref, watch, h, Alert, Button, Input, Select, Space, Tag, ProTable, useTable, useSession, tenantLabel, tenants, formatDate, useColumns, useListSelection, ColumnSettings, ListMore, ListBatchBar, useAuthority, props, emit, session, store, query, scope, status, desc, refreshing, readonly, createAction, canDelete, scopeOptions, prefs, actionButtons, table, columns, filtered, selection, refresh, reset };
38
+ } });
@@ -0,0 +1,2 @@
1
+ <!-- 来源:src/permissions/EffectiveGrants.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
2
+ <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>
@@ -0,0 +1,11 @@
1
+ import { Empty, Tag } from "../../runtime/widgets.js";
2
+ import { usePbcs } from "../pbc/store.js";
3
+ import { actionGroups, tenantLabel } from "../shared/policy.js";
4
+ import { createComponent } from '../../runtime/dom.js';
5
+ export default createComponent({ name: 'EffectiveGrants', propKeys: ["grants"], template: new URL('./EffectiveGrants.html', import.meta.url).href, setup(__props, __emit) {
6
+ __props;
7
+ const label = (code) => actionGroups.flatMap(g => g.items).find(i => i.value === code)?.label || code;
8
+ const directory = usePbcs();
9
+ const pbc = (id) => id === '*' ? '全部 PBC(含新建)' : directory.items.find(p => p.id === id)?.name || id;
10
+ return { Empty, Tag, usePbcs, actionGroups, tenantLabel, label, directory, pbc };
11
+ } });
@@ -0,0 +1,2 @@
1
+ <!-- 来源:src/permissions/GrantEditor.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
2
+ <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>
@@ -0,0 +1,45 @@
1
+ import { computed, ref } from '../../runtime/state.js';
2
+ import { Alert, Button, Drawer, Input, Select, Space, Tabs, Tree, message } from "../../runtime/widgets.js";
3
+ import { ProForm, useForm } from "../../runtime/widgets.js";
4
+ import { actionGroups, allActions, tenants } from "../shared/policy.js";
5
+ import { useSession } from "../shared/session.js";
6
+ import { clone } from "./domain.js";
7
+ import { usePbcs } from "../pbc/store.js";
8
+ import { useAuthority } from "./store.js";
9
+ import { confirmAction } from "../shell/confirmation.js";
10
+ import { createComponent } from '../../runtime/dom.js';
11
+ export default createComponent({ name: 'GrantEditor', propKeys: ["role"], template: new URL('./GrantEditor.html', import.meta.url).href, setup(__props, __emit) {
12
+ const props = __props, emit = __emit, session = useSession(), store = useAuthority(), value = ref(clone(props.role)), tab = ref('features'), error = ref(''), busy = ref(false);
13
+ const form = useForm({ reason: '' }, [{ path: 'reason', label: '变更原因', component: 'textarea', span: 24, rules: [{ required: true, whitespace: true, message: '请填写变更原因' }] }]);
14
+ const allowed = computed(() => !props.role.protected && session.can('permission:grant', props.role.tenantId));
15
+ const affected = computed(() => store.members.filter(m => m.roleIds.includes(props.role.id)).map(m => store.actorName(m.actorId)));
16
+ const scopeOptions = computed(() => props.role.tenantId === 'platform' ? [{ value: '*', label: '全部范围(含后续新增)' }, { value: 'platform', label: '平台统一管理' }, ...tenants] : tenants.filter(t => t.value === props.role.tenantId));
17
+ const pbcDirectory = usePbcs();
18
+ const pbcOptions = computed(() => [{ value: '*', label: '授权租户内全部 PBC(含新建)' }, ...pbcDirectory.items.filter(p => props.role.tenantId === 'platform' || p.tenantId === props.role.tenantId).map(p => ({ value: p.id, label: p.name })), ...[...new Set(value.value.grants.flatMap(g => g.pbcIds || []))].filter(id => id !== '*' && !pbcDirectory.items.some(p => p.id === id)).map(id => ({ value: id, label: id + '(保留的范围引用)' }))]);
19
+ const tree = computed(() => actionGroups.map((g, i) => ({ key: 'group-' + i, title: g.name, children: g.items.map(a => ({ key: a.value, title: a.label, disabled: !allowed.value || (a.value.startsWith('permission:') && !session.can('permission:delegate', props.role.tenantId)) })) })));
20
+ function update(index, keys) { const list = Array.isArray(keys) ? keys : keys.checked; value.value.grants[index].actions = list.filter((v) => allActions.includes(v)); if (value.value.grants[index].actions.some(a => a.startsWith('release:')) && !value.value.grants[index].environmentIds)
21
+ value.value.grants[index].environmentIds = ['*']; }
22
+ function add() { value.value.grants.push({ id: crypto.randomUUID(), name: '授权组 ' + (value.value.grants.length + 1), actions: [], tenantIds: [props.role.tenantId], pbcIds: ['*'], environmentIds: ['*'] }); }
23
+ function close() { if (busy.value)
24
+ return; if (JSON.stringify(value.value) !== JSON.stringify(props.role) || form.formData.reason)
25
+ confirmAction({ title: '放弃未保存的授权?', content: '当前角色权限不会改变。', okText: '放弃修改', cancelText: '继续编辑', onOk: () => emit('close') });
26
+ else
27
+ emit('close'); }
28
+ async function save() { try {
29
+ await form.formRef.value?.validate();
30
+ }
31
+ catch {
32
+ return;
33
+ } busy.value = true; error.value = ''; try {
34
+ store.saveGrants(value.value, form.formData.reason);
35
+ message.success('角色权限已更新,关联成员同步生效');
36
+ emit('saved');
37
+ }
38
+ catch (e) {
39
+ error.value = e.message;
40
+ }
41
+ finally {
42
+ busy.value = false;
43
+ } }
44
+ return { computed, ref, Alert, Button, Drawer, Input, Select, Space, Tabs, Tree, message, ProForm, useForm, actionGroups, allActions, tenants, useSession, clone, usePbcs, useAuthority, confirmAction, props, emit, session, store, value, tab, error, busy, form, allowed, affected, scopeOptions, pbcDirectory, pbcOptions, tree, update, add, close, save };
45
+ } });
@@ -0,0 +1,2 @@
1
+ <!-- 来源:src/permissions/MemberEditor.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
2
+ <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 管理;本页仅维护 EASEL 业务角色关联。" 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>
@@ -0,0 +1,54 @@
1
+ import { computed, ref, watch } from '../../runtime/state.js';
2
+ import { Alert, Button, Drawer, Space, message } from "../../runtime/widgets.js";
3
+ import { ProForm, useForm } from "../../runtime/widgets.js";
4
+ import { actors, metadata, tenants } from "../shared/policy.js";
5
+ import { useSession } from "../shared/session.js";
6
+ import { clone, checkDelegation } from "./domain.js";
7
+ import { useAuthority } from "./store.js";
8
+ import { confirmAction } from "../shell/confirmation.js";
9
+ import RecordMetadata from "../shared/RecordMetadata.js";
10
+ import { createComponent } from '../../runtime/dom.js';
11
+ export default createComponent({ name: 'MemberEditor', propKeys: ["member"], template: new URL('./MemberEditor.html', import.meta.url).href, setup(__props, __emit) {
12
+ const props = __props, emit = __emit, session = useSession(), store = useAuthority(), busy = ref(false), error = ref('');
13
+ const scopes = [{ value: 'platform', label: '平台统一管理' }, ...tenants].filter(t => session.can('permission:members', t.value));
14
+ const initial = props.member ? clone(props.member) : { ...metadata(session.actor, '', scopes[0]?.value || session.actor.tenantId), id: crypto.randomUUID(), actorId: '', roleIds: [] };
15
+ const form = useForm({ ...initial, reason: '' });
16
+ const people = computed(() => actors.filter(a => session.can('permission:members', 'platform') || a.tenantId === form.formData.tenantId).map(a => ({ value: a.id, label: a.name + ' · ' + a.department + (a.id === 'complete' ? '(全程演示身份)' : '') })));
17
+ const roles = computed(() => store.roles.filter(r => r.tenantId === form.formData.tenantId).map(r => { let disabled = !r.enabled; try {
18
+ checkDelegation(session.actor, r);
19
+ }
20
+ catch {
21
+ disabled = true;
22
+ } return { value: r.id, label: r.name + (r.enabled ? '' : '(已停用)'), disabled }; }));
23
+ form.fields.value = [
24
+ { path: 'tenantId', label: '所属范围', component: 'select', span: 24, disabled: !!props.member, options: scopes, rules: [{ required: true, message: '请选择所属范围' }] },
25
+ { path: 'actorId', label: '身份目录成员', component: 'select', span: 24, disabled: !!props.member, options: people, showSearch: true, optionFilterProp: 'label', rules: [{ required: true, message: '请选择已有成员' }] },
26
+ { path: 'roleIds', label: '关联业务角色', component: 'select', span: 24, mode: 'multiple', options: roles, extra: '同一范围内可关联多个角色;停用或不可转授的角色不可新分配。', rules: [{ required: true, type: 'array', min: 1, message: '请选择至少一个角色' }] },
27
+ { path: 'reason', label: '变更原因', component: 'textarea', span: 24, rules: [{ required: true, whitespace: true, message: '请填写变更原因' }] },
28
+ ];
29
+ watch(() => form.formData.tenantId, () => { form.formData.roleIds = []; if (!props.member)
30
+ form.formData.actorId = ''; });
31
+ const allowed = computed(() => session.can('permission:members', form.formData.tenantId));
32
+ function close() { if (busy.value)
33
+ return; if (JSON.stringify(form.formData) !== JSON.stringify({ ...initial, reason: '' }))
34
+ confirmAction({ title: '放弃未保存的成员授权?', content: '现有成员关联和权限保持不变。', okText: '放弃修改', cancelText: '继续编辑', onOk: () => emit('close') });
35
+ else
36
+ emit('close'); }
37
+ async function save() { try {
38
+ await form.formRef.value?.validate();
39
+ }
40
+ catch {
41
+ return;
42
+ } busy.value = true; error.value = ''; try {
43
+ store.saveMember(form.formData, form.formData.reason);
44
+ message.success('成员授权已保存');
45
+ emit('saved');
46
+ }
47
+ catch (e) {
48
+ error.value = e.message;
49
+ }
50
+ finally {
51
+ busy.value = false;
52
+ } }
53
+ return { computed, ref, watch, Alert, Button, Drawer, Space, message, ProForm, useForm, actors, metadata, tenants, useSession, clone, checkDelegation, useAuthority, confirmAction, RecordMetadata, props, emit, session, store, busy, error, scopes, initial, form, people, roles, allowed, close, save };
54
+ } });
@@ -0,0 +1,3 @@
1
+ <!-- 来源:src/permissions/MembersPage.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
2
+ <template data-component="AdminList" kind="members" title="成员授权" description="关联已有成员,按角色统一分配功能和资源权限。" data-bind-rows="(rows)" data-on-create="selected = undefined;
3
+ 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>
@@ -0,0 +1,27 @@
1
+ import { computed, ref } from '../../runtime/state.js';
2
+ import { useRouter } from "../../runtime/router.js";
3
+ import { Drawer } from "../../runtime/widgets.js";
4
+ import { useAuthority } from "./store.js";
5
+ import { clone } from "./domain.js";
6
+ import AdminList from "./AdminList.js";
7
+ import MemberEditor from "./MemberEditor.js";
8
+ import EffectiveGrants from "./EffectiveGrants.js";
9
+ import RecordMetadata from "../shared/RecordMetadata.js";
10
+ import ListDeleteDialog from "../shared/ListDeleteDialog.js";
11
+ import { createComponent } from '../../runtime/dom.js';
12
+ export default createComponent({ name: 'MembersPage', propKeys: [], template: new URL('./MembersPage.html', import.meta.url).href, setup(__props, __emit) {
13
+ const store = useAuthority(), router = useRouter(), overlay = ref(''), selected = ref(), targets = ref([]);
14
+ const rows = computed(() => store.members.map(m => ({ ...m, name: store.actorName(m.actorId), code: m.roleIds.map(store.roleName).join('、'), status: store.effective(m.actorId, m.tenantId).grants.length ? '有生效权限' : '无生效权限', extra: '仅业务角色关联;身份账号归 MaxKey。' })));
15
+ const current = computed(() => store.members.find(m => m.id === selected.value?.id));
16
+ function close() { overlay.value = ''; selected.value = undefined; }
17
+ function remove(rows) { targets.value = rows.map(r => ({ id: r.id, name: r.name, recordVersion: r.recordVersion })); }
18
+ function action(key, row) { const m = store.members.find(m => m.id === row.id); if (!m)
19
+ return; if (key === 'history') {
20
+ router.push({ path: '/permissions/records', query: { target: row.name } });
21
+ return;
22
+ } if (key === 'delete') {
23
+ remove([row]);
24
+ return;
25
+ } selected.value = clone(m); overlay.value = key; }
26
+ return { computed, ref, useRouter, Drawer, useAuthority, clone, AdminList, MemberEditor, EffectiveGrants, RecordMetadata, ListDeleteDialog, store, router, overlay, selected, targets, rows, current, close, remove, action };
27
+ } });
@@ -0,0 +1,2 @@
1
+ <!-- 来源:src/permissions/RecordsPage.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
2
+ <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>
@@ -0,0 +1,12 @@
1
+ import { computed, ref } from '../../runtime/state.js';
2
+ import { useRoute } from "../../runtime/router.js";
3
+ import { Drawer } from "../../runtime/widgets.js";
4
+ import { useAuthority } from "./store.js";
5
+ import AdminList from "./AdminList.js";
6
+ import { createComponent } from '../../runtime/dom.js';
7
+ export default createComponent({ name: 'RecordsPage', propKeys: [], template: new URL('./RecordsPage.html', import.meta.url).href, setup(__props, __emit) {
8
+ const store = useAuthority(), route = useRoute(), selected = ref('');
9
+ const rows = computed(() => store.records.map(r => ({ id: r.id, name: r.target, code: r.operation, status: '已生效', extra: r.reason, createdById: r.actorId, createdBy: r.actorName, createdDept: '—', createdAt: r.at, updatedBy: r.actorName, updatedAt: r.at, tenantId: r.tenantId, recordVersion: 1, isDeleted: false })));
10
+ const record = computed(() => store.records.find(r => r.id === selected.value));
11
+ return { computed, ref, useRoute, Drawer, useAuthority, AdminList, store, route, selected, rows, record };
12
+ } });
@@ -0,0 +1,2 @@
1
+ <!-- 来源:src/permissions/RoleEditor.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
2
+ <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>
@@ -0,0 +1,45 @@
1
+ import { computed, ref } from '../../runtime/state.js';
2
+ import { Alert, Button, Drawer, Space, message } from "../../runtime/widgets.js";
3
+ import { ProForm, useForm } from "../../runtime/widgets.js";
4
+ import { useSession } from "../shared/session.js";
5
+ import { metadata, tenants } from "../shared/policy.js";
6
+ import { clone } from "./domain.js";
7
+ import { useAuthority } from "./store.js";
8
+ import { confirmAction } from "../shell/confirmation.js";
9
+ import RecordMetadata from "../shared/RecordMetadata.js";
10
+ import { createComponent } from '../../runtime/dom.js';
11
+ export default createComponent({ name: 'RoleEditor', propKeys: ["role"], template: new URL('./RoleEditor.html', import.meta.url).href, setup(__props, __emit) {
12
+ const props = __props, emit = __emit, session = useSession(), store = useAuthority(), busy = ref(false), error = ref('');
13
+ const scopes = [{ value: 'platform', label: '平台统一管理' }, ...tenants].filter(t => session.can('permission:roles', t.value));
14
+ const initial = props.role ? clone(props.role) : { ...metadata(session.actor, '', scopes[0]?.value || session.actor.tenantId), id: crypto.randomUUID(), name: '', code: '', description: '', enabled: true, protected: false, grants: [] };
15
+ const form = useForm({ ...initial, reason: '' }, [
16
+ { path: 'name', label: '角色名称', component: 'input', span: 24, rules: [{ required: true, whitespace: true, message: '请输入角色名称' }] },
17
+ { path: 'code', label: '角色编码', component: 'input', span: 24, disabled: !!props.role, extra: '创建后编码不可修改;角色名称可以调整。', rules: [{ required: true, message: '请输入角色编码' }] },
18
+ { path: 'tenantId', label: '所属范围', component: 'select', span: 24, disabled: !!props.role, options: scopes, rules: [{ required: true, message: '请选择所属范围' }] },
19
+ { path: 'description', label: '用途说明', component: 'textarea', span: 24, rules: [{ required: true, whitespace: true, message: '请填写用途说明' }] },
20
+ { path: 'reason', label: '变更原因', component: 'textarea', span: 24, rules: [{ required: true, whitespace: true, message: '请填写变更原因' }] },
21
+ ]);
22
+ const allowed = computed(() => session.can('permission:roles', form.formData.tenantId));
23
+ function close() { if (busy.value)
24
+ return; if (JSON.stringify(form.formData) !== JSON.stringify({ ...initial, reason: '' }))
25
+ confirmAction({ title: '放弃未保存的修改?', content: '本次输入将不保存,现有角色保持不变。', okText: '放弃修改', cancelText: '继续编辑', onOk: () => emit('close') });
26
+ else
27
+ emit('close'); }
28
+ async function save() { try {
29
+ await form.formRef.value?.validate();
30
+ }
31
+ catch {
32
+ return;
33
+ } busy.value = true; error.value = ''; try {
34
+ store.saveRole(form.formData, form.formData.reason);
35
+ message.success('角色已保存');
36
+ emit('saved');
37
+ }
38
+ catch (e) {
39
+ error.value = e.message;
40
+ }
41
+ finally {
42
+ busy.value = false;
43
+ } }
44
+ return { computed, ref, Alert, Button, Drawer, Space, message, ProForm, useForm, useSession, metadata, tenants, clone, useAuthority, confirmAction, RecordMetadata, props, emit, session, store, busy, error, scopes, initial, form, allowed, close, save };
45
+ } });
@@ -0,0 +1,3 @@
1
+ <!-- 来源:src/permissions/RolesPage.vue;HTML / 原生 DOM 绑定,不含 Vue 运行时。 -->
2
+ <template data-component="AdminList" kind="roles" title="角色管理" description="配置角色的功能与资源范围,按需关联成员。" data-bind-rows="(rows)" data-on-create="selected = undefined;
3
+ 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>
@@ -0,0 +1,38 @@
1
+ import { computed, ref } from '../../runtime/state.js';
2
+ import { useRouter } from "../../runtime/router.js";
3
+ import { Alert, Button, Drawer, Space, Tag, Input, message } from "../../runtime/widgets.js";
4
+ import { useAuthority } from "./store.js";
5
+ import { useSession } from "../shared/session.js";
6
+ import { clone } from "./domain.js";
7
+ import AdminList from "./AdminList.js";
8
+ import RoleEditor from "./RoleEditor.js";
9
+ import GrantEditor from "./GrantEditor.js";
10
+ import EffectiveGrants from "./EffectiveGrants.js";
11
+ import RecordMetadata from "../shared/RecordMetadata.js";
12
+ import ListDeleteDialog from "../shared/ListDeleteDialog.js";
13
+ import { createComponent } from '../../runtime/dom.js';
14
+ export default createComponent({ name: 'RolesPage', propKeys: [], template: new URL('./RolesPage.html', import.meta.url).href, setup(__props, __emit) {
15
+ const store = useAuthority(), session = useSession(), router = useRouter(), overlay = ref(''), selected = ref(), targets = ref([]), reason = ref(''), error = ref('');
16
+ const rows = computed(() => store.roles.map(r => ({ ...r, status: r.enabled ? '启用' : '停用', extra: r.description })));
17
+ const current = computed(() => store.roles.find(r => r.id === selected.value?.id));
18
+ const affected = computed(() => store.members.filter(m => m.roleIds.includes(selected.value?.id || '')).map(m => store.actorName(m.actorId)));
19
+ function close() { overlay.value = ''; selected.value = undefined; reason.value = ''; error.value = ''; }
20
+ function action(key, row) { const r = store.roles.find(r => r.id === row.id); if (!r)
21
+ return; if (key === 'history') {
22
+ router.push({ path: '/permissions/records', query: { target: r.name } });
23
+ return;
24
+ } if (key === 'delete') {
25
+ remove([row]);
26
+ return;
27
+ } selected.value = clone(r); overlay.value = key; reason.value = ''; error.value = ''; }
28
+ function remove(rs) { targets.value = rs.map(r => ({ id: r.id, name: r.name, recordVersion: r.recordVersion })); }
29
+ function toggle() { try {
30
+ store.toggleRole(selected.value, reason.value);
31
+ message.success('角色状态已更新');
32
+ close();
33
+ }
34
+ catch (e) {
35
+ error.value = e.message;
36
+ } }
37
+ return { computed, ref, useRouter, Alert, Button, Drawer, Space, Tag, Input, message, useAuthority, useSession, clone, AdminList, RoleEditor, GrantEditor, EffectiveGrants, RecordMetadata, ListDeleteDialog, store, session, router, overlay, selected, targets, reason, error, rows, current, affected, close, action, remove, toggle };
38
+ } });