create-principles-disciple 1.82.0 → 1.83.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 (494) hide show
  1. package/console/dist/server/config/pd-config-store.d.ts +135 -0
  2. package/console/dist/server/config/pd-config-store.js +660 -0
  3. package/console/dist/server/index.js +40 -389
  4. package/console/dist/server/models/ActivationsConsoleModel.d.ts +33 -0
  5. package/console/dist/server/models/ActivationsConsoleModel.js +112 -0
  6. package/console/dist/server/models/ApprovalsConsoleModel.d.ts +5 -0
  7. package/console/dist/server/models/ApprovalsConsoleModel.js +14 -0
  8. package/console/dist/server/models/ApprovalsGroupedConsoleModel.d.ts +25 -0
  9. package/console/dist/server/models/ApprovalsGroupedConsoleModel.js +126 -0
  10. package/console/dist/server/models/ConsoleLifecycleDatasource.d.ts +13 -0
  11. package/console/dist/server/models/ConsoleLifecycleDatasource.js +73 -0
  12. package/console/dist/server/models/EvidenceChainConsoleModel.d.ts +58 -0
  13. package/console/dist/server/models/EvidenceChainConsoleModel.js +493 -0
  14. package/console/dist/server/models/GovernanceConsoleModel.d.ts +74 -0
  15. package/console/dist/server/models/GovernanceConsoleModel.js +246 -0
  16. package/console/dist/server/models/HealthCheckModel.d.ts +0 -4
  17. package/console/dist/server/models/HealthCheckModel.js +49 -80
  18. package/console/dist/server/models/LifecycleConsoleModel.d.ts +19 -0
  19. package/console/dist/server/models/LifecycleConsoleModel.js +55 -0
  20. package/console/dist/server/models/PrincipleClassifier.d.ts +41 -0
  21. package/console/dist/server/models/PrincipleClassifier.js +100 -0
  22. package/console/dist/server/models/PrinciplesConsoleModel.d.ts +12 -1
  23. package/console/dist/server/models/PrinciplesConsoleModel.js +53 -6
  24. package/console/dist/server/models/WorkspaceService.d.ts +2 -1
  25. package/console/dist/server/models/WorkspaceService.js +51 -23
  26. package/console/dist/server/routes/activations.d.ts +3 -0
  27. package/console/dist/server/routes/activations.js +111 -0
  28. package/console/dist/server/routes/approvals-grouped.d.ts +3 -0
  29. package/console/dist/server/routes/approvals-grouped.js +32 -0
  30. package/console/dist/server/routes/approvals.js +28 -4
  31. package/console/dist/server/routes/config.d.ts +27 -0
  32. package/console/dist/server/routes/config.js +213 -0
  33. package/console/dist/server/routes/evidence-chain.d.ts +9 -0
  34. package/console/dist/server/routes/evidence-chain.js +32 -0
  35. package/console/dist/server/routes/governance.d.ts +3 -0
  36. package/console/dist/server/routes/governance.js +32 -0
  37. package/console/dist/server/routes/{evolution.d.ts → lifecycle.d.ts} +2 -2
  38. package/console/dist/server/routes/lifecycle.js +48 -0
  39. package/console/dist/server/routes/principles.js +74 -1
  40. package/console/dist/server/routes/workspaces.js +8 -1
  41. package/console/dist/server/utils/response.d.ts +1 -1
  42. package/console/dist/server/utils/response.js +6 -2
  43. package/console/dist/types.d.ts +1 -0
  44. package/console/dist/ui/App.js +116 -40
  45. package/console/dist/ui/api.d.ts +88 -501
  46. package/console/dist/ui/api.js +139 -162
  47. package/console/dist/ui/components/approval-card.js +1 -1
  48. package/console/dist/ui/components/approval-detail-dialog.js +1 -1
  49. package/console/dist/ui/components/auth/login-form.d.ts +3 -0
  50. package/console/dist/ui/components/auth/login-form.js +36 -0
  51. package/console/dist/ui/components/auth/splash-screen.d.ts +8 -0
  52. package/console/dist/ui/components/auth/splash-screen.js +22 -0
  53. package/console/dist/ui/components/layout/app-sidebar.d.ts +1 -0
  54. package/console/dist/ui/components/layout/app-sidebar.js +56 -0
  55. package/console/dist/ui/components/layout/page-shell.d.ts +11 -0
  56. package/console/dist/ui/components/layout/page-shell.js +10 -0
  57. package/console/dist/ui/components/layout/section-title.d.ts +10 -0
  58. package/console/dist/ui/components/layout/section-title.js +9 -0
  59. package/console/dist/ui/components/theme-provider.d.ts +1 -1
  60. package/console/dist/ui/components/theme-provider.js +13 -8
  61. package/console/dist/ui/components/theme-toggle.js +2 -21
  62. package/console/dist/ui/components/ui/badge.d.ts +1 -1
  63. package/console/dist/ui/components/ui/badge.js +7 -5
  64. package/console/dist/ui/components/ui/button.d.ts +2 -2
  65. package/console/dist/ui/components/ui/button.js +12 -11
  66. package/console/dist/ui/components/ui/card.js +6 -6
  67. package/console/dist/ui/components/ui/sheet.d.ts +1 -1
  68. package/console/dist/ui/i18n/en.json +401 -343
  69. package/console/dist/ui/i18n/index.js +2 -2
  70. package/console/dist/ui/i18n/zh-CN.json +406 -348
  71. package/console/dist/ui/main.d.ts +1 -1
  72. package/console/dist/ui/main.js +1 -0
  73. package/console/dist/ui/pages/activation/ActivationPage.d.ts +1 -0
  74. package/console/dist/ui/pages/activation/ActivationPage.js +150 -0
  75. package/console/dist/ui/pages/activation/ActivationValidators.d.ts +20 -0
  76. package/console/dist/ui/pages/activation/ActivationValidators.js +156 -0
  77. package/console/dist/ui/pages/control-center/ControlCenterPage.d.ts +1 -0
  78. package/console/dist/ui/pages/control-center/ControlCenterPage.js +447 -0
  79. package/console/dist/ui/pages/debt/DebtPage.d.ts +1 -0
  80. package/console/dist/ui/pages/debt/DebtPage.js +5 -0
  81. package/console/dist/ui/pages/design-system/DesignSystemPage.d.ts +1 -0
  82. package/console/dist/ui/pages/design-system/DesignSystemPage.js +30 -0
  83. package/console/dist/ui/pages/focus/FocusPage.d.ts +1 -0
  84. package/console/dist/ui/pages/focus/FocusPage.js +265 -0
  85. package/console/dist/ui/pages/pain/PainEvidenceValidators.d.ts +59 -0
  86. package/console/dist/ui/pages/pain/PainEvidenceValidators.js +125 -0
  87. package/console/dist/ui/pages/pain/PainPage.js +136 -0
  88. package/console/dist/ui/pages/principles/PrincipleDetailPage.js +264 -0
  89. package/console/dist/ui/pages/principles/PrinciplesPage.js +244 -0
  90. package/console/dist/ui/pages/report-problem/ReportProblemPage.js +245 -0
  91. package/console/dist/ui/pages/settings/SettingsPage.d.ts +4 -0
  92. package/console/dist/ui/pages/settings/SettingsPage.js +202 -0
  93. package/console/dist/ui/pages/settings/UpdatePage.d.ts +5 -0
  94. package/console/dist/ui/pages/settings/UpdatePage.js +168 -0
  95. package/console/dist/ui/utils/control-center-helpers.d.ts +58 -0
  96. package/console/dist/ui/utils/control-center-helpers.js +152 -0
  97. package/console/dist/ui/utils/validators.d.ts +350 -0
  98. package/console/dist/ui/utils/validators.js +995 -0
  99. package/console/dist/web/assets/app.css +672 -902
  100. package/console/dist/web/assets/app.js +6404 -15347
  101. package/console/dist/web/assets/jetbrains-mono-cyrillic-400-normal-C5JECUCT.woff2 +0 -0
  102. package/console/dist/web/assets/jetbrains-mono-cyrillic-400-normal-FGCZYWMY.woff +0 -0
  103. package/console/dist/web/assets/jetbrains-mono-cyrillic-ext-400-normal-C7IFWGF6.woff2 +0 -0
  104. package/console/dist/web/assets/jetbrains-mono-cyrillic-ext-400-normal-PWXUA557.woff +0 -0
  105. package/console/dist/web/assets/jetbrains-mono-greek-400-normal-JJNQZMPZ.woff +0 -0
  106. package/console/dist/web/assets/jetbrains-mono-greek-400-normal-O7JTTR3P.woff2 +0 -0
  107. package/console/dist/web/assets/jetbrains-mono-latin-400-normal-3OOWLGQ2.woff2 +0 -0
  108. package/console/dist/web/assets/jetbrains-mono-latin-400-normal-WDD34GPP.woff +0 -0
  109. package/console/dist/web/assets/jetbrains-mono-latin-ext-400-normal-55RNMRQS.woff +0 -0
  110. package/console/dist/web/assets/jetbrains-mono-latin-ext-400-normal-JVR3IR4Z.woff2 +0 -0
  111. package/console/dist/web/assets/jetbrains-mono-vietnamese-400-normal-7ULXAK72.woff +0 -0
  112. package/console/dist/web/assets/jetbrains-mono-vietnamese-400-normal-KU7YLUPA.woff2 +0 -0
  113. package/console/package.json +2 -1
  114. package/core/dist/runtime-v2/__tests__/admission-gate.test.js +49 -0
  115. package/core/dist/runtime-v2/__tests__/admission-gate.test.js.map +1 -1
  116. package/core/dist/runtime-v2/__tests__/architecture-regression.test.js +16 -1
  117. package/core/dist/runtime-v2/__tests__/architecture-regression.test.js.map +1 -1
  118. package/core/dist/runtime-v2/__tests__/evidence-sanitizer.test.d.ts +21 -0
  119. package/core/dist/runtime-v2/__tests__/evidence-sanitizer.test.d.ts.map +1 -0
  120. package/core/dist/runtime-v2/__tests__/evidence-sanitizer.test.js +354 -0
  121. package/core/dist/runtime-v2/__tests__/evidence-sanitizer.test.js.map +1 -0
  122. package/core/dist/runtime-v2/__tests__/language-directive.test.d.ts +12 -0
  123. package/core/dist/runtime-v2/__tests__/language-directive.test.d.ts.map +1 -0
  124. package/core/dist/runtime-v2/__tests__/language-directive.test.js +162 -0
  125. package/core/dist/runtime-v2/__tests__/language-directive.test.js.map +1 -0
  126. package/core/dist/runtime-v2/__tests__/pain-signal-observability.test.js +23 -1
  127. package/core/dist/runtime-v2/__tests__/pain-signal-observability.test.js.map +1 -1
  128. package/core/dist/runtime-v2/__tests__/pain-to-principle-service.test.js +48 -3
  129. package/core/dist/runtime-v2/__tests__/pain-to-principle-service.test.js.map +1 -1
  130. package/core/dist/runtime-v2/__tests__/proven-channel-baseline.test.js +13 -1
  131. package/core/dist/runtime-v2/__tests__/proven-channel-baseline.test.js.map +1 -1
  132. package/core/dist/runtime-v2/__tests__/resolve-runtime-config-from-pd-config.test.d.ts +12 -0
  133. package/core/dist/runtime-v2/__tests__/resolve-runtime-config-from-pd-config.test.d.ts.map +1 -0
  134. package/core/dist/runtime-v2/__tests__/resolve-runtime-config-from-pd-config.test.js +194 -0
  135. package/core/dist/runtime-v2/__tests__/resolve-runtime-config-from-pd-config.test.js.map +1 -0
  136. package/core/dist/runtime-v2/__tests__/runtime-config-boundary.test.js +5 -3
  137. package/core/dist/runtime-v2/__tests__/runtime-config-boundary.test.js.map +1 -1
  138. package/core/dist/runtime-v2/activation/__tests__/activation-dispatcher.test.js +1 -0
  139. package/core/dist/runtime-v2/activation/__tests__/activation-dispatcher.test.js.map +1 -1
  140. package/core/dist/runtime-v2/activation/__tests__/approval-queue.test.js +54 -0
  141. package/core/dist/runtime-v2/activation/__tests__/approval-queue.test.js.map +1 -1
  142. package/core/dist/runtime-v2/activation/__tests__/memory-activation-state-store.test.js +15 -2
  143. package/core/dist/runtime-v2/activation/__tests__/memory-activation-state-store.test.js.map +1 -1
  144. package/core/dist/runtime-v2/activation/__tests__/prompt-activation-reader-contract.test.js +10 -0
  145. package/core/dist/runtime-v2/activation/__tests__/prompt-activation-reader-contract.test.js.map +1 -1
  146. package/core/dist/runtime-v2/activation/__tests__/sqlite-activation-state-store.test.js +17 -2
  147. package/core/dist/runtime-v2/activation/__tests__/sqlite-activation-state-store.test.js.map +1 -1
  148. package/core/dist/runtime-v2/activation/__tests__/sqlite-approval-store.test.js +36 -0
  149. package/core/dist/runtime-v2/activation/__tests__/sqlite-approval-store.test.js.map +1 -1
  150. package/core/dist/runtime-v2/activation/activation-dispatcher.d.ts.map +1 -1
  151. package/core/dist/runtime-v2/activation/activation-dispatcher.js +1 -1
  152. package/core/dist/runtime-v2/activation/activation-dispatcher.js.map +1 -1
  153. package/core/dist/runtime-v2/activation/activation-types.d.ts +10 -0
  154. package/core/dist/runtime-v2/activation/activation-types.d.ts.map +1 -1
  155. package/core/dist/runtime-v2/activation/activation-types.js.map +1 -1
  156. package/core/dist/runtime-v2/activation/approval-queue.d.ts +6 -0
  157. package/core/dist/runtime-v2/activation/approval-queue.d.ts.map +1 -1
  158. package/core/dist/runtime-v2/activation/approval-queue.js +3 -0
  159. package/core/dist/runtime-v2/activation/approval-queue.js.map +1 -1
  160. package/core/dist/runtime-v2/activation/memory-activation-state-store.d.ts +2 -0
  161. package/core/dist/runtime-v2/activation/memory-activation-state-store.d.ts.map +1 -1
  162. package/core/dist/runtime-v2/activation/memory-activation-state-store.js +17 -1
  163. package/core/dist/runtime-v2/activation/memory-activation-state-store.js.map +1 -1
  164. package/core/dist/runtime-v2/activation/memory-approval-store.d.ts +6 -0
  165. package/core/dist/runtime-v2/activation/memory-approval-store.d.ts.map +1 -1
  166. package/core/dist/runtime-v2/activation/memory-approval-store.js +16 -0
  167. package/core/dist/runtime-v2/activation/memory-approval-store.js.map +1 -1
  168. package/core/dist/runtime-v2/activation/prompt-activation-reader-contract.js +1 -1
  169. package/core/dist/runtime-v2/activation/prompt-activation-reader-contract.js.map +1 -1
  170. package/core/dist/runtime-v2/activation/sqlite-activation-state-store.d.ts +2 -0
  171. package/core/dist/runtime-v2/activation/sqlite-activation-state-store.d.ts.map +1 -1
  172. package/core/dist/runtime-v2/activation/sqlite-activation-state-store.js +34 -6
  173. package/core/dist/runtime-v2/activation/sqlite-activation-state-store.js.map +1 -1
  174. package/core/dist/runtime-v2/activation/sqlite-approval-store.d.ts +6 -0
  175. package/core/dist/runtime-v2/activation/sqlite-approval-store.d.ts.map +1 -1
  176. package/core/dist/runtime-v2/activation/sqlite-approval-store.js +10 -0
  177. package/core/dist/runtime-v2/activation/sqlite-approval-store.js.map +1 -1
  178. package/core/dist/runtime-v2/adapter/__tests__/json-extractor.test.js +51 -1
  179. package/core/dist/runtime-v2/adapter/__tests__/json-extractor.test.js.map +1 -1
  180. package/core/dist/runtime-v2/adapter/__tests__/openclaw-cli-runtime-adapter.test.js +145 -0
  181. package/core/dist/runtime-v2/adapter/__tests__/openclaw-cli-runtime-adapter.test.js.map +1 -1
  182. package/core/dist/runtime-v2/adapter/json-extractor.d.ts +13 -0
  183. package/core/dist/runtime-v2/adapter/json-extractor.d.ts.map +1 -1
  184. package/core/dist/runtime-v2/adapter/json-extractor.js +103 -0
  185. package/core/dist/runtime-v2/adapter/json-extractor.js.map +1 -1
  186. package/core/dist/runtime-v2/adapter/openclaw-cli-runtime-adapter.d.ts +4 -2
  187. package/core/dist/runtime-v2/adapter/openclaw-cli-runtime-adapter.d.ts.map +1 -1
  188. package/core/dist/runtime-v2/adapter/openclaw-cli-runtime-adapter.js +57 -5
  189. package/core/dist/runtime-v2/adapter/openclaw-cli-runtime-adapter.js.map +1 -1
  190. package/core/dist/runtime-v2/config/__tests__/pd-config-agent-binding.test.d.ts +18 -0
  191. package/core/dist/runtime-v2/config/__tests__/pd-config-agent-binding.test.d.ts.map +1 -0
  192. package/core/dist/runtime-v2/config/__tests__/pd-config-agent-binding.test.js +633 -0
  193. package/core/dist/runtime-v2/config/__tests__/pd-config-agent-binding.test.js.map +1 -0
  194. package/core/dist/runtime-v2/config/__tests__/pd-config-validation-edge-cases.test.js +92 -0
  195. package/core/dist/runtime-v2/config/__tests__/pd-config-validation-edge-cases.test.js.map +1 -1
  196. package/core/dist/runtime-v2/config/index.d.ts +3 -1
  197. package/core/dist/runtime-v2/config/index.d.ts.map +1 -1
  198. package/core/dist/runtime-v2/config/index.js +1 -0
  199. package/core/dist/runtime-v2/config/index.js.map +1 -1
  200. package/core/dist/runtime-v2/config/pd-config-agent-binding.d.ts +93 -0
  201. package/core/dist/runtime-v2/config/pd-config-agent-binding.d.ts.map +1 -0
  202. package/core/dist/runtime-v2/config/pd-config-agent-binding.js +184 -0
  203. package/core/dist/runtime-v2/config/pd-config-agent-binding.js.map +1 -0
  204. package/core/dist/runtime-v2/config/pd-config-defaults.d.ts.map +1 -1
  205. package/core/dist/runtime-v2/config/pd-config-defaults.js +2 -0
  206. package/core/dist/runtime-v2/config/pd-config-defaults.js.map +1 -1
  207. package/core/dist/runtime-v2/config/pd-config-effective.d.ts.map +1 -1
  208. package/core/dist/runtime-v2/config/pd-config-effective.js +3 -0
  209. package/core/dist/runtime-v2/config/pd-config-effective.js.map +1 -1
  210. package/core/dist/runtime-v2/config/pd-config-types.d.ts +8 -0
  211. package/core/dist/runtime-v2/config/pd-config-types.d.ts.map +1 -1
  212. package/core/dist/runtime-v2/config/pd-config-types.js.map +1 -1
  213. package/core/dist/runtime-v2/diagnostician/__tests__/diagnostician-prompt-language.test.d.ts +13 -0
  214. package/core/dist/runtime-v2/diagnostician/__tests__/diagnostician-prompt-language.test.d.ts.map +1 -0
  215. package/core/dist/runtime-v2/diagnostician/__tests__/diagnostician-prompt-language.test.js +97 -0
  216. package/core/dist/runtime-v2/diagnostician/__tests__/diagnostician-prompt-language.test.js.map +1 -0
  217. package/core/dist/runtime-v2/diagnostician-prompt-builder.d.ts +3 -2
  218. package/core/dist/runtime-v2/diagnostician-prompt-builder.d.ts.map +1 -1
  219. package/core/dist/runtime-v2/diagnostician-prompt-builder.js +6 -4
  220. package/core/dist/runtime-v2/diagnostician-prompt-builder.js.map +1 -1
  221. package/core/dist/runtime-v2/evidence-sanitizer.d.ts +57 -0
  222. package/core/dist/runtime-v2/evidence-sanitizer.d.ts.map +1 -0
  223. package/core/dist/runtime-v2/evidence-sanitizer.js +213 -0
  224. package/core/dist/runtime-v2/evidence-sanitizer.js.map +1 -0
  225. package/core/dist/runtime-v2/evidence-triage/__tests__/admission-events.test.d.ts +7 -0
  226. package/core/dist/runtime-v2/evidence-triage/__tests__/admission-events.test.d.ts.map +1 -0
  227. package/core/dist/runtime-v2/evidence-triage/__tests__/admission-events.test.js +170 -0
  228. package/core/dist/runtime-v2/evidence-triage/__tests__/admission-events.test.js.map +1 -0
  229. package/core/dist/runtime-v2/evidence-triage/__tests__/source-descriptors.test.d.ts +18 -0
  230. package/core/dist/runtime-v2/evidence-triage/__tests__/source-descriptors.test.d.ts.map +1 -0
  231. package/core/dist/runtime-v2/evidence-triage/__tests__/source-descriptors.test.js +277 -0
  232. package/core/dist/runtime-v2/evidence-triage/__tests__/source-descriptors.test.js.map +1 -0
  233. package/core/dist/runtime-v2/evidence-triage/__tests__/triage-policy.test.d.ts +13 -0
  234. package/core/dist/runtime-v2/evidence-triage/__tests__/triage-policy.test.d.ts.map +1 -0
  235. package/core/dist/runtime-v2/evidence-triage/__tests__/triage-policy.test.js +264 -0
  236. package/core/dist/runtime-v2/evidence-triage/__tests__/triage-policy.test.js.map +1 -0
  237. package/core/dist/runtime-v2/evidence-triage/__tests__/trigger-controller.test.d.ts +16 -0
  238. package/core/dist/runtime-v2/evidence-triage/__tests__/trigger-controller.test.d.ts.map +1 -0
  239. package/core/dist/runtime-v2/evidence-triage/__tests__/trigger-controller.test.js +316 -0
  240. package/core/dist/runtime-v2/evidence-triage/__tests__/trigger-controller.test.js.map +1 -0
  241. package/core/dist/runtime-v2/evidence-triage/admission-events.d.ts +126 -0
  242. package/core/dist/runtime-v2/evidence-triage/admission-events.d.ts.map +1 -0
  243. package/core/dist/runtime-v2/evidence-triage/admission-events.js +159 -0
  244. package/core/dist/runtime-v2/evidence-triage/admission-events.js.map +1 -0
  245. package/core/dist/runtime-v2/evidence-triage/index.d.ts +16 -0
  246. package/core/dist/runtime-v2/evidence-triage/index.d.ts.map +1 -0
  247. package/core/dist/runtime-v2/evidence-triage/index.js +13 -0
  248. package/core/dist/runtime-v2/evidence-triage/index.js.map +1 -0
  249. package/core/dist/runtime-v2/evidence-triage/source-descriptors.d.ts +48 -0
  250. package/core/dist/runtime-v2/evidence-triage/source-descriptors.d.ts.map +1 -0
  251. package/core/dist/runtime-v2/evidence-triage/source-descriptors.js +131 -0
  252. package/core/dist/runtime-v2/evidence-triage/source-descriptors.js.map +1 -0
  253. package/core/dist/runtime-v2/evidence-triage/triage-policy.d.ts +32 -0
  254. package/core/dist/runtime-v2/evidence-triage/triage-policy.d.ts.map +1 -0
  255. package/core/dist/runtime-v2/evidence-triage/triage-policy.js +95 -0
  256. package/core/dist/runtime-v2/evidence-triage/triage-policy.js.map +1 -0
  257. package/core/dist/runtime-v2/evidence-triage/trigger-controller.d.ts +116 -0
  258. package/core/dist/runtime-v2/evidence-triage/trigger-controller.d.ts.map +1 -0
  259. package/core/dist/runtime-v2/evidence-triage/trigger-controller.js +218 -0
  260. package/core/dist/runtime-v2/evidence-triage/trigger-controller.js.map +1 -0
  261. package/core/dist/runtime-v2/evidence-triage/types.d.ts +65 -0
  262. package/core/dist/runtime-v2/evidence-triage/types.d.ts.map +1 -0
  263. package/core/dist/runtime-v2/evidence-triage/types.js +38 -0
  264. package/core/dist/runtime-v2/evidence-triage/types.js.map +1 -0
  265. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js +10 -0
  266. package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js.map +1 -1
  267. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.d.ts.map +1 -1
  268. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js +1 -0
  269. package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js.map +1 -1
  270. package/core/dist/runtime-v2/index.d.ts +8 -1
  271. package/core/dist/runtime-v2/index.d.ts.map +1 -1
  272. package/core/dist/runtime-v2/index.js +7 -1
  273. package/core/dist/runtime-v2/index.js.map +1 -1
  274. package/core/dist/runtime-v2/internalization/__tests__/scribe-prompt-language.test.d.ts +12 -0
  275. package/core/dist/runtime-v2/internalization/__tests__/scribe-prompt-language.test.d.ts.map +1 -0
  276. package/core/dist/runtime-v2/internalization/__tests__/scribe-prompt-language.test.js +83 -0
  277. package/core/dist/runtime-v2/internalization/__tests__/scribe-prompt-language.test.js.map +1 -0
  278. package/core/dist/runtime-v2/internalization/scribe-prompt-builder.d.ts +10 -0
  279. package/core/dist/runtime-v2/internalization/scribe-prompt-builder.d.ts.map +1 -1
  280. package/core/dist/runtime-v2/internalization/scribe-prompt-builder.js +13 -1
  281. package/core/dist/runtime-v2/internalization/scribe-prompt-builder.js.map +1 -1
  282. package/core/dist/runtime-v2/internalization/scribe-runner.d.ts +3 -0
  283. package/core/dist/runtime-v2/internalization/scribe-runner.d.ts.map +1 -1
  284. package/core/dist/runtime-v2/internalization/scribe-runner.js +2 -0
  285. package/core/dist/runtime-v2/internalization/scribe-runner.js.map +1 -1
  286. package/core/dist/runtime-v2/internalization-chain-integrity-read-model.js +1 -1
  287. package/core/dist/runtime-v2/internalization-chain-integrity-read-model.js.map +1 -1
  288. package/core/dist/runtime-v2/language-directive.d.ts +80 -0
  289. package/core/dist/runtime-v2/language-directive.d.ts.map +1 -0
  290. package/core/dist/runtime-v2/language-directive.js +108 -0
  291. package/core/dist/runtime-v2/language-directive.js.map +1 -0
  292. package/core/dist/runtime-v2/pain-signal-observability.d.ts.map +1 -1
  293. package/core/dist/runtime-v2/pain-signal-observability.js +24 -11
  294. package/core/dist/runtime-v2/pain-signal-observability.js.map +1 -1
  295. package/core/dist/runtime-v2/pain-signal-runtime-factory.d.ts +16 -0
  296. package/core/dist/runtime-v2/pain-signal-runtime-factory.d.ts.map +1 -1
  297. package/core/dist/runtime-v2/pain-signal-runtime-factory.js +97 -6
  298. package/core/dist/runtime-v2/pain-signal-runtime-factory.js.map +1 -1
  299. package/core/dist/runtime-v2/pain-to-principle-service.d.ts +7 -0
  300. package/core/dist/runtime-v2/pain-to-principle-service.d.ts.map +1 -1
  301. package/core/dist/runtime-v2/pain-to-principle-service.js +2 -0
  302. package/core/dist/runtime-v2/pain-to-principle-service.js.map +1 -1
  303. package/core/dist/runtime-v2/proven-channel-baseline.d.ts.map +1 -1
  304. package/core/dist/runtime-v2/proven-channel-baseline.js +14 -0
  305. package/core/dist/runtime-v2/proven-channel-baseline.js.map +1 -1
  306. package/core/dist/runtime-v2/runner/__tests__/diagnostician-runner.test.js +40 -0
  307. package/core/dist/runtime-v2/runner/__tests__/diagnostician-runner.test.js.map +1 -1
  308. package/core/dist/runtime-v2/runner/base-peer-runner.d.ts.map +1 -1
  309. package/core/dist/runtime-v2/runner/base-peer-runner.js +1 -0
  310. package/core/dist/runtime-v2/runner/base-peer-runner.js.map +1 -1
  311. package/core/dist/runtime-v2/runner/diagnostician-runner-options.d.ts +10 -0
  312. package/core/dist/runtime-v2/runner/diagnostician-runner-options.d.ts.map +1 -1
  313. package/core/dist/runtime-v2/runner/diagnostician-runner-options.js +1 -0
  314. package/core/dist/runtime-v2/runner/diagnostician-runner-options.js.map +1 -1
  315. package/core/dist/runtime-v2/runner/diagnostician-runner.d.ts.map +1 -1
  316. package/core/dist/runtime-v2/runner/diagnostician-runner.js +28 -4
  317. package/core/dist/runtime-v2/runner/diagnostician-runner.js.map +1 -1
  318. package/core/dist/runtime-v2/runner/peer-runner-types.d.ts +9 -0
  319. package/core/dist/runtime-v2/runner/peer-runner-types.d.ts.map +1 -1
  320. package/core/dist/runtime-v2/store/runtime-state-manager.d.ts.map +1 -1
  321. package/core/dist/runtime-v2/store/runtime-state-manager.integration.test.js +34 -1
  322. package/core/dist/runtime-v2/store/runtime-state-manager.integration.test.js.map +1 -1
  323. package/core/dist/runtime-v2/store/runtime-state-manager.js +1 -0
  324. package/core/dist/runtime-v2/store/runtime-state-manager.js.map +1 -1
  325. package/core/dist/runtime-v2/store/sqlite-connection.d.ts.map +1 -1
  326. package/core/dist/runtime-v2/store/sqlite-connection.js +9 -1
  327. package/core/dist/runtime-v2/store/sqlite-connection.js.map +1 -1
  328. package/core/dist/runtime-v2/store/task/sqlite-task-store.js +1 -1
  329. package/core/dist/runtime-v2/store/task/sqlite-task-store.js.map +1 -1
  330. package/core/dist/runtime-v2/task-status.d.ts +4 -4
  331. package/core/dist/runtime-v2/task-status.d.ts.map +1 -1
  332. package/core/dist/runtime-v2/task-status.js +2 -2
  333. package/core/dist/runtime-v2/task-status.js.map +1 -1
  334. package/core/package.json +1 -1
  335. package/package.json +2 -2
  336. package/pd-cli/dist/commands/console.d.ts +2 -0
  337. package/pd-cli/dist/commands/console.d.ts.map +1 -1
  338. package/pd-cli/dist/commands/console.js +6 -1
  339. package/pd-cli/dist/commands/console.js.map +1 -1
  340. package/pd-cli/dist/commands/diagnose.d.ts.map +1 -1
  341. package/pd-cli/dist/commands/diagnose.js +18 -1
  342. package/pd-cli/dist/commands/diagnose.js.map +1 -1
  343. package/pd-cli/dist/commands/pain-evidence.d.ts +41 -0
  344. package/pd-cli/dist/commands/pain-evidence.d.ts.map +1 -0
  345. package/pd-cli/dist/commands/pain-evidence.js +177 -0
  346. package/pd-cli/dist/commands/pain-evidence.js.map +1 -0
  347. package/pd-cli/dist/commands/pain-record.d.ts.map +1 -1
  348. package/pd-cli/dist/commands/pain-record.js +24 -9
  349. package/pd-cli/dist/commands/pain-record.js.map +1 -1
  350. package/pd-cli/dist/commands/pain-retry.d.ts +19 -0
  351. package/pd-cli/dist/commands/pain-retry.d.ts.map +1 -0
  352. package/pd-cli/dist/commands/pain-retry.js +485 -0
  353. package/pd-cli/dist/commands/pain-retry.js.map +1 -0
  354. package/pd-cli/dist/commands/runtime-internalization-run-once.d.ts.map +1 -1
  355. package/pd-cli/dist/commands/runtime-internalization-run-once.js +59 -9
  356. package/pd-cli/dist/commands/runtime-internalization-run-once.js.map +1 -1
  357. package/pd-cli/dist/commands/runtime-uat.d.ts +1 -0
  358. package/pd-cli/dist/commands/runtime-uat.d.ts.map +1 -1
  359. package/pd-cli/dist/commands/runtime-uat.guard.test.d.ts +2 -0
  360. package/pd-cli/dist/commands/runtime-uat.guard.test.d.ts.map +1 -0
  361. package/pd-cli/dist/commands/runtime-uat.guard.test.js +155 -0
  362. package/pd-cli/dist/commands/runtime-uat.guard.test.js.map +1 -0
  363. package/pd-cli/dist/commands/runtime-uat.js +29 -3
  364. package/pd-cli/dist/commands/runtime-uat.js.map +1 -1
  365. package/pd-cli/dist/config-reader.d.ts +25 -0
  366. package/pd-cli/dist/config-reader.d.ts.map +1 -0
  367. package/pd-cli/dist/config-reader.js +109 -0
  368. package/pd-cli/dist/config-reader.js.map +1 -0
  369. package/pd-cli/dist/index.js +40 -5
  370. package/pd-cli/dist/index.js.map +1 -1
  371. package/pd-cli/dist/services/console-launcher.d.ts.map +1 -1
  372. package/pd-cli/dist/services/console-launcher.js +29 -15
  373. package/pd-cli/dist/services/console-launcher.js.map +1 -1
  374. package/pd-cli/dist/services/demo-story-a-runner.d.ts.map +1 -1
  375. package/pd-cli/dist/services/demo-story-a-runner.js +1 -0
  376. package/pd-cli/dist/services/demo-story-a-runner.js.map +1 -1
  377. package/pd-cli/dist/utils/production-workspace-guard.d.ts +77 -0
  378. package/pd-cli/dist/utils/production-workspace-guard.d.ts.map +1 -0
  379. package/pd-cli/dist/utils/production-workspace-guard.js +170 -0
  380. package/pd-cli/dist/utils/production-workspace-guard.js.map +1 -0
  381. package/pd-cli/dist/utils/production-workspace-guard.test.d.ts +2 -0
  382. package/pd-cli/dist/utils/production-workspace-guard.test.d.ts.map +1 -0
  383. package/pd-cli/dist/utils/production-workspace-guard.test.js +95 -0
  384. package/pd-cli/dist/utils/production-workspace-guard.test.js.map +1 -0
  385. package/pd-cli/package.json +1 -1
  386. package/plugin/dist/commands/pain.js +27 -2
  387. package/plugin/dist/core/pain-diagnostic-gate.d.ts +6 -0
  388. package/plugin/dist/core/pain-diagnostic-gate.js +9 -0
  389. package/plugin/dist/hooks/after-tool-call-helpers.d.ts +90 -0
  390. package/plugin/dist/hooks/after-tool-call-helpers.js +486 -0
  391. package/plugin/dist/hooks/after-tool-call-types.d.ts +92 -0
  392. package/plugin/dist/hooks/after-tool-call-types.js +13 -0
  393. package/plugin/dist/hooks/gate-block-helper.js +73 -29
  394. package/plugin/dist/hooks/llm.js +49 -29
  395. package/plugin/dist/hooks/message-sanitize.d.ts +21 -0
  396. package/plugin/dist/hooks/message-sanitize.js +30 -0
  397. package/plugin/dist/hooks/pain.d.ts +26 -3
  398. package/plugin/dist/hooks/pain.js +165 -425
  399. package/plugin/dist/hooks/prompt.js +3 -2
  400. package/plugin/dist/hooks/trajectory-evidence.d.ts +11 -0
  401. package/plugin/dist/hooks/trajectory-evidence.js +65 -0
  402. package/plugin/dist/hooks/triage-adapter.d.ts +82 -0
  403. package/plugin/dist/hooks/triage-adapter.js +121 -0
  404. package/console/dist/server/models/EventLogReadModel.d.ts +0 -33
  405. package/console/dist/server/models/EventLogReadModel.js +0 -218
  406. package/console/dist/server/models/EvolutionConsoleModel.d.ts +0 -79
  407. package/console/dist/server/models/EvolutionConsoleModel.js +0 -179
  408. package/console/dist/server/models/FeedbackConsoleModel.d.ts +0 -38
  409. package/console/dist/server/models/FeedbackConsoleModel.js +0 -129
  410. package/console/dist/server/models/GateConsoleModel.d.ts +0 -50
  411. package/console/dist/server/models/GateConsoleModel.js +0 -151
  412. package/console/dist/server/models/OverviewConsoleModel.d.ts +0 -22
  413. package/console/dist/server/models/OverviewConsoleModel.js +0 -202
  414. package/console/dist/server/models/PipelineStatsModel.d.ts +0 -35
  415. package/console/dist/server/models/PipelineStatsModel.js +0 -129
  416. package/console/dist/server/models/SampleConsoleModel.d.ts +0 -21
  417. package/console/dist/server/models/SampleConsoleModel.js +0 -188
  418. package/console/dist/server/models/ThinkingModelsConsoleModel.d.ts +0 -22
  419. package/console/dist/server/models/ThinkingModelsConsoleModel.js +0 -75
  420. package/console/dist/server/routes/agents.d.ts +0 -3
  421. package/console/dist/server/routes/agents.js +0 -442
  422. package/console/dist/server/routes/central.d.ts +0 -5
  423. package/console/dist/server/routes/central.js +0 -31
  424. package/console/dist/server/routes/events.d.ts +0 -10
  425. package/console/dist/server/routes/events.js +0 -99
  426. package/console/dist/server/routes/evolution.js +0 -73
  427. package/console/dist/server/routes/feedback.d.ts +0 -3
  428. package/console/dist/server/routes/feedback.js +0 -65
  429. package/console/dist/server/routes/gates.d.ts +0 -3
  430. package/console/dist/server/routes/gates.js +0 -52
  431. package/console/dist/server/routes/overview.d.ts +0 -3
  432. package/console/dist/server/routes/overview.js +0 -49
  433. package/console/dist/server/routes/pipeline.d.ts +0 -3
  434. package/console/dist/server/routes/pipeline.js +0 -33
  435. package/console/dist/server/routes/samples.d.ts +0 -3
  436. package/console/dist/server/routes/samples.js +0 -101
  437. package/console/dist/server/routes/thinking-models.d.ts +0 -3
  438. package/console/dist/server/routes/thinking-models.js +0 -54
  439. package/console/dist/ui/components/app-sidebar.d.ts +0 -7
  440. package/console/dist/ui/components/app-sidebar.js +0 -75
  441. package/console/dist/ui/components/compare-view.d.ts +0 -7
  442. package/console/dist/ui/components/compare-view.js +0 -32
  443. package/console/dist/ui/components/data-freshness-indicator.d.ts +0 -10
  444. package/console/dist/ui/components/data-freshness-indicator.js +0 -63
  445. package/console/dist/ui/components/health-diagnostic-card.d.ts +0 -15
  446. package/console/dist/ui/components/health-diagnostic-card.js +0 -42
  447. package/console/dist/ui/components/page-header.d.ts +0 -10
  448. package/console/dist/ui/components/page-header.js +0 -37
  449. package/console/dist/ui/hooks/useAutoRefresh.d.ts +0 -13
  450. package/console/dist/ui/hooks/useAutoRefresh.js +0 -64
  451. package/console/dist/ui/hooks/useBookmarks.d.ts +0 -6
  452. package/console/dist/ui/hooks/useBookmarks.js +0 -43
  453. package/console/dist/ui/hooks/useDebounce.d.ts +0 -2
  454. package/console/dist/ui/hooks/useDebounce.js +0 -32
  455. package/console/dist/ui/hooks/useKeyboardNavigation.d.ts +0 -14
  456. package/console/dist/ui/hooks/useKeyboardNavigation.js +0 -75
  457. package/console/dist/ui/pages/AgentsPage.d.ts +0 -1
  458. package/console/dist/ui/pages/AgentsPage.js +0 -167
  459. package/console/dist/ui/pages/ApprovalsPage.d.ts +0 -1
  460. package/console/dist/ui/pages/ApprovalsPage.js +0 -123
  461. package/console/dist/ui/pages/CentralPage.d.ts +0 -1
  462. package/console/dist/ui/pages/CentralPage.js +0 -57
  463. package/console/dist/ui/pages/DataFlowPage.d.ts +0 -1
  464. package/console/dist/ui/pages/DataFlowPage.js +0 -158
  465. package/console/dist/ui/pages/EventLogPage.d.ts +0 -1
  466. package/console/dist/ui/pages/EventLogPage.js +0 -176
  467. package/console/dist/ui/pages/EvolutionPage.d.ts +0 -1
  468. package/console/dist/ui/pages/EvolutionPage.js +0 -118
  469. package/console/dist/ui/pages/FeedbackPage.d.ts +0 -1
  470. package/console/dist/ui/pages/FeedbackPage.js +0 -46
  471. package/console/dist/ui/pages/GatesPage.d.ts +0 -1
  472. package/console/dist/ui/pages/GatesPage.js +0 -31
  473. package/console/dist/ui/pages/LoginPage.d.ts +0 -5
  474. package/console/dist/ui/pages/LoginPage.js +0 -39
  475. package/console/dist/ui/pages/OverviewPage.d.ts +0 -1
  476. package/console/dist/ui/pages/OverviewPage.js +0 -50
  477. package/console/dist/ui/pages/PainPage.js +0 -50
  478. package/console/dist/ui/pages/PrincipleDetailPage.js +0 -145
  479. package/console/dist/ui/pages/PrinciplesPage.js +0 -322
  480. package/console/dist/ui/pages/ReportProblemPage.js +0 -186
  481. package/console/dist/ui/pages/SamplesPage.d.ts +0 -1
  482. package/console/dist/ui/pages/SamplesPage.js +0 -105
  483. package/console/dist/ui/pages/SettingsPage.d.ts +0 -1
  484. package/console/dist/ui/pages/SettingsPage.js +0 -86
  485. package/console/dist/ui/pages/TasksPage.d.ts +0 -1
  486. package/console/dist/ui/pages/TasksPage.js +0 -373
  487. package/console/dist/ui/pages/ThinkingModelsPage.d.ts +0 -1
  488. package/console/dist/ui/pages/ThinkingModelsPage.js +0 -32
  489. package/console/dist/ui/pages/UpdatePage.d.ts +0 -1
  490. package/console/dist/ui/pages/UpdatePage.js +0 -142
  491. /package/console/dist/ui/pages/{PainPage.d.ts → pain/PainPage.d.ts} +0 -0
  492. /package/console/dist/ui/pages/{PrincipleDetailPage.d.ts → principles/PrincipleDetailPage.d.ts} +0 -0
  493. /package/console/dist/ui/pages/{PrinciplesPage.d.ts → principles/PrinciplesPage.d.ts} +0 -0
  494. /package/console/dist/ui/pages/{ReportProblemPage.d.ts → report-problem/ReportProblemPage.d.ts} +0 -0
@@ -0,0 +1,264 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useEffect, useCallback } from "react";
3
+ import { useParams, useNavigate } from "react-router-dom";
4
+ import { useTranslation } from "react-i18next";
5
+ import { toast } from "sonner";
6
+ import { PageShell } from "../../components/layout/page-shell.js";
7
+ import { SectionTitle } from "../../components/layout/section-title.js";
8
+ import { Button } from "../../components/ui/button.js";
9
+ import { fetchPrincipleDetail, fetchApprovalsGrouped, fetchLifecycleMetrics, approveApproval, rejectApproval, } from "../../api.js";
10
+ // ── Runtime validation (H section) ──────────────────────────────────────────
11
+ function isString(v) {
12
+ return typeof v === "string";
13
+ }
14
+ function isRecord(v) {
15
+ return typeof v === "object" && v !== null && !Array.isArray(v);
16
+ }
17
+ function safeStringArray(v) {
18
+ if (!Array.isArray(v))
19
+ return [];
20
+ return v.filter(isString);
21
+ }
22
+ function safeString(v, fallback = "") {
23
+ return typeof v === "string" ? v : fallback;
24
+ }
25
+ /**
26
+ * Validate and normalize a PrincipleDetail from untrusted network data.
27
+ * Returns a normalized object with safe defaults for all fields the page
28
+ * actually accesses. Never returns null for individual fields — only for
29
+ * completely unparseable top-level structures.
30
+ *
31
+ * Fields the page uses: id, text, status, triggerPattern, action,
32
+ * derivedFromPainIds (length + map), rules (length).
33
+ */
34
+ function validatePrincipleDetail(data) {
35
+ if (!isRecord(data))
36
+ return null;
37
+ if (!Object.hasOwn(data, "principle") || !isRecord(data.principle))
38
+ return null;
39
+ const raw = data.principle;
40
+ // Required fields — fail loud if missing
41
+ if (!Object.hasOwn(raw, "id") || !isString(raw.id))
42
+ return null;
43
+ if (!Object.hasOwn(raw, "text") || !isString(raw.text))
44
+ return null;
45
+ if (!Object.hasOwn(raw, "status") || !isString(raw.status))
46
+ return null;
47
+ // Normalize fields the page accesses with safe defaults
48
+ const normalized = {
49
+ ...raw,
50
+ triggerPattern: safeString(raw.triggerPattern),
51
+ action: safeString(raw.action),
52
+ derivedFromPainIds: safeStringArray(raw.derivedFromPainIds),
53
+ rules: Array.isArray(raw.rules) ? raw.rules : [],
54
+ };
55
+ return { principle: normalized };
56
+ }
57
+ function validateApprovalsGrouped(data) {
58
+ if (!isRecord(data))
59
+ return null;
60
+ if (!Object.hasOwn(data, "groups") || !Array.isArray(data.groups))
61
+ return null;
62
+ for (const g of data.groups) {
63
+ if (!isRecord(g))
64
+ return null;
65
+ if (!Object.hasOwn(g, "principleId") || !isString(g.principleId))
66
+ return null;
67
+ if (!Object.hasOwn(g, "status") || !isString(g.status))
68
+ return null;
69
+ if (!Object.hasOwn(g, "records") || !Array.isArray(g.records))
70
+ return null;
71
+ for (const r of g.records) {
72
+ if (!isRecord(r))
73
+ return null;
74
+ if (!Object.hasOwn(r, "id") || !isString(r.id))
75
+ return null;
76
+ if (!Object.hasOwn(r, "channel") || !isString(r.channel))
77
+ return null;
78
+ }
79
+ }
80
+ return data;
81
+ }
82
+ function validateLifecycleMetrics(data) {
83
+ if (!isRecord(data))
84
+ return null;
85
+ if (!Object.hasOwn(data, "adherence") || !isRecord(data.adherence))
86
+ return null;
87
+ const a = data.adherence;
88
+ if (!Object.hasOwn(a, "insufficientData") || typeof a.insufficientData !== "boolean")
89
+ return null;
90
+ if (!Object.hasOwn(a, "note") || !isString(a.note))
91
+ return null;
92
+ // rate can be number or null
93
+ if (Object.hasOwn(a, "rate") && a.rate !== null && typeof a.rate !== "number")
94
+ return null;
95
+ if (!Object.hasOwn(data, "ruleMetrics") || !Array.isArray(data.ruleMetrics))
96
+ return null;
97
+ return data;
98
+ }
99
+ // ── Trajectory stages for Layer 3 ───────────────────────────────────────────
100
+ const TRAJECTORY_STAGES = [
101
+ { key: "evidence", label: "evidence" },
102
+ { key: "diagnosis", label: "diagnosis" },
103
+ { key: "proposal", label: "proposal" },
104
+ { key: "review", label: "review" },
105
+ { key: "deploy", label: "deploy" },
106
+ { key: "behavior", label: "behavior" },
107
+ ];
108
+ // ── Component ───────────────────────────────────────────────────────────────
109
+ export function PrincipleDetailPage() {
110
+ const { t } = useTranslation("pages");
111
+ const { id } = useParams();
112
+ const navigate = useNavigate();
113
+ const [principle, setPrinciple] = useState(null);
114
+ const [approvalGroup, setApprovalGroup] = useState(null);
115
+ const [lifecycle, setLifecycle] = useState(null);
116
+ const [loading, setLoading] = useState(true);
117
+ const [error, setError] = useState(null);
118
+ // Decision state
119
+ const [showConfirm, setShowConfirm] = useState(false);
120
+ const [showRejectInput, setShowRejectInput] = useState(false);
121
+ const [rejectReason, setRejectReason] = useState("");
122
+ const [actionLoading, setActionLoading] = useState(false);
123
+ // Fetch data
124
+ const loadData = useCallback(async () => {
125
+ if (!id)
126
+ return;
127
+ setLoading(true);
128
+ setError(null);
129
+ try {
130
+ const [pResult, aResult, lResult] = await Promise.all([
131
+ fetchPrincipleDetail(id),
132
+ fetchApprovalsGrouped(),
133
+ fetchLifecycleMetrics(id),
134
+ ]);
135
+ if (!pResult.success) {
136
+ setError(pResult.error ?? "Failed to load principle");
137
+ return;
138
+ }
139
+ const pData = validatePrincipleDetail(pResult.data);
140
+ if (!pData) {
141
+ setError("Invalid principle data received");
142
+ return;
143
+ }
144
+ setPrinciple(pData.principle);
145
+ const aData = aResult.success ? validateApprovalsGrouped(aResult.data) : null;
146
+ if (aData) {
147
+ const group = aData.groups.find((g) => g.principleId === id);
148
+ setApprovalGroup(group ?? null);
149
+ }
150
+ const lData = lResult.success ? validateLifecycleMetrics(lResult.data) : null;
151
+ setLifecycle(lData);
152
+ }
153
+ catch (err) {
154
+ setError(err instanceof Error ? err.message : "Unknown error");
155
+ }
156
+ finally {
157
+ setLoading(false);
158
+ }
159
+ }, [id]);
160
+ useEffect(() => {
161
+ loadData();
162
+ }, [loadData]);
163
+ // ── Actions ─────────────────────────────────────────────────────────────
164
+ const handleApprove = () => setShowConfirm(true);
165
+ const cancelConfirm = () => setShowConfirm(false);
166
+ // ── Apply decision to all records in the group ──────────────────────────
167
+ // Constraint: "多通道审批记录在 UI 上收拢成对一条原则的单次治理决策"
168
+ // When owner approves/rejects a principle, ALL pending records must receive
169
+ // the same decision. Partial failure is reported loudly (ERR-002 / EP-03).
170
+ async function applyDecisionToAllRecords(action, reason) {
171
+ if (!approvalGroup)
172
+ return { allSucceeded: false, failedCount: 0, totalCount: 0 };
173
+ const records = approvalGroup.records;
174
+ let failedCount = 0;
175
+ for (const record of records) {
176
+ const result = action === "approve"
177
+ ? await approveApproval(record.id)
178
+ : await rejectApproval(record.id, reason ?? "");
179
+ if (!result.success) {
180
+ failedCount++;
181
+ }
182
+ }
183
+ return {
184
+ allSucceeded: failedCount === 0,
185
+ failedCount,
186
+ totalCount: records.length,
187
+ };
188
+ }
189
+ const confirmApprove = async () => {
190
+ if (!approvalGroup || actionLoading)
191
+ return;
192
+ setActionLoading(true);
193
+ try {
194
+ const { allSucceeded, failedCount, totalCount } = await applyDecisionToAllRecords("approve");
195
+ if (allSucceeded) {
196
+ toast.success(t("principles.detail.approved"));
197
+ setShowConfirm(false);
198
+ loadData();
199
+ }
200
+ else {
201
+ // Partial failure — fail loud (EP-03)
202
+ toast.error(t("principles.detail.partialFailure", {
203
+ defaultValue: `批准完成,但 ${failedCount}/${totalCount} 条记录失败。请检查后重试。`,
204
+ failedCount,
205
+ totalCount,
206
+ }));
207
+ loadData();
208
+ }
209
+ }
210
+ catch {
211
+ toast.error(t("principles.detail.approveFailed"));
212
+ }
213
+ finally {
214
+ setActionLoading(false);
215
+ }
216
+ };
217
+ const handleReject = () => setShowRejectInput(true);
218
+ const cancelReject = () => {
219
+ setShowRejectInput(false);
220
+ setRejectReason("");
221
+ };
222
+ const confirmReject = async () => {
223
+ if (!approvalGroup || !rejectReason.trim() || actionLoading)
224
+ return;
225
+ setActionLoading(true);
226
+ try {
227
+ const { allSucceeded, failedCount, totalCount } = await applyDecisionToAllRecords("reject", rejectReason.trim());
228
+ if (allSucceeded) {
229
+ toast.success(t("principles.detail.rejected"));
230
+ setShowRejectInput(false);
231
+ setRejectReason("");
232
+ loadData();
233
+ }
234
+ else {
235
+ // Partial failure — fail loud (EP-03)
236
+ toast.error(t("principles.detail.partialFailure", {
237
+ defaultValue: `拒绝完成,但 ${failedCount}/${totalCount} 条记录失败。请检查后重试。`,
238
+ failedCount,
239
+ totalCount,
240
+ }));
241
+ loadData();
242
+ }
243
+ }
244
+ catch {
245
+ toast.error(t("principles.detail.rejectFailed"));
246
+ }
247
+ finally {
248
+ setActionLoading(false);
249
+ }
250
+ };
251
+ const handlePark = () => {
252
+ toast.success(t("principles.detail.parked"));
253
+ };
254
+ // ── Render ──────────────────────────────────────────────────────────────
255
+ if (loading) {
256
+ return (_jsx(PageShell, { children: _jsx("p", { className: "text-ink-3 text-sm", children: t("principles.loading", { defaultValue: "Loading…" }) }) }));
257
+ }
258
+ if (error || !principle) {
259
+ return (_jsxs(PageShell, { children: [_jsxs(Button, { variant: "ghost", onClick: () => navigate("/principles"), className: "mb-4", children: ["\u2190 ", t("principles.detail.backToList")] }), _jsxs("div", { className: "border border-danger/30 rounded-[var(--radius-md)] p-4", children: [_jsx("p", { className: "text-danger text-sm", children: error ?? t("principles.notFound") }), _jsx(Button, { variant: "outline", size: "sm", onClick: loadData, className: "mt-2", children: t("principles.retry", { defaultValue: "Retry" }) })] })] }));
260
+ }
261
+ const isPending = approvalGroup?.status === "pending" || principle.status === "candidate" || principle.status === "probation";
262
+ const hasRules = principle.rules.length > 0;
263
+ return (_jsxs(PageShell, { children: [_jsxs(Button, { variant: "ghost", onClick: () => navigate("/principles"), className: "mb-4 -ml-2", children: ["\u2190 ", t("principles.detail.backToList")] }), _jsxs("section", { className: "mb-8", children: [_jsx(SectionTitle, { children: t("principles.detail.conclusion") }), _jsx("h1", { className: "text-[22px] font-semibold text-ink leading-snug mb-3", children: principle.text }), _jsx("p", { className: "text-ink-3 text-[14px] leading-relaxed mb-3", children: t("principles.detail.policyNote") }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Button, { variant: "outline", size: "sm", disabled: true, children: t("principles.detail.modifyWording") }), _jsx("span", { className: "text-ink-4 text-[13px]", children: t("principles.detail.modifyWordingNote") })] })] }), _jsxs("section", { className: "mb-8", children: [_jsx(SectionTitle, { children: t("principles.detail.channel") }), _jsx("p", { className: "text-ink-2 text-[14px] leading-relaxed", children: t("principles.detail.channelPromptReversible") })] }), _jsxs("section", { className: "mb-8", children: [_jsx(SectionTitle, { children: t("principles.detail.whyExists") }), _jsxs("div", { className: "space-y-3 mb-6", children: [_jsxs("div", { children: [_jsx("span", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3", children: t("principles.detail.applicable", { defaultValue: "适用场景" }) }), _jsx("p", { className: "text-ink-2 text-[14px] leading-relaxed", children: principle.triggerPattern || t("principles.detail.notSpecified", { defaultValue: "未指定" }) })] }), _jsxs("div", { children: [_jsx("span", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3", children: t("principles.detail.expectedBehavior", { defaultValue: "预期行为" }) }), _jsx("p", { className: "text-ink-2 text-[14px] leading-relaxed", children: principle.action || t("principles.detail.notSpecified", { defaultValue: "未指定" }) })] })] }), principle.derivedFromPainIds.length > 0 && (_jsxs("div", { children: [_jsx("span", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3", children: t("principles.detail.evidence") }), _jsx("ul", { className: "mt-2 space-y-1", children: principle.derivedFromPainIds.map((painId, idx) => (_jsxs("li", { className: "text-ink-2 text-[13px] font-mono", children: [idx + 1, ". ", painId] }, painId))) })] }))] }), _jsxs("section", { className: "mb-8 border-t border-line pt-6", children: [_jsx(SectionTitle, { children: t("principles.detail.ownerReflection") }), _jsxs("div", { className: "space-y-3", children: [_jsx("div", { className: "border-l-2 border-l-gov pl-3 text-ink-2 text-[13px] leading-relaxed", children: t("principles.detail.reflectionQ1") }), _jsx("div", { className: "border-l-2 border-l-gov pl-3 text-ink-2 text-[13px] leading-relaxed", children: t("principles.detail.reflectionQ2") }), _jsx("div", { className: "border-l-2 border-l-gov pl-3 text-ink-2 text-[13px] leading-relaxed", children: t("principles.detail.reflectionQ3") })] })] }), _jsxs("details", { className: "mb-8 border border-line rounded-[var(--radius-md)]", children: [_jsx("summary", { className: "px-4 py-3 cursor-pointer font-mono text-[11px] uppercase tracking-[0.1em] text-ink-3 hover:text-ink focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gov", children: t("principles.detail.trajectory") }), _jsxs("div", { className: "px-4 pb-4 border-t border-line pt-4", children: [_jsx("div", { className: "space-y-4", children: TRAJECTORY_STAGES.map((stage) => (_jsxs("div", { className: "flex gap-4", children: [_jsx("span", { className: "font-mono text-[12px] text-ink-3 min-w-[80px]", children: t("principles.detail.stage" + stage.key.charAt(0).toUpperCase() + stage.key.slice(1), { defaultValue: stage.label }) }), _jsx("div", { className: "flex-1", children: _jsx("p", { className: "text-ink-3 text-[13px]", children: t("principles.detail.stage" + stage.key.charAt(0).toUpperCase() + stage.key.slice(1) + "Desc", { defaultValue: "—" }) }) })] }, stage.key))) }), hasRules && lifecycle && (_jsxs("div", { className: "mt-6 pt-4 border-t border-line", children: [_jsx("span", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3", children: t("principles.detail.lifecycleMetrics", { defaultValue: "生命周期指标" }) }), _jsx("p", { className: "text-amber text-[12px] font-mono mt-1 mb-3", children: t("principles.detail.lifecycleNote") }), lifecycle.adherence.insufficientData ? (_jsx("p", { className: "text-ink-3 text-[13px] leading-relaxed", children: t("principles.detail.insufficientData") })) : (_jsxs("div", { children: [_jsxs("p", { className: "text-ink-2 text-[14px]", children: [t("principles.detail.adherenceRate", { defaultValue: "遵守率" }), ": ", lifecycle.adherence.rate !== null ? `${(lifecycle.adherence.rate * 100).toFixed(1)}%` : "—"] }), _jsx("p", { className: "text-ink-3 text-[12px] mt-1", children: lifecycle.adherence.note })] })), lifecycle.ruleMetrics.length > 0 && (_jsx("div", { className: "mt-3", children: lifecycle.ruleMetrics.map((rm) => (_jsxs("div", { className: "flex gap-3 text-[12px] font-mono text-ink-3", children: [_jsx("span", { children: rm.ruleId }), _jsxs("span", { children: [t("principles.detail.triggered", { defaultValue: "触发" }), ": ", rm.triggered] })] }, rm.ruleId))) }))] })), hasRules && !lifecycle && (_jsx("div", { className: "mt-6 pt-4 border-t border-line", children: _jsx("p", { className: "text-ink-3 text-[13px]", children: t("principles.detail.lifecycleLoadFailed", { defaultValue: "无法加载生命周期指标。你可以稍后重试。" }) }) }))] })] }), isPending && (_jsxs("div", { className: "border-t border-line pt-6", children: [_jsxs("div", { className: "flex gap-3 flex-wrap", children: [_jsx(Button, { variant: "default", onClick: handleApprove, disabled: actionLoading, children: t("principles.detail.approve") }), _jsx(Button, { variant: "outline", onClick: handlePark, disabled: actionLoading, children: t("principles.detail.park") }), _jsx(Button, { variant: "destructive", onClick: handleReject, disabled: actionLoading, children: t("principles.detail.reject") })] }), showConfirm && (_jsxs("div", { className: "mt-4 p-3 bg-gov/5 border border-gov/20 rounded-[var(--radius-md)]", children: [_jsx("p", { className: "text-ink-2 text-[13px] mb-3", children: t("principles.detail.confirmApprove") }), _jsxs("div", { className: "flex gap-2", children: [_jsx(Button, { variant: "default", size: "sm", onClick: confirmApprove, disabled: actionLoading, children: t("principles.detail.confirm") }), _jsx(Button, { variant: "outline", size: "sm", onClick: cancelConfirm, children: t("principles.detail.cancel") })] })] })), showRejectInput && (_jsxs("div", { className: "mt-4 p-3 border border-danger/20 rounded-[var(--radius-md)]", children: [_jsx("label", { className: "block font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3 mb-2", children: t("principles.detail.rejectReasonLabel", { defaultValue: "拒绝原因" }) }), _jsx("textarea", { value: rejectReason, onChange: (e) => setRejectReason(e.target.value), placeholder: t("principles.detail.rejectReasonPlaceholder"), className: "w-full border border-line rounded-[var(--radius-md)] bg-surface text-ink px-3 py-2 text-[13px] min-h-[80px] resize-y focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gov", "aria-label": t("principles.detail.rejectReasonPlaceholder") }), _jsxs("div", { className: "flex gap-2 mt-2", children: [_jsx(Button, { variant: "destructive", size: "sm", onClick: confirmReject, disabled: !rejectReason.trim() || actionLoading, children: t("principles.detail.confirmReject") }), _jsx(Button, { variant: "outline", size: "sm", onClick: cancelReject, children: t("principles.detail.cancel") })] })] }))] })), !isPending && approvalGroup && (_jsx("div", { className: "border-t border-line pt-6", children: _jsxs("p", { className: "text-ink-3 text-[13px]", children: [approvalGroup.status === "approved" && t("principles.detail.alreadyApproved", { defaultValue: "此原则已批准。" }), approvalGroup.status === "rejected" && t("principles.detail.alreadyRejected", { defaultValue: "此原则已拒绝。" })] }) }))] }));
264
+ }
@@ -0,0 +1,244 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useState, useEffect, useCallback } from "react";
3
+ import { useNavigate } from "react-router-dom";
4
+ import { useTranslation } from "react-i18next";
5
+ import { PageShell } from "../../components/layout/page-shell.js";
6
+ import { SectionTitle } from "../../components/layout/section-title.js";
7
+ import { Button } from "../../components/ui/button.js";
8
+ import { fetchPrinciples, fetchApprovalsGrouped, } from "../../api.js";
9
+ // ── Map principle status to review status ───────────────────────────────────
10
+ function toReviewStatus(principleStatus, approvalStatus) {
11
+ if (approvalStatus === "approved")
12
+ return "approved";
13
+ if (approvalStatus === "rejected")
14
+ return "rejected";
15
+ if (principleStatus === "active")
16
+ return "approved";
17
+ if (principleStatus === "archived")
18
+ return "parked";
19
+ if (principleStatus === "deprecated")
20
+ return "rejected";
21
+ if (principleStatus === "probation")
22
+ return "pending";
23
+ return "pending";
24
+ }
25
+ // ── Status visual mapping ───────────────────────────────────────────────────
26
+ const STATUS_BORDER = {
27
+ pending: "border-l-gov",
28
+ approved: "border-l-green",
29
+ rejected: "border-l-danger",
30
+ parked: "border-l-ink-3",
31
+ };
32
+ const STATUS_TEXT = {
33
+ pending: "text-gov",
34
+ approved: "text-green",
35
+ rejected: "text-danger",
36
+ parked: "text-ink-3",
37
+ };
38
+ const CHANNEL_LABELS = {
39
+ prompt: "channelPrompt",
40
+ defer_archive: "channelDeferArchive",
41
+ code_tool_hook: "channelCodeToolHook",
42
+ };
43
+ // ── Runtime validation helpers (H section) ──────────────────────────────────
44
+ function isString(v) {
45
+ return typeof v === "string";
46
+ }
47
+ function isRecord(v) {
48
+ return typeof v === "object" && v !== null && !Array.isArray(v);
49
+ }
50
+ function isStringArray(v) {
51
+ return Array.isArray(v) && v.every(isString);
52
+ }
53
+ function validatePrinciplesData(data) {
54
+ if (!isRecord(data))
55
+ return null;
56
+ if (!Object.hasOwn(data, "principles") || !Array.isArray(data.principles))
57
+ return null;
58
+ // Validate each principle element has required string fields
59
+ for (const item of data.principles) {
60
+ if (!isRecord(item))
61
+ return null;
62
+ if (!Object.hasOwn(item, "id") || !isString(item.id))
63
+ return null;
64
+ if (!Object.hasOwn(item, "text") || !isString(item.text))
65
+ return null;
66
+ if (!Object.hasOwn(item, "status") || !isString(item.status))
67
+ return null;
68
+ if (!Object.hasOwn(item, "updatedAt") || !isString(item.updatedAt))
69
+ return null;
70
+ if (!Object.hasOwn(item, "createdAt") || !isString(item.createdAt))
71
+ return null;
72
+ }
73
+ return data;
74
+ }
75
+ function validateApprovalsGrouped(data) {
76
+ if (!isRecord(data))
77
+ return null;
78
+ if (!Object.hasOwn(data, "groups") || !Array.isArray(data.groups))
79
+ return null;
80
+ // Validate each group element
81
+ for (const g of data.groups) {
82
+ if (!isRecord(g))
83
+ return null;
84
+ if (!Object.hasOwn(g, "principleId") || !isString(g.principleId))
85
+ return null;
86
+ if (!Object.hasOwn(g, "status") || !isString(g.status))
87
+ return null;
88
+ if (!Object.hasOwn(g, "records") || !Array.isArray(g.records))
89
+ return null;
90
+ for (const r of g.records) {
91
+ if (!isRecord(r))
92
+ return null;
93
+ if (!Object.hasOwn(r, "id") || !isString(r.id))
94
+ return null;
95
+ if (!Object.hasOwn(r, "channel") || !isString(r.channel))
96
+ return null;
97
+ }
98
+ }
99
+ return data;
100
+ }
101
+ // ── Component ───────────────────────────────────────────────────────────────
102
+ export function PrinciplesPage() {
103
+ const { t, i18n } = useTranslation("pages");
104
+ const navigate = useNavigate();
105
+ const [principles, setPrinciples] = useState([]);
106
+ const [approvalGroups, setApprovalGroups] = useState([]);
107
+ const [loading, setLoading] = useState(true);
108
+ const [error, setError] = useState(null);
109
+ // Search / filter / sort
110
+ const [search, setSearch] = useState("");
111
+ const [statusFilter, setStatusFilter] = useState("all");
112
+ const [sortBy, setSortBy] = useState("updatedAt");
113
+ // PRI-330: Default to actionable filter
114
+ const [filterMode, setFilterMode] = useState('actionable');
115
+ const [categories, setCategories] = useState();
116
+ // Fetch data
117
+ const loadData = useCallback(async () => {
118
+ setLoading(true);
119
+ setError(null);
120
+ try {
121
+ const [pResult, aResult] = await Promise.all([
122
+ fetchPrinciples(filterMode),
123
+ fetchApprovalsGrouped(),
124
+ ]);
125
+ if (!pResult.success) {
126
+ setError(pResult.error ?? "Failed to load principles");
127
+ return;
128
+ }
129
+ const pData = validatePrinciplesData(pResult.data);
130
+ if (!pData) {
131
+ setError("Invalid principles data received");
132
+ return;
133
+ }
134
+ setPrinciples(pData.principles);
135
+ // PRI-330: Store categories for UI display
136
+ setCategories(pData.categories);
137
+ const aData = aResult.success ? validateApprovalsGrouped(aResult.data) : null;
138
+ setApprovalGroups(aData?.groups ?? []);
139
+ }
140
+ catch (err) {
141
+ setError(err instanceof Error ? err.message : "Unknown error");
142
+ }
143
+ finally {
144
+ setLoading(false);
145
+ }
146
+ }, [filterMode]);
147
+ useEffect(() => {
148
+ loadData();
149
+ }, [loadData]);
150
+ // Build approval lookup
151
+ const approvalByPrinciple = new Map();
152
+ for (const g of approvalGroups) {
153
+ approvalByPrinciple.set(g.principleId, g);
154
+ }
155
+ // Merge principle + approval data into cards
156
+ const cards = principles.map((p) => {
157
+ const ag = approvalByPrinciple.get(p.id);
158
+ const channels = ag
159
+ ? ag.records.map((r) => r.channel).filter(isString)
160
+ : ["prompt"];
161
+ const uniqueChannels = [...new Set(channels)];
162
+ const confidence = p.evaluability === "deterministic"
163
+ ? "high"
164
+ : p.evaluability === "weak_heuristic"
165
+ ? "low"
166
+ : "medium";
167
+ // PRI-332: Determine display title with bounded fallback for unreadable titles
168
+ const rawTitle = p.triggerPattern || p.text.slice(0, 80);
169
+ const detectedLang = p.detectedLanguage ?? 'unknown';
170
+ const readWarningCode = p.readabilityWarningCode;
171
+ let displayTitle = rawTitle;
172
+ let usedFallback = false;
173
+ if (readWarningCode) {
174
+ displayTitle = t("principles.readabilityFallbackTitle");
175
+ usedFallback = true;
176
+ }
177
+ return {
178
+ principleId: p.id,
179
+ title: displayTitle,
180
+ originalTitle: rawTitle,
181
+ titleUsedFallback: usedFallback,
182
+ text: p.text,
183
+ status: toReviewStatus(p.status, ag?.status),
184
+ channels: uniqueChannels,
185
+ confidence,
186
+ updatedAt: p.updatedAt,
187
+ createdAt: p.createdAt,
188
+ priority: p.priority,
189
+ detectedLanguage: detectedLang,
190
+ readabilityWarningCode: readWarningCode,
191
+ };
192
+ });
193
+ // Filter + sort
194
+ const filtered = cards
195
+ .filter((c) => {
196
+ if (statusFilter !== "all" && c.status !== statusFilter)
197
+ return false;
198
+ if (search) {
199
+ const q = search.toLowerCase();
200
+ if (!c.text.toLowerCase().includes(q) && !c.title.toLowerCase().includes(q))
201
+ return false;
202
+ }
203
+ return true;
204
+ })
205
+ .sort((a, b) => {
206
+ const key = sortBy === "updatedAt" ? "updatedAt" : "createdAt";
207
+ return new Date(b[key]).getTime() - new Date(a[key]).getTime();
208
+ });
209
+ const statusFilters = [
210
+ { value: "all", label: t("principles.allStatuses") },
211
+ { value: "pending", label: t("principles.statusPending") },
212
+ { value: "approved", label: t("principles.statusApproved") },
213
+ { value: "rejected", label: t("principles.statusRejected") },
214
+ { value: "parked", label: t("principles.statusParked") },
215
+ ];
216
+ return (_jsxs(PageShell, { children: [_jsx(SectionTitle, { children: t("principles.reviewTitle") }), _jsx("h1", { className: "text-[29px] font-semibold tracking-tight text-ink mb-2", children: t("principles.reviewSubtitle") }), _jsx("p", { className: "text-ink-3 text-[14px] leading-relaxed mb-6", children: t("principles.reviewDescription") }), _jsxs("div", { className: "flex flex-wrap items-center gap-3 mb-6", children: [_jsxs("div", { className: "flex gap-1", role: "group", "aria-label": "Filter mode", children: [_jsxs("button", { onClick: () => setFilterMode('actionable'), className: "font-mono text-[11px] uppercase tracking-[0.02em] border rounded-[2px] px-2 py-1 transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gov " +
217
+ (filterMode === 'actionable'
218
+ ? "bg-gov text-paper border-gov"
219
+ : "bg-surface text-ink-3 border-line hover:border-line-2"), children: [t("principles.filterActionable", { defaultValue: "Actionable" }), categories?.owner_actionable ? ` (${categories.owner_actionable})` : ''] }), _jsxs("button", { onClick: () => setFilterMode('all'), className: "font-mono text-[11px] uppercase tracking-[0.02em] border rounded-[2px] px-2 py-1 transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gov " +
220
+ (filterMode === 'all'
221
+ ? "bg-gov text-paper border-gov"
222
+ : "bg-surface text-ink-3 border-line hover:border-line-2"), children: [t("principles.filterAll", { defaultValue: "Show All" }), categories ? ` (${Object.values(categories).reduce((a, b) => a + b, 0)})` : ''] })] }), _jsx("input", { type: "text", value: search, onChange: (e) => setSearch(e.target.value), placeholder: t("principles.searchPlaceholder"), className: "flex-1 min-w-[200px] border border-line rounded-[var(--radius-md)] bg-surface text-ink px-3 py-2 text-[13px] focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gov", "aria-label": t("principles.searchPlaceholder") }), _jsx("div", { className: "flex gap-1", role: "group", "aria-label": "Status filter", children: statusFilters.map((sf) => (_jsx("button", { onClick: () => setStatusFilter(sf.value), className: "font-mono text-[11px] uppercase tracking-[0.02em] border rounded-[2px] px-2 py-1 transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gov " +
223
+ (statusFilter === sf.value
224
+ ? "bg-gov text-paper border-gov"
225
+ : "bg-surface text-ink-3 border-line hover:border-line-2"), children: sf.label }, sf.value))) }), _jsxs("select", { value: sortBy, onChange: (e) => setSortBy(e.target.value), className: "border border-line rounded-[var(--radius-md)] bg-surface text-ink-3 px-2 py-1 text-[12px] font-mono focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gov", "aria-label": "Sort order", children: [_jsx("option", { value: "updatedAt", children: t("principles.sortByUpdated") }), _jsx("option", { value: "createdAt", children: t("principles.sortByCreated") })] })] }), loading && (_jsx("p", { className: "text-ink-3 text-sm", children: t("principles.loading", { defaultValue: "Loading…" }) })), error && (_jsxs("div", { className: "border border-danger/30 rounded-[var(--radius-md)] p-4 mb-4", children: [_jsx("p", { className: "text-danger text-sm", children: error }), _jsx(Button, { variant: "outline", size: "sm", onClick: loadData, className: "mt-2", children: t("principles.retry", { defaultValue: "Retry" }) })] })), !loading && !error && filtered.length === 0 && principles.length === 0 && (_jsxs("div", { className: "text-center py-12", children: [_jsx("h2", { className: "text-ink-2 text-lg font-semibold mb-2", children: t("principles.emptyTitle") }), _jsx("p", { className: "text-ink-3 text-[14px] max-w-[480px] mx-auto leading-relaxed", children: filterMode === 'actionable'
226
+ ? t("principles.emptyActionable", { defaultValue: "No owner-actionable principles at this time. When PD captures behavior deviation signals, principle candidates will appear here for your review." })
227
+ : t("principles.emptyDescription") }), categories && filterMode === 'actionable' && (_jsx("div", { className: "flex justify-center gap-2 flex-wrap mt-4", children: Object.entries(categories).map(([cat, count]) => (_jsxs("span", { className: "font-mono text-[11px] uppercase tracking-[0.02em] border border-line rounded-[2px] px-2 py-0.5 text-ink-4", children: [cat, ": ", count] }, cat))) }))] })), !loading && !error && filtered.length === 0 && principles.length > 0 && (_jsx("p", { className: "text-ink-3 text-sm", children: t("principles.noResults") })), !loading && !error && filtered.length > 0 && (_jsx("div", { className: "grid gap-3", children: filtered.map((card) => (_jsxs("article", { onClick: () => navigate(`/principles/${card.principleId}`), className: "bg-panel border border-line rounded-[var(--radius-md)] p-4 cursor-pointer " +
228
+ "border-l-[3px] " +
229
+ STATUS_BORDER[card.status] + " " +
230
+ "transition-[border-color,background] duration-150 " +
231
+ "hover:border-line-2 hover:bg-surface " +
232
+ "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gov", tabIndex: 0, role: "link", "aria-label": card.title, onKeyDown: (e) => {
233
+ if (e.key === "Enter" || e.key === " ") {
234
+ e.preventDefault();
235
+ navigate(`/principles/${card.principleId}`);
236
+ }
237
+ }, children: [_jsxs("div", { className: "flex items-center gap-2 mb-2 flex-wrap", children: [_jsx("span", { className: "font-mono text-[11px] uppercase tracking-[0.02em] border rounded-[2px] px-2 py-0.5 " +
238
+ STATUS_TEXT[card.status] +
239
+ " border-current/20", children: t("principles.status" + card.status.charAt(0).toUpperCase() + card.status.slice(1)) }), card.channels.map((ch) => (_jsx("span", { className: "font-mono text-[11px] uppercase tracking-[0.02em] border border-line rounded-[2px] px-2 py-0.5 text-ink-3", children: CHANNEL_LABELS[ch]
240
+ ? t("principles." + CHANNEL_LABELS[ch])
241
+ : ch }, ch))), card.detectedLanguage && card.detectedLanguage !== 'unknown' && (_jsx("span", { className: "font-mono text-[11px] tracking-[0.02em] border border-line rounded-[2px] px-2 py-0.5 text-ink-4", children: card.detectedLanguage === 'zh'
242
+ ? t("principles.languageHintZh")
243
+ : t("principles.languageHintEn") })), _jsxs("span", { className: "font-mono text-[11px] text-ink-4", children: [t("principles.confidence"), ": ", card.confidence] })] }), card.readabilityWarningCode && (_jsx("div", { className: "mb-2 px-3 py-1.5 bg-amber/5 border border-amber/20 rounded-[3px] text-ink-3 text-[12px] leading-snug", children: t("principles.readabilityWarning." + card.readabilityWarningCode, { defaultValue: t("principles.readabilityFallbackTitle") }) })), card.detectedLanguage && card.detectedLanguage !== 'unknown' && i18n.language && !i18n.language.startsWith(card.detectedLanguage) && (_jsx("div", { className: "mb-2 px-3 py-1.5 bg-surface/60 border-l-2 border-line rounded-[3px] text-ink-4 text-[12px] leading-snug", children: t("principles.languageMismatchHint", { lang: card.detectedLanguage === 'en' ? 'English' : '中文' }) })), _jsx("h3", { className: "font-semibold text-ink mb-1", children: card.title }), card.titleUsedFallback && card.originalTitle && (_jsxs("details", { className: "mb-1", children: [_jsx("summary", { className: "text-ink-4 text-[11px] font-mono cursor-pointer hover:underline", children: t("principles.readabilityOriginalLabel") }), _jsx("div", { className: "text-ink-4 text-[12px] leading-snug mt-1 font-mono bg-surface/40 px-2 py-1 rounded-[3px] break-all", children: card.originalTitle })] })), _jsx("p", { className: "text-ink-3 text-[13px] line-clamp-3 leading-relaxed", children: card.text }), _jsxs("p", { className: "font-mono text-[11px] text-ink-4 mt-2", children: [t("principles.updatedAt"), ": ", new Date(card.updatedAt).toLocaleDateString()] })] }, card.principleId))) }))] }));
244
+ }