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.
- package/console/dist/server/config/pd-config-store.d.ts +135 -0
- package/console/dist/server/config/pd-config-store.js +660 -0
- package/console/dist/server/index.js +40 -389
- package/console/dist/server/models/ActivationsConsoleModel.d.ts +33 -0
- package/console/dist/server/models/ActivationsConsoleModel.js +112 -0
- package/console/dist/server/models/ApprovalsConsoleModel.d.ts +5 -0
- package/console/dist/server/models/ApprovalsConsoleModel.js +14 -0
- package/console/dist/server/models/ApprovalsGroupedConsoleModel.d.ts +25 -0
- package/console/dist/server/models/ApprovalsGroupedConsoleModel.js +126 -0
- package/console/dist/server/models/ConsoleLifecycleDatasource.d.ts +13 -0
- package/console/dist/server/models/ConsoleLifecycleDatasource.js +73 -0
- package/console/dist/server/models/EvidenceChainConsoleModel.d.ts +58 -0
- package/console/dist/server/models/EvidenceChainConsoleModel.js +493 -0
- package/console/dist/server/models/GovernanceConsoleModel.d.ts +74 -0
- package/console/dist/server/models/GovernanceConsoleModel.js +246 -0
- package/console/dist/server/models/HealthCheckModel.d.ts +0 -4
- package/console/dist/server/models/HealthCheckModel.js +49 -80
- package/console/dist/server/models/LifecycleConsoleModel.d.ts +19 -0
- package/console/dist/server/models/LifecycleConsoleModel.js +55 -0
- package/console/dist/server/models/PrincipleClassifier.d.ts +41 -0
- package/console/dist/server/models/PrincipleClassifier.js +100 -0
- package/console/dist/server/models/PrinciplesConsoleModel.d.ts +12 -1
- package/console/dist/server/models/PrinciplesConsoleModel.js +53 -6
- package/console/dist/server/models/WorkspaceService.d.ts +2 -1
- package/console/dist/server/models/WorkspaceService.js +51 -23
- package/console/dist/server/routes/activations.d.ts +3 -0
- package/console/dist/server/routes/activations.js +111 -0
- package/console/dist/server/routes/approvals-grouped.d.ts +3 -0
- package/console/dist/server/routes/approvals-grouped.js +32 -0
- package/console/dist/server/routes/approvals.js +28 -4
- package/console/dist/server/routes/config.d.ts +27 -0
- package/console/dist/server/routes/config.js +213 -0
- package/console/dist/server/routes/evidence-chain.d.ts +9 -0
- package/console/dist/server/routes/evidence-chain.js +32 -0
- package/console/dist/server/routes/governance.d.ts +3 -0
- package/console/dist/server/routes/governance.js +32 -0
- package/console/dist/server/routes/{evolution.d.ts → lifecycle.d.ts} +2 -2
- package/console/dist/server/routes/lifecycle.js +48 -0
- package/console/dist/server/routes/principles.js +74 -1
- package/console/dist/server/routes/workspaces.js +8 -1
- package/console/dist/server/utils/response.d.ts +1 -1
- package/console/dist/server/utils/response.js +6 -2
- package/console/dist/types.d.ts +1 -0
- package/console/dist/ui/App.js +116 -40
- package/console/dist/ui/api.d.ts +88 -501
- package/console/dist/ui/api.js +139 -162
- package/console/dist/ui/components/approval-card.js +1 -1
- package/console/dist/ui/components/approval-detail-dialog.js +1 -1
- package/console/dist/ui/components/auth/login-form.d.ts +3 -0
- package/console/dist/ui/components/auth/login-form.js +36 -0
- package/console/dist/ui/components/auth/splash-screen.d.ts +8 -0
- package/console/dist/ui/components/auth/splash-screen.js +22 -0
- package/console/dist/ui/components/layout/app-sidebar.d.ts +1 -0
- package/console/dist/ui/components/layout/app-sidebar.js +56 -0
- package/console/dist/ui/components/layout/page-shell.d.ts +11 -0
- package/console/dist/ui/components/layout/page-shell.js +10 -0
- package/console/dist/ui/components/layout/section-title.d.ts +10 -0
- package/console/dist/ui/components/layout/section-title.js +9 -0
- package/console/dist/ui/components/theme-provider.d.ts +1 -1
- package/console/dist/ui/components/theme-provider.js +13 -8
- package/console/dist/ui/components/theme-toggle.js +2 -21
- package/console/dist/ui/components/ui/badge.d.ts +1 -1
- package/console/dist/ui/components/ui/badge.js +7 -5
- package/console/dist/ui/components/ui/button.d.ts +2 -2
- package/console/dist/ui/components/ui/button.js +12 -11
- package/console/dist/ui/components/ui/card.js +6 -6
- package/console/dist/ui/components/ui/sheet.d.ts +1 -1
- package/console/dist/ui/i18n/en.json +401 -343
- package/console/dist/ui/i18n/index.js +2 -2
- package/console/dist/ui/i18n/zh-CN.json +406 -348
- package/console/dist/ui/main.d.ts +1 -1
- package/console/dist/ui/main.js +1 -0
- package/console/dist/ui/pages/activation/ActivationPage.d.ts +1 -0
- package/console/dist/ui/pages/activation/ActivationPage.js +150 -0
- package/console/dist/ui/pages/activation/ActivationValidators.d.ts +20 -0
- package/console/dist/ui/pages/activation/ActivationValidators.js +156 -0
- package/console/dist/ui/pages/control-center/ControlCenterPage.d.ts +1 -0
- package/console/dist/ui/pages/control-center/ControlCenterPage.js +447 -0
- package/console/dist/ui/pages/debt/DebtPage.d.ts +1 -0
- package/console/dist/ui/pages/debt/DebtPage.js +5 -0
- package/console/dist/ui/pages/design-system/DesignSystemPage.d.ts +1 -0
- package/console/dist/ui/pages/design-system/DesignSystemPage.js +30 -0
- package/console/dist/ui/pages/focus/FocusPage.d.ts +1 -0
- package/console/dist/ui/pages/focus/FocusPage.js +265 -0
- package/console/dist/ui/pages/pain/PainEvidenceValidators.d.ts +59 -0
- package/console/dist/ui/pages/pain/PainEvidenceValidators.js +125 -0
- package/console/dist/ui/pages/pain/PainPage.js +136 -0
- package/console/dist/ui/pages/principles/PrincipleDetailPage.js +264 -0
- package/console/dist/ui/pages/principles/PrinciplesPage.js +244 -0
- package/console/dist/ui/pages/report-problem/ReportProblemPage.js +245 -0
- package/console/dist/ui/pages/settings/SettingsPage.d.ts +4 -0
- package/console/dist/ui/pages/settings/SettingsPage.js +202 -0
- package/console/dist/ui/pages/settings/UpdatePage.d.ts +5 -0
- package/console/dist/ui/pages/settings/UpdatePage.js +168 -0
- package/console/dist/ui/utils/control-center-helpers.d.ts +58 -0
- package/console/dist/ui/utils/control-center-helpers.js +152 -0
- package/console/dist/ui/utils/validators.d.ts +350 -0
- package/console/dist/ui/utils/validators.js +995 -0
- package/console/dist/web/assets/app.css +672 -902
- package/console/dist/web/assets/app.js +6404 -15347
- package/console/dist/web/assets/jetbrains-mono-cyrillic-400-normal-C5JECUCT.woff2 +0 -0
- package/console/dist/web/assets/jetbrains-mono-cyrillic-400-normal-FGCZYWMY.woff +0 -0
- package/console/dist/web/assets/jetbrains-mono-cyrillic-ext-400-normal-C7IFWGF6.woff2 +0 -0
- package/console/dist/web/assets/jetbrains-mono-cyrillic-ext-400-normal-PWXUA557.woff +0 -0
- package/console/dist/web/assets/jetbrains-mono-greek-400-normal-JJNQZMPZ.woff +0 -0
- package/console/dist/web/assets/jetbrains-mono-greek-400-normal-O7JTTR3P.woff2 +0 -0
- package/console/dist/web/assets/jetbrains-mono-latin-400-normal-3OOWLGQ2.woff2 +0 -0
- package/console/dist/web/assets/jetbrains-mono-latin-400-normal-WDD34GPP.woff +0 -0
- package/console/dist/web/assets/jetbrains-mono-latin-ext-400-normal-55RNMRQS.woff +0 -0
- package/console/dist/web/assets/jetbrains-mono-latin-ext-400-normal-JVR3IR4Z.woff2 +0 -0
- package/console/dist/web/assets/jetbrains-mono-vietnamese-400-normal-7ULXAK72.woff +0 -0
- package/console/dist/web/assets/jetbrains-mono-vietnamese-400-normal-KU7YLUPA.woff2 +0 -0
- package/console/package.json +2 -1
- package/core/dist/runtime-v2/__tests__/admission-gate.test.js +49 -0
- package/core/dist/runtime-v2/__tests__/admission-gate.test.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/architecture-regression.test.js +16 -1
- package/core/dist/runtime-v2/__tests__/architecture-regression.test.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/evidence-sanitizer.test.d.ts +21 -0
- package/core/dist/runtime-v2/__tests__/evidence-sanitizer.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/__tests__/evidence-sanitizer.test.js +354 -0
- package/core/dist/runtime-v2/__tests__/evidence-sanitizer.test.js.map +1 -0
- package/core/dist/runtime-v2/__tests__/language-directive.test.d.ts +12 -0
- package/core/dist/runtime-v2/__tests__/language-directive.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/__tests__/language-directive.test.js +162 -0
- package/core/dist/runtime-v2/__tests__/language-directive.test.js.map +1 -0
- package/core/dist/runtime-v2/__tests__/pain-signal-observability.test.js +23 -1
- package/core/dist/runtime-v2/__tests__/pain-signal-observability.test.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/pain-to-principle-service.test.js +48 -3
- package/core/dist/runtime-v2/__tests__/pain-to-principle-service.test.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/proven-channel-baseline.test.js +13 -1
- package/core/dist/runtime-v2/__tests__/proven-channel-baseline.test.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/resolve-runtime-config-from-pd-config.test.d.ts +12 -0
- package/core/dist/runtime-v2/__tests__/resolve-runtime-config-from-pd-config.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/__tests__/resolve-runtime-config-from-pd-config.test.js +194 -0
- package/core/dist/runtime-v2/__tests__/resolve-runtime-config-from-pd-config.test.js.map +1 -0
- package/core/dist/runtime-v2/__tests__/runtime-config-boundary.test.js +5 -3
- package/core/dist/runtime-v2/__tests__/runtime-config-boundary.test.js.map +1 -1
- package/core/dist/runtime-v2/activation/__tests__/activation-dispatcher.test.js +1 -0
- package/core/dist/runtime-v2/activation/__tests__/activation-dispatcher.test.js.map +1 -1
- package/core/dist/runtime-v2/activation/__tests__/approval-queue.test.js +54 -0
- package/core/dist/runtime-v2/activation/__tests__/approval-queue.test.js.map +1 -1
- package/core/dist/runtime-v2/activation/__tests__/memory-activation-state-store.test.js +15 -2
- package/core/dist/runtime-v2/activation/__tests__/memory-activation-state-store.test.js.map +1 -1
- package/core/dist/runtime-v2/activation/__tests__/prompt-activation-reader-contract.test.js +10 -0
- package/core/dist/runtime-v2/activation/__tests__/prompt-activation-reader-contract.test.js.map +1 -1
- package/core/dist/runtime-v2/activation/__tests__/sqlite-activation-state-store.test.js +17 -2
- package/core/dist/runtime-v2/activation/__tests__/sqlite-activation-state-store.test.js.map +1 -1
- package/core/dist/runtime-v2/activation/__tests__/sqlite-approval-store.test.js +36 -0
- package/core/dist/runtime-v2/activation/__tests__/sqlite-approval-store.test.js.map +1 -1
- package/core/dist/runtime-v2/activation/activation-dispatcher.d.ts.map +1 -1
- package/core/dist/runtime-v2/activation/activation-dispatcher.js +1 -1
- package/core/dist/runtime-v2/activation/activation-dispatcher.js.map +1 -1
- package/core/dist/runtime-v2/activation/activation-types.d.ts +10 -0
- package/core/dist/runtime-v2/activation/activation-types.d.ts.map +1 -1
- package/core/dist/runtime-v2/activation/activation-types.js.map +1 -1
- package/core/dist/runtime-v2/activation/approval-queue.d.ts +6 -0
- package/core/dist/runtime-v2/activation/approval-queue.d.ts.map +1 -1
- package/core/dist/runtime-v2/activation/approval-queue.js +3 -0
- package/core/dist/runtime-v2/activation/approval-queue.js.map +1 -1
- package/core/dist/runtime-v2/activation/memory-activation-state-store.d.ts +2 -0
- package/core/dist/runtime-v2/activation/memory-activation-state-store.d.ts.map +1 -1
- package/core/dist/runtime-v2/activation/memory-activation-state-store.js +17 -1
- package/core/dist/runtime-v2/activation/memory-activation-state-store.js.map +1 -1
- package/core/dist/runtime-v2/activation/memory-approval-store.d.ts +6 -0
- package/core/dist/runtime-v2/activation/memory-approval-store.d.ts.map +1 -1
- package/core/dist/runtime-v2/activation/memory-approval-store.js +16 -0
- package/core/dist/runtime-v2/activation/memory-approval-store.js.map +1 -1
- package/core/dist/runtime-v2/activation/prompt-activation-reader-contract.js +1 -1
- package/core/dist/runtime-v2/activation/prompt-activation-reader-contract.js.map +1 -1
- package/core/dist/runtime-v2/activation/sqlite-activation-state-store.d.ts +2 -0
- package/core/dist/runtime-v2/activation/sqlite-activation-state-store.d.ts.map +1 -1
- package/core/dist/runtime-v2/activation/sqlite-activation-state-store.js +34 -6
- package/core/dist/runtime-v2/activation/sqlite-activation-state-store.js.map +1 -1
- package/core/dist/runtime-v2/activation/sqlite-approval-store.d.ts +6 -0
- package/core/dist/runtime-v2/activation/sqlite-approval-store.d.ts.map +1 -1
- package/core/dist/runtime-v2/activation/sqlite-approval-store.js +10 -0
- package/core/dist/runtime-v2/activation/sqlite-approval-store.js.map +1 -1
- package/core/dist/runtime-v2/adapter/__tests__/json-extractor.test.js +51 -1
- package/core/dist/runtime-v2/adapter/__tests__/json-extractor.test.js.map +1 -1
- package/core/dist/runtime-v2/adapter/__tests__/openclaw-cli-runtime-adapter.test.js +145 -0
- package/core/dist/runtime-v2/adapter/__tests__/openclaw-cli-runtime-adapter.test.js.map +1 -1
- package/core/dist/runtime-v2/adapter/json-extractor.d.ts +13 -0
- package/core/dist/runtime-v2/adapter/json-extractor.d.ts.map +1 -1
- package/core/dist/runtime-v2/adapter/json-extractor.js +103 -0
- package/core/dist/runtime-v2/adapter/json-extractor.js.map +1 -1
- package/core/dist/runtime-v2/adapter/openclaw-cli-runtime-adapter.d.ts +4 -2
- package/core/dist/runtime-v2/adapter/openclaw-cli-runtime-adapter.d.ts.map +1 -1
- package/core/dist/runtime-v2/adapter/openclaw-cli-runtime-adapter.js +57 -5
- package/core/dist/runtime-v2/adapter/openclaw-cli-runtime-adapter.js.map +1 -1
- package/core/dist/runtime-v2/config/__tests__/pd-config-agent-binding.test.d.ts +18 -0
- package/core/dist/runtime-v2/config/__tests__/pd-config-agent-binding.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/config/__tests__/pd-config-agent-binding.test.js +633 -0
- package/core/dist/runtime-v2/config/__tests__/pd-config-agent-binding.test.js.map +1 -0
- package/core/dist/runtime-v2/config/__tests__/pd-config-validation-edge-cases.test.js +92 -0
- package/core/dist/runtime-v2/config/__tests__/pd-config-validation-edge-cases.test.js.map +1 -1
- package/core/dist/runtime-v2/config/index.d.ts +3 -1
- package/core/dist/runtime-v2/config/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/config/index.js +1 -0
- package/core/dist/runtime-v2/config/index.js.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-agent-binding.d.ts +93 -0
- package/core/dist/runtime-v2/config/pd-config-agent-binding.d.ts.map +1 -0
- package/core/dist/runtime-v2/config/pd-config-agent-binding.js +184 -0
- package/core/dist/runtime-v2/config/pd-config-agent-binding.js.map +1 -0
- package/core/dist/runtime-v2/config/pd-config-defaults.d.ts.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-defaults.js +2 -0
- package/core/dist/runtime-v2/config/pd-config-defaults.js.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-effective.d.ts.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-effective.js +3 -0
- package/core/dist/runtime-v2/config/pd-config-effective.js.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-types.d.ts +8 -0
- package/core/dist/runtime-v2/config/pd-config-types.d.ts.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-types.js.map +1 -1
- package/core/dist/runtime-v2/diagnostician/__tests__/diagnostician-prompt-language.test.d.ts +13 -0
- package/core/dist/runtime-v2/diagnostician/__tests__/diagnostician-prompt-language.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/diagnostician/__tests__/diagnostician-prompt-language.test.js +97 -0
- package/core/dist/runtime-v2/diagnostician/__tests__/diagnostician-prompt-language.test.js.map +1 -0
- package/core/dist/runtime-v2/diagnostician-prompt-builder.d.ts +3 -2
- package/core/dist/runtime-v2/diagnostician-prompt-builder.d.ts.map +1 -1
- package/core/dist/runtime-v2/diagnostician-prompt-builder.js +6 -4
- package/core/dist/runtime-v2/diagnostician-prompt-builder.js.map +1 -1
- package/core/dist/runtime-v2/evidence-sanitizer.d.ts +57 -0
- package/core/dist/runtime-v2/evidence-sanitizer.d.ts.map +1 -0
- package/core/dist/runtime-v2/evidence-sanitizer.js +213 -0
- package/core/dist/runtime-v2/evidence-sanitizer.js.map +1 -0
- package/core/dist/runtime-v2/evidence-triage/__tests__/admission-events.test.d.ts +7 -0
- package/core/dist/runtime-v2/evidence-triage/__tests__/admission-events.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/evidence-triage/__tests__/admission-events.test.js +170 -0
- package/core/dist/runtime-v2/evidence-triage/__tests__/admission-events.test.js.map +1 -0
- package/core/dist/runtime-v2/evidence-triage/__tests__/source-descriptors.test.d.ts +18 -0
- package/core/dist/runtime-v2/evidence-triage/__tests__/source-descriptors.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/evidence-triage/__tests__/source-descriptors.test.js +277 -0
- package/core/dist/runtime-v2/evidence-triage/__tests__/source-descriptors.test.js.map +1 -0
- package/core/dist/runtime-v2/evidence-triage/__tests__/triage-policy.test.d.ts +13 -0
- package/core/dist/runtime-v2/evidence-triage/__tests__/triage-policy.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/evidence-triage/__tests__/triage-policy.test.js +264 -0
- package/core/dist/runtime-v2/evidence-triage/__tests__/triage-policy.test.js.map +1 -0
- package/core/dist/runtime-v2/evidence-triage/__tests__/trigger-controller.test.d.ts +16 -0
- package/core/dist/runtime-v2/evidence-triage/__tests__/trigger-controller.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/evidence-triage/__tests__/trigger-controller.test.js +316 -0
- package/core/dist/runtime-v2/evidence-triage/__tests__/trigger-controller.test.js.map +1 -0
- package/core/dist/runtime-v2/evidence-triage/admission-events.d.ts +126 -0
- package/core/dist/runtime-v2/evidence-triage/admission-events.d.ts.map +1 -0
- package/core/dist/runtime-v2/evidence-triage/admission-events.js +159 -0
- package/core/dist/runtime-v2/evidence-triage/admission-events.js.map +1 -0
- package/core/dist/runtime-v2/evidence-triage/index.d.ts +16 -0
- package/core/dist/runtime-v2/evidence-triage/index.d.ts.map +1 -0
- package/core/dist/runtime-v2/evidence-triage/index.js +13 -0
- package/core/dist/runtime-v2/evidence-triage/index.js.map +1 -0
- package/core/dist/runtime-v2/evidence-triage/source-descriptors.d.ts +48 -0
- package/core/dist/runtime-v2/evidence-triage/source-descriptors.d.ts.map +1 -0
- package/core/dist/runtime-v2/evidence-triage/source-descriptors.js +131 -0
- package/core/dist/runtime-v2/evidence-triage/source-descriptors.js.map +1 -0
- package/core/dist/runtime-v2/evidence-triage/triage-policy.d.ts +32 -0
- package/core/dist/runtime-v2/evidence-triage/triage-policy.d.ts.map +1 -0
- package/core/dist/runtime-v2/evidence-triage/triage-policy.js +95 -0
- package/core/dist/runtime-v2/evidence-triage/triage-policy.js.map +1 -0
- package/core/dist/runtime-v2/evidence-triage/trigger-controller.d.ts +116 -0
- package/core/dist/runtime-v2/evidence-triage/trigger-controller.d.ts.map +1 -0
- package/core/dist/runtime-v2/evidence-triage/trigger-controller.js +218 -0
- package/core/dist/runtime-v2/evidence-triage/trigger-controller.js.map +1 -0
- package/core/dist/runtime-v2/evidence-triage/types.d.ts +65 -0
- package/core/dist/runtime-v2/evidence-triage/types.d.ts.map +1 -0
- package/core/dist/runtime-v2/evidence-triage/types.js +38 -0
- package/core/dist/runtime-v2/evidence-triage/types.js.map +1 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js +10 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js.map +1 -1
- package/core/dist/runtime-v2/feature-flags/feature-flag-contract.d.ts.map +1 -1
- package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js +1 -0
- package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js.map +1 -1
- package/core/dist/runtime-v2/index.d.ts +8 -1
- package/core/dist/runtime-v2/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/index.js +7 -1
- package/core/dist/runtime-v2/index.js.map +1 -1
- package/core/dist/runtime-v2/internalization/__tests__/scribe-prompt-language.test.d.ts +12 -0
- package/core/dist/runtime-v2/internalization/__tests__/scribe-prompt-language.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/internalization/__tests__/scribe-prompt-language.test.js +83 -0
- package/core/dist/runtime-v2/internalization/__tests__/scribe-prompt-language.test.js.map +1 -0
- package/core/dist/runtime-v2/internalization/scribe-prompt-builder.d.ts +10 -0
- package/core/dist/runtime-v2/internalization/scribe-prompt-builder.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/scribe-prompt-builder.js +13 -1
- package/core/dist/runtime-v2/internalization/scribe-prompt-builder.js.map +1 -1
- package/core/dist/runtime-v2/internalization/scribe-runner.d.ts +3 -0
- package/core/dist/runtime-v2/internalization/scribe-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/scribe-runner.js +2 -0
- package/core/dist/runtime-v2/internalization/scribe-runner.js.map +1 -1
- package/core/dist/runtime-v2/internalization-chain-integrity-read-model.js +1 -1
- package/core/dist/runtime-v2/internalization-chain-integrity-read-model.js.map +1 -1
- package/core/dist/runtime-v2/language-directive.d.ts +80 -0
- package/core/dist/runtime-v2/language-directive.d.ts.map +1 -0
- package/core/dist/runtime-v2/language-directive.js +108 -0
- package/core/dist/runtime-v2/language-directive.js.map +1 -0
- package/core/dist/runtime-v2/pain-signal-observability.d.ts.map +1 -1
- package/core/dist/runtime-v2/pain-signal-observability.js +24 -11
- package/core/dist/runtime-v2/pain-signal-observability.js.map +1 -1
- package/core/dist/runtime-v2/pain-signal-runtime-factory.d.ts +16 -0
- package/core/dist/runtime-v2/pain-signal-runtime-factory.d.ts.map +1 -1
- package/core/dist/runtime-v2/pain-signal-runtime-factory.js +97 -6
- package/core/dist/runtime-v2/pain-signal-runtime-factory.js.map +1 -1
- package/core/dist/runtime-v2/pain-to-principle-service.d.ts +7 -0
- package/core/dist/runtime-v2/pain-to-principle-service.d.ts.map +1 -1
- package/core/dist/runtime-v2/pain-to-principle-service.js +2 -0
- package/core/dist/runtime-v2/pain-to-principle-service.js.map +1 -1
- package/core/dist/runtime-v2/proven-channel-baseline.d.ts.map +1 -1
- package/core/dist/runtime-v2/proven-channel-baseline.js +14 -0
- package/core/dist/runtime-v2/proven-channel-baseline.js.map +1 -1
- package/core/dist/runtime-v2/runner/__tests__/diagnostician-runner.test.js +40 -0
- package/core/dist/runtime-v2/runner/__tests__/diagnostician-runner.test.js.map +1 -1
- package/core/dist/runtime-v2/runner/base-peer-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/runner/base-peer-runner.js +1 -0
- package/core/dist/runtime-v2/runner/base-peer-runner.js.map +1 -1
- package/core/dist/runtime-v2/runner/diagnostician-runner-options.d.ts +10 -0
- package/core/dist/runtime-v2/runner/diagnostician-runner-options.d.ts.map +1 -1
- package/core/dist/runtime-v2/runner/diagnostician-runner-options.js +1 -0
- package/core/dist/runtime-v2/runner/diagnostician-runner-options.js.map +1 -1
- package/core/dist/runtime-v2/runner/diagnostician-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/runner/diagnostician-runner.js +28 -4
- package/core/dist/runtime-v2/runner/diagnostician-runner.js.map +1 -1
- package/core/dist/runtime-v2/runner/peer-runner-types.d.ts +9 -0
- package/core/dist/runtime-v2/runner/peer-runner-types.d.ts.map +1 -1
- package/core/dist/runtime-v2/store/runtime-state-manager.d.ts.map +1 -1
- package/core/dist/runtime-v2/store/runtime-state-manager.integration.test.js +34 -1
- package/core/dist/runtime-v2/store/runtime-state-manager.integration.test.js.map +1 -1
- package/core/dist/runtime-v2/store/runtime-state-manager.js +1 -0
- package/core/dist/runtime-v2/store/runtime-state-manager.js.map +1 -1
- package/core/dist/runtime-v2/store/sqlite-connection.d.ts.map +1 -1
- package/core/dist/runtime-v2/store/sqlite-connection.js +9 -1
- package/core/dist/runtime-v2/store/sqlite-connection.js.map +1 -1
- package/core/dist/runtime-v2/store/task/sqlite-task-store.js +1 -1
- package/core/dist/runtime-v2/store/task/sqlite-task-store.js.map +1 -1
- package/core/dist/runtime-v2/task-status.d.ts +4 -4
- package/core/dist/runtime-v2/task-status.d.ts.map +1 -1
- package/core/dist/runtime-v2/task-status.js +2 -2
- package/core/dist/runtime-v2/task-status.js.map +1 -1
- package/core/package.json +1 -1
- package/package.json +2 -2
- package/pd-cli/dist/commands/console.d.ts +2 -0
- package/pd-cli/dist/commands/console.d.ts.map +1 -1
- package/pd-cli/dist/commands/console.js +6 -1
- package/pd-cli/dist/commands/console.js.map +1 -1
- package/pd-cli/dist/commands/diagnose.d.ts.map +1 -1
- package/pd-cli/dist/commands/diagnose.js +18 -1
- package/pd-cli/dist/commands/diagnose.js.map +1 -1
- package/pd-cli/dist/commands/pain-evidence.d.ts +41 -0
- package/pd-cli/dist/commands/pain-evidence.d.ts.map +1 -0
- package/pd-cli/dist/commands/pain-evidence.js +177 -0
- package/pd-cli/dist/commands/pain-evidence.js.map +1 -0
- package/pd-cli/dist/commands/pain-record.d.ts.map +1 -1
- package/pd-cli/dist/commands/pain-record.js +24 -9
- package/pd-cli/dist/commands/pain-record.js.map +1 -1
- package/pd-cli/dist/commands/pain-retry.d.ts +19 -0
- package/pd-cli/dist/commands/pain-retry.d.ts.map +1 -0
- package/pd-cli/dist/commands/pain-retry.js +485 -0
- package/pd-cli/dist/commands/pain-retry.js.map +1 -0
- package/pd-cli/dist/commands/runtime-internalization-run-once.d.ts.map +1 -1
- package/pd-cli/dist/commands/runtime-internalization-run-once.js +59 -9
- package/pd-cli/dist/commands/runtime-internalization-run-once.js.map +1 -1
- package/pd-cli/dist/commands/runtime-uat.d.ts +1 -0
- package/pd-cli/dist/commands/runtime-uat.d.ts.map +1 -1
- package/pd-cli/dist/commands/runtime-uat.guard.test.d.ts +2 -0
- package/pd-cli/dist/commands/runtime-uat.guard.test.d.ts.map +1 -0
- package/pd-cli/dist/commands/runtime-uat.guard.test.js +155 -0
- package/pd-cli/dist/commands/runtime-uat.guard.test.js.map +1 -0
- package/pd-cli/dist/commands/runtime-uat.js +29 -3
- package/pd-cli/dist/commands/runtime-uat.js.map +1 -1
- package/pd-cli/dist/config-reader.d.ts +25 -0
- package/pd-cli/dist/config-reader.d.ts.map +1 -0
- package/pd-cli/dist/config-reader.js +109 -0
- package/pd-cli/dist/config-reader.js.map +1 -0
- package/pd-cli/dist/index.js +40 -5
- package/pd-cli/dist/index.js.map +1 -1
- package/pd-cli/dist/services/console-launcher.d.ts.map +1 -1
- package/pd-cli/dist/services/console-launcher.js +29 -15
- package/pd-cli/dist/services/console-launcher.js.map +1 -1
- package/pd-cli/dist/services/demo-story-a-runner.d.ts.map +1 -1
- package/pd-cli/dist/services/demo-story-a-runner.js +1 -0
- package/pd-cli/dist/services/demo-story-a-runner.js.map +1 -1
- package/pd-cli/dist/utils/production-workspace-guard.d.ts +77 -0
- package/pd-cli/dist/utils/production-workspace-guard.d.ts.map +1 -0
- package/pd-cli/dist/utils/production-workspace-guard.js +170 -0
- package/pd-cli/dist/utils/production-workspace-guard.js.map +1 -0
- package/pd-cli/dist/utils/production-workspace-guard.test.d.ts +2 -0
- package/pd-cli/dist/utils/production-workspace-guard.test.d.ts.map +1 -0
- package/pd-cli/dist/utils/production-workspace-guard.test.js +95 -0
- package/pd-cli/dist/utils/production-workspace-guard.test.js.map +1 -0
- package/pd-cli/package.json +1 -1
- package/plugin/dist/commands/pain.js +27 -2
- package/plugin/dist/core/pain-diagnostic-gate.d.ts +6 -0
- package/plugin/dist/core/pain-diagnostic-gate.js +9 -0
- package/plugin/dist/hooks/after-tool-call-helpers.d.ts +90 -0
- package/plugin/dist/hooks/after-tool-call-helpers.js +486 -0
- package/plugin/dist/hooks/after-tool-call-types.d.ts +92 -0
- package/plugin/dist/hooks/after-tool-call-types.js +13 -0
- package/plugin/dist/hooks/gate-block-helper.js +73 -29
- package/plugin/dist/hooks/llm.js +49 -29
- package/plugin/dist/hooks/message-sanitize.d.ts +21 -0
- package/plugin/dist/hooks/message-sanitize.js +30 -0
- package/plugin/dist/hooks/pain.d.ts +26 -3
- package/plugin/dist/hooks/pain.js +165 -425
- package/plugin/dist/hooks/prompt.js +3 -2
- package/plugin/dist/hooks/trajectory-evidence.d.ts +11 -0
- package/plugin/dist/hooks/trajectory-evidence.js +65 -0
- package/plugin/dist/hooks/triage-adapter.d.ts +82 -0
- package/plugin/dist/hooks/triage-adapter.js +121 -0
- package/console/dist/server/models/EventLogReadModel.d.ts +0 -33
- package/console/dist/server/models/EventLogReadModel.js +0 -218
- package/console/dist/server/models/EvolutionConsoleModel.d.ts +0 -79
- package/console/dist/server/models/EvolutionConsoleModel.js +0 -179
- package/console/dist/server/models/FeedbackConsoleModel.d.ts +0 -38
- package/console/dist/server/models/FeedbackConsoleModel.js +0 -129
- package/console/dist/server/models/GateConsoleModel.d.ts +0 -50
- package/console/dist/server/models/GateConsoleModel.js +0 -151
- package/console/dist/server/models/OverviewConsoleModel.d.ts +0 -22
- package/console/dist/server/models/OverviewConsoleModel.js +0 -202
- package/console/dist/server/models/PipelineStatsModel.d.ts +0 -35
- package/console/dist/server/models/PipelineStatsModel.js +0 -129
- package/console/dist/server/models/SampleConsoleModel.d.ts +0 -21
- package/console/dist/server/models/SampleConsoleModel.js +0 -188
- package/console/dist/server/models/ThinkingModelsConsoleModel.d.ts +0 -22
- package/console/dist/server/models/ThinkingModelsConsoleModel.js +0 -75
- package/console/dist/server/routes/agents.d.ts +0 -3
- package/console/dist/server/routes/agents.js +0 -442
- package/console/dist/server/routes/central.d.ts +0 -5
- package/console/dist/server/routes/central.js +0 -31
- package/console/dist/server/routes/events.d.ts +0 -10
- package/console/dist/server/routes/events.js +0 -99
- package/console/dist/server/routes/evolution.js +0 -73
- package/console/dist/server/routes/feedback.d.ts +0 -3
- package/console/dist/server/routes/feedback.js +0 -65
- package/console/dist/server/routes/gates.d.ts +0 -3
- package/console/dist/server/routes/gates.js +0 -52
- package/console/dist/server/routes/overview.d.ts +0 -3
- package/console/dist/server/routes/overview.js +0 -49
- package/console/dist/server/routes/pipeline.d.ts +0 -3
- package/console/dist/server/routes/pipeline.js +0 -33
- package/console/dist/server/routes/samples.d.ts +0 -3
- package/console/dist/server/routes/samples.js +0 -101
- package/console/dist/server/routes/thinking-models.d.ts +0 -3
- package/console/dist/server/routes/thinking-models.js +0 -54
- package/console/dist/ui/components/app-sidebar.d.ts +0 -7
- package/console/dist/ui/components/app-sidebar.js +0 -75
- package/console/dist/ui/components/compare-view.d.ts +0 -7
- package/console/dist/ui/components/compare-view.js +0 -32
- package/console/dist/ui/components/data-freshness-indicator.d.ts +0 -10
- package/console/dist/ui/components/data-freshness-indicator.js +0 -63
- package/console/dist/ui/components/health-diagnostic-card.d.ts +0 -15
- package/console/dist/ui/components/health-diagnostic-card.js +0 -42
- package/console/dist/ui/components/page-header.d.ts +0 -10
- package/console/dist/ui/components/page-header.js +0 -37
- package/console/dist/ui/hooks/useAutoRefresh.d.ts +0 -13
- package/console/dist/ui/hooks/useAutoRefresh.js +0 -64
- package/console/dist/ui/hooks/useBookmarks.d.ts +0 -6
- package/console/dist/ui/hooks/useBookmarks.js +0 -43
- package/console/dist/ui/hooks/useDebounce.d.ts +0 -2
- package/console/dist/ui/hooks/useDebounce.js +0 -32
- package/console/dist/ui/hooks/useKeyboardNavigation.d.ts +0 -14
- package/console/dist/ui/hooks/useKeyboardNavigation.js +0 -75
- package/console/dist/ui/pages/AgentsPage.d.ts +0 -1
- package/console/dist/ui/pages/AgentsPage.js +0 -167
- package/console/dist/ui/pages/ApprovalsPage.d.ts +0 -1
- package/console/dist/ui/pages/ApprovalsPage.js +0 -123
- package/console/dist/ui/pages/CentralPage.d.ts +0 -1
- package/console/dist/ui/pages/CentralPage.js +0 -57
- package/console/dist/ui/pages/DataFlowPage.d.ts +0 -1
- package/console/dist/ui/pages/DataFlowPage.js +0 -158
- package/console/dist/ui/pages/EventLogPage.d.ts +0 -1
- package/console/dist/ui/pages/EventLogPage.js +0 -176
- package/console/dist/ui/pages/EvolutionPage.d.ts +0 -1
- package/console/dist/ui/pages/EvolutionPage.js +0 -118
- package/console/dist/ui/pages/FeedbackPage.d.ts +0 -1
- package/console/dist/ui/pages/FeedbackPage.js +0 -46
- package/console/dist/ui/pages/GatesPage.d.ts +0 -1
- package/console/dist/ui/pages/GatesPage.js +0 -31
- package/console/dist/ui/pages/LoginPage.d.ts +0 -5
- package/console/dist/ui/pages/LoginPage.js +0 -39
- package/console/dist/ui/pages/OverviewPage.d.ts +0 -1
- package/console/dist/ui/pages/OverviewPage.js +0 -50
- package/console/dist/ui/pages/PainPage.js +0 -50
- package/console/dist/ui/pages/PrincipleDetailPage.js +0 -145
- package/console/dist/ui/pages/PrinciplesPage.js +0 -322
- package/console/dist/ui/pages/ReportProblemPage.js +0 -186
- package/console/dist/ui/pages/SamplesPage.d.ts +0 -1
- package/console/dist/ui/pages/SamplesPage.js +0 -105
- package/console/dist/ui/pages/SettingsPage.d.ts +0 -1
- package/console/dist/ui/pages/SettingsPage.js +0 -86
- package/console/dist/ui/pages/TasksPage.d.ts +0 -1
- package/console/dist/ui/pages/TasksPage.js +0 -373
- package/console/dist/ui/pages/ThinkingModelsPage.d.ts +0 -1
- package/console/dist/ui/pages/ThinkingModelsPage.js +0 -32
- package/console/dist/ui/pages/UpdatePage.d.ts +0 -1
- package/console/dist/ui/pages/UpdatePage.js +0 -142
- /package/console/dist/ui/pages/{PainPage.d.ts → pain/PainPage.d.ts} +0 -0
- /package/console/dist/ui/pages/{PrincipleDetailPage.d.ts → principles/PrincipleDetailPage.d.ts} +0 -0
- /package/console/dist/ui/pages/{PrinciplesPage.d.ts → principles/PrinciplesPage.d.ts} +0 -0
- /package/console/dist/ui/pages/{ReportProblemPage.d.ts → report-problem/ReportProblemPage.d.ts} +0 -0
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useEffect, useCallback } from "react";
|
|
3
|
+
import { Link } 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 { fetchGovernanceQueue, fetchApprovalsGrouped, } from "../../api.js";
|
|
8
|
+
// ── Approval group validator (not in validators.ts, page-specific) ─────────
|
|
9
|
+
/** Type guard: is this a non-null object with own properties (not inherited)? */
|
|
10
|
+
function isRecord(value) {
|
|
11
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
12
|
+
}
|
|
13
|
+
function validateApprovalGroup(raw) {
|
|
14
|
+
if (!isRecord(raw))
|
|
15
|
+
return null;
|
|
16
|
+
if (!Object.hasOwn(raw, "principleId") ||
|
|
17
|
+
!Object.hasOwn(raw, "principleTitle") ||
|
|
18
|
+
!Object.hasOwn(raw, "status") ||
|
|
19
|
+
!Object.hasOwn(raw, "records")) {
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
const principleId = raw.principleId;
|
|
23
|
+
const principleTitle = raw.principleTitle;
|
|
24
|
+
const status = raw.status;
|
|
25
|
+
const records = raw.records;
|
|
26
|
+
if (typeof principleId !== "string" ||
|
|
27
|
+
typeof principleTitle !== "string" ||
|
|
28
|
+
typeof status !== "string" ||
|
|
29
|
+
!["pending", "approved", "rejected"].includes(status) ||
|
|
30
|
+
!Array.isArray(records)) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
const validRecords = [];
|
|
34
|
+
for (const r of records) {
|
|
35
|
+
if (!isRecord(r))
|
|
36
|
+
return null;
|
|
37
|
+
if (!Object.hasOwn(r, "id") ||
|
|
38
|
+
!Object.hasOwn(r, "artifactId") ||
|
|
39
|
+
!Object.hasOwn(r, "channel") ||
|
|
40
|
+
!Object.hasOwn(r, "createdAt") ||
|
|
41
|
+
typeof r.id !== "string" ||
|
|
42
|
+
typeof r.artifactId !== "string" ||
|
|
43
|
+
typeof r.channel !== "string" ||
|
|
44
|
+
typeof r.createdAt !== "string") {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
validRecords.push({
|
|
48
|
+
id: r.id,
|
|
49
|
+
artifactId: r.artifactId,
|
|
50
|
+
channel: r.channel,
|
|
51
|
+
createdAt: r.createdAt,
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
principleId,
|
|
56
|
+
principleTitle,
|
|
57
|
+
status: status,
|
|
58
|
+
records: validRecords,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
function validateApprovalsGroupedData(raw) {
|
|
62
|
+
if (!isRecord(raw))
|
|
63
|
+
return null;
|
|
64
|
+
if (!Object.hasOwn(raw, "groups") ||
|
|
65
|
+
!Object.hasOwn(raw, "generatedAt")) {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
const groups = raw.groups;
|
|
69
|
+
const generatedAt = raw.generatedAt;
|
|
70
|
+
if (!Array.isArray(groups) || typeof generatedAt !== "string") {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
const validatedGroups = [];
|
|
74
|
+
for (const g of groups) {
|
|
75
|
+
const validated = validateApprovalGroup(g);
|
|
76
|
+
if (validated === null)
|
|
77
|
+
return null;
|
|
78
|
+
validatedGroups.push(validated);
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
groups: validatedGroups,
|
|
82
|
+
generatedAt,
|
|
83
|
+
note: Object.hasOwn(raw, "note") && typeof raw.note === "string" ? raw.note : undefined,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
// ── i18n code mapping helpers ─────────────────────────────────────────────
|
|
87
|
+
/** Map a stateReasonCode to an i18n key, with optional interpolation params. */
|
|
88
|
+
function getStateReasonText(code, t, pendingReviewCount) {
|
|
89
|
+
const i18nKey = `pages.focus.stateReason.${code}`;
|
|
90
|
+
const text = t(i18nKey, { count: pendingReviewCount });
|
|
91
|
+
// If i18n key is not found, t() returns the key itself — fall back to code
|
|
92
|
+
return text === i18nKey ? code : text;
|
|
93
|
+
}
|
|
94
|
+
/** Map a nextActionCode to an i18n key. */
|
|
95
|
+
function getNextActionText(code, t) {
|
|
96
|
+
const i18nKey = `pages.focus.nextAction.${code}`;
|
|
97
|
+
const text = t(i18nKey);
|
|
98
|
+
return text === i18nKey ? code : text;
|
|
99
|
+
}
|
|
100
|
+
/** Map a degraded signal reasonCode to an i18n key. */
|
|
101
|
+
function getDegradedReasonText(code, t) {
|
|
102
|
+
const i18nKey = `pages.focus.degradedReason.${code}`;
|
|
103
|
+
const text = t(i18nKey);
|
|
104
|
+
return text === i18nKey ? code : text;
|
|
105
|
+
}
|
|
106
|
+
/** Map a degraded signal nextActionCode to an i18n key. */
|
|
107
|
+
function getDegradedNextActionText(code, t) {
|
|
108
|
+
const i18nKey = `pages.focus.degradedNextAction.${code}`;
|
|
109
|
+
const text = t(i18nKey);
|
|
110
|
+
return text === i18nKey ? code : text;
|
|
111
|
+
}
|
|
112
|
+
// ── Channel label helper ─────────────────────────────────────────────────────
|
|
113
|
+
function getChannelLabel(channel, t) {
|
|
114
|
+
switch (channel) {
|
|
115
|
+
case "prompt":
|
|
116
|
+
return t("pages.focus.channelPrompt");
|
|
117
|
+
case "defer_archive":
|
|
118
|
+
return t("pages.focus.channelDeferArchive");
|
|
119
|
+
case "code_tool_hook":
|
|
120
|
+
return t("pages.focus.channelCodeToolHook");
|
|
121
|
+
default:
|
|
122
|
+
return channel;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// ── Sub-components ───────────────────────────────────────────────────────────
|
|
126
|
+
function ProseSummary({ pendingCount, deviationCount, stagnationCount, }) {
|
|
127
|
+
const { t } = useTranslation();
|
|
128
|
+
return (_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: "text-ink-3", children: t("pages.focus.summaryLabel") }), " ", _jsx("span", { className: "font-mono font-semibold text-ink", children: pendingCount }), " ", _jsx("span", { className: "text-ink-3", children: t("pages.focus.summaryPending") }), " ", "/", " ", _jsx("span", { className: "font-mono font-semibold text-ink", children: deviationCount }), " ", _jsx("span", { className: "text-ink-3", children: t("pages.focus.summaryDeviation") }), " ", "/", " ", _jsx("span", { className: "font-mono font-semibold text-ink", children: stagnationCount }), " ", _jsx("span", { className: "text-ink-3", children: t("pages.focus.summaryStagnation") })] }));
|
|
129
|
+
}
|
|
130
|
+
function PendingReviewCard({ group, }) {
|
|
131
|
+
const { t } = useTranslation();
|
|
132
|
+
const primaryChannel = group.records[0]?.channel ?? "prompt";
|
|
133
|
+
const channelLabel = getChannelLabel(primaryChannel, t);
|
|
134
|
+
const isReversible = primaryChannel === "prompt" || primaryChannel === "defer_archive";
|
|
135
|
+
return (_jsxs("article", { className: "relative pl-[22px] py-[18px] pr-[18px] bg-panel border border-line rounded-[6px] cursor-pointer transition-colors hover:border-line-2", children: [_jsx("div", { className: "absolute left-0 top-0 bottom-0 w-[3px] rounded-l-[6px] bg-gov" }), _jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [_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 }), isReversible && (_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: primaryChannel === "prompt" ? t("pages.focus.tagReversible") : t("pages.focus.tagLowRisk") }))] }), _jsx("div", { className: "mt-[14px] mb-2 font-semibold text-ink", children: group.principleTitle }), _jsx("div", { className: "mt-2 px-3 py-2 bg-surface/60 border-l-2 border-gov text-ink-3 text-[13px] leading-snug", children: t("pages.focus.evidenceSummary", { count: group.records.length }) }), _jsxs("div", { className: "flex gap-2 mt-4", children: [_jsx(Link, { to: `/principles/${group.principleId}`, className: "inline-flex items-center border border-gov bg-gov text-paper rounded-[3px] px-[14px] py-[6px] text-[12.5px] font-medium hover:bg-gov-2 transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", "data-testid": `review-principle-${group.principleId}`, children: t("pages.focus.reviewAction") }), _jsx(Link, { to: `/principles/${group.principleId}`, 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("pages.focus.viewFullChain") })] })] }));
|
|
136
|
+
}
|
|
137
|
+
function StagnationSignalCard({ signal }) {
|
|
138
|
+
const { t } = useTranslation();
|
|
139
|
+
const label = signal.type === "never_activated"
|
|
140
|
+
? t("pages.focus.stagnationNeverActivated")
|
|
141
|
+
: t("pages.focus.stagnationNoPain");
|
|
142
|
+
return (_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: label }), " ", "\u2014 ", signal.principleId, " \u00B7 ", signal.daysSince, " ", t("pages.focus.stagnationDaysSince")] }), _jsxs(Link, { to: `/activation`, 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.focus.viewFullChain"), " \u2192"] })] }));
|
|
143
|
+
}
|
|
144
|
+
function DegradedSignalCard({ signal }) {
|
|
145
|
+
const { t } = useTranslation();
|
|
146
|
+
const sourceLabel = signal.source === "internalization_task"
|
|
147
|
+
? t("pages.focus.degradedSourceInternalization")
|
|
148
|
+
: signal.source === "chain_integrity"
|
|
149
|
+
? t("pages.focus.degradedSourceChainIntegrity")
|
|
150
|
+
: signal.source === "source_unavailable"
|
|
151
|
+
? t("pages.focus.degradedSourceUnavailable")
|
|
152
|
+
: signal.source;
|
|
153
|
+
// Use i18n-mapped text from reasonCode/nextActionCode
|
|
154
|
+
const reasonText = getDegradedReasonText(signal.reasonCode, t);
|
|
155
|
+
const nextActionText = getDegradedNextActionText(signal.nextActionCode, t);
|
|
156
|
+
return (_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: [_jsx("div", { className: "flex items-center gap-2 mb-2", children: _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: sourceLabel }) }), _jsx("div", { className: "text-ink-2 text-sm leading-relaxed", children: reasonText }), signal.reason && (_jsxs("details", { className: "mt-1", children: [_jsx("summary", { className: "text-ink-4 text-[11px] font-mono cursor-pointer hover:underline", children: t("pages.focus.advancedDiagnostics") }), _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: signal.reason })] })), _jsxs("div", { className: "mt-2 text-ink-4 text-[13px] leading-snug", children: [_jsx("span", { className: "font-medium", children: t("pages.focus.degradedNextActionLabel") }), " ", nextActionText] })] }));
|
|
157
|
+
}
|
|
158
|
+
function OnboardingGuide() {
|
|
159
|
+
const { t } = useTranslation();
|
|
160
|
+
const steps = [
|
|
161
|
+
t("pages.focus.onboardingStep1"),
|
|
162
|
+
t("pages.focus.onboardingStep2"),
|
|
163
|
+
t("pages.focus.onboardingStep3"),
|
|
164
|
+
t("pages.focus.onboardingStep4"),
|
|
165
|
+
t("pages.focus.onboardingStep5"),
|
|
166
|
+
];
|
|
167
|
+
return (_jsxs("div", { className: "bg-panel border border-line rounded-[6px] p-6", children: [_jsx(SectionTitle, { children: t("pages.focus.onboardingTitle") }), _jsx("ol", { className: "space-y-3", children: steps.map((step, i) => (_jsxs("li", { className: "flex gap-3 text-ink-2 text-sm leading-relaxed", children: [_jsx("span", { className: "font-mono text-ink-4 text-[11px] mt-0.5 shrink-0", children: String(i + 1).padStart(2, "0") }), _jsx("span", { children: step })] }, i))) })] }));
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* PRI-332: Shown when all counts are zero and sources are healthy.
|
|
171
|
+
* Explains to the owner that PD has checked everything — not that PD is broken.
|
|
172
|
+
*/
|
|
173
|
+
function ZeroStateHealthy() {
|
|
174
|
+
const { t } = useTranslation();
|
|
175
|
+
return (_jsx("div", { className: "bg-panel border border-line rounded-[6px] p-6", children: _jsx("p", { className: "text-ink-2 text-sm leading-relaxed", children: t("pages.focus.zeroStateHealthy") }) }));
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* PRI-332: Shown when state_db_missing — first-time setup explanation.
|
|
179
|
+
*/
|
|
180
|
+
function ZeroStateDbMissing() {
|
|
181
|
+
const { t } = useTranslation();
|
|
182
|
+
return (_jsxs("div", { className: "bg-panel border border-line rounded-[6px] p-6", children: [_jsx("p", { className: "text-ink-2 text-sm leading-relaxed", children: t("pages.focus.zeroStateDbMissing") }), _jsxs("div", { className: "mt-3 text-ink-4 text-[13px]", children: [_jsx("span", { className: "font-medium", children: t("pages.focus.nextActionLabel") }), " ", getNextActionText("run_config_doctor", t)] })] }));
|
|
183
|
+
}
|
|
184
|
+
function InProgressGuide({ summary }) {
|
|
185
|
+
const { t } = useTranslation();
|
|
186
|
+
return (_jsxs("div", { className: "bg-panel border border-line rounded-[6px] p-6", children: [_jsx(SectionTitle, { children: t("pages.focus.inProgressTitle") }), _jsx("p", { className: "text-ink-2 text-sm leading-relaxed mt-2", children: summary }), _jsx("p", { className: "text-ink-4 text-[13px] leading-relaxed mt-3", children: t("pages.focus.inProgressDetail") })] }));
|
|
187
|
+
}
|
|
188
|
+
function DegradedSummary({ signals }) {
|
|
189
|
+
const { t } = useTranslation();
|
|
190
|
+
return (_jsxs("div", { className: "bg-panel border border-amber/20 border-l-[3px] border-l-amber rounded-[6px] p-5", children: [_jsx(SectionTitle, { children: t("pages.focus.degradedTitle") }), _jsx("p", { className: "text-ink-2 text-sm leading-relaxed mt-2", children: t("pages.focus.degradedStateReason") }), _jsx("div", { className: "mt-4 space-y-[10px]", children: signals.map((signal, i) => (_jsx(DegradedSignalCard, { signal: signal }, `${signal.source}-${i}`))) })] }));
|
|
191
|
+
}
|
|
192
|
+
export function FocusPage() {
|
|
193
|
+
const { t } = useTranslation();
|
|
194
|
+
const [queueData, setQueueData] = useState(null);
|
|
195
|
+
const [groupedData, setGroupedData] = useState(null);
|
|
196
|
+
const [loadingState, setLoadingState] = useState("loading");
|
|
197
|
+
const [errorMessage, setErrorMessage] = useState(null);
|
|
198
|
+
const [groupedErrorReason, setGroupedErrorReason] = useState(null);
|
|
199
|
+
const loadData = useCallback(async () => {
|
|
200
|
+
setLoadingState("loading");
|
|
201
|
+
setErrorMessage(null);
|
|
202
|
+
setGroupedErrorReason(null);
|
|
203
|
+
const [queueResult, groupedResult] = await Promise.all([
|
|
204
|
+
fetchGovernanceQueue(),
|
|
205
|
+
fetchApprovalsGrouped(),
|
|
206
|
+
]);
|
|
207
|
+
// Queue data is already validated by the API layer (validateGovernanceQueue)
|
|
208
|
+
if (!queueResult.success) {
|
|
209
|
+
setLoadingState("error");
|
|
210
|
+
setErrorMessage(queueResult.error);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
setQueueData(queueResult.data);
|
|
214
|
+
// Validate grouped data (ERR-002: degradation with reason)
|
|
215
|
+
if (!groupedResult.success) {
|
|
216
|
+
setGroupedData(null);
|
|
217
|
+
setGroupedErrorReason(groupedResult.error ?? "Approvals data unavailable");
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
const validatedGrouped = validateApprovalsGroupedData(groupedResult.data);
|
|
221
|
+
setGroupedData(validatedGrouped);
|
|
222
|
+
if (validatedGrouped === null) {
|
|
223
|
+
setGroupedErrorReason("Approvals data has unexpected shape");
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
setLoadingState("loaded");
|
|
227
|
+
}, []);
|
|
228
|
+
useEffect(() => {
|
|
229
|
+
loadData();
|
|
230
|
+
}, [loadData]);
|
|
231
|
+
// ── Loading state ────────────────────────────────────────────────────────
|
|
232
|
+
if (loadingState === "loading") {
|
|
233
|
+
return (_jsx(PageShell, { children: _jsxs("div", { className: "text-ink-3 text-sm", role: "status", "aria-live": "polite", children: [t("common.loading"), "\u2026"] }) }));
|
|
234
|
+
}
|
|
235
|
+
// ── Error state (ERR-002: degradation with reason) ───────────────────────
|
|
236
|
+
if (loadingState === "error") {
|
|
237
|
+
return (_jsxs(PageShell, { children: [_jsx("div", { className: "font-mono text-[11px] uppercase tracking-[0.1em] text-ink-3 mb-2", children: t("pages.focus.eyebrow") }), _jsx("h1", { className: "text-[29px] font-semibold tracking-tight text-ink mb-2", children: t("pages.focus.title") }), _jsxs("div", { className: "mt-6 p-4 bg-panel border border-line rounded-[6px] text-ink-2 text-sm", children: [_jsx("p", { children: t("pages.focus.loadError") }), errorMessage && (_jsx("p", { className: "mt-2 text-ink-4 text-[13px] font-mono", children: errorMessage }))] })] }));
|
|
238
|
+
}
|
|
239
|
+
// ── Loaded state ─────────────────────────────────────────────────────────
|
|
240
|
+
const pendingGroups = groupedData?.groups.filter((g) => g.status === "pending") ?? [];
|
|
241
|
+
const pendingCount = queueData?.pendingReviewCount ?? 0;
|
|
242
|
+
const deviationCount = queueData?.behaviorDeviationCount ?? 0;
|
|
243
|
+
const stagnationSignals = queueData?.stagnationSignals ?? [];
|
|
244
|
+
const stagnationCount = stagnationSignals.length;
|
|
245
|
+
const governanceState = queueData?.governanceState ?? "none";
|
|
246
|
+
const stateReasonCode = queueData?.stateReasonCode ?? "no_pipeline_activity";
|
|
247
|
+
const nextActionCode = queueData?.nextActionCode ?? "wait_for_pipeline";
|
|
248
|
+
const inProgressSummary = queueData?.inProgressSummary;
|
|
249
|
+
const degradedSignals = queueData?.degradedSignals;
|
|
250
|
+
const approvalDataUnavailable = (groupedData === null || groupedData.groups.length === 0) && pendingCount > 0;
|
|
251
|
+
// Map codes to i18n text
|
|
252
|
+
const stateReason = getStateReasonText(stateReasonCode, t, pendingCount);
|
|
253
|
+
const nextAction = getNextActionText(nextActionCode, t);
|
|
254
|
+
return (_jsxs(PageShell, { children: [_jsx("div", { className: "font-mono text-[12px] tracking-[0.14em] text-ink-3 uppercase mb-3", children: t("pages.focus.eyebrow") }), _jsx("h1", { className: "text-[29px] font-semibold tracking-tight text-ink mb-2", children: t("pages.focus.title") }), _jsx("p", { className: "text-ink-3 text-[14px] max-w-[760px] leading-relaxed mb-7", children: t("pages.focus.subtitle") }), _jsxs("div", { className: "mb-7 px-[18px] py-[14px] bg-panel border border-line rounded-[6px]", children: [_jsx("div", { className: "flex items-center gap-2 mb-1", children: _jsx("span", { className: `inline-flex items-center rounded-[2px] px-[7px] py-1 font-mono text-[11px] uppercase ${governanceState === "owner_review_ready"
|
|
255
|
+
? "bg-gov/10 text-gov border border-gov/20"
|
|
256
|
+
: governanceState === "degraded"
|
|
257
|
+
? "bg-amber/10 text-amber border border-amber/20"
|
|
258
|
+
: governanceState === "in_progress"
|
|
259
|
+
? "bg-green/10 text-green border border-green/20"
|
|
260
|
+
: "text-ink-4 border border-line bg-surface/80"}`, role: "status", children: t(`pages.focus.stateLabel.${governanceState}`) }) }), _jsx("div", { className: "text-ink-2 text-[13px] leading-relaxed mt-1", children: stateReason }), _jsxs("div", { className: "text-ink-4 text-[13px] leading-relaxed mt-1", children: [_jsx("span", { className: "font-medium", children: t("pages.focus.nextActionLabel") }), " ", nextAction] })] }), _jsx(ProseSummary, { pendingCount: pendingCount, deviationCount: deviationCount, stagnationCount: stagnationCount }), governanceState === "none" && pendingCount === 0 && deviationCount === 0 && stagnationCount === 0 && (stateReasonCode === "state_db_missing" ? (_jsx(ZeroStateDbMissing, {})) : (_jsxs(_Fragment, { children: [_jsx(ZeroStateHealthy, {}), _jsx("div", { className: "mt-4", children: _jsx(OnboardingGuide, {}) })] }))), governanceState === "in_progress" && inProgressSummary && (_jsx(InProgressGuide, { summary: inProgressSummary })), degradedSignals && degradedSignals.length > 0 && (_jsx(DegradedSummary, { signals: degradedSignals })), _jsxs("section", { className: "mt-8", "aria-labelledby": "section-pending", children: [_jsx(SectionTitle, { id: "section-pending", children: t("pages.focus.sectionPending") }), pendingGroups.length > 0 ? (_jsx("div", { className: "space-y-[14px]", children: pendingGroups.map((group) => (_jsx(PendingReviewCard, { group: group }, group.principleId))) })) : (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: approvalDataUnavailable
|
|
261
|
+
? (groupedErrorReason
|
|
262
|
+
? `${t("pages.focus.loadError")} (${groupedErrorReason})`
|
|
263
|
+
: t("pages.focus.loadError"))
|
|
264
|
+
: t("pages.focus.emptyPending") }))] }), _jsxs("section", { className: "mt-8", "aria-labelledby": "section-deviation", children: [_jsx(SectionTitle, { id: "section-deviation", children: t("pages.focus.sectionDeviation") }), deviationCount > 0 ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "text-ink-2 text-sm mb-3", children: [_jsx("span", { className: "font-mono font-semibold text-ink", children: deviationCount }), " ", t("pages.focus.deviationCount", { count: deviationCount })] }), _jsx("div", { className: "text-ink-4 text-[13px] bg-surface/60 border-l-2 border-amber px-3 py-2 mb-4", children: t("pages.focus.deviationDisclaimer") }), _jsxs("details", { className: "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.focus.viewFullChain") }), _jsx("div", { className: "mt-2 pl-4 border-l-2 border-line text-ink-3 text-[13px]", children: t("pages.focus.deviationDetailPending") })] })] })) : (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: t("pages.focus.emptyDeviation") }))] }), _jsxs("section", { className: "mt-8", "aria-labelledby": "section-signals", children: [_jsx(SectionTitle, { id: "section-signals", children: t("pages.focus.sectionSignals") }), stagnationSignals.length > 0 ? (_jsx("div", { className: "space-y-[10px]", children: stagnationSignals.map((signal) => (_jsx(StagnationSignalCard, { signal: signal }, signal.principleId))) })) : (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: t("pages.focus.emptySignals") }))] }), _jsx("footer", { className: "mt-12 pt-6 border-t border-line text-ink-3 text-[13px]", children: t("pages.focus.footer") })] }));
|
|
265
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime validators and derivation logic for Pain Evidence page data.
|
|
3
|
+
*
|
|
4
|
+
* Derives behavior evidence from existing principles data — no new backend
|
|
5
|
+
* route needed. Principles with `derivedFromPainIds` or `painPreventedCount > 0`
|
|
6
|
+
* represent evidence that was captured and internalized.
|
|
7
|
+
*
|
|
8
|
+
* This follows H-section rules and ERR-001/005/009/010.
|
|
9
|
+
*/
|
|
10
|
+
export interface PainEvidence {
|
|
11
|
+
/** The principle ID that was derived from this pain evidence */
|
|
12
|
+
id: string;
|
|
13
|
+
/** Principle text — serves as the evidence title */
|
|
14
|
+
title: string;
|
|
15
|
+
/** The trigger pattern — describes the context where the deviation occurred */
|
|
16
|
+
context: string;
|
|
17
|
+
/** The action — describes what the agent should do instead */
|
|
18
|
+
expectedBehavior: string;
|
|
19
|
+
/** Source: always 'principle_derivation' since we derive from principles */
|
|
20
|
+
source: 'principle_derivation';
|
|
21
|
+
/** Maps principle status to recommendation state */
|
|
22
|
+
recommendationState: 'pending' | 'candidate' | 'principle' | 'dismissed';
|
|
23
|
+
/** Pain-related metadata from the principle */
|
|
24
|
+
trajectorySummary: {
|
|
25
|
+
principleId: string;
|
|
26
|
+
painPreventedCount: number;
|
|
27
|
+
lastPainPreventedAt: string;
|
|
28
|
+
derivedFromPainIds: string[];
|
|
29
|
+
};
|
|
30
|
+
createdAt: string;
|
|
31
|
+
}
|
|
32
|
+
export interface PainEvidenceListData {
|
|
33
|
+
evidence: PainEvidence[];
|
|
34
|
+
generatedAt: string;
|
|
35
|
+
/** Present when data is degraded/missing rather than genuinely zero */
|
|
36
|
+
note?: string;
|
|
37
|
+
}
|
|
38
|
+
export interface PainEvidenceDegraded {
|
|
39
|
+
reason: string;
|
|
40
|
+
nextAction: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Derive a single PainEvidence from a principle list item + detail.
|
|
44
|
+
* Returns null if the principle has no pain-related data.
|
|
45
|
+
*/
|
|
46
|
+
export declare function derivePainEvidenceFromPrinciple(listItem: unknown, detail?: unknown): PainEvidence | null;
|
|
47
|
+
/**
|
|
48
|
+
* Validate the principles list response and derive pain evidence.
|
|
49
|
+
* Uses existing /api/principles data — no new backend route needed.
|
|
50
|
+
*/
|
|
51
|
+
export declare function derivePainEvidenceFromPrinciplesList(raw: unknown): PainEvidenceListData | PainEvidenceDegraded;
|
|
52
|
+
/**
|
|
53
|
+
* Check if a parsed result is degraded (missing data).
|
|
54
|
+
*/
|
|
55
|
+
export declare function isDegraded(result: PainEvidenceListData | PainEvidenceDegraded): result is PainEvidenceDegraded;
|
|
56
|
+
/**
|
|
57
|
+
* Get error message from an unknown API error.
|
|
58
|
+
*/
|
|
59
|
+
export declare function getErrorMessage(err: unknown): string;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime validators and derivation logic for Pain Evidence page data.
|
|
3
|
+
*
|
|
4
|
+
* Derives behavior evidence from existing principles data — no new backend
|
|
5
|
+
* route needed. Principles with `derivedFromPainIds` or `painPreventedCount > 0`
|
|
6
|
+
* represent evidence that was captured and internalized.
|
|
7
|
+
*
|
|
8
|
+
* This follows H-section rules and ERR-001/005/009/010.
|
|
9
|
+
*/
|
|
10
|
+
// ── Validators ────────────────────────────────────────────────────────────────
|
|
11
|
+
const VALID_PRINCIPLE_STATUSES = ['candidate', 'active', 'archived', 'deprecated', 'probation'];
|
|
12
|
+
function isString(value) {
|
|
13
|
+
return typeof value === 'string';
|
|
14
|
+
}
|
|
15
|
+
function isNumber(value) {
|
|
16
|
+
return typeof value === 'number' && !Number.isNaN(value);
|
|
17
|
+
}
|
|
18
|
+
function isRecord(value) {
|
|
19
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Map a principle status to a pain evidence recommendationState.
|
|
23
|
+
* - candidate → pending (not yet reviewed)
|
|
24
|
+
* - active → principle (internalized)
|
|
25
|
+
* - probation → candidate (under review)
|
|
26
|
+
* - archived/deprecated → dismissed
|
|
27
|
+
*/
|
|
28
|
+
function mapRecommendationState(status) {
|
|
29
|
+
switch (status) {
|
|
30
|
+
case 'candidate': return 'pending';
|
|
31
|
+
case 'active': return 'principle';
|
|
32
|
+
case 'probation': return 'candidate';
|
|
33
|
+
case 'archived':
|
|
34
|
+
case 'deprecated': return 'dismissed';
|
|
35
|
+
default: return 'pending';
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Derive a single PainEvidence from a principle list item + detail.
|
|
40
|
+
* Returns null if the principle has no pain-related data.
|
|
41
|
+
*/
|
|
42
|
+
export function derivePainEvidenceFromPrinciple(listItem, detail) {
|
|
43
|
+
if (!isRecord(listItem))
|
|
44
|
+
return null;
|
|
45
|
+
// Must have pain-related fields
|
|
46
|
+
const { painPreventedCount, derivedFromPainIds, lastPainPreventedAt } = detail && isRecord(detail) ? detail : listItem;
|
|
47
|
+
const painCount = isNumber(painPreventedCount) ? painPreventedCount : 0;
|
|
48
|
+
const painIds = Array.isArray(derivedFromPainIds)
|
|
49
|
+
? derivedFromPainIds.filter(isString)
|
|
50
|
+
: [];
|
|
51
|
+
const lastPainAt = isString(lastPainPreventedAt) ? lastPainPreventedAt : '';
|
|
52
|
+
// Only derive evidence if there's actual pain data
|
|
53
|
+
if (painCount === 0 && painIds.length === 0 && !lastPainAt) {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
// Required fields from list item
|
|
57
|
+
const { id, text, triggerPattern, action, status, createdAt } = listItem;
|
|
58
|
+
if (!isString(id) || !isString(text))
|
|
59
|
+
return null;
|
|
60
|
+
const principleStatus = isString(status) && VALID_PRINCIPLE_STATUSES.includes(status)
|
|
61
|
+
? status
|
|
62
|
+
: 'candidate';
|
|
63
|
+
return {
|
|
64
|
+
id,
|
|
65
|
+
title: isString(text) ? text : '',
|
|
66
|
+
context: isString(triggerPattern) ? triggerPattern : '',
|
|
67
|
+
expectedBehavior: isString(action) ? action : '',
|
|
68
|
+
source: 'principle_derivation',
|
|
69
|
+
recommendationState: mapRecommendationState(principleStatus),
|
|
70
|
+
trajectorySummary: {
|
|
71
|
+
principleId: id,
|
|
72
|
+
painPreventedCount: painCount,
|
|
73
|
+
lastPainPreventedAt: lastPainAt,
|
|
74
|
+
derivedFromPainIds: painIds,
|
|
75
|
+
},
|
|
76
|
+
createdAt: isString(createdAt) ? createdAt : new Date().toISOString(),
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Validate the principles list response and derive pain evidence.
|
|
81
|
+
* Uses existing /api/principles data — no new backend route needed.
|
|
82
|
+
*/
|
|
83
|
+
export function derivePainEvidenceFromPrinciplesList(raw) {
|
|
84
|
+
if (!isRecord(raw)) {
|
|
85
|
+
return {
|
|
86
|
+
reason: 'Invalid response format from server',
|
|
87
|
+
nextAction: 'Try refreshing the page. If the problem persists, check the Console API.',
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
const { principles: rawPrinciples } = raw;
|
|
91
|
+
if (!Array.isArray(rawPrinciples)) {
|
|
92
|
+
return {
|
|
93
|
+
reason: 'Response missing principles array',
|
|
94
|
+
nextAction: 'Try refreshing the page.',
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
// Derive evidence from each principle (ERR-005/007: validate array element types)
|
|
98
|
+
const evidence = [];
|
|
99
|
+
for (const item of rawPrinciples) {
|
|
100
|
+
const derived = derivePainEvidenceFromPrinciple(item);
|
|
101
|
+
if (derived !== null) {
|
|
102
|
+
evidence.push(derived);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return {
|
|
106
|
+
evidence,
|
|
107
|
+
generatedAt: new Date().toISOString(),
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Check if a parsed result is degraded (missing data).
|
|
112
|
+
*/
|
|
113
|
+
export function isDegraded(result) {
|
|
114
|
+
return !('evidence' in result);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Get error message from an unknown API error.
|
|
118
|
+
*/
|
|
119
|
+
export function getErrorMessage(err) {
|
|
120
|
+
if (err instanceof Error)
|
|
121
|
+
return err.message;
|
|
122
|
+
if (typeof err === 'string')
|
|
123
|
+
return err;
|
|
124
|
+
return 'Unknown error';
|
|
125
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* PainPage — Behavior Evidence page showing real evidence/pain/diagnosis chain states.
|
|
4
|
+
*
|
|
5
|
+
* PRI-331: Replaces the old approach of deriving evidence from principle metrics
|
|
6
|
+
* with a direct read model from pain_events, tasks, candidates, and ledger.
|
|
7
|
+
*
|
|
8
|
+
* Privacy boundary (G.2 / F.3 / F.5):
|
|
9
|
+
* - No raw prompt, chat, trajectory, token, full absolute path, or stack trace
|
|
10
|
+
* - All summaries are already sanitized by the backend EvidenceChainConsoleModel
|
|
11
|
+
* - Degraded paths show reason + nextAction, never silent fallback (ERR-002)
|
|
12
|
+
*/
|
|
13
|
+
import { useState, useEffect, useCallback } from 'react';
|
|
14
|
+
import { useTranslation } from 'react-i18next';
|
|
15
|
+
import { PageShell } from '../../components/layout/page-shell.js';
|
|
16
|
+
import { Badge } from '../../components/ui/badge.js';
|
|
17
|
+
import { Card, CardContent, CardHeader, CardTitle } from '../../components/ui/card.js';
|
|
18
|
+
import { Button } from '../../components/ui/button.js';
|
|
19
|
+
import { fetchEvidenceChain } from '../../api.js';
|
|
20
|
+
import { formatDate } from '../../utils/format.js';
|
|
21
|
+
/**
|
|
22
|
+
* Translate with fallback — if the i18n key doesn't exist (returns the key itself),
|
|
23
|
+
* return the fallback instead. Prevents raw keys like "pages.pain.source_unknown_value"
|
|
24
|
+
* from being displayed to the user.
|
|
25
|
+
*/
|
|
26
|
+
function tFallback(t, key, fallback) {
|
|
27
|
+
const result = t(key);
|
|
28
|
+
return result === key ? fallback : result;
|
|
29
|
+
}
|
|
30
|
+
function groupForState(state) {
|
|
31
|
+
switch (state) {
|
|
32
|
+
case 'pain_recorded':
|
|
33
|
+
case 'diagnosis_queued':
|
|
34
|
+
case 'diagnosis_running':
|
|
35
|
+
case 'diagnosis_succeeded':
|
|
36
|
+
case 'candidate_generated':
|
|
37
|
+
case 'internalization_started':
|
|
38
|
+
return 'active_chain';
|
|
39
|
+
case 'evidence_only':
|
|
40
|
+
return 'evidence_only';
|
|
41
|
+
case 'diagnosis_failed':
|
|
42
|
+
case 'diagnosis_retry_wait':
|
|
43
|
+
return 'failed';
|
|
44
|
+
default:
|
|
45
|
+
return 'evidence_only';
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
const GROUP_ORDER = ['active_chain', 'failed', 'evidence_only'];
|
|
49
|
+
export function PainPage() {
|
|
50
|
+
const { t } = useTranslation();
|
|
51
|
+
const [state, setState] = useState({ status: 'loading' });
|
|
52
|
+
const [expandedIds, setExpandedIds] = useState(new Set());
|
|
53
|
+
const loadData = useCallback(async () => {
|
|
54
|
+
setState({ status: 'loading' });
|
|
55
|
+
const result = await fetchEvidenceChain();
|
|
56
|
+
if (!result.success) {
|
|
57
|
+
setState({ status: 'error', message: result.error ?? 'Unknown error' });
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
if (result.data) {
|
|
61
|
+
setState({ status: 'loaded', data: result.data });
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
// Validation returned null — degraded state
|
|
65
|
+
setState({
|
|
66
|
+
status: 'error',
|
|
67
|
+
message: t('pages.pain.validationError'),
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}, [t]);
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
loadData();
|
|
73
|
+
}, [loadData]);
|
|
74
|
+
const toggleExpanded = (id) => {
|
|
75
|
+
setExpandedIds((prev) => {
|
|
76
|
+
const next = new Set(prev);
|
|
77
|
+
if (next.has(id)) {
|
|
78
|
+
next.delete(id);
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
next.add(id);
|
|
82
|
+
}
|
|
83
|
+
return next;
|
|
84
|
+
});
|
|
85
|
+
};
|
|
86
|
+
return (_jsxs(PageShell, { children: [_jsxs("div", { className: "mb-8", children: [_jsx("div", { className: "font-mono text-[11px] uppercase tracking-[0.14em] text-ink-3", children: t('pages.pain.eyebrow') }), _jsx("h1", { className: "text-[29px] font-semibold tracking-tight text-ink mt-3 mb-2", children: t('pages.pain.title') }), _jsx("p", { className: "text-ink-3 text-sm leading-relaxed max-w-[712px]", children: t('pages.pain.description') })] }), _jsx("div", { className: "mb-6 p-3 bg-panel border border-line rounded-[var(--radius-md)] text-ink-3 text-[13px] leading-relaxed", children: t('pages.pain.honestyNote') }), state.status === 'loading' && (_jsxs("div", { className: "text-ink-3 text-sm py-8", children: [t('common.loading'), "\u2026"] })), state.status === 'error' && (_jsxs("div", { className: "py-8", children: [_jsxs("div", { className: "text-danger text-sm mb-2", children: [t('pages.pain.loadError'), ": ", state.message] }), _jsx(Button, { variant: "outline", size: "sm", onClick: loadData, children: t('common.refresh') })] })), state.status === 'loaded' && (_jsx(LoadedContent, { data: state.data, expandedIds: expandedIds, onToggle: toggleExpanded, onRefresh: loadData, t: t }))] }));
|
|
87
|
+
}
|
|
88
|
+
function LoadedContent({ data, expandedIds, onToggle, onRefresh, t }) {
|
|
89
|
+
// Show degraded banner if data sources are partially unavailable
|
|
90
|
+
const hasDegraded = !!data.degradedReason;
|
|
91
|
+
// Group records by state category
|
|
92
|
+
const grouped = new Map();
|
|
93
|
+
for (const record of data.records) {
|
|
94
|
+
const group = groupForState(record.state);
|
|
95
|
+
const existing = grouped.get(group) ?? [];
|
|
96
|
+
existing.push(record);
|
|
97
|
+
grouped.set(group, existing);
|
|
98
|
+
}
|
|
99
|
+
const hasRecords = data.records.length > 0;
|
|
100
|
+
return (_jsxs(_Fragment, { children: [hasDegraded && (_jsxs("div", { className: "mb-4 p-3 bg-panel border border-amber/20 rounded-[var(--radius-md)] text-amber text-[13px]", children: [_jsx("div", { className: "mb-1", children: data.degradedReason }), data.nextAction && (_jsx("div", { className: "text-ink-3 text-[12px]", children: data.nextAction }))] })), !hasRecords && data.note && (_jsx("div", { className: "mb-4 p-3 bg-panel border border-line rounded-[var(--radius-md)] text-ink-3 text-[13px]", children: data.note })), !hasRecords && !hasDegraded && _jsx(EmptyState, { t: t }), hasRecords && (_jsx("div", { className: "space-y-8", children: GROUP_ORDER.map((group) => {
|
|
101
|
+
const records = grouped.get(group);
|
|
102
|
+
if (!records || records.length === 0)
|
|
103
|
+
return null;
|
|
104
|
+
return (_jsxs("div", { children: [_jsxs("div", { className: "font-mono text-[11px] uppercase tracking-[0.12em] text-ink-4 mb-3", children: [t(`pages.pain.group_${group}`), " (", records.length, ")"] }), _jsx("div", { className: "space-y-4", children: records.map((record) => (_jsx(EvidenceChainCard, { record: record, expanded: expandedIds.has(record.id), onToggle: () => onToggle(record.id), t: t }, record.id))) })] }, group));
|
|
105
|
+
}) })), _jsxs("div", { className: "mt-8 font-mono text-[11px] text-ink-4", children: [t('pages.pain.generatedAt'), ": ", formatDate(data.generatedAt)] })] }));
|
|
106
|
+
}
|
|
107
|
+
// ── Empty state (E section: guide next step, not "暂无数据") ──────────────────
|
|
108
|
+
function EmptyState({ t }) {
|
|
109
|
+
return (_jsx("div", { className: "py-8", children: _jsxs("div", { className: "p-5 bg-panel border border-line rounded-[var(--radius-md)]", children: [_jsx("h3", { className: "text-[17px] font-semibold text-ink mb-2", children: t('pages.pain.emptyTitle') }), _jsx("p", { className: "text-ink-3 text-sm leading-relaxed", children: t('pages.pain.emptyDescription') })] }) }));
|
|
110
|
+
}
|
|
111
|
+
function EvidenceChainCard({ record, expanded, onToggle, t }) {
|
|
112
|
+
const stateVariant = stateToVariant(record.state);
|
|
113
|
+
const stateLabel = tFallback(t, `pages.pain.state_${record.state}`, record.state);
|
|
114
|
+
const sourceLabel = tFallback(t, `pages.pain.source_${record.sourceKind}`, record.sourceKind);
|
|
115
|
+
return (_jsxs(Card, { className: "overflow-hidden", children: [_jsxs(CardHeader, { children: [_jsxs("div", { className: "flex items-start justify-between gap-3", children: [_jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [_jsx(Badge, { variant: stateVariant, children: stateLabel }), _jsx(Badge, { variant: "outline", children: sourceLabel }), record.admissionDecision && (_jsx(Badge, { variant: "secondary", children: tFallback(t, `pages.pain.admission_${record.admissionDecision}`, record.admissionDecision) }))] }), _jsx("span", { className: "font-mono text-[11px] text-ink-4 whitespace-nowrap", children: formatDate(record.observedAt) })] }), _jsx(CardTitle, { className: "mt-2", children: record.summary })] }), _jsxs(CardContent, { children: [_jsxs("div", { className: "space-y-3 mb-4", children: [record.failureReason && (_jsxs("div", { children: [_jsx("div", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-4 mb-1", children: t('pages.pain.fieldFailureReason') }), _jsx("p", { className: "text-danger text-sm leading-relaxed", children: record.failureReason })] })), record.nextAction && (_jsxs("div", { children: [_jsx("div", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-4 mb-1", children: t('pages.pain.fieldNextAction') }), _jsx("p", { className: "text-ink-2 text-sm leading-relaxed", children: record.nextAction })] })), record.degradedReason && (_jsxs("div", { children: [_jsx("div", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-4 mb-1", children: t('pages.pain.fieldDegradedReason') }), _jsx("p", { className: "text-amber text-sm leading-relaxed", children: record.degradedReason })] }))] }), _jsxs("details", { open: expanded, onToggle: onToggle, children: [_jsx("summary", { className: "font-mono text-[11px] uppercase tracking-[0.1em] text-ink-3 cursor-pointer select-none hover:text-ink transition-colors", children: t('pages.pain.chainToggle') }), _jsx("div", { className: "mt-3 p-3 bg-paper-2 border border-line rounded-[var(--radius-sm)]", children: _jsxs("div", { className: "grid grid-cols-[auto_1fr] gap-x-4 gap-y-2 text-[13px]", children: [_jsx("span", { className: "font-mono text-ink-4", children: t('pages.pain.chainId') }), _jsx("span", { className: "font-mono text-ink-2", children: record.id }), record.linkedTaskId && (_jsxs(_Fragment, { children: [_jsx("span", { className: "font-mono text-ink-4", children: t('pages.pain.chainTaskId') }), _jsx("span", { className: "font-mono text-ink-2", children: record.linkedTaskId })] })), record.linkedTaskStatus && (_jsxs(_Fragment, { children: [_jsx("span", { className: "font-mono text-ink-4", children: t('pages.pain.chainTaskStatus') }), _jsx("span", { className: "font-mono text-ink-2", children: record.linkedTaskStatus })] })), record.linkedCandidateId && (_jsxs(_Fragment, { children: [_jsx("span", { className: "font-mono text-ink-4", children: t('pages.pain.chainCandidateId') }), _jsx("span", { className: "font-mono text-ink-2", children: record.linkedCandidateId })] })), record.linkedPrincipleId && (_jsxs(_Fragment, { children: [_jsx("span", { className: "font-mono text-ink-4", children: t('pages.pain.chainPrincipleId') }), _jsx("span", { className: "font-mono text-ink-2", children: record.linkedPrincipleId })] })), _jsx("span", { className: "font-mono text-ink-4", children: t('pages.pain.chainSourceKind') }), _jsx("span", { className: "font-mono text-ink-2", children: record.sourceKind }), _jsx("span", { className: "font-mono text-ink-4", children: t('pages.pain.chainState') }), _jsx("span", { className: "font-mono text-ink-2", children: record.state })] }) })] })] })] }));
|
|
116
|
+
}
|
|
117
|
+
// ── Helpers ────────────────────────────────────────────────────────────────────
|
|
118
|
+
function stateToVariant(state) {
|
|
119
|
+
switch (state) {
|
|
120
|
+
case 'pain_recorded':
|
|
121
|
+
case 'diagnosis_queued':
|
|
122
|
+
case 'diagnosis_running':
|
|
123
|
+
return 'amber';
|
|
124
|
+
case 'diagnosis_succeeded':
|
|
125
|
+
case 'candidate_generated':
|
|
126
|
+
case 'internalization_started':
|
|
127
|
+
return 'green';
|
|
128
|
+
case 'diagnosis_failed':
|
|
129
|
+
return 'destructive';
|
|
130
|
+
case 'diagnosis_retry_wait':
|
|
131
|
+
return 'amber';
|
|
132
|
+
case 'evidence_only':
|
|
133
|
+
default:
|
|
134
|
+
return 'secondary';
|
|
135
|
+
}
|
|
136
|
+
}
|