create-principles-disciple 1.101.0 → 1.103.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 (317) hide show
  1. package/console/dist/server/config/pd-config-store.d.ts +50 -1
  2. package/console/dist/server/config/pd-config-store.js +364 -1
  3. package/console/dist/server/index.js +9 -0
  4. package/console/dist/server/models/ActivationsConsoleModel.d.ts +44 -5
  5. package/console/dist/server/models/ActivationsConsoleModel.js +118 -16
  6. package/console/dist/server/routes/config.js +92 -2
  7. package/console/dist/server/routes/onboarding.d.ts +34 -0
  8. package/console/dist/server/routes/onboarding.js +324 -0
  9. package/console/dist/ui/App.js +74 -15
  10. package/console/dist/ui/api.d.ts +60 -3
  11. package/console/dist/ui/api.js +63 -2
  12. package/console/dist/ui/components/onboarding/CircuitDiagram.d.ts +8 -0
  13. package/console/dist/ui/components/onboarding/CircuitDiagram.js +18 -0
  14. package/console/dist/ui/components/onboarding/DemoResultView.d.ts +22 -0
  15. package/console/dist/ui/components/onboarding/DemoResultView.js +33 -0
  16. package/console/dist/ui/i18n/en.json +189 -1
  17. package/console/dist/ui/i18n/zh-CN.json +189 -1
  18. package/console/dist/ui/pages/activation/ActivationPage.js +11 -11
  19. package/console/dist/ui/pages/activation/ActivationValidators.js +15 -14
  20. package/console/dist/ui/pages/control-center/AgentCard.js +66 -10
  21. package/console/dist/ui/pages/control-center/ControlCenterPage.js +3 -2
  22. package/console/dist/ui/pages/control-center/RuntimeProfileManager.d.ts +31 -0
  23. package/console/dist/ui/pages/control-center/RuntimeProfileManager.js +234 -0
  24. package/console/dist/ui/pages/debt/DebtPage.js +2 -2
  25. package/console/dist/ui/pages/settings/SettingsPage.js +64 -5
  26. package/console/dist/ui/pages/signal-keywords/KeywordEditDialog.d.ts +12 -0
  27. package/console/dist/ui/pages/signal-keywords/KeywordEditDialog.js +41 -0
  28. package/console/dist/ui/pages/signal-keywords/KeywordListSection.d.ts +10 -0
  29. package/console/dist/ui/pages/signal-keywords/KeywordListSection.js +39 -0
  30. package/console/dist/ui/pages/signal-keywords/PendingTermsSection.d.ts +14 -0
  31. package/console/dist/ui/pages/signal-keywords/PendingTermsSection.js +35 -0
  32. package/console/dist/ui/pages/signal-keywords/SignalKeywordsPage.d.ts +1 -0
  33. package/console/dist/ui/pages/signal-keywords/SignalKeywordsPage.js +49 -0
  34. package/console/dist/ui/pages/welcome/WelcomePage.d.ts +5 -0
  35. package/console/dist/ui/pages/welcome/WelcomePage.js +185 -0
  36. package/console/dist/ui/utils/__tests__/onboarding-state.test.d.ts +1 -0
  37. package/console/dist/ui/utils/__tests__/onboarding-state.test.js +72 -0
  38. package/console/dist/ui/utils/agent-metadata.d.ts +13 -0
  39. package/console/dist/ui/utils/agent-metadata.js +26 -0
  40. package/console/dist/ui/utils/onboarding-state.d.ts +25 -0
  41. package/console/dist/ui/utils/onboarding-state.js +77 -0
  42. package/console/dist/ui/utils/signal-keywords-api.d.ts +68 -0
  43. package/console/dist/ui/utils/signal-keywords-api.js +121 -0
  44. package/console/dist/ui/utils/signal-keywords-types.d.ts +57 -0
  45. package/console/dist/ui/utils/signal-keywords-types.js +10 -0
  46. package/console/dist/ui/utils/signal-keywords-validators.d.ts +20 -0
  47. package/console/dist/ui/utils/signal-keywords-validators.js +114 -0
  48. package/console/dist/ui/utils/validators.d.ts +26 -3
  49. package/console/dist/ui/utils/validators.js +23 -6
  50. package/console/dist/web/assets/app.css +442 -0
  51. package/console/dist/web/assets/app.js +7793 -1966
  52. package/core/dist/index.d.ts +2 -0
  53. package/core/dist/index.d.ts.map +1 -1
  54. package/core/dist/index.js +1 -0
  55. package/core/dist/index.js.map +1 -1
  56. package/core/dist/runtime-v2/__tests__/architecture-regression.test.js +14 -2
  57. package/core/dist/runtime-v2/__tests__/architecture-regression.test.js.map +1 -1
  58. package/core/dist/runtime-v2/__tests__/evaluator-runner-vslice-v2.test.js +28 -0
  59. package/core/dist/runtime-v2/__tests__/evaluator-runner-vslice-v2.test.js.map +1 -1
  60. package/core/dist/runtime-v2/__tests__/pain-to-principle-service.test.js +8 -0
  61. package/core/dist/runtime-v2/__tests__/pain-to-principle-service.test.js.map +1 -1
  62. package/core/dist/runtime-v2/__tests__/resolve-runtime-config-from-pd-config.test.js +8 -10
  63. package/core/dist/runtime-v2/__tests__/resolve-runtime-config-from-pd-config.test.js.map +1 -1
  64. package/core/dist/runtime-v2/activation/index.d.ts +1 -1
  65. package/core/dist/runtime-v2/activation/index.d.ts.map +1 -1
  66. package/core/dist/runtime-v2/activation/index.js +1 -1
  67. package/core/dist/runtime-v2/activation/index.js.map +1 -1
  68. package/core/dist/runtime-v2/activation/writers/__tests__/rule-host-writer.test.js +240 -1
  69. package/core/dist/runtime-v2/activation/writers/__tests__/rule-host-writer.test.js.map +1 -1
  70. package/core/dist/runtime-v2/activation/writers/rule-host-writer.d.ts +12 -0
  71. package/core/dist/runtime-v2/activation/writers/rule-host-writer.d.ts.map +1 -1
  72. package/core/dist/runtime-v2/activation/writers/rule-host-writer.js +81 -1
  73. package/core/dist/runtime-v2/activation/writers/rule-host-writer.js.map +1 -1
  74. package/core/dist/runtime-v2/adapter/__tests__/l2-resolve-model-compat.test.d.ts +2 -0
  75. package/core/dist/runtime-v2/adapter/__tests__/l2-resolve-model-compat.test.d.ts.map +1 -0
  76. package/core/dist/runtime-v2/adapter/__tests__/l2-resolve-model-compat.test.js +81 -0
  77. package/core/dist/runtime-v2/adapter/__tests__/l2-resolve-model-compat.test.js.map +1 -0
  78. package/core/dist/runtime-v2/adapter/__tests__/pi-ai-runtime-adapter.test.js +19 -0
  79. package/core/dist/runtime-v2/adapter/__tests__/pi-ai-runtime-adapter.test.js.map +1 -1
  80. package/core/dist/runtime-v2/adapter/pi-ai-runtime-adapter.d.ts +8 -0
  81. package/core/dist/runtime-v2/adapter/pi-ai-runtime-adapter.d.ts.map +1 -1
  82. package/core/dist/runtime-v2/adapter/pi-ai-runtime-adapter.js +4 -1
  83. package/core/dist/runtime-v2/adapter/pi-ai-runtime-adapter.js.map +1 -1
  84. package/core/dist/runtime-v2/candidate-intake-service.d.ts.map +1 -1
  85. package/core/dist/runtime-v2/candidate-intake-service.js +92 -6
  86. package/core/dist/runtime-v2/candidate-intake-service.js.map +1 -1
  87. package/core/dist/runtime-v2/candidate-intake.d.ts +38 -0
  88. package/core/dist/runtime-v2/candidate-intake.d.ts.map +1 -1
  89. package/core/dist/runtime-v2/candidate-intake.js +48 -0
  90. package/core/dist/runtime-v2/candidate-intake.js.map +1 -1
  91. package/core/dist/runtime-v2/config/__tests__/internal-agent-names.test.d.ts +2 -0
  92. package/core/dist/runtime-v2/config/__tests__/internal-agent-names.test.d.ts.map +1 -0
  93. package/core/dist/runtime-v2/config/__tests__/internal-agent-names.test.js +15 -0
  94. package/core/dist/runtime-v2/config/__tests__/internal-agent-names.test.js.map +1 -0
  95. package/core/dist/runtime-v2/config/__tests__/pd-config-agent-binding.test.js +33 -1
  96. package/core/dist/runtime-v2/config/__tests__/pd-config-agent-binding.test.js.map +1 -1
  97. package/core/dist/runtime-v2/config/__tests__/pd-config-contract.test.js +10 -5
  98. package/core/dist/runtime-v2/config/__tests__/pd-config-contract.test.js.map +1 -1
  99. package/core/dist/runtime-v2/config/__tests__/pd-config-redaction-deep.test.js +1 -0
  100. package/core/dist/runtime-v2/config/__tests__/pd-config-redaction-deep.test.js.map +1 -1
  101. package/core/dist/runtime-v2/config/__tests__/pd-config-validation-edge-cases.test.js +54 -33
  102. package/core/dist/runtime-v2/config/__tests__/pd-config-validation-edge-cases.test.js.map +1 -1
  103. package/core/dist/runtime-v2/config/index.d.ts +5 -3
  104. package/core/dist/runtime-v2/config/index.d.ts.map +1 -1
  105. package/core/dist/runtime-v2/config/index.js +8 -2
  106. package/core/dist/runtime-v2/config/index.js.map +1 -1
  107. package/core/dist/runtime-v2/config/pd-config-agent-binding.d.ts +2 -0
  108. package/core/dist/runtime-v2/config/pd-config-agent-binding.d.ts.map +1 -1
  109. package/core/dist/runtime-v2/config/pd-config-agent-binding.js +3 -0
  110. package/core/dist/runtime-v2/config/pd-config-agent-binding.js.map +1 -1
  111. package/core/dist/runtime-v2/config/pd-config-defaults.d.ts +8 -3
  112. package/core/dist/runtime-v2/config/pd-config-defaults.d.ts.map +1 -1
  113. package/core/dist/runtime-v2/config/pd-config-defaults.js +39 -3
  114. package/core/dist/runtime-v2/config/pd-config-defaults.js.map +1 -1
  115. package/core/dist/runtime-v2/config/pd-config-effective.d.ts.map +1 -1
  116. package/core/dist/runtime-v2/config/pd-config-effective.js +25 -1
  117. package/core/dist/runtime-v2/config/pd-config-effective.js.map +1 -1
  118. package/core/dist/runtime-v2/config/pd-config-redaction.d.ts.map +1 -1
  119. package/core/dist/runtime-v2/config/pd-config-redaction.js +14 -2
  120. package/core/dist/runtime-v2/config/pd-config-redaction.js.map +1 -1
  121. package/core/dist/runtime-v2/config/pd-config-types.d.ts +116 -1
  122. package/core/dist/runtime-v2/config/pd-config-types.d.ts.map +1 -1
  123. package/core/dist/runtime-v2/config/pd-config-types.js +7 -0
  124. package/core/dist/runtime-v2/config/pd-config-types.js.map +1 -1
  125. package/core/dist/runtime-v2/config/pd-config-validate.d.ts.map +1 -1
  126. package/core/dist/runtime-v2/config/pd-config-validate.js +125 -7
  127. package/core/dist/runtime-v2/config/pd-config-validate.js.map +1 -1
  128. package/core/dist/runtime-v2/config/pd-profile-constants.d.ts +27 -0
  129. package/core/dist/runtime-v2/config/pd-profile-constants.d.ts.map +1 -0
  130. package/core/dist/runtime-v2/config/pd-profile-constants.js +145 -0
  131. package/core/dist/runtime-v2/config/pd-profile-constants.js.map +1 -0
  132. package/core/dist/runtime-v2/config/pd-validate-profile.d.ts +28 -0
  133. package/core/dist/runtime-v2/config/pd-validate-profile.d.ts.map +1 -0
  134. package/core/dist/runtime-v2/config/pd-validate-profile.js +482 -0
  135. package/core/dist/runtime-v2/config/pd-validate-profile.js.map +1 -0
  136. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js +26 -0
  137. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js.map +1 -1
  138. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.d.ts.map +1 -1
  139. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js +8 -0
  140. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js.map +1 -1
  141. package/core/dist/runtime-v2/index.d.ts +7 -4
  142. package/core/dist/runtime-v2/index.d.ts.map +1 -1
  143. package/core/dist/runtime-v2/index.js +5 -2
  144. package/core/dist/runtime-v2/index.js.map +1 -1
  145. package/core/dist/runtime-v2/internalization/__tests__/artificer-prompt-builder-v2.test.js +32 -0
  146. package/core/dist/runtime-v2/internalization/__tests__/artificer-prompt-builder-v2.test.js.map +1 -1
  147. package/core/dist/runtime-v2/internalization/__tests__/artificer-rule-output.test.js +139 -0
  148. package/core/dist/runtime-v2/internalization/__tests__/artificer-rule-output.test.js.map +1 -1
  149. package/core/dist/runtime-v2/internalization/__tests__/diag-chain-e2e.test.js +20 -1
  150. package/core/dist/runtime-v2/internalization/__tests__/diag-chain-e2e.test.js.map +1 -1
  151. package/core/dist/runtime-v2/internalization/__tests__/diag-rootcause-intent-tension.test.js +7 -0
  152. package/core/dist/runtime-v2/internalization/__tests__/diag-rootcause-intent-tension.test.js.map +1 -1
  153. package/core/dist/runtime-v2/internalization/__tests__/diag-rootcause-runner.test.js +7 -6
  154. package/core/dist/runtime-v2/internalization/__tests__/diag-rootcause-runner.test.js.map +1 -1
  155. package/core/dist/runtime-v2/internalization/__tests__/internalization-task-guards.test.js +1 -53
  156. package/core/dist/runtime-v2/internalization/__tests__/internalization-task-guards.test.js.map +1 -1
  157. package/core/dist/runtime-v2/internalization/__tests__/rule-host-input-builder.test.js +23 -0
  158. package/core/dist/runtime-v2/internalization/__tests__/rule-host-input-builder.test.js.map +1 -1
  159. package/core/dist/runtime-v2/internalization/artificer-output.d.ts +7 -0
  160. package/core/dist/runtime-v2/internalization/artificer-output.d.ts.map +1 -1
  161. package/core/dist/runtime-v2/internalization/artificer-output.js +22 -1
  162. package/core/dist/runtime-v2/internalization/artificer-output.js.map +1 -1
  163. package/core/dist/runtime-v2/internalization/artificer-prompt-builder.d.ts.map +1 -1
  164. package/core/dist/runtime-v2/internalization/artificer-prompt-builder.js +2 -0
  165. package/core/dist/runtime-v2/internalization/artificer-prompt-builder.js.map +1 -1
  166. package/core/dist/runtime-v2/internalization/artificer-runner.d.ts.map +1 -1
  167. package/core/dist/runtime-v2/internalization/artificer-runner.js +13 -0
  168. package/core/dist/runtime-v2/internalization/artificer-runner.js.map +1 -1
  169. package/core/dist/runtime-v2/internalization/diag-distiller-runner.js +4 -4
  170. package/core/dist/runtime-v2/internalization/diag-distiller-runner.js.map +1 -1
  171. package/core/dist/runtime-v2/internalization/diag-rootcause-runner.js +5 -5
  172. package/core/dist/runtime-v2/internalization/diag-rootcause-runner.js.map +1 -1
  173. package/core/dist/runtime-v2/internalization/diag-router-runner.js +4 -4
  174. package/core/dist/runtime-v2/internalization/diag-router-runner.js.map +1 -1
  175. package/core/dist/runtime-v2/internalization/evaluator-runner.d.ts.map +1 -1
  176. package/core/dist/runtime-v2/internalization/evaluator-runner.js +7 -1
  177. package/core/dist/runtime-v2/internalization/evaluator-runner.js.map +1 -1
  178. package/core/dist/runtime-v2/internalization/index.d.ts +1 -1
  179. package/core/dist/runtime-v2/internalization/index.d.ts.map +1 -1
  180. package/core/dist/runtime-v2/internalization/index.js +1 -1
  181. package/core/dist/runtime-v2/internalization/index.js.map +1 -1
  182. package/core/dist/runtime-v2/internalization/internalization-task-guards.d.ts +0 -19
  183. package/core/dist/runtime-v2/internalization/internalization-task-guards.d.ts.map +1 -1
  184. package/core/dist/runtime-v2/internalization/internalization-task-guards.js +1 -29
  185. package/core/dist/runtime-v2/internalization/internalization-task-guards.js.map +1 -1
  186. package/core/dist/runtime-v2/pain-signal-runtime-factory.d.ts +2 -0
  187. package/core/dist/runtime-v2/pain-signal-runtime-factory.d.ts.map +1 -1
  188. package/core/dist/runtime-v2/pain-signal-runtime-factory.js +2 -0
  189. package/core/dist/runtime-v2/pain-signal-runtime-factory.js.map +1 -1
  190. package/core/dist/runtime-v2/signal-collector/__tests__/keyword-stage.test.d.ts +2 -0
  191. package/core/dist/runtime-v2/signal-collector/__tests__/keyword-stage.test.d.ts.map +1 -0
  192. package/core/dist/runtime-v2/signal-collector/__tests__/keyword-stage.test.js +39 -0
  193. package/core/dist/runtime-v2/signal-collector/__tests__/keyword-stage.test.js.map +1 -0
  194. package/core/dist/runtime-v2/signal-collector/__tests__/llm-stage.test.d.ts +2 -0
  195. package/core/dist/runtime-v2/signal-collector/__tests__/llm-stage.test.d.ts.map +1 -0
  196. package/core/dist/runtime-v2/signal-collector/__tests__/llm-stage.test.js +34 -0
  197. package/core/dist/runtime-v2/signal-collector/__tests__/llm-stage.test.js.map +1 -0
  198. package/core/dist/runtime-v2/signal-collector/__tests__/signal-collector.test.d.ts +2 -0
  199. package/core/dist/runtime-v2/signal-collector/__tests__/signal-collector.test.d.ts.map +1 -0
  200. package/core/dist/runtime-v2/signal-collector/__tests__/signal-collector.test.js +222 -0
  201. package/core/dist/runtime-v2/signal-collector/__tests__/signal-collector.test.js.map +1 -0
  202. package/core/dist/runtime-v2/signal-collector/__tests__/types.test.d.ts +2 -0
  203. package/core/dist/runtime-v2/signal-collector/__tests__/types.test.d.ts.map +1 -0
  204. package/core/dist/runtime-v2/signal-collector/__tests__/types.test.js +35 -0
  205. package/core/dist/runtime-v2/signal-collector/__tests__/types.test.js.map +1 -0
  206. package/core/dist/runtime-v2/signal-collector/index.d.ts +5 -0
  207. package/core/dist/runtime-v2/signal-collector/index.d.ts.map +1 -0
  208. package/core/dist/runtime-v2/signal-collector/index.js +5 -0
  209. package/core/dist/runtime-v2/signal-collector/index.js.map +1 -0
  210. package/core/dist/runtime-v2/signal-collector/keyword-stage.d.ts +20 -0
  211. package/core/dist/runtime-v2/signal-collector/keyword-stage.d.ts.map +1 -0
  212. package/core/dist/runtime-v2/signal-collector/keyword-stage.js +61 -0
  213. package/core/dist/runtime-v2/signal-collector/keyword-stage.js.map +1 -0
  214. package/core/dist/runtime-v2/signal-collector/llm-stage.d.ts +16 -0
  215. package/core/dist/runtime-v2/signal-collector/llm-stage.d.ts.map +1 -0
  216. package/core/dist/runtime-v2/signal-collector/llm-stage.js +34 -0
  217. package/core/dist/runtime-v2/signal-collector/llm-stage.js.map +1 -0
  218. package/core/dist/runtime-v2/signal-collector/signal-collector.d.ts +16 -0
  219. package/core/dist/runtime-v2/signal-collector/signal-collector.d.ts.map +1 -0
  220. package/core/dist/runtime-v2/signal-collector/signal-collector.js +71 -0
  221. package/core/dist/runtime-v2/signal-collector/signal-collector.js.map +1 -0
  222. package/core/dist/runtime-v2/signal-collector/types.d.ts +61 -0
  223. package/core/dist/runtime-v2/signal-collector/types.d.ts.map +1 -0
  224. package/core/dist/runtime-v2/signal-collector/types.js +45 -0
  225. package/core/dist/runtime-v2/signal-collector/types.js.map +1 -0
  226. package/core/dist/runtime-v2/store/schema-conformance.test.js +43 -0
  227. package/core/dist/runtime-v2/store/schema-conformance.test.js.map +1 -1
  228. package/core/dist/runtime-v2/types/event-types.d.ts +40 -3
  229. package/core/dist/runtime-v2/types/event-types.d.ts.map +1 -1
  230. package/core/dist/runtime-v2/types/event-types.js +9 -0
  231. package/core/dist/runtime-v2/types/event-types.js.map +1 -1
  232. package/core/dist/runtime-v2/types/index.d.ts +2 -2
  233. package/core/dist/runtime-v2/types/index.d.ts.map +1 -1
  234. package/core/dist/runtime-v2/types/index.js +1 -1
  235. package/core/dist/runtime-v2/types/index.js.map +1 -1
  236. package/core/dist/workflow-funnel-loader.js +1 -1
  237. package/core/dist/workflow-funnel-loader.js.map +1 -1
  238. package/dist/i18n.d.ts.map +1 -1
  239. package/dist/i18n.js +6 -0
  240. package/dist/i18n.js.map +1 -1
  241. package/dist/index.js +12 -3
  242. package/dist/index.js.map +1 -1
  243. package/dist/installer.d.ts +3 -0
  244. package/dist/installer.d.ts.map +1 -1
  245. package/dist/installer.js +150 -1
  246. package/dist/installer.js.map +1 -1
  247. package/dist/mvp-config.d.ts +8 -0
  248. package/dist/mvp-config.d.ts.map +1 -1
  249. package/dist/mvp-config.js +34 -12
  250. package/dist/mvp-config.js.map +1 -1
  251. package/package.json +1 -1
  252. package/pd-cli/dist/commands/__tests__/runtime-probe-config.test.js +2 -2
  253. package/pd-cli/dist/commands/__tests__/runtime-probe-config.test.js.map +1 -1
  254. package/pd-cli/dist/commands/demo-story-a.d.ts.map +1 -1
  255. package/pd-cli/dist/commands/demo-story-a.js +4 -2
  256. package/pd-cli/dist/commands/demo-story-a.js.map +1 -1
  257. package/pd-cli/dist/commands/proven-channel-baseline.d.ts.map +1 -1
  258. package/pd-cli/dist/commands/proven-channel-baseline.js +4 -2
  259. package/pd-cli/dist/commands/proven-channel-baseline.js.map +1 -1
  260. package/pd-cli/dist/commands/runtime-activation.d.ts +4 -0
  261. package/pd-cli/dist/commands/runtime-activation.d.ts.map +1 -1
  262. package/pd-cli/dist/commands/runtime-activation.js +187 -10
  263. package/pd-cli/dist/commands/runtime-activation.js.map +1 -1
  264. package/pd-cli/dist/commands/runtime-canary.d.ts.map +1 -1
  265. package/pd-cli/dist/commands/runtime-canary.js +4 -2
  266. package/pd-cli/dist/commands/runtime-canary.js.map +1 -1
  267. package/pd-cli/dist/commands/runtime-health-snapshot.d.ts.map +1 -1
  268. package/pd-cli/dist/commands/runtime-health-snapshot.js +4 -2
  269. package/pd-cli/dist/commands/runtime-health-snapshot.js.map +1 -1
  270. package/pd-cli/dist/commands/runtime-internalization-integrity.d.ts.map +1 -1
  271. package/pd-cli/dist/commands/runtime-internalization-integrity.js +4 -2
  272. package/pd-cli/dist/commands/runtime-internalization-integrity.js.map +1 -1
  273. package/pd-cli/dist/index.js +5 -63
  274. package/pd-cli/dist/index.js.map +1 -1
  275. package/pd-cli/dist/services/config-doctor.d.ts.map +1 -1
  276. package/pd-cli/dist/services/config-doctor.js +9 -2
  277. package/pd-cli/dist/services/config-doctor.js.map +1 -1
  278. package/pd-cli/dist/services/runtime-adapter-resolver.d.ts.map +1 -1
  279. package/pd-cli/dist/services/runtime-adapter-resolver.js +1 -0
  280. package/pd-cli/dist/services/runtime-adapter-resolver.js.map +1 -1
  281. package/plugin/dist/commands/context.js +17 -11
  282. package/plugin/dist/commands/samples.js +25 -0
  283. package/plugin/dist/core/event-log.d.ts +11 -1
  284. package/plugin/dist/core/event-log.js +13 -0
  285. package/plugin/dist/core/init.js +3 -4
  286. package/plugin/dist/core/rule-host.d.ts +50 -0
  287. package/plugin/dist/core/rule-host.js +116 -19
  288. package/plugin/dist/core/signal-collector-host.d.ts +105 -0
  289. package/plugin/dist/core/signal-collector-host.js +337 -0
  290. package/plugin/dist/hooks/gate.js +1 -1
  291. package/plugin/dist/hooks/prompt.d.ts +3 -2
  292. package/plugin/dist/hooks/prompt.js +48 -586
  293. package/plugin/dist/service/evolution-dedup.d.ts +1 -1
  294. package/plugin/dist/service/evolution-worker.d.ts +7 -31
  295. package/plugin/dist/service/evolution-worker.js +17 -36
  296. package/plugin/dist/service/queue-io.js +14 -2
  297. package/plugin/dist/service/queue-migration.d.ts +27 -26
  298. package/plugin/dist/service/queue-migration.js +57 -0
  299. package/plugin/dist/types/event-types.d.ts +1 -1
  300. package/plugin/dist/types.d.ts +5 -25
  301. package/plugin/dist/types.js +4 -9
  302. package/plugin/dist/utils/hashing.js +1 -1
  303. package/plugin/templates/langs/en/core/AGENTS.md +2 -2
  304. package/plugin/templates/langs/en/core/TOOLS.md +1 -1
  305. package/plugin/templates/langs/zh/core/AGENTS.md +2 -2
  306. package/plugin/templates/langs/zh/core/TOOLS.md +1 -1
  307. package/templates/langs/en/core/AGENTS.md +2 -2
  308. package/templates/langs/en/core/TOOLS.md +1 -1
  309. package/templates/langs/zh/core/AGENTS.md +2 -2
  310. package/templates/langs/zh/core/TOOLS.md +1 -1
  311. package/plugin/dist/constants/diagnostician.d.ts +0 -12
  312. package/plugin/dist/constants/diagnostician.js +0 -65
  313. package/plugin/dist/service/evolution-queue-migration.d.ts +0 -128
  314. package/plugin/dist/service/evolution-queue-migration.js +0 -53
  315. package/plugin/templates/langs/en/skills/pd-diagnostician/SKILL.md +0 -466
  316. package/plugin/templates/langs/zh/skills/pd-diagnostician/SKILL.md +0 -391
  317. package/templates/langs/zh/skills/pd-diagnostician/SKILL.md +0 -287
@@ -697,8 +697,116 @@
697
697
  },
698
698
  "techDetail": "技术细节",
699
699
  "profileLabelShort": "运行时",
700
+ "manageProfiles": "管理 Profiles",
701
+ "readinessChecking": "探测就绪中…",
700
702
  "unknownAgentsWarning": "检测到 {{count}} 个未识别的代理:{{names}}。它们未被分组显示。",
701
- "footerNote": "9 个代理分布在内化管道与侧链服务两条路径上。核心三件套必须一起开,否则 PD 无法把错误转化为原则。"
703
+ "footerNote": "9 个代理分布在内化管道与侧链服务两条路径上。核心三件套必须一起开,否则 PD 无法把错误转化为原则。",
704
+ "profiles": {
705
+ "sectionTitle": "运行时配置管理",
706
+ "sectionDescription": "创建、编辑、删除 runtime profile。被智能体引用或设为默认的 profile 无法删除。",
707
+ "createButton": "新建 Profile",
708
+ "editButton": "编辑",
709
+ "deleteButton": "删除",
710
+ "cancelButton": "取消",
711
+ "saveButton": "保存",
712
+ "creating": "创建中…",
713
+ "saving": "保存中…",
714
+ "deleting": "删除中…",
715
+ "empty": "暂无 runtime profile。",
716
+ "columnId": "ID",
717
+ "columnType": "类型",
718
+ "columnProvider": "Provider",
719
+ "columnModel": "Model",
720
+ "columnApiKeyEnv": "API Key 环境变量",
721
+ "columnReadiness": "就绪",
722
+ "columnActions": "操作",
723
+ "formTitleCreate": "新建 Runtime Profile",
724
+ "formTitleEdit": "编辑 Profile: {{id}}",
725
+ "fieldId": "Profile ID",
726
+ "fieldIdHint": "唯一标识符,创建后不可修改(如 anthropic-cloud)",
727
+ "fieldIdPlaceholder": "my-profile",
728
+ "fieldType": "类型",
729
+ "fieldProvider": "Provider",
730
+ "fieldProviderPlaceholder": "anthropic",
731
+ "fieldModel": "Model",
732
+ "fieldModelPlaceholder": "claude-sonnet-4",
733
+ "fieldApiKeyEnv": "API Key 环境变量名",
734
+ "fieldApiKeyEnvHint": "环境变量名,不是 key 值(如 ANTHROPIC_API_KEY)",
735
+ "fieldApiKeyEnvPlaceholder": "ANTHROPIC_API_KEY",
736
+ "fieldBaseUrl": "Base URL(可选)",
737
+ "fieldBaseUrlPlaceholder": "https://api.anthropic.com",
738
+ "fieldSource": "Source(可选)",
739
+ "fieldSourcePlaceholder": "default",
740
+ "typeOpenclaw": "openclaw",
741
+ "typePiAi": "pi-ai",
742
+ "validationIdRequired": "Profile ID 不能为空",
743
+ "validationProviderRequired": "pi-ai profile 必须填写 provider",
744
+ "validationModelRequired": "pi-ai profile 必须填写 model",
745
+ "validationApiKeyEnvRequired": "pi-ai profile 必须填写 apiKeyEnv",
746
+ "deleteConfirmTitle": "确认删除",
747
+ "deleteConfirmMessage": "确定要删除 profile「{{id}}」吗?此操作不可撤销。",
748
+ "deleteConfirmAck": "确认删除",
749
+ "deleteConfirmCancel": "取消",
750
+ "createSuccess": "Profile 创建成功",
751
+ "updateSuccess": "Profile 已更新",
752
+ "deleteSuccess": "Profile 已删除",
753
+ "operationFailed": "操作失败"
754
+ }
755
+ },
756
+ "signalKeywords": {
757
+ "title": "信号词库",
758
+ "subtitle": "管理智能体的信号关键词——当信号采集器检测到这些关键词时,会进行深度分析。",
759
+ "empty": "暂无信号关键词",
760
+ "loadError": "无法加载信号关键词",
761
+ "saveError": "保存失败",
762
+ "saving": "保存中…",
763
+ "searchPlaceholder": "搜索关键词…",
764
+ "filterAll": "全部",
765
+ "filterActive": "活跃",
766
+ "filterArchived": "归档",
767
+ "active": "活跃",
768
+ "archived": "归档",
769
+ "confirmDeleteTitle": "确认删除关键词",
770
+ "confirmDeleteMessage": "确定要删除「{{term}}」吗?此操作不可撤销。",
771
+ "confirmDeleteAck": "确认删除",
772
+ "confirmDeleteCancel": "取消",
773
+ "deleteSuccess": "已删除",
774
+ "archiveSuccess": "已归档",
775
+ "unarchiveSuccess": "已恢复",
776
+ "phase2Tooltip": "此操作将在后续版本中启用",
777
+ "colTerm": "术语",
778
+ "colCategory": "分类",
779
+ "colPrecision": "精度",
780
+ "colWeight": "权重",
781
+ "colReason": "原因",
782
+ "colActions": "操作",
783
+ "categoryCorrection": "纠正",
784
+ "categoryEmpathy": "共情",
785
+ "precisionHigh": "高",
786
+ "precisionAmbiguous": "歧义",
787
+ "nTerms": "{{count}} 条",
788
+ "selectedNOfTotal": "已选 {{selected}} / {{total}}",
789
+ "nTermsPendingReview": "{{count}} 条待审",
790
+ "weightLabel": "权重:{{percent}}%",
791
+ "addKeyword": "添加关键词",
792
+ "addKeywordDialogTitle": "添加信号关键词",
793
+ "submitAdd": "添加",
794
+ "noSearchResults": "无匹配关键词",
795
+ "pendingTerms": {
796
+ "title": "待确认信号词",
797
+ "subtitle": "信号采集器建议以下术语从未匹配消息中提取为潜在关键词。审查后确认或忽略。",
798
+ "empty": "暂无待确认信号词",
799
+ "emptyDescription": "当共情观察器检测到重复出现的未命中模式时,会建议新的信号词。",
800
+ "confirm": "确认添加",
801
+ "ignore": "忽略",
802
+ "confirmBatch": "全部确认",
803
+ "ignoreBatch": "全部忽略",
804
+ "sourceCount": "来自 {{count}} 条消息",
805
+ "confirmSuccess": "已确认添加",
806
+ "ignoreSuccess": "已忽略",
807
+ "batchConfirmSuccess": "已确认 {{count}} 个信号词",
808
+ "batchIgnoreSuccess": "已忽略 {{count}} 个信号词"
809
+ }
702
810
  },
703
811
  "login": {
704
812
  "title": "登录",
@@ -942,6 +1050,69 @@
942
1050
  "demoteTooltip": "降权端点开发中",
943
1051
  "principleAriaLabel": "原则债务 {{id}}",
944
1052
  "listAriaLabel": "原则债务列表"
1053
+ },
1054
+ "welcome": {
1055
+ "title": "欢迎使用 Principles Disciple",
1056
+ "subtitle": "把你对智能体的反复纠正,沉淀为可审查、可撤回的行为原则。",
1057
+ "stateSaveError": "无法保存引导进度,请检查浏览器存储权限后重试。",
1058
+ "stepIndicator": "第 {{current}} 步 / 共 {{total}} 步",
1059
+ "step1": {
1060
+ "title": "PD 是什么?",
1061
+ "description": "拥有者治理下的智能体行为内化系统。PD 把行为证据沉淀为可审查、可回滚的原则,让原则进入智能体的后续行为。",
1062
+ "circuitLabel": "核心治理回路",
1063
+ "circuitNodes": {
1064
+ "evidence": "行为证据",
1065
+ "principle": "原则",
1066
+ "ownerGate": "拥有者审查",
1067
+ "behavior": "行为变更"
1068
+ },
1069
+ "startButton": "开始",
1070
+ "skipButton": "跳过引导"
1071
+ },
1072
+ "step2": {
1073
+ "title": "看一次完整治理回路演示",
1074
+ "description": "这是用模拟证据做的受控演示。真实使用时,由你的智能体通过 pd-pain-signal 技能产生证据。",
1075
+ "runDemoButton": "运行演示",
1076
+ "demoRunning": "演示运行中...",
1077
+ "demoComplete": "演示完成",
1078
+ "demoFailed": "演示失败",
1079
+ "demoSimulatedNote": "此证据为演示模拟数据。",
1080
+ "nextButton": "下一步",
1081
+ "evidenceLabel": "证据(模拟)",
1082
+ "candidateLabel": "候选原则",
1083
+ "ownerGateLabel": "拥有者审查:批准 / 修改 / 拒绝",
1084
+ "activationLabel": "激活结果",
1085
+ "rollbackLabel": "可回滚路径已就绪",
1086
+ "stages": {
1087
+ "evidenceSeed": "证据(模拟)",
1088
+ "principleProposal": "候选原则",
1089
+ "ownerReview": "拥有者审查",
1090
+ "activation": "激活结果",
1091
+ "followUpObservation": "后续观察",
1092
+ "rollbackProof": "可回滚路径已就绪"
1093
+ }
1094
+ },
1095
+ "step3": {
1096
+ "title": "准备好记录真实证据",
1097
+ "description": "当你下次使用智能体时,如果智能体犯错或你重复纠正了它,告诉智能体:'用 pd-pain-signal 记录一下'。",
1098
+ "examplePrompt": "给智能体的示例提示:",
1099
+ "examplePromptText": "我刚纠正了你关于 X 的问题。用 pd-pain-signal 把这个记录为 pain signal。",
1100
+ "tryNowButton": "我现在就试试(2 小时窗口)",
1101
+ "goToFocusButton": "知道了,先看 Focus",
1102
+ "skipButton": "暂时跳过",
1103
+ "windowHint": "我们会在 2 小时后查看。不强制——你随时可以稍后记录证据。",
1104
+ "pollingActive": "正在监听证据... 我们会每 30 秒检查一次,持续 2 小时。",
1105
+ "stopPollingButton": "停止并继续",
1106
+ "evidenceFound": "检测到证据!你现在可以在 Focus 页面查看。",
1107
+ "timeoutHint": "2 小时内未检测到证据。没关系——你随时可以用 pd-pain-signal 记录证据。",
1108
+ "pollingError": "无法检查证据。证据服务可能不可用。",
1109
+ "retryButton": "重试"
1110
+ },
1111
+ "progress": {
1112
+ "step1": "欢迎",
1113
+ "step2": "演示",
1114
+ "step3": "邀请"
1115
+ }
945
1116
  }
946
1117
  },
947
1118
  "components": {
@@ -1050,6 +1221,23 @@
1050
1221
  "tooShort": "拒绝原因至少需要10个字符",
1051
1222
  "cancel": "取消",
1052
1223
  "submit": "确认拒绝"
1224
+ },
1225
+ "onboardingReset": {
1226
+ "title": "引导流程",
1227
+ "resetButton": "重置引导状态",
1228
+ "resetConfirm": "这将在下次登录时重新启动引导向导。继续吗?",
1229
+ "resetSuccess": "引导状态已重置。下次访问时会看到欢迎页。",
1230
+ "resetFailed": "无法重置引导,请检查浏览器存储权限后重试。"
1231
+ },
1232
+ "onboardingFlag": {
1233
+ "title": "引导功能",
1234
+ "label": "新用户引导向导",
1235
+ "description": "首次访问时显示欢迎向导。熟练用户可关闭。",
1236
+ "toggleAriaLabel": "切换新用户引导功能",
1237
+ "enabled": "引导向导已启用",
1238
+ "disabled": "引导向导已关闭",
1239
+ "toggleFailed": "切换引导功能失败",
1240
+ "loadFailed": "加载引导开关状态失败"
1053
1241
  }
1054
1242
  }
1055
1243
  }
@@ -25,14 +25,14 @@ function ActivationFactCard({ record, lifecycleData, onDisable, disabling, }) {
25
25
  const neverActivated = record.activatedAt === null;
26
26
  const channelLabel = getChannelLabel(record.channel, t);
27
27
  const reversible = isReversibleChannel(record.channel);
28
- return (_jsxs("article", { className: `relative pl-[22px] py-[18px] pr-[18px] bg-panel border rounded-[6px] transition-colors hover:border-line-2 ${neverActivated ? "border-amber/30 border-l-[3px] border-l-amber" : "border-line"}`, "data-testid": `activation-card-${record.id}`, children: [_jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [_jsx("span", { className: `inline-flex items-center border rounded-[2px] px-[7px] py-1 font-mono text-[11px] uppercase ${record.status === "active"
28
+ return (_jsxs("article", { className: `relative pl-[22px] py-[18px] pr-[18px] bg-panel border rounded-[6px] transition-colors hover:border-line-2 ${neverActivated ? "border-amber/30 border-l-[3px] border-l-amber" : "border-line"}`, "data-testid": `activation-card-${record.activationId}`, children: [_jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [_jsx("span", { className: `inline-flex items-center border rounded-[2px] px-[7px] py-1 font-mono text-[11px] uppercase ${record.status === "active"
29
29
  ? "border-green/35 text-green bg-green/5"
30
30
  : "border-line text-ink-4 bg-surface/80"}`, role: "status", children: record.status === "active" ? t("pages.activation.statusActive") : t("pages.activation.statusInactive") }), _jsx("span", { className: "inline-flex items-center border border-line rounded-[2px] px-[7px] py-1 font-mono text-[11px] text-ink-3 bg-surface/80 uppercase", children: channelLabel }), reversible && (_jsx("span", { className: "inline-flex items-center border border-amber/35 text-amber rounded-[2px] px-[7px] py-1 font-mono text-[11px] uppercase", children: t("pages.activation.tagReversible") })), !reversible && record.channel === "code_tool_hook" && (_jsx("span", { className: "inline-flex items-center border border-danger/35 text-danger rounded-[2px] px-[7px] py-1 font-mono text-[11px] uppercase", children: t("pages.activation.tagHighRisk") })), neverActivated && (_jsx("span", { className: "inline-flex items-center border border-amber/35 text-amber rounded-[2px] px-[7px] py-1 font-mono text-[11px] uppercase", children: t("pages.activation.tagNeverActivated") }))] }), _jsxs("div", { className: "mt-[14px] mb-2", children: [_jsx("span", { className: "text-ink-2 text-[13px]", children: t("pages.activation.principleLabel") }), " ", _jsx(Link, { to: `/principles/${record.principleId}`, className: "text-gov text-[13px] hover:underline focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", "data-testid": `principle-link-${record.principleId}`, title: record.principleId, children: record.action }), _jsx("span", { className: "ml-2 font-mono text-[11px] text-ink-4", children: record.principleId })] }), _jsxs("div", { className: "text-ink-3 text-[13px] leading-relaxed space-y-1", children: [_jsxs("div", { children: [_jsx("span", { className: "text-ink-4 font-mono text-[11px] uppercase", children: t("pages.activation.actionLabel") }), " ", _jsx("span", { className: "text-ink-2", children: record.action })] }), _jsxs("div", { children: [_jsx("span", { className: "text-ink-4 font-mono text-[11px] uppercase", children: t("pages.activation.targetLabel") }), " ", _jsx("span", { className: "text-ink-2 font-mono text-[12px]", children: record.targetRef })] }), _jsxs("div", { children: [_jsx("span", { className: "text-ink-4 font-mono text-[11px] uppercase", children: t("pages.activation.activatedAtLabel") }), " ", neverActivated ? (_jsx("span", { className: "text-amber", children: t("pages.activation.neverActivated") })) : (_jsx("span", { className: "text-ink-2 font-mono text-[12px] tabular-nums", children: new Date(record.activatedAt).toLocaleString() }))] })] }), lifecycleData !== undefined && (_jsxs("details", { className: "mt-4 group", children: [_jsx("summary", { className: "text-gov text-[13px] cursor-pointer hover:underline focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.activation.lifecycleToggle") }), _jsx("div", { className: "mt-2 pl-4 border-l-2 border-line", children: lifecycleData === null ? (_jsx("div", { className: "text-ink-4 text-[13px] py-2", children: t("pages.activation.lifecycleUnavailable") })) : lifecycleData.adherence.insufficientData ? (_jsx("div", { className: "text-ink-4 text-[13px] py-2", children: t("pages.activation.insufficientData") })) : (_jsxs("div", { className: "py-2 space-y-2", children: [_jsxs("div", { className: "text-ink-2 text-[13px]", children: [_jsx("span", { className: "font-mono font-semibold text-ink tabular-nums", children: lifecycleData.adherence.rate !== null
31
31
  ? `${(lifecycleData.adherence.rate * 100).toFixed(0)}%`
32
- : "—" }), " ", _jsx("span", { className: "text-ink-3", children: t("pages.activation.adherenceLabel") }), _jsx("div", { className: "text-ink-4 text-[11px] mt-1 font-mono", children: t("pages.activation.lifecycleNote") })] }), lifecycleData.ruleMetrics.length > 0 && (_jsx("div", { className: "space-y-1", children: lifecycleData.ruleMetrics.map((rm) => (_jsxs("div", { className: "text-ink-3 text-[12px] font-mono", children: [_jsx("span", { className: "text-ink-2", children: rm.ruleId }), ":", " ", rm.triggered, " ", t("pages.activation.triggered"), " ", rm.lastTriggeredAt && (_jsxs("span", { className: "text-ink-4", children: ["(", new Date(rm.lastTriggeredAt).toLocaleString(), ")"] }))] }, rm.ruleId))) }))] })) })] })), record.status === "active" && reversible && (_jsx("div", { className: "mt-4", children: !showConfirm ? (_jsx("button", { onClick: () => setShowConfirm(true), disabled: disabling, className: "inline-flex items-center border border-line bg-surface text-ink rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:border-line-2 transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", "data-testid": `disable-btn-${record.id}`, children: t("pages.activation.disableAction") })) : (_jsxs("div", { className: "flex items-center gap-3 px-[14px] py-[10px] bg-surface border border-amber/25 rounded-[4px]", role: "alert", "data-testid": `confirm-bar-${record.id}`, children: [_jsx("span", { className: "text-ink-2 text-[13px] flex-1", children: t("pages.activation.confirmDisable") }), _jsx("button", { onClick: () => {
32
+ : "—" }), " ", _jsx("span", { className: "text-ink-3", children: t("pages.activation.adherenceLabel") }), _jsx("div", { className: "text-ink-4 text-[11px] mt-1 font-mono", children: t("pages.activation.lifecycleNote") })] }), lifecycleData.ruleMetrics.length > 0 && (_jsx("div", { className: "space-y-1", children: lifecycleData.ruleMetrics.map((rm) => (_jsxs("div", { className: "text-ink-3 text-[12px] font-mono", children: [_jsx("span", { className: "text-ink-2", children: rm.ruleId }), ":", " ", rm.triggered, " ", t("pages.activation.triggered"), " ", rm.lastTriggeredAt && (_jsxs("span", { className: "text-ink-4", children: ["(", new Date(rm.lastTriggeredAt).toLocaleString(), ")"] }))] }, rm.ruleId))) }))] })) })] })), record.status === "active" && reversible && (_jsx("div", { className: "mt-4", children: !showConfirm ? (_jsx("button", { onClick: () => setShowConfirm(true), disabled: disabling, className: "inline-flex items-center border border-line bg-surface text-ink rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:border-line-2 transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", "data-testid": `disable-btn-${record.activationId}`, children: t("pages.activation.disableAction") })) : (_jsxs("div", { className: "flex items-center gap-3 px-[14px] py-[10px] bg-surface border border-amber/25 rounded-[4px]", role: "alert", "data-testid": `confirm-bar-${record.activationId}`, children: [_jsx("span", { className: "text-ink-2 text-[13px] flex-1", children: t("pages.activation.confirmDisable") }), _jsx("button", { onClick: () => {
33
33
  onDisable(record);
34
34
  setShowConfirm(false);
35
- }, disabled: disabling, className: "inline-flex items-center border border-danger/40 text-danger bg-surface rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:bg-danger/5 transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", "data-testid": `confirm-disable-${record.id}`, children: disabling ? t("pages.activation.disabling") : t("common.confirm") }), _jsx("button", { onClick: () => setShowConfirm(false), className: "inline-flex items-center border border-line bg-surface text-ink rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:border-line-2 transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("common.cancel") })] })) }))] }));
35
+ }, disabled: disabling, className: "inline-flex items-center border border-danger/40 text-danger bg-surface rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:bg-danger/5 transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", "data-testid": `confirm-disable-${record.activationId}`, children: disabling ? t("pages.activation.disabling") : t("common.confirm") }), _jsx("button", { onClick: () => setShowConfirm(false), className: "inline-flex items-center border border-line bg-surface text-ink rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:border-line-2 transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("common.cancel") })] })) }))] }));
36
36
  }
37
37
  export function ActivationPage() {
38
38
  const { t } = useTranslation();
@@ -59,8 +59,8 @@ export function ActivationPage() {
59
59
  return;
60
60
  }
61
61
  setActivationsData(validated);
62
- if (validated.note) {
63
- setDegradedNote(validated.note);
62
+ if (validated.reason) {
63
+ setDegradedNote(validated.reason);
64
64
  }
65
65
  // Pre-fetch lifecycle metrics for active principles with rules
66
66
  // (only for principles that are active, to populate the expandable section)
@@ -92,8 +92,8 @@ export function ActivationPage() {
92
92
  loadData();
93
93
  }, [loadData]);
94
94
  const handleDisable = useCallback(async (record) => {
95
- setDisablingIds((prev) => new Set(prev).add(record.id));
96
- const result = await disableActivation(record.id);
95
+ setDisablingIds((prev) => new Set(prev).add(record.activationId));
96
+ const result = await disableActivation(record.activationId);
97
97
  if (result.success) {
98
98
  toast.success(t("pages.activation.disableSuccess"), {
99
99
  description: t("pages.activation.disableSuccessDescription", { id: record.principleId }),
@@ -105,7 +105,7 @@ export function ActivationPage() {
105
105
  return prev;
106
106
  return {
107
107
  ...prev,
108
- activations: prev.activations.map((a) => a.id === record.id ? { ...a, status: "inactive" } : a),
108
+ activations: prev.activations.map((a) => a.activationId === record.activationId ? { ...a, status: "inactive" } : a),
109
109
  };
110
110
  });
111
111
  }
@@ -121,7 +121,7 @@ export function ActivationPage() {
121
121
  }
122
122
  setDisablingIds((prev) => {
123
123
  const next = new Set(prev);
124
- next.delete(record.id);
124
+ next.delete(record.activationId);
125
125
  return next;
126
126
  });
127
127
  }, [t]);
@@ -138,7 +138,7 @@ export function ActivationPage() {
138
138
  const activeActivations = activations.filter((a) => a.status === "active");
139
139
  const inactiveActivations = activations.filter((a) => a.status === "inactive");
140
140
  const neverActivatedCount = activations.filter((a) => a.activatedAt === null).length;
141
- return (_jsx(PageShell, { children: _jsxs("div", { className: "animate-[pdFadeIn_400ms_ease-out]", children: [_jsx("div", { className: "font-mono text-[12px] tracking-[0.14em] text-ink-3 uppercase mb-3", children: t("pages.activation.eyebrow") }), _jsx(ShinyText, { as: "h1", className: "text-[29px] font-semibold tracking-tight text-ink mb-2", duration: 4.5, brightness: 0.5, disabled: activeActivations.length === 0, children: t("pages.activation.title") }), _jsx("p", { className: "text-ink-3 text-[14px] max-w-[760px] leading-relaxed mb-7", children: t("pages.activation.subtitle") }), _jsxs("div", { className: "text-sm leading-relaxed text-ink-2 mb-7 px-[18px] py-[14px] bg-panel border border-line rounded-[6px]", role: "status", "aria-live": "polite", children: [_jsx("span", { className: "font-mono font-semibold text-ink tabular-nums", children: activeActivations.length }), " ", _jsx("span", { className: "text-ink-3", children: t("pages.activation.summaryActive") }), " ", "/", " ", _jsx("span", { className: "font-mono font-semibold text-ink tabular-nums", children: inactiveActivations.length }), " ", _jsx("span", { className: "text-ink-3", children: t("pages.activation.summaryInactive") }), neverActivatedCount > 0 && (_jsxs(_Fragment, { children: [" ", "/", " ", _jsx("span", { className: "font-mono font-semibold text-amber tabular-nums", children: neverActivatedCount }), " ", _jsx("span", { className: "text-amber", children: t("pages.activation.summaryNeverActivated") })] }))] }), _jsx(CapabilityBoundaryDeclaration, {}), degradedNote && (_jsx("div", { className: "mt-4 text-ink-4 text-[13px] bg-surface/60 border-l-2 border-amber px-3 py-2", children: degradedNote })), _jsxs("section", { className: "mt-8", "aria-labelledby": "section-active", children: [_jsx(SectionTitle, { id: "section-active", children: t("pages.activation.sectionActive") }), activeActivations.length > 0 ? (_jsx("div", { className: "space-y-[14px]", children: activeActivations.map((record) => (_jsx(ActivationFactCard, { record: record, lifecycleData: lifecycleCache[record.principleId], onDisable: handleDisable, disabling: disablingIds.has(record.id) }, record.id))) })) : (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: t("pages.activation.emptyActive") }))] }), inactiveActivations.length > 0 && (_jsxs("section", { className: "mt-8", "aria-labelledby": "section-inactive", children: [_jsx(SectionTitle, { id: "section-inactive", children: t("pages.activation.sectionInactive") }), _jsx("div", { className: "space-y-[14px]", children: inactiveActivations.map((record) => (_jsx(ActivationFactCard, { record: record, lifecycleData: lifecycleCache[record.principleId], onDisable: handleDisable, disabling: disablingIds.has(record.id) }, record.id))) })] })), neverActivatedCount > 0 && (_jsxs("section", { className: "mt-8", "aria-labelledby": "section-never-activated", children: [_jsx(SectionTitle, { id: "section-never-activated", children: t("pages.activation.sectionNeverActivated") }), _jsx("div", { className: "space-y-[10px]", children: activations
141
+ return (_jsx(PageShell, { children: _jsxs("div", { className: "animate-[pdFadeIn_400ms_ease-out]", children: [_jsx("div", { className: "font-mono text-[12px] tracking-[0.14em] text-ink-3 uppercase mb-3", children: t("pages.activation.eyebrow") }), _jsx(ShinyText, { as: "h1", className: "text-[29px] font-semibold tracking-tight text-ink mb-2", duration: 4.5, brightness: 0.5, disabled: activeActivations.length === 0, children: t("pages.activation.title") }), _jsx("p", { className: "text-ink-3 text-[14px] max-w-[760px] leading-relaxed mb-7", children: t("pages.activation.subtitle") }), _jsxs("div", { className: "text-sm leading-relaxed text-ink-2 mb-7 px-[18px] py-[14px] bg-panel border border-line rounded-[6px]", role: "status", "aria-live": "polite", children: [_jsx("span", { className: "font-mono font-semibold text-ink tabular-nums", children: activeActivations.length }), " ", _jsx("span", { className: "text-ink-3", children: t("pages.activation.summaryActive") }), " ", "/", " ", _jsx("span", { className: "font-mono font-semibold text-ink tabular-nums", children: inactiveActivations.length }), " ", _jsx("span", { className: "text-ink-3", children: t("pages.activation.summaryInactive") }), neverActivatedCount > 0 && (_jsxs(_Fragment, { children: [" ", "/", " ", _jsx("span", { className: "font-mono font-semibold text-amber tabular-nums", children: neverActivatedCount }), " ", _jsx("span", { className: "text-amber", children: t("pages.activation.summaryNeverActivated") })] }))] }), _jsx(CapabilityBoundaryDeclaration, {}), degradedNote && (_jsx("div", { className: "mt-4 text-ink-4 text-[13px] bg-surface/60 border-l-2 border-amber px-3 py-2", children: degradedNote })), _jsxs("section", { className: "mt-8", "aria-labelledby": "section-active", children: [_jsx(SectionTitle, { id: "section-active", children: t("pages.activation.sectionActive") }), activeActivations.length > 0 ? (_jsx("div", { className: "space-y-[14px]", children: activeActivations.map((record) => (_jsx(ActivationFactCard, { record: record, lifecycleData: lifecycleCache[record.principleId], onDisable: handleDisable, disabling: disablingIds.has(record.activationId) }, record.activationId))) })) : (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: t("pages.activation.emptyActive") }))] }), inactiveActivations.length > 0 && (_jsxs("section", { className: "mt-8", "aria-labelledby": "section-inactive", children: [_jsx(SectionTitle, { id: "section-inactive", children: t("pages.activation.sectionInactive") }), _jsx("div", { className: "space-y-[14px]", children: inactiveActivations.map((record) => (_jsx(ActivationFactCard, { record: record, lifecycleData: lifecycleCache[record.principleId], onDisable: handleDisable, disabling: disablingIds.has(record.activationId) }, record.activationId))) })] })), neverActivatedCount > 0 && (_jsxs("section", { className: "mt-8", "aria-labelledby": "section-never-activated", children: [_jsx(SectionTitle, { id: "section-never-activated", children: t("pages.activation.sectionNeverActivated") }), _jsx("div", { className: "space-y-[10px]", children: activations
142
142
  .filter((a) => a.activatedAt === null)
143
- .map((record) => (_jsxs("article", { className: "relative pl-[22px] py-[14px] pr-[18px] bg-panel border border-amber/20 border-l-[3px] border-l-amber rounded-[6px]", children: [_jsxs("div", { className: "text-ink-2 text-sm leading-relaxed", children: [_jsx("span", { className: "font-medium text-ink", children: t("pages.activation.neverActivatedCard") }), " ", "\u2014 ", record.action, " \u00B7 ", getChannelLabel(record.channel, t), _jsx("span", { className: "ml-2 font-mono text-[11px] text-ink-4", children: record.principleId })] }), _jsxs(Link, { to: "/debt", className: "inline-flex items-center mt-2 text-gov text-[13px] hover:underline focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: [t("pages.activation.viewDebt"), " \u2192"] })] }, record.id))) })] })), _jsx("footer", { className: "mt-12 pt-6 border-t border-line text-ink-3 text-[13px]", children: t("pages.activation.footer") })] }) }));
143
+ .map((record) => (_jsxs("article", { className: "relative pl-[22px] py-[14px] pr-[18px] bg-panel border border-amber/20 border-l-[3px] border-l-amber rounded-[6px]", children: [_jsxs("div", { className: "text-ink-2 text-sm leading-relaxed", children: [_jsx("span", { className: "font-medium text-ink", children: t("pages.activation.neverActivatedCard") }), " ", "\u2014 ", record.action, " \u00B7 ", getChannelLabel(record.channel, t), _jsx("span", { className: "ml-2 font-mono text-[11px] text-ink-4", children: record.principleId })] }), _jsxs(Link, { to: "/debt", className: "inline-flex items-center mt-2 text-gov text-[13px] hover:underline focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: [t("pages.activation.viewDebt"), " \u2192"] })] }, record.activationId))) })] })), _jsx("footer", { className: "mt-12 pt-6 border-t border-line text-ink-3 text-[13px]", children: t("pages.activation.footer") })] }) }));
144
144
  }
@@ -14,12 +14,12 @@
14
14
  export function isRecord(value) {
15
15
  return typeof value === "object" && value !== null && !Array.isArray(value);
16
16
  }
17
- const VALID_ACTIVATION_STATUSES = new Set(["active", "inactive"]);
17
+ const VALID_ACTIVATION_STATUSES = new Set(["active", "inactive", "deactivated", "suspended_by_flag"]);
18
18
  // ── Activation validators ────────────────────────────────────────────────────
19
19
  export function validateActivationRecord(raw) {
20
20
  if (!isRecord(raw))
21
21
  return null;
22
- if (!Object.hasOwn(raw, "id") ||
22
+ if (!Object.hasOwn(raw, "activationId") ||
23
23
  !Object.hasOwn(raw, "artifactId") ||
24
24
  !Object.hasOwn(raw, "principleId") ||
25
25
  !Object.hasOwn(raw, "channel") ||
@@ -29,9 +29,9 @@ export function validateActivationRecord(raw) {
29
29
  !Object.hasOwn(raw, "status")) {
30
30
  return null;
31
31
  }
32
- const { id, artifactId, principleId, channel, action, targetRef, activatedAt, status } = raw;
33
- if (typeof id !== "string" ||
34
- id.length === 0 ||
32
+ const { activationId, artifactId, principleId, channel, action, targetRef, activatedAt, status } = raw;
33
+ if (typeof activationId !== "string" ||
34
+ activationId.length === 0 ||
35
35
  typeof artifactId !== "string" ||
36
36
  typeof principleId !== "string" ||
37
37
  typeof channel !== "string" ||
@@ -45,7 +45,7 @@ export function validateActivationRecord(raw) {
45
45
  // Narrow status from string to union type via const assertion
46
46
  const narrowStatus = status;
47
47
  return {
48
- id: id,
48
+ activationId: activationId,
49
49
  artifactId: artifactId,
50
50
  principleId: principleId,
51
51
  channel: channel,
@@ -58,11 +58,11 @@ export function validateActivationRecord(raw) {
58
58
  export function validateActivationsData(raw) {
59
59
  if (!isRecord(raw))
60
60
  return null;
61
- if (!Object.hasOwn(raw, "activations") || !Object.hasOwn(raw, "generatedAt")) {
61
+ if (!Object.hasOwn(raw, "activations") || !Object.hasOwn(raw, "status")) {
62
62
  return null;
63
63
  }
64
- const { activations, generatedAt } = raw;
65
- if (!Array.isArray(activations) || typeof generatedAt !== "string") {
64
+ const { activations, status } = raw;
65
+ if (!Array.isArray(activations) || typeof status !== "string") {
66
66
  return null;
67
67
  }
68
68
  // Fail loud: any invalid record rejects the entire payload (ERR-009)
@@ -73,11 +73,12 @@ export function validateActivationsData(raw) {
73
73
  return null;
74
74
  validatedRecords.push(validated);
75
75
  }
76
- return {
77
- activations: validatedRecords,
78
- generatedAt,
79
- note: Object.hasOwn(raw, "note") && typeof raw.note === "string" ? raw.note : undefined,
80
- };
76
+ const result = { activations: validatedRecords, status };
77
+ if (Object.hasOwn(raw, "reason") && typeof raw.reason === "string")
78
+ result.reason = raw.reason;
79
+ if (Object.hasOwn(raw, "nextAction") && typeof raw.nextAction === "string")
80
+ result.nextAction = raw.nextAction;
81
+ return result;
81
82
  }
82
83
  // ── Lifecycle validators ─────────────────────────────────────────────────────
83
84
  export function validateLifecycleRuleMetric(raw) {
@@ -1,15 +1,21 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { useState } from "react";
2
+ import { useState, useEffect } from "react";
3
3
  import { useTranslation } from "react-i18next";
4
+ import { useNavigate } from "react-router-dom";
4
5
  import { ChevronRight } from "lucide-react";
5
6
  import { cn } from "../../../lib/utils.js";
6
- /** 状态点样式:ready / notready / off */
7
- function statusDotClasses(agent) {
7
+ import { fetchAgentReadiness } from "../../api.js";
8
+ /** 状态点样式:ready / notready / off
9
+ *
10
+ * 接受 readiness + enabled 而非整个 agent 对象,以便 L1 状态点可以使用
11
+ * 动态获取的 readiness(fetchAgentReadiness)替换静态悲观值。
12
+ */
13
+ function statusDotClasses(readiness, enabled) {
8
14
  const base = "w-2 h-2 rounded-full border-2 shrink-0";
9
- if (!agent.enabled) {
15
+ if (!enabled) {
10
16
  return cn(base, "border-ink-4 bg-surface opacity-50");
11
17
  }
12
- switch (agent.readiness) {
18
+ switch (readiness) {
13
19
  case "ready":
14
20
  return cn(base, "border-green bg-green");
15
21
  case "not_ready":
@@ -68,11 +74,50 @@ function renderTextWithCode(text) {
68
74
  }
69
75
  export function AgentCard({ agent, meta, profiles, onBindingChange, saving, locale, }) {
70
76
  const { t } = useTranslation();
77
+ const navigate = useNavigate();
71
78
  const isSaving = saving === agent.name;
72
79
  // L2 / L3 / confirm 状态
73
80
  const [isOpen, setIsOpen] = useState(false);
74
81
  const [showTechDetail, setShowTechDetail] = useState(false);
75
82
  const [confirming, setConfirming] = useState(false);
83
+ // 动态 readiness:L2 展开时,若静态 readiness 为 'unknown'(悲观值),
84
+ // 调用 /api/v1/config/readiness/:agentName 获取实时探测结果替换静态值。
85
+ // 仅在 agent.enabled && agent.readiness === 'unknown' 时发起请求。
86
+ const [dynamicReadiness, setDynamicReadiness] = useState(null);
87
+ const [readinessLoading, setReadinessLoading] = useState(false);
88
+ const [readinessFetched, setReadinessFetched] = useState(false);
89
+ useEffect(() => {
90
+ if (!isOpen)
91
+ return;
92
+ if (readinessFetched)
93
+ return;
94
+ if (!agent.enabled)
95
+ return;
96
+ if (agent.readiness !== "unknown")
97
+ return;
98
+ let cancelled = false;
99
+ setReadinessFetched(true);
100
+ setReadinessLoading(true);
101
+ fetchAgentReadiness(agent.name).then((result) => {
102
+ if (cancelled)
103
+ return;
104
+ setReadinessLoading(false);
105
+ if (result.success && result.data) {
106
+ setDynamicReadiness(result.data.readiness);
107
+ }
108
+ // rc-9: 调用失败时不静默吞错——result.error 已由 request() 提取;
109
+ // 此处 fallback 到静态 agent.readiness('unknown'),状态点保持 amber。
110
+ // loading 指示器消失即告知用户探测已结束但未获得确定结果。
111
+ });
112
+ return () => {
113
+ cancelled = true;
114
+ };
115
+ }, [isOpen, readinessFetched, agent.enabled, agent.readiness, agent.name]);
116
+ // 有效 readiness:静态值为 'unknown' 且已获取动态值时使用动态值;
117
+ // 否则使用静态值(父组件 re-fetch 后若不再是 'unknown' 则自动优先)。
118
+ const effectiveReadiness = agent.readiness === "unknown" && dynamicReadiness !== null
119
+ ? dynamicReadiness
120
+ : agent.readiness;
76
121
  // locale 决定取 Zh 还是 En 字段
77
122
  const isZh = locale === "zh-CN";
78
123
  const displayName = isZh ? meta.displayNameZh : meta.displayNameEn;
@@ -81,14 +126,16 @@ export function AgentCard({ agent, meta, profiles, onBindingChange, saving, loca
81
126
  const impact = isZh ? meta.impactZh : meta.impactEn;
82
127
  const techDetail = isZh ? meta.techDetailZh : meta.techDetailEn;
83
128
  const mvpNote = isZh ? meta.mvpNoteZh : meta.mvpNoteEn;
129
+ const actionLinkText = isZh ? meta.action?.linkTextZh : meta.action?.linkTextEn;
84
130
  // 段落用 \n\n 分隔
85
131
  const detailParagraphs = detail.split("\n\n").filter((p) => p.length > 0);
86
- // 头部点击:toggle isOpen(但点击 toggle 按钮 / confirm-bar / tech-toggle 不触发)
132
+ // 头部点击:toggle isOpen(但点击 toggle 按钮 / confirm-bar / tech-toggle / action-row 不触发)
87
133
  const handleHeadClick = (e) => {
88
134
  const target = e.target;
89
135
  if (target.closest("[data-agent-toggle]") ||
90
136
  target.closest("[data-confirm-bar]") ||
91
- target.closest("[data-tech-toggle]")) {
137
+ target.closest("[data-tech-toggle]") ||
138
+ target.closest("[data-action-row]")) {
92
139
  return;
93
140
  }
94
141
  setIsOpen((prev) => !prev);
@@ -138,7 +185,7 @@ export function AgentCard({ agent, meta, profiles, onBindingChange, saving, loca
138
185
  e.preventDefault();
139
186
  setIsOpen((prev) => !prev);
140
187
  }
141
- }, children: [_jsx("div", { className: statusDotClasses(agent), "aria-hidden": "true" }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsxs("div", { className: cn("text-[14px] font-semibold tracking-[-0.005em] flex items-center gap-[8px]", agent.enabled ? "text-ink" : "text-ink-3"), children: [_jsx("span", { children: displayName }), _jsx("span", { className: "font-mono text-[11.5px] text-ink-4 font-normal", children: agent.name })] }), _jsx("div", { className: "text-[12.5px] text-ink-3 mt-[2px] leading-[1.5]", children: role })] }), _jsx("button", { type: "button", "data-agent-toggle": true, onClick: handleToggleClick, disabled: isSaving, "aria-label": agent.enabled
188
+ }, children: [_jsx("div", { className: statusDotClasses(effectiveReadiness, agent.enabled), "aria-hidden": "true" }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsxs("div", { className: cn("text-[14px] font-semibold tracking-[-0.005em] flex items-center gap-[8px]", agent.enabled ? "text-ink" : "text-ink-3"), children: [_jsx("span", { children: displayName }), _jsx("span", { className: "font-mono text-[11.5px] text-ink-4 font-normal", children: agent.name })] }), _jsx("div", { className: "text-[12.5px] text-ink-3 mt-[2px] leading-[1.5]", children: role })] }), _jsx("button", { type: "button", "data-agent-toggle": true, onClick: handleToggleClick, disabled: isSaving, "aria-label": agent.enabled
142
189
  ? t("pages.controlCenter.agentDisabled")
143
190
  : t("pages.controlCenter.agentEnabled"), className: cn("rounded-[3px] px-[14px] py-[6px] text-[12.5px] font-medium transition-colors disabled:opacity-50", agent.enabled
144
191
  ? "border border-gov bg-gov text-paper hover:bg-gov-2"
@@ -146,11 +193,20 @@ export function AgentCard({ agent, meta, profiles, onBindingChange, saving, loca
146
193
  ? t("pages.controlCenter.saving")
147
194
  : agent.enabled
148
195
  ? t("pages.controlCenter.on")
149
- : t("pages.controlCenter.off") }), _jsx(ChevronRight, { className: cn("w-[14px] h-[14px] text-ink-4 transition-transform shrink-0", isOpen && "rotate-90"), "aria-hidden": "true" })] }), isOpen && (_jsxs("div", { className: "px-[16px] pb-[14px] border-t border-line-2 bg-panel", children: [_jsx("div", { className: "pt-[14px] text-[13px] text-ink-3 leading-[1.62]", children: detailParagraphs.map((para, i) => (_jsx("p", { className: i > 0 ? "mt-2" : undefined, children: renderTextWithCode(para) }, i))) }), mvpNote && (_jsx("div", { className: "mt-3 text-[12px] text-ink-4 font-mono italic", children: mvpNote })), _jsxs("div", { className: cn("mt-[12px] px-[12px] py-[10px] border border-line-2 border-l-[2.5px] rounded-[4px] bg-paper-2 text-[12.5px] text-ink-3 leading-[1.55]", impactBorderClass(meta.impactLevel)), children: [_jsx("span", { className: cn("block mb-[3px] text-[10px] font-mono uppercase tracking-[0.08em] font-medium", impactLabelClass(meta.impactLevel)), children: t("pages.controlCenter.impact.label") }), impact] }), Object.keys(techDetail).length > 0 && (_jsxs(_Fragment, { children: [_jsxs("div", { "data-tech-toggle": true, className: "mt-[12px] pt-[12px] border-t border-line-2 flex items-center gap-[6px] cursor-pointer text-[11px] text-ink-4 font-mono uppercase tracking-[0.04em] hover:text-ink-2 transition-colors", onClick: handleTechToggleClick, role: "button", tabIndex: 0, "aria-expanded": showTechDetail, onKeyDown: (e) => {
196
+ : t("pages.controlCenter.off") }), _jsx(ChevronRight, { className: cn("w-[14px] h-[14px] text-ink-4 transition-transform shrink-0", isOpen && "rotate-90"), "aria-hidden": "true" })] }), isOpen && (_jsxs("div", { className: "px-[16px] pb-[14px] border-t border-line-2 bg-panel", children: [_jsx("div", { className: "pt-[14px] text-[13px] text-ink-3 leading-[1.62]", children: detailParagraphs.map((para, i) => (_jsx("p", { className: i > 0 ? "mt-2" : undefined, children: renderTextWithCode(para) }, i))) }), mvpNote && (_jsx("div", { className: "mt-3 text-[12px] text-ink-4 font-mono italic", children: mvpNote })), _jsxs("div", { className: cn("mt-[12px] px-[12px] py-[10px] border border-line-2 border-l-[2.5px] rounded-[4px] bg-paper-2 text-[12.5px] text-ink-3 leading-[1.55]", impactBorderClass(meta.impactLevel)), children: [_jsx("span", { className: cn("block mb-[3px] text-[10px] font-mono uppercase tracking-[0.08em] font-medium", impactLabelClass(meta.impactLevel)), children: t("pages.controlCenter.impact.label") }), impact] }), meta.action && actionLinkText && (_jsx("div", { "data-action-row": true, className: "mt-[12px] pt-[12px] border-t border-line-2", children: _jsxs("button", { type: "button", onClick: (e) => {
197
+ e.stopPropagation();
198
+ navigate(meta.action.to);
199
+ }, className: "flex items-center gap-[6px] text-[12px] text-gov hover:text-gov-2 transition-colors font-medium", children: [_jsx("span", { children: actionLinkText }), _jsx(ChevronRight, { className: "w-[12px] h-[12px]", "aria-hidden": "true" })] }) })), Object.keys(techDetail).length > 0 && (_jsxs(_Fragment, { children: [_jsxs("div", { "data-tech-toggle": true, className: "mt-[12px] pt-[12px] border-t border-line-2 flex items-center gap-[6px] cursor-pointer text-[11px] text-ink-4 font-mono uppercase tracking-[0.04em] hover:text-ink-2 transition-colors", onClick: handleTechToggleClick, role: "button", tabIndex: 0, "aria-expanded": showTechDetail, onKeyDown: (e) => {
150
200
  if (e.key === "Enter" || e.key === " ") {
151
201
  e.preventDefault();
152
202
  e.stopPropagation();
153
203
  setShowTechDetail((prev) => !prev);
154
204
  }
155
- }, children: [_jsx(ChevronRight, { className: cn("w-[12px] h-[12px] transition-transform", showTechDetail && "rotate-90"), "aria-hidden": "true" }), t("pages.controlCenter.techDetail")] }), showTechDetail && (_jsx("div", { className: "mt-2 grid grid-cols-[72px_1fr] gap-x-[14px] gap-y-[6px] text-[12px] leading-[1.55]", children: Object.entries(techDetail).map(([k, v]) => (_jsxs("div", { className: "contents", children: [_jsx("div", { className: "text-ink-4 font-mono text-[10.5px] uppercase tracking-[0.04em] pt-px", children: k }), _jsx("div", { className: "text-ink-3", children: renderTextWithCode(v) })] }, k))) }))] })), _jsxs("div", { className: "mt-[12px] pt-[12px] border-t border-line-2 flex items-center gap-[10px] text-[12px]", children: [_jsx("span", { className: "text-ink-4 font-mono text-[10.5px] uppercase tracking-[0.04em]", children: t("pages.controlCenter.profileLabelShort") }), _jsx("select", { value: agent.runtimeProfileId, onChange: handleProfileChange, disabled: isSaving, className: "font-mono text-[11px] text-ink-2 bg-surface border border-line-2 rounded-[3px] px-2 py-1 cursor-pointer focus:outline-none focus:border-gov disabled:opacity-50", "aria-label": t("pages.controlCenter.profileLabel"), children: profiles.map((p) => (_jsx("option", { value: p.id, children: p.label }, p.id))) })] }), confirming && (_jsxs("div", { "data-confirm-bar": true, className: "mt-[10px] px-[12px] py-[10px] border border-danger rounded-[4px] bg-danger/10 text-[12px] text-ink-2 leading-[1.55]", children: [_jsx("div", { children: impact }), _jsxs("div", { className: "mt-2 flex gap-[8px]", children: [_jsx("button", { type: "button", onClick: handleConfirmOff, className: "text-[11.5px] px-[12px] py-[4px] rounded-[3px] border border-transparent bg-danger text-paper font-medium hover:opacity-90 transition-opacity focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.controlCenter.impact.confirmAck") }), _jsx("button", { type: "button", onClick: handleCancelConfirm, className: "text-[11.5px] px-[12px] py-[4px] rounded-[3px] border border-line bg-transparent text-ink-3 hover:border-line-2 transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.controlCenter.impact.confirmCancel") })] })] }))] }))] }));
205
+ }, children: [_jsx(ChevronRight, { className: cn("w-[12px] h-[12px] transition-transform", showTechDetail && "rotate-90"), "aria-hidden": "true" }), t("pages.controlCenter.techDetail")] }), showTechDetail && (_jsx("div", { className: "mt-2 grid grid-cols-[72px_1fr] gap-x-[14px] gap-y-[6px] text-[12px] leading-[1.55]", children: Object.entries(techDetail).map(([k, v]) => (_jsxs("div", { className: "contents", children: [_jsx("div", { className: "text-ink-4 font-mono text-[10.5px] uppercase tracking-[0.04em] pt-px", children: k }), _jsx("div", { className: "text-ink-3", children: renderTextWithCode(v) })] }, k))) }))] })), _jsxs("div", { className: "mt-[12px] pt-[12px] border-t border-line-2 flex items-center gap-[10px] text-[12px] flex-wrap", children: [_jsx("span", { className: "text-ink-4 font-mono text-[10.5px] uppercase tracking-[0.04em]", children: t("pages.controlCenter.profileLabelShort") }), _jsx("select", { value: agent.runtimeProfileId, onChange: handleProfileChange, disabled: isSaving, className: "font-mono text-[11px] text-ink-2 bg-surface border border-line-2 rounded-[3px] px-2 py-1 cursor-pointer focus:outline-none focus:border-gov disabled:opacity-50", "aria-label": t("pages.controlCenter.profileLabel"), children: profiles.map((p) => (_jsx("option", { value: p.id, children: p.label }, p.id))) }), readinessLoading && (_jsx("span", { className: "text-[10.5px] text-ink-4 font-mono animate-pulse", children: t("pages.controlCenter.readinessChecking") })), _jsx("button", { type: "button", "data-manage-profiles": true, onClick: (e) => {
206
+ e.stopPropagation();
207
+ const el = document.getElementById("runtime-profile-manager");
208
+ if (el) {
209
+ el.scrollIntoView({ behavior: "smooth", block: "start" });
210
+ }
211
+ }, className: "ml-auto text-[11px] text-ink-4 hover:text-ink-2 transition-colors px-[8px] py-[3px] border border-line-2 rounded-[3px] focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", "aria-label": t("pages.controlCenter.manageProfiles"), children: t("pages.controlCenter.manageProfiles") })] }), confirming && (_jsxs("div", { "data-confirm-bar": true, className: "mt-[10px] px-[12px] py-[10px] border border-danger rounded-[4px] bg-danger/10 text-[12px] text-ink-2 leading-[1.55]", children: [_jsx("div", { children: impact }), _jsxs("div", { className: "mt-2 flex gap-[8px]", children: [_jsx("button", { type: "button", onClick: handleConfirmOff, className: "text-[11.5px] px-[12px] py-[4px] rounded-[3px] border border-transparent bg-danger text-paper font-medium hover:opacity-90 transition-opacity focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.controlCenter.impact.confirmAck") }), _jsx("button", { type: "button", onClick: handleCancelConfirm, className: "text-[11.5px] px-[12px] py-[4px] rounded-[3px] border border-line bg-transparent text-ink-3 hover:border-line-2 transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.controlCenter.impact.confirmCancel") })] })] }))] }))] }));
156
212
  }
@@ -11,6 +11,7 @@ import { enumLabel } from "../../utils/enum-labels.js";
11
11
  import { EmpathyObserverCostHint } from "./EmpathyObserverCostHint.js";
12
12
  import { WorkflowDiagram } from "./WorkflowDiagram.js";
13
13
  import { AgentGroup } from "./AgentGroup.js";
14
+ import { RuntimeProfileManager } from "./RuntimeProfileManager.js";
14
15
  import { AGENT_GROUPS, AGENT_METADATA, } from "../../utils/agent-metadata.js";
15
16
  // ── Runtime validators (H section / ERR-001/005/009/013) ─────────────────────
16
17
  function validateSource(raw) {
@@ -503,9 +504,9 @@ export function ControlCenterPage() {
503
504
  const locale = i18n.language.startsWith("en")
504
505
  ? "en"
505
506
  : "zh-CN";
506
- return (_jsxs(_Fragment, { children: [AGENT_GROUPS.map((groupMeta) => (_jsx(AgentGroup, { groupMeta: groupMeta, agents: groups[groupMeta.id], profiles: availableProfiles, onBindingChange: handleBindingChange, saving: savingAgent, locale: locale }, groupMeta.id))), unknown.length > 0 && (_jsx("div", { className: "mt-3 px-3 py-2 border border-amber/30 border-l-2 border-l-amber rounded-[4px] bg-amber/10 text-[12.5px] text-ink-3", children: t("pages.controlCenter.unknownAgentsWarning", {
507
+ return (_jsxs(_Fragment, { children: [AGENT_GROUPS.map((groupMeta) => (_jsx(AgentGroup, { groupMeta: groupMeta, agents: (groups[groupMeta.id] ?? []).filter((a) => a.name !== AGENT_METADATA.signalCollector.name), profiles: availableProfiles, onBindingChange: handleBindingChange, saving: savingAgent, locale: locale }, groupMeta.id))), unknown.length > 0 && (_jsx("div", { className: "mt-3 px-3 py-2 border border-amber/30 border-l-2 border-l-amber rounded-[4px] bg-amber/10 text-[12.5px] text-ink-3", children: t("pages.controlCenter.unknownAgentsWarning", {
507
508
  count: unknown.length,
508
509
  names: unknown.map((a) => a.name).join(", "),
509
510
  }) }))] }));
510
- })()] }), _jsxs("section", { className: "mt-8", "aria-labelledby": "section-default-runtime", children: [_jsx(SectionTitle, { id: "section-default-runtime", children: t("pages.controlCenter.defaultRuntime") }), _jsx(DefaultRuntimeSelector, { currentDefault: configData.defaultRuntime, profiles: availableProfiles, onDefaultChange: handleDefaultRuntimeChange, saving: savingDefault })] }), _jsx("section", { className: "mt-8", "aria-labelledby": "section-diagnostics", children: _jsx(AdvancedDiagnostics, { config: configData }) }), _jsx("p", { className: "mt-10 pt-[18px] border-t border-line-2 text-ink-4 text-[12px] leading-[1.6] max-w-[60ch] font-mono", children: t("pages.controlCenter.footerNote") })] }) }));
511
+ })()] }), _jsxs("section", { className: "mt-8", "aria-labelledby": "section-default-runtime", children: [_jsx(SectionTitle, { id: "section-default-runtime", children: t("pages.controlCenter.defaultRuntime") }), _jsx(DefaultRuntimeSelector, { currentDefault: configData.defaultRuntime, profiles: availableProfiles, onDefaultChange: handleDefaultRuntimeChange, saving: savingDefault })] }), _jsxs("section", { className: "mt-8", "aria-labelledby": "section-runtime-profiles", children: [_jsx(SectionTitle, { id: "section-runtime-profiles", children: t("pages.controlCenter.profiles.sectionTitle") }), _jsx(RuntimeProfileManager, { profiles: availableProfiles, defaultRuntimeId: configData.defaultRuntime, onMutated: loadData })] }), _jsx("section", { className: "mt-8", "aria-labelledby": "section-diagnostics", children: _jsx(AdvancedDiagnostics, { config: configData }) }), _jsx("p", { className: "mt-10 pt-[18px] border-t border-line-2 text-ink-4 text-[12px] leading-[1.6] max-w-[60ch] font-mono", children: t("pages.controlCenter.footerNote") })] }) }));
511
512
  }
@@ -0,0 +1,31 @@
1
+ import type { RedactedRuntimeProfileSummary } from "../../api.js";
2
+ /**
3
+ * RuntimeProfileManager — runtime profile CRUD UI.
4
+ *
5
+ * Renders a table of all runtime profiles with Create / Edit / Delete actions.
6
+ * The form is an inline panel (not a modal) to match the subtle, restrained
7
+ * aesthetic of AgentCard. Delete uses an inline confirmation bar.
8
+ *
9
+ * rc 合规:
10
+ * - rc-1: profiles 已由父组件 (ControlCenterPage) 用 validateRuntimeProfileSummary
11
+ * 验证;本组件不再重新解析。
12
+ * - rc-2: 无 as 绕过 — 表单 state 用强类型 ProfileFormState,API 响应用
13
+ * validateRuntimeProfileMutation 校验。
14
+ * - rc-3: 必填字段 (id / pi-ai 的 provider/model/apiKeyEnv) 缺失时 fail loud,
15
+ * 显示内联校验错误,不发请求。
16
+ * - rc-9: API 失败时通过 toast + 内联错误消息展示原因,不静默。
17
+ *
18
+ * 品牌约束 (PRI-CR1 B.4.4):
19
+ * - 无 translateY / scale hover,无硬编码色值
20
+ * - 状态点色板与 AgentCard 一致 (ready=green, needs_setup/not_ready/unknown=amber,
21
+ * disabled=ink-4)
22
+ */
23
+ interface RuntimeProfileManagerProps {
24
+ profiles: RedactedRuntimeProfileSummary[];
25
+ /** ID of the profile currently set as defaultRuntime (cannot be deleted). */
26
+ defaultRuntimeId: string;
27
+ /** Called after a successful create/update/delete so the parent re-fetches. */
28
+ onMutated: () => void;
29
+ }
30
+ export declare function RuntimeProfileManager({ profiles, defaultRuntimeId, onMutated, }: RuntimeProfileManagerProps): import("react/jsx-runtime").JSX.Element;
31
+ export {};