create-principles-disciple 1.121.7 → 1.121.9
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/README.md +13 -1
- package/console/dist/server/config/pd-config-store.d.ts +1 -3
- package/console/dist/server/config/pd-config-store.js +4 -4
- package/console/dist/server/feedback/channels.d.ts +2 -8
- package/console/dist/server/feedback/channels.js +0 -11
- package/console/dist/server/index.js +34 -5
- package/console/dist/server/models/ActivationsConsoleModel.d.ts +28 -1
- package/console/dist/server/models/ActivationsConsoleModel.js +72 -30
- package/console/dist/server/models/GovernanceExperienceCollector.d.ts +28 -0
- package/console/dist/server/models/GovernanceExperienceCollector.js +305 -0
- package/console/dist/server/models/GovernanceProjectionCollector.d.ts +60 -2
- package/console/dist/server/models/GovernanceProjectionCollector.js +323 -285
- package/console/dist/server/models/PrincipleClassifier.d.ts +1 -1
- package/console/dist/server/models/PrincipleClassifier.js +7 -4
- package/console/dist/server/models/PrinciplesConsoleModel.d.ts +2 -1
- package/console/dist/server/models/ReceiptsConsoleModel.d.ts +5 -0
- package/console/dist/server/models/ReceiptsConsoleModel.js +140 -13
- package/console/dist/server/routes/activations.js +1 -1
- package/console/dist/server/routes/failed-tasks.js +28 -11
- package/console/dist/server/routes/governance.d.ts +26 -0
- package/console/dist/server/routes/governance.js +51 -0
- package/console/dist/server/routes/owner-identity.d.ts +31 -0
- package/console/dist/server/routes/owner-identity.js +76 -0
- package/console/dist/server/routes/update-history.d.ts +5 -0
- package/console/dist/server/routes/update-history.js +50 -4
- package/console/dist/server/routes/update.js +186 -32
- package/console/dist/shared/feedback-channel-ids.d.ts +13 -0
- package/console/dist/shared/feedback-channel-ids.js +12 -0
- package/console/dist/shared/feedback-contract.d.ts +46 -0
- package/console/dist/shared/feedback-contract.js +45 -0
- package/console/dist/ui/App.js +1 -1
- package/console/dist/ui/api.d.ts +22 -3
- package/console/dist/ui/api.js +63 -3
- package/console/dist/ui/components/receipts/ReceiptCoverageDisclosure.d.ts +6 -0
- package/console/dist/ui/components/receipts/ReceiptCoverageDisclosure.js +66 -0
- package/console/dist/ui/i18n/en.json +198 -2
- package/console/dist/ui/i18n/zh-CN.json +196 -0
- package/console/dist/ui/pages/activation/ActivationPage.js +14 -2
- package/console/dist/ui/pages/failed-tasks/FailedTasksPage.js +25 -5
- package/console/dist/ui/pages/focus/FocusPage.d.ts +28 -1
- package/console/dist/ui/pages/focus/FocusPage.js +128 -15
- package/console/dist/ui/pages/principles/PrincipleDetailPage.d.ts +30 -0
- package/console/dist/ui/pages/principles/PrincipleDetailPage.js +49 -6
- package/console/dist/ui/pages/settings/SettingsPage.js +67 -2
- package/console/dist/ui/pages/settings/UpdatePage.js +7 -7
- package/console/dist/ui/utils/enum-labels.js +0 -1
- package/console/dist/ui/utils/validators.d.ts +53 -21
- package/console/dist/ui/utils/validators.js +248 -21
- package/console/dist/web/assets/app.css +6 -0
- package/console/dist/web/assets/app.js +2721 -1664
- package/console/package.json +4 -2
- package/core/dist/host/host-adapter.d.ts +1 -1
- package/core/dist/host/host-adapter.d.ts.map +1 -1
- package/core/dist/host/host-adapter.js +1 -0
- package/core/dist/host/host-adapter.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/architecture-regression.test.js +12 -2
- package/core/dist/runtime-v2/__tests__/architecture-regression.test.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/attack-e2e-pipeline-smoke.test.js +1 -1
- package/core/dist/runtime-v2/__tests__/attack-e2e-pipeline-smoke.test.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/governance-experience.test.d.ts +2 -0
- package/core/dist/runtime-v2/__tests__/governance-experience.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/__tests__/governance-experience.test.js +300 -0
- package/core/dist/runtime-v2/__tests__/governance-experience.test.js.map +1 -0
- package/core/dist/runtime-v2/__tests__/owner-identity.test.d.ts +2 -0
- package/core/dist/runtime-v2/__tests__/owner-identity.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/__tests__/owner-identity.test.js +147 -0
- package/core/dist/runtime-v2/__tests__/owner-identity.test.js.map +1 -0
- package/core/dist/runtime-v2/__tests__/product-telemetry-contract.test.d.ts +18 -0
- package/core/dist/runtime-v2/__tests__/product-telemetry-contract.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/__tests__/product-telemetry-contract.test.js +303 -0
- package/core/dist/runtime-v2/__tests__/product-telemetry-contract.test.js.map +1 -0
- package/core/dist/runtime-v2/__tests__/recovery-actions-log.test.js +40 -0
- package/core/dist/runtime-v2/__tests__/recovery-actions-log.test.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/status-contract.test.d.ts +2 -0
- package/core/dist/runtime-v2/__tests__/status-contract.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/__tests__/status-contract.test.js +107 -0
- package/core/dist/runtime-v2/__tests__/status-contract.test.js.map +1 -0
- package/core/dist/runtime-v2/activation/__tests__/promotion-evidence-snapshot.test.d.ts +2 -0
- package/core/dist/runtime-v2/activation/__tests__/promotion-evidence-snapshot.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/activation/__tests__/promotion-evidence-snapshot.test.js +104 -0
- package/core/dist/runtime-v2/activation/__tests__/promotion-evidence-snapshot.test.js.map +1 -0
- package/core/dist/runtime-v2/activation/__tests__/promotion-readiness-evaluator.test.js +19 -0
- package/core/dist/runtime-v2/activation/__tests__/promotion-readiness-evaluator.test.js.map +1 -1
- package/core/dist/runtime-v2/activation/__tests__/rulecode-owner-decision-service.test.js +20 -0
- package/core/dist/runtime-v2/activation/__tests__/rulecode-owner-decision-service.test.js.map +1 -1
- package/core/dist/runtime-v2/activation/__tests__/sqlite-activation-safety-store.test.js +40 -0
- package/core/dist/runtime-v2/activation/__tests__/sqlite-activation-safety-store.test.js.map +1 -1
- package/core/dist/runtime-v2/activation/index.d.ts +2 -0
- package/core/dist/runtime-v2/activation/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/activation/index.js +1 -0
- package/core/dist/runtime-v2/activation/index.js.map +1 -1
- package/core/dist/runtime-v2/activation/promotion-evidence-snapshot.d.ts +30 -0
- package/core/dist/runtime-v2/activation/promotion-evidence-snapshot.d.ts.map +1 -0
- package/core/dist/runtime-v2/activation/promotion-evidence-snapshot.js +87 -0
- package/core/dist/runtime-v2/activation/promotion-evidence-snapshot.js.map +1 -0
- package/core/dist/runtime-v2/activation/promotion-readiness-evaluator.d.ts.map +1 -1
- package/core/dist/runtime-v2/activation/promotion-readiness-evaluator.js +3 -0
- package/core/dist/runtime-v2/activation/promotion-readiness-evaluator.js.map +1 -1
- package/core/dist/runtime-v2/activation/promotion-readiness-reader.d.ts +1 -1
- package/core/dist/runtime-v2/activation/promotion-readiness-reader.d.ts.map +1 -1
- package/core/dist/runtime-v2/activation/promotion-readiness-reader.js +2 -2
- package/core/dist/runtime-v2/activation/promotion-readiness-reader.js.map +1 -1
- package/core/dist/runtime-v2/activation/rulecode-owner-decision-service.d.ts.map +1 -1
- package/core/dist/runtime-v2/activation/rulecode-owner-decision-service.js +18 -9
- package/core/dist/runtime-v2/activation/rulecode-owner-decision-service.js.map +1 -1
- package/core/dist/runtime-v2/adapter/__tests__/chaos-json-repair.test.js +1 -1
- package/core/dist/runtime-v2/adapter/__tests__/chaos-json-repair.test.js.map +1 -1
- package/core/dist/runtime-v2/adapter/__tests__/json-extractor.test.js +91 -1
- package/core/dist/runtime-v2/adapter/__tests__/json-extractor.test.js.map +1 -1
- package/core/dist/runtime-v2/adapter/__tests__/pi-ai-runtime-adapter.test.js +59 -12
- package/core/dist/runtime-v2/adapter/__tests__/pi-ai-runtime-adapter.test.js.map +1 -1
- package/core/dist/runtime-v2/adapter/__tests__/runtime-config-contract.test.js +10 -9
- package/core/dist/runtime-v2/adapter/__tests__/runtime-config-contract.test.js.map +1 -1
- package/core/dist/runtime-v2/adapter/__tests__/structured-output-repair.test.js +42 -1
- package/core/dist/runtime-v2/adapter/__tests__/structured-output-repair.test.js.map +1 -1
- package/core/dist/runtime-v2/adapter/json-extractor.d.ts +25 -0
- package/core/dist/runtime-v2/adapter/json-extractor.d.ts.map +1 -1
- package/core/dist/runtime-v2/adapter/json-extractor.js +126 -0
- package/core/dist/runtime-v2/adapter/json-extractor.js.map +1 -1
- package/core/dist/runtime-v2/adapter/l2-agent-loop-adapter.d.ts +9 -4
- package/core/dist/runtime-v2/adapter/l2-agent-loop-adapter.d.ts.map +1 -1
- package/core/dist/runtime-v2/adapter/l2-agent-loop-adapter.js +9 -4
- package/core/dist/runtime-v2/adapter/l2-agent-loop-adapter.js.map +1 -1
- package/core/dist/runtime-v2/adapter/output-repair-contract.d.ts +5 -1
- package/core/dist/runtime-v2/adapter/output-repair-contract.d.ts.map +1 -1
- package/core/dist/runtime-v2/adapter/output-repair-contract.js +4 -1
- package/core/dist/runtime-v2/adapter/output-repair-contract.js.map +1 -1
- package/core/dist/runtime-v2/adapter/pi-ai-catalog.d.ts +7 -0
- package/core/dist/runtime-v2/adapter/pi-ai-catalog.d.ts.map +1 -0
- package/core/dist/runtime-v2/adapter/pi-ai-catalog.js +19 -0
- package/core/dist/runtime-v2/adapter/pi-ai-catalog.js.map +1 -0
- package/core/dist/runtime-v2/adapter/pi-ai-runtime-adapter.d.ts +13 -15
- package/core/dist/runtime-v2/adapter/pi-ai-runtime-adapter.d.ts.map +1 -1
- package/core/dist/runtime-v2/adapter/pi-ai-runtime-adapter.js +104 -37
- package/core/dist/runtime-v2/adapter/pi-ai-runtime-adapter.js.map +1 -1
- package/core/dist/runtime-v2/adapter/structured-output-repair.d.ts +16 -1
- package/core/dist/runtime-v2/adapter/structured-output-repair.d.ts.map +1 -1
- package/core/dist/runtime-v2/adapter/structured-output-repair.js +38 -6
- package/core/dist/runtime-v2/adapter/structured-output-repair.js.map +1 -1
- package/core/dist/runtime-v2/adapter/tools/diagnostician-tool.d.ts +1 -1
- package/core/dist/runtime-v2/adapter/tools/diagnostician-tool.d.ts.map +1 -1
- package/core/dist/runtime-v2/config/__tests__/pd-config-agent-binding.test.js +8 -9
- package/core/dist/runtime-v2/config/__tests__/pd-config-agent-binding.test.js.map +1 -1
- package/core/dist/runtime-v2/config/__tests__/pd-config-contract.test.js +27 -3
- package/core/dist/runtime-v2/config/__tests__/pd-config-contract.test.js.map +1 -1
- package/core/dist/runtime-v2/config/__tests__/pd-config-principles.test.d.ts +11 -0
- package/core/dist/runtime-v2/config/__tests__/pd-config-principles.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/config/__tests__/pd-config-principles.test.js +93 -0
- package/core/dist/runtime-v2/config/__tests__/pd-config-principles.test.js.map +1 -0
- package/core/dist/runtime-v2/config/__tests__/pd-config-workspace.test.js +41 -0
- package/core/dist/runtime-v2/config/__tests__/pd-config-workspace.test.js.map +1 -1
- package/core/dist/runtime-v2/config/index.d.ts +2 -2
- package/core/dist/runtime-v2/config/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/config/index.js +2 -0
- package/core/dist/runtime-v2/config/index.js.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-agent-binding.d.ts.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-agent-binding.js +4 -13
- package/core/dist/runtime-v2/config/pd-config-agent-binding.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 +14 -7
- package/core/dist/runtime-v2/config/pd-config-effective.js.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-feature-flags.d.ts.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-feature-flags.js +5 -12
- package/core/dist/runtime-v2/config/pd-config-feature-flags.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 +2 -0
- package/core/dist/runtime-v2/config/pd-config-types.js.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-validate.d.ts.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-validate.js +48 -3
- package/core/dist/runtime-v2/config/pd-config-validate.js.map +1 -1
- package/core/dist/runtime-v2/core-principles/__tests__/core-axiom-block.test.js +36 -8
- package/core/dist/runtime-v2/core-principles/__tests__/core-axiom-block.test.js.map +1 -1
- package/core/dist/runtime-v2/core-principles/__tests__/core-principle-registry.test.js +36 -12
- package/core/dist/runtime-v2/core-principles/__tests__/core-principle-registry.test.js.map +1 -1
- package/core/dist/runtime-v2/core-principles/core-axiom-block.d.ts +22 -8
- package/core/dist/runtime-v2/core-principles/core-axiom-block.d.ts.map +1 -1
- package/core/dist/runtime-v2/core-principles/core-axiom-block.js +28 -13
- package/core/dist/runtime-v2/core-principles/core-axiom-block.js.map +1 -1
- package/core/dist/runtime-v2/core-principles/core-principle-registry.d.ts +29 -4
- package/core/dist/runtime-v2/core-principles/core-principle-registry.d.ts.map +1 -1
- package/core/dist/runtime-v2/core-principles/core-principle-registry.js +68 -33
- package/core/dist/runtime-v2/core-principles/core-principle-registry.js.map +1 -1
- package/core/dist/runtime-v2/core-principles/index.d.ts +3 -3
- package/core/dist/runtime-v2/core-principles/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/core-principles/index.js +1 -1
- package/core/dist/runtime-v2/core-principles/index.js.map +1 -1
- package/core/dist/runtime-v2/evolution/evolution-types.d.ts +2 -1
- package/core/dist/runtime-v2/evolution/evolution-types.d.ts.map +1 -1
- package/core/dist/runtime-v2/evolution/evolution-types.js.map +1 -1
- package/core/dist/runtime-v2/feature-flags/__tests__/anonymous-product-telemetry-flag.test.d.ts +2 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/anonymous-product-telemetry-flag.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/anonymous-product-telemetry-flag.test.js +48 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/anonymous-product-telemetry-flag.test.js.map +1 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/codex-conversation-ingestion-flag.test.d.ts +2 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/codex-conversation-ingestion-flag.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/codex-conversation-ingestion-flag.test.js +46 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/codex-conversation-ingestion-flag.test.js.map +1 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js +86 -31
- package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js.map +1 -1
- package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-lifecycle.test.d.ts +2 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-lifecycle.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-lifecycle.test.js +83 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-lifecycle.test.js.map +1 -0
- package/core/dist/runtime-v2/feature-flags/feature-flag-contract.d.ts +19 -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 +128 -10
- package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js.map +1 -1
- package/core/dist/runtime-v2/feature-flags/feature-flag-lifecycle.d.ts +37 -0
- package/core/dist/runtime-v2/feature-flags/feature-flag-lifecycle.d.ts.map +1 -0
- package/core/dist/runtime-v2/feature-flags/feature-flag-lifecycle.js +304 -0
- package/core/dist/runtime-v2/feature-flags/feature-flag-lifecycle.js.map +1 -0
- package/core/dist/runtime-v2/feature-flags/index.d.ts +4 -2
- package/core/dist/runtime-v2/feature-flags/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/feature-flags/index.js +3 -1
- package/core/dist/runtime-v2/feature-flags/index.js.map +1 -1
- package/core/dist/runtime-v2/governance-experience-contract.d.ts +468 -0
- package/core/dist/runtime-v2/governance-experience-contract.d.ts.map +1 -0
- package/core/dist/runtime-v2/governance-experience-contract.js +208 -0
- package/core/dist/runtime-v2/governance-experience-contract.js.map +1 -0
- package/core/dist/runtime-v2/governance-experience.d.ts +11 -0
- package/core/dist/runtime-v2/governance-experience.d.ts.map +1 -0
- package/core/dist/runtime-v2/governance-experience.js +276 -0
- package/core/dist/runtime-v2/governance-experience.js.map +1 -0
- package/core/dist/runtime-v2/index.d.ts +20 -8
- package/core/dist/runtime-v2/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/index.js +20 -6
- package/core/dist/runtime-v2/index.js.map +1 -1
- package/core/dist/runtime-v2/internalization/__tests__/artificer-output-retry-flag.test.js +29 -10
- package/core/dist/runtime-v2/internalization/__tests__/artificer-output-retry-flag.test.js.map +1 -1
- package/core/dist/runtime-v2/owner-identity.d.ts +69 -0
- package/core/dist/runtime-v2/owner-identity.d.ts.map +1 -0
- package/core/dist/runtime-v2/owner-identity.js +179 -0
- package/core/dist/runtime-v2/owner-identity.js.map +1 -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 +2 -3
- package/core/dist/runtime-v2/pain-signal-runtime-factory.js.map +1 -1
- package/core/dist/runtime-v2/product-telemetry/daily-identity.d.ts +70 -0
- package/core/dist/runtime-v2/product-telemetry/daily-identity.d.ts.map +1 -0
- package/core/dist/runtime-v2/product-telemetry/daily-identity.js +89 -0
- package/core/dist/runtime-v2/product-telemetry/daily-identity.js.map +1 -0
- package/core/dist/runtime-v2/product-telemetry/snapshot-contract.d.ts +110 -0
- package/core/dist/runtime-v2/product-telemetry/snapshot-contract.d.ts.map +1 -0
- package/core/dist/runtime-v2/product-telemetry/snapshot-contract.js +250 -0
- package/core/dist/runtime-v2/product-telemetry/snapshot-contract.js.map +1 -0
- package/core/dist/runtime-v2/pruning-read-model.d.ts +2 -1
- package/core/dist/runtime-v2/pruning-read-model.d.ts.map +1 -1
- package/core/dist/runtime-v2/pruning-read-model.js.map +1 -1
- package/core/dist/runtime-v2/receipt-coverage.d.ts +63 -0
- package/core/dist/runtime-v2/receipt-coverage.d.ts.map +1 -0
- package/core/dist/runtime-v2/receipt-coverage.js +19 -0
- package/core/dist/runtime-v2/receipt-coverage.js.map +1 -0
- package/core/dist/runtime-v2/recovery-actions-log.d.ts +7 -0
- package/core/dist/runtime-v2/recovery-actions-log.d.ts.map +1 -1
- package/core/dist/runtime-v2/recovery-actions-log.js +6 -0
- package/core/dist/runtime-v2/recovery-actions-log.js.map +1 -1
- package/core/dist/runtime-v2/runtime-protocol.js +1 -1
- package/core/dist/runtime-v2/runtime-protocol.js.map +1 -1
- package/core/dist/runtime-v2/store/task/__tests__/sqlite-task-store.failed-tasks.test.js +17 -1
- package/core/dist/runtime-v2/store/task/__tests__/sqlite-task-store.failed-tasks.test.js.map +1 -1
- package/core/dist/runtime-v2/store/task/sqlite-task-store.d.ts.map +1 -1
- package/core/dist/runtime-v2/store/task/sqlite-task-store.js +10 -0
- package/core/dist/runtime-v2/store/task/sqlite-task-store.js.map +1 -1
- package/core/dist/runtime-v2/store/task/task-types.d.ts +2 -0
- package/core/dist/runtime-v2/store/task/task-types.d.ts.map +1 -1
- package/core/dist/runtime-v2/task-status.d.ts +9 -5
- package/core/dist/runtime-v2/task-status.d.ts.map +1 -1
- package/core/dist/runtime-v2/task-status.js +15 -7
- package/core/dist/runtime-v2/task-status.js.map +1 -1
- package/core/dist/runtime-v2/types/event-types.d.ts +4 -0
- package/core/dist/runtime-v2/types/event-types.d.ts.map +1 -1
- package/core/dist/runtime-v2/types/event-types.js.map +1 -1
- package/core/dist/runtime-v2/types/index.d.ts +1 -1
- package/core/dist/runtime-v2/types/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/types/index.js +1 -1
- package/core/dist/runtime-v2/types/index.js.map +1 -1
- package/core/dist/runtime-v2/types/principle-enums.d.ts +3 -2
- package/core/dist/runtime-v2/types/principle-enums.d.ts.map +1 -1
- package/core/dist/runtime-v2/types/principle-enums.js +11 -5
- package/core/dist/runtime-v2/types/principle-enums.js.map +1 -1
- package/core/dist/runtime-v2/types/principle-schema.d.ts +1 -1
- package/core/dist/runtime-v2/types/principle-tree-store.d.ts +1 -1
- package/core/dist/runtime-v2/utils/cli-process-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/utils/cli-process-runner.js +3 -2
- package/core/dist/runtime-v2/utils/cli-process-runner.js.map +1 -1
- package/core/package.json +4 -5
- package/dist/i18n.d.ts.map +1 -1
- package/dist/i18n.js +4 -2
- package/dist/i18n.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +47 -11
- package/dist/index.js.map +1 -1
- package/dist/installer.d.ts +31 -5
- package/dist/installer.d.ts.map +1 -1
- package/dist/installer.js +472 -161
- package/dist/installer.js.map +1 -1
- package/dist/installers/codex-host-installer.d.ts.map +1 -1
- package/dist/installers/codex-host-installer.js +4 -0
- package/dist/installers/codex-host-installer.js.map +1 -1
- package/dist/mvp-config.d.ts +10 -0
- package/dist/mvp-config.d.ts.map +1 -1
- package/dist/mvp-config.js +30 -3
- package/dist/mvp-config.js.map +1 -1
- package/dist/uninstaller.d.ts +9 -1
- package/dist/uninstaller.d.ts.map +1 -1
- package/dist/uninstaller.js +103 -23
- package/dist/uninstaller.js.map +1 -1
- package/dist/update/atomic-file.d.ts +35 -0
- package/dist/update/atomic-file.d.ts.map +1 -0
- package/dist/update/atomic-file.js +120 -0
- package/dist/update/atomic-file.js.map +1 -0
- package/dist/update/bootstrap-protocol.d.ts +55 -0
- package/dist/update/bootstrap-protocol.d.ts.map +1 -0
- package/dist/update/bootstrap-protocol.js +132 -0
- package/dist/update/bootstrap-protocol.js.map +1 -0
- package/dist/update/channel-metadata.d.ts +28 -0
- package/dist/update/channel-metadata.d.ts.map +1 -0
- package/dist/update/channel-metadata.js +90 -0
- package/dist/update/channel-metadata.js.map +1 -0
- package/dist/update/channel-promotion.d.ts +39 -0
- package/dist/update/channel-promotion.d.ts.map +1 -0
- package/dist/update/channel-promotion.js +55 -0
- package/dist/update/channel-promotion.js.map +1 -0
- package/dist/update/data-compatibility.d.ts +35 -0
- package/dist/update/data-compatibility.d.ts.map +1 -0
- package/dist/update/data-compatibility.js +45 -0
- package/dist/update/data-compatibility.js.map +1 -0
- package/dist/update/install-layout.d.ts +59 -0
- package/dist/update/install-layout.d.ts.map +1 -0
- package/dist/update/install-layout.js +127 -0
- package/dist/update/install-layout.js.map +1 -0
- package/dist/update/legacy-migration.d.ts +56 -0
- package/dist/update/legacy-migration.d.ts.map +1 -0
- package/dist/update/legacy-migration.js +254 -0
- package/dist/update/legacy-migration.js.map +1 -0
- package/dist/update/product-identity.d.ts +50 -0
- package/dist/update/product-identity.d.ts.map +1 -0
- package/dist/update/product-identity.js +63 -0
- package/dist/update/product-identity.js.map +1 -0
- package/dist/update/release-asset-manifest.d.ts +31 -0
- package/dist/update/release-asset-manifest.d.ts.map +1 -0
- package/dist/update/release-asset-manifest.js +161 -0
- package/dist/update/release-asset-manifest.js.map +1 -0
- package/dist/update/release-identity.d.ts +33 -0
- package/dist/update/release-identity.d.ts.map +1 -0
- package/dist/update/release-identity.js +108 -0
- package/dist/update/release-identity.js.map +1 -0
- package/dist/update/release-manager.d.ts +96 -0
- package/dist/update/release-manager.d.ts.map +1 -0
- package/dist/update/release-manager.js +253 -0
- package/dist/update/release-manager.js.map +1 -0
- package/dist/update/release-metadata.d.ts +57 -0
- package/dist/update/release-metadata.d.ts.map +1 -0
- package/dist/update/release-metadata.js +200 -0
- package/dist/update/release-metadata.js.map +1 -0
- package/dist/update/release-policy.d.ts +51 -0
- package/dist/update/release-policy.d.ts.map +1 -0
- package/dist/update/release-policy.js +103 -0
- package/dist/update/release-policy.js.map +1 -0
- package/dist/update/rollback-policy.d.ts +56 -0
- package/dist/update/rollback-policy.d.ts.map +1 -0
- package/dist/update/rollback-policy.js +61 -0
- package/dist/update/rollback-policy.js.map +1 -0
- package/dist/update/transaction-journal.d.ts +121 -0
- package/dist/update/transaction-journal.d.ts.map +1 -0
- package/dist/update/transaction-journal.js +333 -0
- package/dist/update/transaction-journal.js.map +1 -0
- package/dist/update/trust-metadata.d.ts +55 -0
- package/dist/update/trust-metadata.d.ts.map +1 -0
- package/dist/update/trust-metadata.js +170 -0
- package/dist/update/trust-metadata.js.map +1 -0
- package/dist/update/update-history.d.ts +46 -0
- package/dist/update/update-history.d.ts.map +1 -0
- package/dist/update/update-history.js +123 -0
- package/dist/update/update-history.js.map +1 -0
- package/dist/utils/env.d.ts +7 -0
- package/dist/utils/env.d.ts.map +1 -1
- package/dist/utils/env.js +134 -44
- package/dist/utils/env.js.map +1 -1
- package/host-runtime/dist/governance-observation-store.d.ts +172 -0
- package/host-runtime/dist/governance-observation-store.js +649 -0
- package/host-runtime/dist/index.d.ts +6 -0
- package/host-runtime/dist/index.js +8 -0
- package/host-runtime/dist/product-telemetry/consent-store.d.ts +107 -0
- package/host-runtime/dist/product-telemetry/consent-store.js +329 -0
- package/host-runtime/dist/product-telemetry/eligibility.d.ts +53 -0
- package/host-runtime/dist/product-telemetry/eligibility.js +69 -0
- package/host-runtime/dist/product-telemetry/exporter.d.ts +46 -0
- package/host-runtime/dist/product-telemetry/exporter.js +71 -0
- package/host-runtime/dist/product-telemetry/milestone-readers.d.ts +61 -0
- package/host-runtime/dist/product-telemetry/milestone-readers.js +234 -0
- package/host-runtime/dist/product-telemetry/service.d.ts +142 -0
- package/host-runtime/dist/product-telemetry/service.js +532 -0
- package/host-runtime/dist/product-telemetry/workspace-scope.d.ts +38 -0
- package/host-runtime/dist/product-telemetry/workspace-scope.js +64 -0
- package/host-runtime/package.json +7 -2
- package/install-layout/dist/index.d.ts +48 -0
- package/install-layout/dist/index.js +81 -0
- package/install-layout/dist/index.test.d.ts +1 -0
- package/install-layout/dist/index.test.js +34 -0
- package/install-layout/package.json +33 -0
- package/package.json +16 -6
- package/pd-cli/dist/commands/__tests__/telemetry-flag-wiring.test.d.ts +9 -0
- package/pd-cli/dist/commands/__tests__/telemetry-flag-wiring.test.d.ts.map +1 -0
- package/pd-cli/dist/commands/__tests__/telemetry-flag-wiring.test.js +76 -0
- package/pd-cli/dist/commands/__tests__/telemetry-flag-wiring.test.js.map +1 -0
- package/pd-cli/dist/commands/__tests__/version.test.d.ts +2 -0
- package/pd-cli/dist/commands/__tests__/version.test.d.ts.map +1 -0
- package/pd-cli/dist/commands/__tests__/version.test.js +134 -0
- package/pd-cli/dist/commands/__tests__/version.test.js.map +1 -0
- package/pd-cli/dist/commands/console.d.ts.map +1 -1
- package/pd-cli/dist/commands/console.js +29 -10
- package/pd-cli/dist/commands/console.js.map +1 -1
- package/pd-cli/dist/commands/pain-record.d.ts.map +1 -1
- package/pd-cli/dist/commands/pain-record.js +6 -15
- package/pd-cli/dist/commands/pain-record.js.map +1 -1
- package/pd-cli/dist/commands/runtime-activation.d.ts +29 -0
- package/pd-cli/dist/commands/runtime-activation.d.ts.map +1 -1
- package/pd-cli/dist/commands/runtime-activation.js +70 -31
- package/pd-cli/dist/commands/runtime-activation.js.map +1 -1
- package/pd-cli/dist/commands/runtime-internalization-enqueue-successors.d.ts.map +1 -1
- package/pd-cli/dist/commands/runtime-internalization-enqueue-successors.js +2 -2
- package/pd-cli/dist/commands/runtime-internalization-enqueue-successors.js.map +1 -1
- package/pd-cli/dist/commands/telemetry.d.ts +82 -0
- package/pd-cli/dist/commands/telemetry.d.ts.map +1 -0
- package/pd-cli/dist/commands/telemetry.js +268 -0
- package/pd-cli/dist/commands/telemetry.js.map +1 -0
- package/pd-cli/dist/commands/version.d.ts +11 -0
- package/pd-cli/dist/commands/version.d.ts.map +1 -0
- package/pd-cli/dist/commands/version.js +48 -0
- package/pd-cli/dist/commands/version.js.map +1 -0
- package/pd-cli/dist/index.js +35 -2
- package/pd-cli/dist/index.js.map +1 -1
- package/pd-cli/dist/services/version-report.d.ts +44 -0
- package/pd-cli/dist/services/version-report.d.ts.map +1 -0
- package/pd-cli/dist/services/version-report.js +152 -0
- package/pd-cli/dist/services/version-report.js.map +1 -0
- package/pd-cli/package.json +3 -2
- package/plugin/dist/bundle.js +870 -932
- package/plugin/dist/core/init.d.ts +2 -1
- package/plugin/dist/core/principle-application-ledger.d.ts +10 -0
- package/plugin/dist/core/product-telemetry-trigger.d.ts +14 -0
- package/plugin/dist/core/thinking-os-parser.d.ts +5 -2
- package/plugin/dist/governance-audit.js +386 -0
- package/plugin/dist/hooks/gate-block-helper.d.ts +25 -1
- package/plugin/dist/hooks/gate.d.ts +22 -0
- package/plugin/dist/openclaw.plugin.json +1 -1
- package/plugin/dist/rulehost-evidence.js +832 -0
- package/plugin/dist/templates/langs/en/principles/THINKING_OS.md +53 -45
- package/plugin/dist/templates/langs/en/skills/pd-mentor/SKILL.md +1 -1
- package/plugin/dist/templates/langs/zh/principles/THINKING_OS.md +62 -46
- package/plugin/dist/templates/langs/zh/skills/pd-mentor/SKILL.md +1 -1
- package/plugin/dist/templates/workspace/.principles/THINKING_OS.md +66 -38
- package/plugin/openclaw.plugin.json +1 -1
- package/plugin/package.json +1 -1
- package/plugin/templates/langs/en/principles/THINKING_OS.md +53 -45
- package/plugin/templates/langs/en/skills/pd-mentor/SKILL.md +1 -1
- package/plugin/templates/langs/zh/principles/THINKING_OS.md +62 -46
- package/plugin/templates/langs/zh/skills/pd-mentor/SKILL.md +1 -1
- package/plugin/templates/workspace/.principles/THINKING_OS.md +66 -38
|
@@ -9,6 +9,7 @@ import { SectionTitle } from "../../components/layout/section-title.js";
|
|
|
9
9
|
import { DailyThoughtCard } from "../../components/focus/daily-thought-card.js";
|
|
10
10
|
import { ShinyText } from "../../components/ui/shiny-text.js";
|
|
11
11
|
import { fetchGovernanceQueue, fetchApprovalsGrouped, approveApproval, rejectApproval, editApproval, fetchAllActivations, } from "../../api.js";
|
|
12
|
+
import { fetchGovernanceExperience } from "../../api.js";
|
|
12
13
|
export function summarizeDecisionResults(results) {
|
|
13
14
|
const failures = results.filter((result) => !result.success);
|
|
14
15
|
const first = failures[0];
|
|
@@ -137,6 +138,23 @@ function getDegradedNextActionText(code, t) {
|
|
|
137
138
|
const text = t(i18nKey);
|
|
138
139
|
return text === i18nKey ? code : text;
|
|
139
140
|
}
|
|
141
|
+
export const OWNER_CONFIGURE_DOC_URL = "https://github.com/csuzngjh/principles/blob/main/docs/runbooks/ops/owner-identity-configuration.md";
|
|
142
|
+
export const OWNER_CONFIGURE_COMMANDS = [
|
|
143
|
+
{
|
|
144
|
+
labelKey: "pages.focus.experience.ownerGuide.cmdPowerShell",
|
|
145
|
+
command: "[Environment]::SetEnvironmentVariable('PD_OWNER_ID', '<owner-id>', 'User')\n[Environment]::SetEnvironmentVariable('PD_OWNER_CREDENTIAL_ID', '<credential-id>', 'User')",
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
labelKey: "pages.focus.experience.ownerGuide.cmdBash",
|
|
149
|
+
command: "echo 'export PD_OWNER_ID=\"<owner-id>\"' >> ~/.bashrc\necho 'export PD_OWNER_CREDENTIAL_ID=\"<credential-id>\"' >> ~/.bashrc\nsource ~/.bashrc",
|
|
150
|
+
},
|
|
151
|
+
];
|
|
152
|
+
/** Returns the configure guide when the Owner identity is missing, else null. */
|
|
153
|
+
export function deriveOwnerConfigureGuide(ownerIdentityConfiguration) {
|
|
154
|
+
if (ownerIdentityConfiguration !== "missing")
|
|
155
|
+
return null;
|
|
156
|
+
return { docUrl: OWNER_CONFIGURE_DOC_URL, commands: OWNER_CONFIGURE_COMMANDS };
|
|
157
|
+
}
|
|
140
158
|
// ── Channel label helper ─────────────────────────────────────────────────────
|
|
141
159
|
function getChannelLabel(channel, t) {
|
|
142
160
|
switch (channel) {
|
|
@@ -351,9 +369,89 @@ function DegradedSummary({ signals }) {
|
|
|
351
369
|
const { t } = useTranslation();
|
|
352
370
|
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}`))) })] }));
|
|
353
371
|
}
|
|
354
|
-
|
|
372
|
+
// ── PRI-586: Governance Experience Snapshot display ─────────────────────────
|
|
373
|
+
// Exhaustive Record maps over the snapshot enums (ERR-106: no binary ternaries
|
|
374
|
+
// folding union members into a default branch). Exported for the i18n parity
|
|
375
|
+
// test; keys must exist in BOTH en.json and zh-CN.json (cr10).
|
|
376
|
+
export const EXPERIENCE_ATTENTION = {
|
|
377
|
+
setup_required: { labelKey: "pages.focus.experience.attention.setupRequired", badgeClass: "bg-amber/10 text-amber border border-amber/20" },
|
|
378
|
+
owner_decision_required: { labelKey: "pages.focus.experience.attention.ownerDecisionRequired", badgeClass: "bg-gov/10 text-gov border border-gov/20" },
|
|
379
|
+
recovery_required: { labelKey: "pages.focus.experience.attention.recoveryRequired", badgeClass: "bg-amber/10 text-amber border border-amber/20" },
|
|
380
|
+
degraded: { labelKey: "pages.focus.experience.attention.degraded", badgeClass: "bg-amber/10 text-amber border border-amber/20" },
|
|
381
|
+
background_processing: { labelKey: "pages.focus.experience.attention.backgroundProcessing", badgeClass: "bg-green/10 text-green border border-green/20" },
|
|
382
|
+
all_clear: { labelKey: "pages.focus.experience.attention.allClear", badgeClass: "text-ink-4 border border-line bg-surface/80" },
|
|
383
|
+
};
|
|
384
|
+
export const EXPERIENCE_REASON = {
|
|
385
|
+
"governance.exp.reason.owner_identity_missing": "pages.focus.experience.reason.ownerIdentityMissing",
|
|
386
|
+
"governance.exp.reason.approval_pending": "pages.focus.experience.reason.approvalPending",
|
|
387
|
+
"governance.exp.reason.rulecode_owner_decision": "pages.focus.experience.reason.rulecodeOwnerDecision",
|
|
388
|
+
"governance.exp.reason.no_pending_decision": "pages.focus.experience.reason.noPendingDecision",
|
|
389
|
+
"governance.exp.reason.owner_decision_available": "pages.focus.experience.reason.ownerDecisionAvailable",
|
|
390
|
+
"governance.exp.reason.break_glass_entry": "pages.focus.experience.reason.breakGlassEntry",
|
|
391
|
+
"governance.exp.reason.recovery_required": "pages.focus.experience.reason.recoveryRequired",
|
|
392
|
+
"governance.exp.reason.source_unavailable": "pages.focus.experience.reason.sourceUnavailable",
|
|
393
|
+
"governance.exp.reason.config_invalid": "pages.focus.experience.reason.configInvalid",
|
|
394
|
+
"governance.exp.reason.processing": "pages.focus.experience.reason.processing",
|
|
395
|
+
"governance.exp.reason.workspace_clear": "pages.focus.experience.reason.workspaceClear",
|
|
396
|
+
"governance.exp.reason.workspace_empty": "pages.focus.experience.reason.workspaceEmpty",
|
|
397
|
+
};
|
|
398
|
+
export const EXPERIENCE_NEXT_ACTION = {
|
|
399
|
+
"governance.exp.next.configure_owner": "pages.focus.experience.next.configureOwner",
|
|
400
|
+
"governance.exp.next.review_approvals": "pages.focus.experience.next.reviewApprovals",
|
|
401
|
+
"governance.exp.next.inspect_recovery": "pages.focus.experience.next.inspectRecovery",
|
|
402
|
+
"governance.exp.next.inspect_sources": "pages.focus.experience.next.inspectSources",
|
|
403
|
+
"governance.exp.next.fix_config": "pages.focus.experience.next.fixConfig",
|
|
404
|
+
"governance.exp.next.monitor": "pages.focus.experience.next.monitor",
|
|
405
|
+
"governance.exp.next.none": "pages.focus.experience.next.none",
|
|
406
|
+
};
|
|
407
|
+
const EXPERIENCE_ENVIRONMENT = {
|
|
408
|
+
production: "pages.focus.experience.trust.environment.production",
|
|
409
|
+
development: "pages.focus.experience.trust.environment.development",
|
|
410
|
+
demo: "pages.focus.experience.trust.environment.demo",
|
|
411
|
+
test: "pages.focus.experience.trust.environment.test",
|
|
412
|
+
unknown: "pages.focus.experience.trust.environment.unknown",
|
|
413
|
+
};
|
|
414
|
+
function ExperienceSummaryCard({ snapshot }) {
|
|
355
415
|
const { t } = useTranslation();
|
|
416
|
+
const [copiedCommandIdx, setCopiedCommandIdx] = useState(null);
|
|
417
|
+
const attention = EXPERIENCE_ATTENTION[snapshot.summary.primaryAttention];
|
|
418
|
+
const categoryOf = (category) => snapshot.activity.categories.find(entry => entry.category === category);
|
|
419
|
+
const decision = categoryOf("needs_decision");
|
|
420
|
+
const recovery = categoryOf("needs_recovery");
|
|
421
|
+
const blocked = categoryOf("blocked");
|
|
422
|
+
const processing = categoryOf("processing");
|
|
423
|
+
const actionOf = (kind) => snapshot.readiness.governanceActions.find(action => action.kind === kind);
|
|
424
|
+
const rulecodeAction = actionOf("rulecode_owner_decision");
|
|
425
|
+
const pauseAction = actionOf("emergency_pause");
|
|
426
|
+
const firstIssue = snapshot.dataQuality.issueGroups[0];
|
|
427
|
+
const ownerGuide = deriveOwnerConfigureGuide(snapshot.readiness.ownerIdentityConfiguration);
|
|
428
|
+
return (_jsxs("div", { className: "mb-7 px-[18px] py-[14px] bg-panel border border-line rounded-[6px]", "data-testid": "experience-summary", 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 ${attention.badgeClass}`, role: "status", children: t(attention.labelKey) }) }), _jsx("div", { className: "text-ink-2 text-[13px] leading-relaxed mt-1", "data-testid": "experience-reason", children: t(EXPERIENCE_REASON[snapshot.summary.reasonCode]) }), _jsxs("div", { className: "text-ink-4 text-[13px] leading-relaxed mt-1", children: [_jsx("span", { className: "font-medium", children: t("pages.focus.nextActionLabel") }), " ", t(EXPERIENCE_NEXT_ACTION[snapshot.summary.nextActionCode])] }), (decision !== undefined || recovery !== undefined || blocked !== undefined || processing !== undefined) && (_jsxs("div", { className: "text-[13px] text-ink-3 mt-2 leading-relaxed", "data-testid": "experience-activity", children: [decision !== undefined && (_jsx("span", { className: "mr-4", children: t("pages.focus.experience.activity.needsDecision", { count: decision.count }) })), recovery !== undefined && (_jsx("span", { className: "mr-4", children: t("pages.focus.experience.activity.needsRecovery", { count: recovery.count }) })), blocked !== undefined && _jsx("span", { className: "mr-4", children: t("pages.focus.experience.activity.blocked") }), processing !== undefined && (_jsx("span", { children: t("pages.focus.experience.activity.processing", { count: processing.count }) }))] })), _jsxs("div", { className: "mt-2 text-[12px] text-ink-4 leading-relaxed", "data-testid": "experience-readiness", children: [t(`pages.focus.experience.readiness.identity.${snapshot.readiness.ownerIdentityConfiguration}`), " · ", t("pages.focus.experience.readiness.principleApproval"), t(`pages.focus.experience.readiness.rulecode.${rulecodeAction?.status === "blocked" ? "blocked" : "ready"}`), t(`pages.focus.experience.readiness.pause.${pauseAction?.observedAuthority === "break_glass" ? "breakGlass" : "owner"}`)] }), ownerGuide !== null && (_jsxs("div", { className: "mt-3 border border-line rounded-[6px] bg-panel px-3 py-2.5", "data-testid": "owner-configure-guide", children: [_jsx("div", { className: "text-[13px] font-medium", children: t("pages.focus.experience.ownerGuide.title") }), _jsx("div", { className: "mt-0.5 text-[12px] text-ink-3 leading-relaxed", children: t("pages.focus.experience.ownerGuide.intro") }), _jsx("div", { className: "mt-2 space-y-2", children: ownerGuide.commands.map((cmd, idx) => (_jsxs("div", { className: "border border-line rounded-[4px] overflow-hidden bg-surface", children: [_jsxs("div", { className: "flex items-center justify-between px-2.5 py-1", children: [_jsx("span", { className: "font-mono text-[11px] uppercase text-ink-3", children: t(cmd.labelKey) }), _jsx("button", { type: "button", onClick: async () => {
|
|
429
|
+
try {
|
|
430
|
+
await navigator.clipboard.writeText(cmd.command);
|
|
431
|
+
setCopiedCommandIdx(idx);
|
|
432
|
+
setTimeout(() => setCopiedCommandIdx(null), 2000);
|
|
433
|
+
}
|
|
434
|
+
catch (error) {
|
|
435
|
+
// clipboard unavailable — keep the command visible as fallback
|
|
436
|
+
console.warn("Owner configure command copy failed.", error);
|
|
437
|
+
}
|
|
438
|
+
}, className: "font-mono text-[11px] text-gov hover:text-gov-2", children: copiedCommandIdx === idx
|
|
439
|
+
? t("pages.focus.experience.ownerGuide.copied")
|
|
440
|
+
: t("pages.focus.experience.ownerGuide.copy") })] }), _jsx("pre", { className: "px-2.5 pb-2 pt-0.5 text-[11px] font-mono text-ink-2 leading-relaxed overflow-x-auto whitespace-pre-wrap", children: cmd.command })] }, cmd.labelKey))) }), _jsx("p", { className: "mt-2 text-[12px] text-amber leading-relaxed", "data-testid": "owner-guide-token-auth-hint", children: t("pages.focus.experience.ownerGuide.tokenAuthHint") }), _jsx("a", { href: ownerGuide.docUrl, target: "_blank", rel: "noreferrer", className: "mt-2 inline-block text-[12px] text-gov underline hover:text-gov-2", children: t("pages.focus.experience.ownerGuide.docLink") })] })), _jsxs("div", { className: "mt-1 text-[12px] text-ink-4", "data-testid": "experience-trust", children: [t(EXPERIENCE_ENVIRONMENT[snapshot.trustContext.environmentContext.environment]), " · ", t(`pages.focus.experience.trust.lineage.${snapshot.trustContext.lineageTransparency.confidence}`)] }), snapshot.dataQuality.degraded && (_jsx("div", { className: "mt-2 text-[12px] text-amber leading-relaxed", "data-testid": "experience-data-quality", children: t("pages.focus.experience.dataQuality.degraded", { count: firstIssue?.count ?? 0, reasonCode: firstIssue?.reasonCode ?? "" }) }))] }));
|
|
441
|
+
}
|
|
442
|
+
export function FocusPage({ featureFlags }) {
|
|
443
|
+
const { t } = useTranslation();
|
|
444
|
+
// PRI-586: when governance_experience_v1 is enabled the governance summary
|
|
445
|
+
// comes ONLY from the experience snapshot — the legacy queue endpoint is not
|
|
446
|
+
// consulted (SPEC §14.2 no old-queue + snapshot merge). Approvals and
|
|
447
|
+
// activations remain the MUTATION surface (action cards), not a status source.
|
|
448
|
+
const experienceMode = featureFlags?.governance_experience_v1?.enabled === true;
|
|
449
|
+
// Flags still loading (undefined): fire NEITHER governance status endpoint —
|
|
450
|
+
// otherwise a transient legacy queue request goes out before the flag turns
|
|
451
|
+
// experience mode on (wasted call + legacy-panel flash). Hold in `loading`.
|
|
452
|
+
const flagsResolved = featureFlags !== undefined;
|
|
356
453
|
const [queueData, setQueueData] = useState(null);
|
|
454
|
+
const [experienceData, setExperienceData] = useState(null);
|
|
357
455
|
const [groupedData, setGroupedData] = useState(null);
|
|
358
456
|
const [loadingState, setLoadingState] = useState("loading");
|
|
359
457
|
const [errorMessage, setErrorMessage] = useState(null);
|
|
@@ -365,18 +463,31 @@ export function FocusPage() {
|
|
|
365
463
|
setErrorMessage(null);
|
|
366
464
|
setGroupedErrorReason(null);
|
|
367
465
|
setRuleCodeErrorReason(null);
|
|
368
|
-
const [queueResult, groupedResult, activationsResult] = await Promise.all([
|
|
369
|
-
|
|
466
|
+
const [experienceResult, queueResult, groupedResult, activationsResult] = await Promise.all([
|
|
467
|
+
experienceMode ? fetchGovernanceExperience() : Promise.resolve(null),
|
|
468
|
+
experienceMode ? Promise.resolve(null) : fetchGovernanceQueue(),
|
|
370
469
|
fetchApprovalsGrouped(),
|
|
371
470
|
fetchAllActivations(),
|
|
372
471
|
]);
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
472
|
+
if (experienceMode) {
|
|
473
|
+
if (experienceResult === null || !experienceResult.success) {
|
|
474
|
+
setLoadingState("error");
|
|
475
|
+
setErrorMessage(experienceResult === null ? t("pages.focus.experience.error.snapshotUnavailable") : experienceResult.error);
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
setExperienceData(experienceResult.data);
|
|
479
|
+
setQueueData(null);
|
|
480
|
+
}
|
|
481
|
+
else {
|
|
482
|
+
// Queue data is already validated by the API layer (validateGovernanceQueue)
|
|
483
|
+
if (queueResult === null || !queueResult.success) {
|
|
484
|
+
setLoadingState("error");
|
|
485
|
+
setErrorMessage(queueResult === null ? t("pages.focus.loadError") : queueResult.error);
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
488
|
+
setQueueData(queueResult.data);
|
|
489
|
+
setExperienceData(null);
|
|
378
490
|
}
|
|
379
|
-
setQueueData(queueResult.data);
|
|
380
491
|
// Validate grouped data (ERR-002: degradation with reason)
|
|
381
492
|
if (!groupedResult.success) {
|
|
382
493
|
setGroupedData(null);
|
|
@@ -397,10 +508,12 @@ export function FocusPage() {
|
|
|
397
508
|
setRuleCodeErrorReason(activationsResult.error);
|
|
398
509
|
}
|
|
399
510
|
setLoadingState("loaded");
|
|
400
|
-
}, []);
|
|
511
|
+
}, [experienceMode, t]);
|
|
401
512
|
useEffect(() => {
|
|
513
|
+
if (!flagsResolved)
|
|
514
|
+
return;
|
|
402
515
|
loadData();
|
|
403
|
-
}, [loadData]);
|
|
516
|
+
}, [flagsResolved, loadData]);
|
|
404
517
|
// ── Loading state ────────────────────────────────────────────────────────
|
|
405
518
|
if (loadingState === "loading") {
|
|
406
519
|
return (_jsx(PageShell, { children: _jsx(PageLoading, { cardCount: 3, label: t("common.loading") }) }));
|
|
@@ -432,17 +545,17 @@ export function FocusPage() {
|
|
|
432
545
|
const stateReasonCount = stateReasonCode === "tasks_need_human_review" ? humanReviewCount : pendingCount;
|
|
433
546
|
const stateReason = getStateReasonText(stateReasonCode, t, stateReasonCount);
|
|
434
547
|
const nextAction = getNextActionText(nextActionCode, t);
|
|
435
|
-
return (_jsx(PageShell, { children: _jsxs("div", { className: "animate-[pdFadeIn_400ms_ease-out]", children: [_jsx("div", { className: "font-mono text-[12px] tracking-[0.14em] text-ink-3 uppercase mb-3", children: t("pages.focus.eyebrow") }), _jsx(ShinyText, { as: "h1", className: "text-[29px] font-semibold tracking-tight text-ink mb-2", duration: 4.5, brightness: 0.5, disabled: pendingCount === 0, 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"
|
|
548
|
+
return (_jsx(PageShell, { children: _jsxs("div", { className: "animate-[pdFadeIn_400ms_ease-out]", children: [_jsx("div", { className: "font-mono text-[12px] tracking-[0.14em] text-ink-3 uppercase mb-3", children: t("pages.focus.eyebrow") }), _jsx(ShinyText, { as: "h1", className: "text-[29px] font-semibold tracking-tight text-ink mb-2", duration: 4.5, brightness: 0.5, disabled: pendingCount === 0, 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") }), experienceMode && experienceData !== null ? (_jsx(ExperienceSummaryCard, { snapshot: experienceData })) : !experienceMode ? (_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"
|
|
436
549
|
? "bg-gov/10 text-gov border border-gov/20"
|
|
437
550
|
: governanceState === "degraded"
|
|
438
551
|
? "bg-amber/10 text-amber border border-amber/20"
|
|
439
552
|
: governanceState === "in_progress"
|
|
440
553
|
? "bg-green/10 text-green border border-green/20"
|
|
441
|
-
: "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, evidenceCount: evidenceCount }), _jsx(
|
|
554
|
+
: "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] })] })) : null, !experienceMode && (_jsxs(_Fragment, { children: [_jsx(ProseSummary, { pendingCount: pendingCount, deviationCount: deviationCount, stagnationCount: stagnationCount, evidenceCount: evidenceCount }), _jsx(FeedbackStratification, { gateBlocksToday: gateBlocksToday, inProgressCount: evidenceCount, pendingCount: pendingCount }), !experienceMode && 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 }))] })), _jsx(DailyThoughtCard, {}), experienceMode && experienceData !== null && experienceData.summary.primaryAttention === "all_clear" && pendingGroups.length === 0 && (_jsx("div", { className: "mt-4", children: _jsx(OnboardingGuide, {}) })), (ruleCodeErrorReason || ruleCodePending.length > 0 || ruleCodeAlerts.length > 0) && (_jsxs("section", { className: "mt-8", "aria-labelledby": "section-rulecode-owner", children: [_jsx(SectionTitle, { id: "section-rulecode-owner", children: t("pages.focus.ruleCodeOwnerQueue") }), ruleCodeErrorReason && (_jsxs("div", { className: "mb-3 rounded border border-amber/30 bg-panel p-4 text-[12px] text-ink-3", children: [_jsx("div", { className: "font-medium text-amber", children: t("pages.focus.ruleCodeUnavailable") }), _jsx("div", { className: "mt-1 font-mono", children: ruleCodeErrorReason }), _jsx("div", { className: "mt-1", children: t("pages.focus.ruleCodeUnavailableNextAction") })] })), _jsxs("div", { className: "grid gap-3 md:grid-cols-2", children: [ruleCodePending.length > 0 && (_jsxs(Link, { to: "/activation", className: "rounded border border-gov/30 bg-panel p-4 hover:border-gov", children: [_jsx("div", { className: "font-medium text-ink", children: t("pages.focus.ruleCodePending") }), _jsx("div", { className: "mt-1 text-[12px] text-ink-3", children: t("pages.focus.ruleCodePendingCount", { count: ruleCodePending.length }) })] })), ruleCodeAlerts.length > 0 && (_jsxs(Link, { to: "/activation", className: "rounded border border-danger/30 bg-panel p-4 hover:border-danger", children: [_jsx("div", { className: "font-medium text-danger", children: t("pages.focus.ruleCodeAlerts") }), _jsx("div", { className: "mt-1 text-[12px] text-ink-3", children: t("pages.focus.ruleCodeAlertCount", { count: ruleCodeAlerts.length }) })] }))] })] })), _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, onDecisionApplied: loadData }, group.principleId))) })) : (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: approvalDataUnavailable
|
|
442
555
|
? (groupedErrorReason
|
|
443
556
|
? `${t("pages.focus.loadError")} (${groupedErrorReason})`
|
|
444
557
|
: t("pages.focus.loadError"))
|
|
445
|
-
: t("pages.focus.emptyPending") }))] }), _jsxs("section", { className: "mt-8", "aria-labelledby": "section-deviation", children: [_jsx(SectionTitle, { id: "section-deviation", children: evidenceCount > 0
|
|
558
|
+
: t("pages.focus.emptyPending") }))] }), !experienceMode && (_jsxs("section", { className: "mt-8", "aria-labelledby": "section-deviation", children: [_jsx(SectionTitle, { id: "section-deviation", children: evidenceCount > 0
|
|
446
559
|
? t("pages.focus.sectionEvidenceInProgress")
|
|
447
|
-
: 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") })] })] })) : evidenceCount > 0 ? (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: t("pages.focus.evidenceInProgress", { count: evidenceCount }) })) : (_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") })] }) }));
|
|
560
|
+
: 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") })] })] })) : evidenceCount > 0 ? (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: t("pages.focus.evidenceInProgress", { count: evidenceCount }) })) : (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3", children: t("pages.focus.emptyDeviation") }))] })), !experienceMode && (_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") })] }) }));
|
|
448
561
|
}
|
|
@@ -2,4 +2,34 @@ export declare function getReceiptPresentation(effectCount: number): {
|
|
|
2
2
|
headlineKey: 'principles.detail.receipts.headline' | 'principles.detail.receipts.headlinePresence';
|
|
3
3
|
showZeroEffectExplanation: boolean;
|
|
4
4
|
};
|
|
5
|
+
export type GovernanceControlBlock = {
|
|
6
|
+
source: 'server';
|
|
7
|
+
reason: string;
|
|
8
|
+
nextAction?: string;
|
|
9
|
+
} | {
|
|
10
|
+
source: 'i18n';
|
|
11
|
+
reasonKey: string;
|
|
12
|
+
nextActionKey?: string;
|
|
13
|
+
};
|
|
14
|
+
export declare const GOVERNANCE_BLOCK_I18N_KEYS: {
|
|
15
|
+
readonly recoveryReason: 'principles.detail.governance.reason.recovery_required';
|
|
16
|
+
readonly recoveryNextAction: 'principles.detail.governance.next.inspect_recovery';
|
|
17
|
+
readonly noDecisionReason: 'principles.detail.governance.actionsNotAuthorized';
|
|
18
|
+
readonly nextActionLabel: 'principles.detail.governance.nextActionLabel';
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Returns `null` when decision controls may render; otherwise the reason they
|
|
22
|
+
* must stay hidden.
|
|
23
|
+
*/
|
|
24
|
+
export declare function deriveGovernanceControlBlock(input: {
|
|
25
|
+
governance: {
|
|
26
|
+
attention: {
|
|
27
|
+
primary: 'none' | 'owner_required' | 'recovery_required';
|
|
28
|
+
};
|
|
29
|
+
} | null;
|
|
30
|
+
governanceUnavailable: {
|
|
31
|
+
reason: string;
|
|
32
|
+
nextAction?: string;
|
|
33
|
+
} | null;
|
|
34
|
+
}): GovernanceControlBlock | null;
|
|
5
35
|
export declare function PrincipleDetailPage(): import("react").JSX.Element;
|
|
@@ -8,6 +8,7 @@ import { PageLoading } from "../../components/layout/page-loading.js";
|
|
|
8
8
|
import { SectionTitle } from "../../components/layout/section-title.js";
|
|
9
9
|
import { Button } from "../../components/ui/button.js";
|
|
10
10
|
import { fetchPrincipleDetail, fetchApprovalsGrouped, fetchLifecycleMetrics, fetchPrincipleTrajectory, fetchPrincipleGovernance, fetchPrincipleReceipts, approveApproval, rejectApproval, editApproval, } from "../../api.js";
|
|
11
|
+
import { ReceiptCoverageDisclosure, getReceiptSourceStatusLabelKey } from "../../components/receipts/ReceiptCoverageDisclosure.js";
|
|
11
12
|
import { formatDate } from "../../utils/format-date.js";
|
|
12
13
|
// ── Runtime validation (H section) ──────────────────────────────────────────
|
|
13
14
|
function isString(v) {
|
|
@@ -113,6 +114,38 @@ export function getReceiptPresentation(effectCount) {
|
|
|
113
114
|
? { headlineKey: 'principles.detail.receipts.headline', showZeroEffectExplanation: false }
|
|
114
115
|
: { headlineKey: 'principles.detail.receipts.headlinePresence', showZeroEffectExplanation: true };
|
|
115
116
|
}
|
|
117
|
+
export const GOVERNANCE_BLOCK_I18N_KEYS = {
|
|
118
|
+
recoveryReason: 'principles.detail.governance.reason.recovery_required',
|
|
119
|
+
recoveryNextAction: 'principles.detail.governance.next.inspect_recovery',
|
|
120
|
+
noDecisionReason: 'principles.detail.governance.actionsNotAuthorized',
|
|
121
|
+
nextActionLabel: 'principles.detail.governance.nextActionLabel',
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Returns `null` when decision controls may render; otherwise the reason they
|
|
125
|
+
* must stay hidden.
|
|
126
|
+
*/
|
|
127
|
+
export function deriveGovernanceControlBlock(input) {
|
|
128
|
+
const { governance, governanceUnavailable } = input;
|
|
129
|
+
if (governance === null) {
|
|
130
|
+
// Flag-off keeps the pre-projection experience: controls stay available and
|
|
131
|
+
// no blocked notice is shown (ERR-102: disabled ≠ unavailable).
|
|
132
|
+
if (governanceUnavailable === null)
|
|
133
|
+
return null;
|
|
134
|
+
return governanceUnavailable.nextAction === undefined
|
|
135
|
+
? { source: 'server', reason: governanceUnavailable.reason }
|
|
136
|
+
: { source: 'server', reason: governanceUnavailable.reason, nextAction: governanceUnavailable.nextAction };
|
|
137
|
+
}
|
|
138
|
+
if (governance.attention.primary === 'owner_required')
|
|
139
|
+
return null;
|
|
140
|
+
if (governance.attention.primary === 'recovery_required') {
|
|
141
|
+
return {
|
|
142
|
+
source: 'i18n',
|
|
143
|
+
reasonKey: GOVERNANCE_BLOCK_I18N_KEYS.recoveryReason,
|
|
144
|
+
nextActionKey: GOVERNANCE_BLOCK_I18N_KEYS.recoveryNextAction,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
return { source: 'i18n', reasonKey: GOVERNANCE_BLOCK_I18N_KEYS.noDecisionReason };
|
|
148
|
+
}
|
|
116
149
|
export function PrincipleDetailPage() {
|
|
117
150
|
const { t, i18n } = useTranslation("pages");
|
|
118
151
|
const { id } = useParams();
|
|
@@ -235,13 +268,21 @@ export function PrincipleDetailPage() {
|
|
|
235
268
|
isActionable = true;
|
|
236
269
|
}
|
|
237
270
|
}
|
|
238
|
-
|
|
239
|
-
|
|
271
|
+
// PRI-582: the projection authorizes the decision controls. When it cannot,
|
|
272
|
+
// controls are hidden together with a truthful reason instead of the generic
|
|
273
|
+
// “no Owner decision is required” copy, which inverted the real cause.
|
|
274
|
+
const governanceBlock = deriveGovernanceControlBlock({ governance, governanceUnavailable });
|
|
275
|
+
const showDecisionControls = governanceBlock === null;
|
|
240
276
|
if (!showDecisionControls) {
|
|
241
277
|
isActionable = false;
|
|
242
|
-
reasonKey = 'principles.detail.governance.actionsNotAuthorized';
|
|
243
|
-
defaultReason = 'No current Owner decision is required.';
|
|
244
278
|
}
|
|
279
|
+
const governanceBlockedNextAction = governanceBlock === null
|
|
280
|
+
? undefined
|
|
281
|
+
: governanceBlock.source === 'server'
|
|
282
|
+
? governanceBlock.nextAction
|
|
283
|
+
: governanceBlock.nextActionKey === undefined
|
|
284
|
+
? undefined
|
|
285
|
+
: t(governanceBlock.nextActionKey);
|
|
245
286
|
const handleApprove = () => {
|
|
246
287
|
if (!isActionable)
|
|
247
288
|
return;
|
|
@@ -426,7 +467,7 @@ export function PrincipleDetailPage() {
|
|
|
426
467
|
effectCount: receipts.effectCount,
|
|
427
468
|
lastEffectAt: receipts.lastEffectAt ? formatDate(receipts.lastEffectAt, i18n.language) : '',
|
|
428
469
|
})
|
|
429
|
-
: t('principles.detail.receipts.headlinePresence') }), _jsx("span", { "data-testid": "receipt-history-counts", className: "font-mono text-[11px] text-ink-3", children: t('principles.detail.receipts.counts', { effectCount: receipts.effectCount, presenceCount: receipts.presenceCount }) })] }), receiptPresentation?.showZeroEffectExplanation && (_jsx("p", { "data-testid": "receipt-history-zero-effect", className: "mt-2 text-[12px] leading-relaxed text-ink-3", children: t('principles.detail.receipts.zeroEffect') })), receipts.events.length > 0 ? (_jsx("ul", { className: "mt-3 space-y-1.5", children: receipts.events.map((event, index) => (_jsxs("li", { className: `flex flex-wrap items-baseline gap-2 text-[13px] ${event.level === 'presence' ? 'text-ink-4' : 'text-ink-2'}`, children: [_jsx("span", { className: "font-mono text-[11px] text-ink-4", children: event.createdAt.slice(0, 16).replace('T', ' ') }), _jsx("span", { className: "font-mono text-[11px]", children: t(`principles.detail.receipts.kind.${event.kind}`, { defaultValue: event.kind }) }), event.digest && _jsx("span", { className: "min-w-0 flex-1 truncate", title: event.digest, children: event.digest })] }, `${event.createdAt}-${index}`))) })) : (_jsx("p", { className: "mt-2 text-[13px] text-ink-3", children: t('principles.detail.receipts.empty') })), _jsx("p", { className: "mt-3 text-[11px] leading-relaxed text-ink-4", children: t('principles.detail.receipts.note') })] })) : (_jsxs("div", { "data-testid": "receipt-history-degraded", className: "rounded-[var(--radius-md)] border border-amber/30 bg-amber/5 p-4", role: "status", children: [_jsx("p", { className: "text-[13px] text-ink-2", children: receipts.reason ?? t('principles.detail.receipts.unavailableReason') }), receipts.nextAction && _jsx("p", { className: "mt-1 text-[12px] text-ink-3", children: receipts.nextAction })] }))] })), _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") }), _jsxs("div", { className: "mt-2 flex items-center gap-3 flex-wrap", children: [_jsx("p", { className: "text-ink-2 text-[14px] leading-relaxed", children: t("principles.detail.evidenceCount", {
|
|
470
|
+
: t('principles.detail.receipts.headlinePresence') }), _jsx("span", { "data-testid": "receipt-history-counts", className: "font-mono text-[11px] text-ink-3", children: t('principles.detail.receipts.counts', { effectCount: receipts.effectCount, presenceCount: receipts.presenceCount }) })] }), receiptPresentation?.showZeroEffectExplanation && (_jsx("p", { "data-testid": "receipt-history-zero-effect", className: "mt-2 text-[12px] leading-relaxed text-ink-3", children: t('principles.detail.receipts.zeroEffect') })), receipts.events.length > 0 ? (_jsx("ul", { className: "mt-3 space-y-1.5", children: receipts.events.map((event, index) => (_jsxs("li", { className: `flex flex-wrap items-baseline gap-2 text-[13px] ${event.level === 'presence' ? 'text-ink-4' : 'text-ink-2'}`, children: [_jsx("span", { className: "font-mono text-[11px] text-ink-4", children: event.createdAt.slice(0, 16).replace('T', ' ') }), _jsx("span", { className: "font-mono text-[11px]", children: t(`principles.detail.receipts.kind.${event.kind}`, { defaultValue: event.kind }) }), event.digest && _jsx("span", { className: "min-w-0 flex-1 truncate", title: event.digest, children: event.digest })] }, `${event.createdAt}-${index}`))) })) : (_jsx("p", { className: "mt-2 text-[13px] text-ink-3", children: t('principles.detail.receipts.empty') })), _jsx("p", { className: "mt-3 text-[11px] leading-relaxed text-ink-4", children: t('principles.detail.receipts.note') }), _jsx("div", { className: "mt-3 border-t border-line pt-3", children: _jsx(ReceiptCoverageDisclosure, { coverage: receipts.coverage }) })] })) : (_jsxs("div", { "data-testid": "receipt-history-degraded", className: "rounded-[var(--radius-md)] border border-amber/30 bg-amber/5 p-4", role: "status", children: [_jsx("h3", { className: "text-[13px] font-semibold text-ink", children: i18n.t(getReceiptSourceStatusLabelKey(receipts.coverage.sourceStatus)) }), _jsx("p", { className: "mt-1 text-[13px] text-ink-2", children: receipts.reason ?? t('principles.detail.receipts.unavailableReason') }), receipts.nextAction && _jsx("p", { className: "mt-1 text-[12px] text-ink-3", children: receipts.nextAction })] }))] })), _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") }), _jsxs("div", { className: "mt-2 flex items-center gap-3 flex-wrap", children: [_jsx("p", { className: "text-ink-2 text-[14px] leading-relaxed", children: t("principles.detail.evidenceCount", {
|
|
430
471
|
defaultValue: "已关联 {{count}} 条证据记录",
|
|
431
472
|
count: principle.derivedFromPainIds.length,
|
|
432
473
|
}) }), _jsx(Button, { variant: "ghost", size: "sm", onClick: async () => {
|
|
@@ -456,5 +497,7 @@ export function PrincipleDetailPage() {
|
|
|
456
497
|
// Fallback: show loading state or no-data message
|
|
457
498
|
['evidence', 'diagnosis', 'proposal', 'review', 'deploy', 'behavior'].map((key) => (_jsxs("div", { className: "flex gap-4", children: [_jsx("span", { className: "font-mono text-[12px] text-ink-3 min-w-[80px]", children: t(STAGE_LABEL_KEYS[key] ?? `principles.detail.stage${key}`, { defaultValue: key }) }), _jsx("div", { className: "flex-1", children: _jsx("p", { className: "text-ink-4 text-[13px]", children: trajectory === null
|
|
458
499
|
? t("principles.detail.trajectoryLoadFailed", { defaultValue: "无法加载轨迹数据" })
|
|
459
|
-
: "—" }) })] }, 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: "无法加载生命周期指标。你可以稍后重试。" }) }) }))] })] }), showDecisionControls && (_jsxs("div", { className: "border-t border-line pt-6 mt-6", children: [_jsx(SectionTitle, { children: t("principles.detail.decisionTitle", { defaultValue: "决策操作" }) }), _jsxs("div", { className: "flex gap-3 flex-wrap items-center", children: [_jsx(Button, { variant: "default", onClick: handleApprove, disabled: !isActionable || actionLoading, children: t("principles.detail.approve") }), _jsx(Button, { variant: "outline", onClick: handleEdit, disabled: !isActionable || actionLoading, children: t("principles.detail.editAction", { defaultValue: "编辑" }) }), _jsx(Button, { variant: "outline", onClick: handlePark, disabled: true, children: t("principles.detail.park") }), _jsx(Button, { variant: "destructive", onClick: handleReject, disabled: !isActionable || actionLoading, children: t("principles.detail.reject") }), _jsxs("span", { className: "text-ink-4 text-[13px]", children: ["(", t("principles.detail.parkUnavailable", { defaultValue: "暂存尚未可用" }), ")"] })] }), !isActionable && (_jsxs("p", { className: "text-danger text-[13px] mt-3 font-mono", children: [t("principles.detail.unactionableReasonPrefix", { defaultValue: "不可操作原因: " }), t(reasonKey, { defaultValue: defaultReason })] })), isActionable && 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") })] })] })), isActionable && 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") })] })] })), isActionable && showEditInput && (_jsxs("div", { className: "mt-4 p-3 border border-gov/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.editReasonLabel", { defaultValue: "编辑原因" }) }), _jsxs("div", { className: "mb-2 text-ink-4 text-[12px] font-mono", children: [t("principles.detail.currentArtifactLabel", { defaultValue: "当前工件" }), ": ", currentArtifactId] }), _jsx("input", { type: "text", value: newArtifactId, onChange: (e) => setNewArtifactId(e.target.value), placeholder: t("principles.detail.editNewArtifactPlaceholder", { defaultValue: "输入新的已验证工件 ID" }), className: "w-full border border-line rounded-[var(--radius-md)] bg-surface text-ink px-3 py-2 text-[13px] mb-2 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gov", "aria-label": t("principles.detail.editNewArtifactPlaceholder", { defaultValue: "输入新的已验证工件 ID" }) }), _jsx("textarea", { value: editReason, onChange: (e) => setEditReason(e.target.value), placeholder: t("principles.detail.editReasonPlaceholder", { defaultValue: "请说明编辑原因" }), 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" }), _jsxs("div", { className: "flex gap-2 mt-2", children: [_jsx(Button, { variant: "default", size: "sm", onClick: confirmEdit, disabled: !editReason.trim() || !newArtifactId.trim() || actionLoading, children: t("principles.detail.confirmEdit", { defaultValue: "确认编辑" }) }), _jsx(Button, { variant: "outline", size: "sm", onClick: cancelEdit, children: t("principles.detail.cancel") })] })] }))] }))
|
|
500
|
+
: "—" }) })] }, 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: "无法加载生命周期指标。你可以稍后重试。" }) }) }))] })] }), showDecisionControls && (_jsxs("div", { className: "border-t border-line pt-6 mt-6", children: [_jsx(SectionTitle, { children: t("principles.detail.decisionTitle", { defaultValue: "决策操作" }) }), _jsxs("div", { className: "flex gap-3 flex-wrap items-center", children: [_jsx(Button, { variant: "default", onClick: handleApprove, disabled: !isActionable || actionLoading, children: t("principles.detail.approve") }), _jsx(Button, { variant: "outline", onClick: handleEdit, disabled: !isActionable || actionLoading, children: t("principles.detail.editAction", { defaultValue: "编辑" }) }), _jsx(Button, { variant: "outline", onClick: handlePark, disabled: true, children: t("principles.detail.park") }), _jsx(Button, { variant: "destructive", onClick: handleReject, disabled: !isActionable || actionLoading, children: t("principles.detail.reject") }), _jsxs("span", { className: "text-ink-4 text-[13px]", children: ["(", t("principles.detail.parkUnavailable", { defaultValue: "暂存尚未可用" }), ")"] })] }), !isActionable && (_jsxs("p", { className: "text-danger text-[13px] mt-3 font-mono", children: [t("principles.detail.unactionableReasonPrefix", { defaultValue: "不可操作原因: " }), t(reasonKey, { defaultValue: defaultReason })] })), isActionable && 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") })] })] })), isActionable && 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") })] })] })), isActionable && showEditInput && (_jsxs("div", { className: "mt-4 p-3 border border-gov/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.editReasonLabel", { defaultValue: "编辑原因" }) }), _jsxs("div", { className: "mb-2 text-ink-4 text-[12px] font-mono", children: [t("principles.detail.currentArtifactLabel", { defaultValue: "当前工件" }), ": ", currentArtifactId] }), _jsx("input", { type: "text", value: newArtifactId, onChange: (e) => setNewArtifactId(e.target.value), placeholder: t("principles.detail.editNewArtifactPlaceholder", { defaultValue: "输入新的已验证工件 ID" }), className: "w-full border border-line rounded-[var(--radius-md)] bg-surface text-ink px-3 py-2 text-[13px] mb-2 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gov", "aria-label": t("principles.detail.editNewArtifactPlaceholder", { defaultValue: "输入新的已验证工件 ID" }) }), _jsx("textarea", { value: editReason, onChange: (e) => setEditReason(e.target.value), placeholder: t("principles.detail.editReasonPlaceholder", { defaultValue: "请说明编辑原因" }), 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" }), _jsxs("div", { className: "flex gap-2 mt-2", children: [_jsx(Button, { variant: "default", size: "sm", onClick: confirmEdit, disabled: !editReason.trim() || !newArtifactId.trim() || actionLoading, children: t("principles.detail.confirmEdit", { defaultValue: "确认编辑" }) }), _jsx(Button, { variant: "outline", size: "sm", onClick: cancelEdit, children: t("principles.detail.cancel") })] })] }))] })), governanceBlock !== null && (_jsxs("div", { className: "border-t border-line pt-6 mt-6", "data-testid": "governance-decision-blocked", children: [_jsx(SectionTitle, { children: t("principles.detail.decisionTitle", { defaultValue: "决策操作" }) }), _jsx("p", { className: "text-danger text-[13px] mt-3 font-mono", "data-testid": "governance-decision-blocked-reason", children: governanceBlock.source === 'server'
|
|
501
|
+
? governanceBlock.reason
|
|
502
|
+
: t(governanceBlock.reasonKey) }), governanceBlockedNextAction !== undefined && (_jsxs("p", { className: "text-ink-3 text-[13px] mt-1 font-mono", "data-testid": "governance-decision-blocked-next-action", children: [_jsx("span", { className: "font-medium", children: t(GOVERNANCE_BLOCK_I18N_KEYS.nextActionLabel) }), " ", governanceBlockedNextAction] }))] }))] }) }));
|
|
460
503
|
}
|
|
@@ -7,7 +7,7 @@ import { cn } from "../../../lib/utils.js";
|
|
|
7
7
|
import { PageShell } from "../../components/layout/page-shell.js";
|
|
8
8
|
import { PageLoading } from "../../components/layout/page-loading.js";
|
|
9
9
|
import { SectionTitle } from "../../components/layout/section-title.js";
|
|
10
|
-
import { getToken, setToken, fetchWorkspaces, addWorkspace, removeWorkspace, syncWorkspace, fetchOutputLanguage, updateOutputLanguage, fetchConfigSummary, patchFeatureFlag, } from "../../api.js";
|
|
10
|
+
import { getToken, setToken, fetchWorkspaces, addWorkspace, removeWorkspace, syncWorkspace, fetchOutputLanguage, updateOutputLanguage, fetchConfigSummary, patchFeatureFlag, fetchOwnerIdentity, registerOwnerIdentity, unregisterOwnerIdentity, } from "../../api.js";
|
|
11
11
|
import { resetOnboardingState } from "../../utils/onboarding-state.js";
|
|
12
12
|
// ── Runtime validators (H section / ERR-001/005/009/013) ─────────────────────
|
|
13
13
|
/** Type guard: is this a non-null object with own properties (not inherited)? */
|
|
@@ -81,6 +81,11 @@ export function SettingsPage() {
|
|
|
81
81
|
const [errorMessage, setErrorMessage] = useState(null);
|
|
82
82
|
// Auth token state
|
|
83
83
|
const [tokenInput, setTokenInput] = useState("");
|
|
84
|
+
// ADR-0022 (PRI-578): Owner identity registration state
|
|
85
|
+
const [ownerIdentity, setOwnerIdentity] = useState(null);
|
|
86
|
+
const [ownerIdInput, setOwnerIdInput] = useState("");
|
|
87
|
+
const [credentialIdInput, setCredentialIdInput] = useState("");
|
|
88
|
+
const [ownerActionPending, setOwnerActionPending] = useState(false);
|
|
84
89
|
// Workspace state
|
|
85
90
|
const [workspaces, setWorkspaces] = useState([]);
|
|
86
91
|
const [addName, setAddName] = useState("");
|
|
@@ -122,6 +127,12 @@ export function SettingsPage() {
|
|
|
122
127
|
}
|
|
123
128
|
}
|
|
124
129
|
// Non-fatal: if language load fails, keep default zh-CN
|
|
130
|
+
// ADR-0022 (PRI-578): Load owner identity status
|
|
131
|
+
const ownerResult = await fetchOwnerIdentity();
|
|
132
|
+
if (ownerResult.success && ownerResult.data) {
|
|
133
|
+
setOwnerIdentity(ownerResult.data);
|
|
134
|
+
}
|
|
135
|
+
// Non-fatal: failures keep the section collapsed to its loading state
|
|
125
136
|
setLoadingState("loaded");
|
|
126
137
|
}, []);
|
|
127
138
|
useEffect(() => {
|
|
@@ -146,6 +157,47 @@ export function SettingsPage() {
|
|
|
146
157
|
setOnboardingFlagEnabled(flag.enabled);
|
|
147
158
|
}, [t]);
|
|
148
159
|
useEffect(() => { void loadOnboardingFlag(); }, [loadOnboardingFlag]);
|
|
160
|
+
// ── ADR-0022 (PRI-578): owner identity handlers ─────────────────────────
|
|
161
|
+
const handleRegisterOwner = useCallback(async () => {
|
|
162
|
+
if (ownerIdInput.trim().length === 0 || credentialIdInput.trim().length === 0) {
|
|
163
|
+
toast.error(t("pages.settings.ownerIdentity.required"));
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
setOwnerActionPending(true);
|
|
167
|
+
try {
|
|
168
|
+
const result = await registerOwnerIdentity(ownerIdInput.trim(), credentialIdInput.trim());
|
|
169
|
+
if (!result.success) {
|
|
170
|
+
toast.error(t("pages.settings.ownerIdentity.operationFailed"));
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
const refresh = await fetchOwnerIdentity();
|
|
174
|
+
if (refresh.success && refresh.data)
|
|
175
|
+
setOwnerIdentity(refresh.data);
|
|
176
|
+
setOwnerIdInput("");
|
|
177
|
+
setCredentialIdInput("");
|
|
178
|
+
toast.success(t("pages.settings.ownerIdentity.registered"));
|
|
179
|
+
}
|
|
180
|
+
finally {
|
|
181
|
+
setOwnerActionPending(false);
|
|
182
|
+
}
|
|
183
|
+
}, [ownerIdInput, credentialIdInput, t]);
|
|
184
|
+
const handleUnregisterOwner = useCallback(async () => {
|
|
185
|
+
setOwnerActionPending(true);
|
|
186
|
+
try {
|
|
187
|
+
const result = await unregisterOwnerIdentity();
|
|
188
|
+
if (!result.success) {
|
|
189
|
+
toast.error(t("pages.settings.ownerIdentity.operationFailed"));
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const refresh = await fetchOwnerIdentity();
|
|
193
|
+
if (refresh.success && refresh.data)
|
|
194
|
+
setOwnerIdentity(refresh.data);
|
|
195
|
+
toast.success(t("pages.settings.ownerIdentity.unregistered"));
|
|
196
|
+
}
|
|
197
|
+
finally {
|
|
198
|
+
setOwnerActionPending(false);
|
|
199
|
+
}
|
|
200
|
+
}, [t]);
|
|
149
201
|
// ── Auth token handlers ────────────────────────────────────────────────
|
|
150
202
|
const handleSaveToken = useCallback(async () => {
|
|
151
203
|
const trimmed = tokenInput.trim();
|
|
@@ -259,7 +311,20 @@ export function SettingsPage() {
|
|
|
259
311
|
return (_jsxs(PageShell, { children: [_jsx("div", { className: "font-mono text-[12px] tracking-[0.14em] text-ink-3 uppercase mb-3", children: t("pages.settings.eyebrow") }), _jsx("h1", { className: "text-[29px] font-semibold tracking-tight text-ink mb-2", children: t("pages.settings.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.settings.loadError") }), errorMessage && (_jsx("p", { className: "mt-2 text-ink-4 text-[13px] font-mono", children: errorMessage }))] })] }));
|
|
260
312
|
}
|
|
261
313
|
// ── Loaded state ─────────────────────────────────────────────────────────
|
|
262
|
-
return (_jsx(PageShell, { children: _jsxs("div", { className: "animate-[pdFadeIn_400ms_ease-out]", children: [_jsx("div", { className: "font-mono text-[12px] tracking-[0.14em] text-ink-3 uppercase mb-3", children: t("pages.settings.eyebrow") }), _jsx("h1", { className: "text-[29px] font-semibold tracking-tight text-ink mb-2", children: t("pages.settings.title") }), _jsx("p", { className: "text-ink-3 text-[14px] max-w-[760px] leading-relaxed mb-7", children: t("pages.settings.subtitle") }), _jsxs("section", { className: "mb-8", "aria-labelledby": "section-auth", children: [_jsx(SectionTitle, { id: "section-auth", children: t("pages.settings.auth") }), _jsxs("div", { className: "bg-panel border border-line rounded-[6px] p-5", children: [_jsx("label", { htmlFor: "bearer-token-input", className: "block text-sm font-medium text-ink mb-2", children: t("pages.settings.bearerToken") }), _jsx("input", { id: "bearer-token-input", type: "password", value: tokenInput, onChange: (e) => setTokenInput(e.target.value), placeholder: t("pages.settings.enterAccessToken"), className: "w-full border border-line bg-surface rounded-[3px] px-3 py-2 text-sm text-ink focus:outline-none focus:border-gov focus:ring-1 focus:ring-gov" }), _jsxs("div", { className: "flex items-center justify-between mt-3", children: [_jsx("button", { onClick: handleSaveToken, disabled: tokenInput.trim().length === 0, className: "border border-gov bg-gov text-paper rounded-[3px] px-[14px] py-[6px] text-[12.5px] font-medium hover:bg-gov-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("common.save") }), _jsx("span", { className: "text-ink-4 text-[12px]", children: t("pages.settings.tokenSessionOnly") })] })] })] }), _jsxs("section", { className: "mb-8", "aria-labelledby": "section-
|
|
314
|
+
return (_jsx(PageShell, { children: _jsxs("div", { className: "animate-[pdFadeIn_400ms_ease-out]", children: [_jsx("div", { className: "font-mono text-[12px] tracking-[0.14em] text-ink-3 uppercase mb-3", children: t("pages.settings.eyebrow") }), _jsx("h1", { className: "text-[29px] font-semibold tracking-tight text-ink mb-2", children: t("pages.settings.title") }), _jsx("p", { className: "text-ink-3 text-[14px] max-w-[760px] leading-relaxed mb-7", children: t("pages.settings.subtitle") }), _jsxs("section", { className: "mb-8", "aria-labelledby": "section-auth", children: [_jsx(SectionTitle, { id: "section-auth", children: t("pages.settings.auth") }), _jsxs("div", { className: "bg-panel border border-line rounded-[6px] p-5", children: [_jsx("label", { htmlFor: "bearer-token-input", className: "block text-sm font-medium text-ink mb-2", children: t("pages.settings.bearerToken") }), _jsx("input", { id: "bearer-token-input", type: "password", value: tokenInput, onChange: (e) => setTokenInput(e.target.value), placeholder: t("pages.settings.enterAccessToken"), className: "w-full border border-line bg-surface rounded-[3px] px-3 py-2 text-sm text-ink focus:outline-none focus:border-gov focus:ring-1 focus:ring-gov" }), _jsxs("div", { className: "flex items-center justify-between mt-3", children: [_jsx("button", { onClick: handleSaveToken, disabled: tokenInput.trim().length === 0, className: "border border-gov bg-gov text-paper rounded-[3px] px-[14px] py-[6px] text-[12.5px] font-medium hover:bg-gov-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("common.save") }), _jsx("span", { className: "text-ink-4 text-[12px]", children: t("pages.settings.tokenSessionOnly") })] })] })] }), _jsxs("section", { className: "mb-8", "aria-labelledby": "section-owner-identity", children: [_jsx(SectionTitle, { id: "section-owner-identity", children: t("pages.settings.ownerIdentity.title") }), _jsxs("div", { className: "bg-panel border border-line rounded-[6px] p-5", children: [_jsx("p", { className: "text-ink-3 text-[13px] leading-relaxed mb-3", children: t("pages.settings.ownerIdentity.intro") }), ownerIdentity === null ? (_jsx("div", { className: "text-ink-4 text-[12px]", children: t("pages.settings.ownerIdentity.loading") })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center gap-2 text-[13px] mb-2", "data-testid": "owner-identity-status", children: [_jsx("span", { className: `inline-flex items-center rounded-[2px] px-[7px] py-1 font-mono text-[11px] uppercase ${ownerIdentity.resolved.source === "none"
|
|
315
|
+
? "bg-amber text-ink"
|
|
316
|
+
: ownerIdentity.resolved.source === "invalid_env"
|
|
317
|
+
? "bg-danger text-paper"
|
|
318
|
+
: "bg-green text-ink"}`, role: "status", children: ownerIdentity.resolved.source === "none"
|
|
319
|
+
? t("pages.settings.ownerIdentity.statusMissing")
|
|
320
|
+
: ownerIdentity.resolved.source === "invalid_env"
|
|
321
|
+
? t("pages.settings.ownerIdentity.statusInvalid")
|
|
322
|
+
: t("pages.settings.ownerIdentity.statusConfigured") }), _jsxs("span", { className: "text-ink-3 text-[12px]", children: [ownerIdentity.resolved.source === "env" && t("pages.settings.ownerIdentity.sourceEnv"), ownerIdentity.resolved.source === "file" && t("pages.settings.ownerIdentity.sourceFile"), ownerIdentity.resolved.source === "invalid_env" && t("pages.settings.ownerIdentity.sourceInvalid"), ownerIdentity.resolved.source === "none" && t("pages.settings.ownerIdentity.sourceNone")] })] }), _jsxs("div", { className: "flex items-center gap-2 text-[13px] mb-2", "data-testid": "owner-governance-readiness", "data-ready": ownerIdentity.governance.ownerIdentityConfiguration === "configured" ? "true" : "false", children: [_jsx("span", { className: `inline-flex items-center rounded-[2px] px-[7px] py-1 font-mono text-[11px] uppercase ${ownerIdentity.governance.ownerIdentityConfiguration === "configured" ? "bg-green text-ink" : "bg-amber text-ink"}`, role: "status", children: ownerIdentity.governance.ownerIdentityConfiguration === "configured"
|
|
323
|
+
? t("pages.settings.ownerIdentity.governanceReady")
|
|
324
|
+
: t("pages.settings.ownerIdentity.governanceNotReady") }), ownerIdentity.governance.ownerIdentityConfiguration !== "configured" && (_jsx("span", { className: "text-ink-3 text-[12px]", children: ownerIdentity.governance.authenticationMode === "no_auth"
|
|
325
|
+
? t("pages.settings.ownerIdentity.governanceReasonTokenAuth")
|
|
326
|
+
: t("pages.settings.ownerIdentity.governanceReasonIdentity") }))] }), ownerIdentity.governance.ownerIdentityConfiguration !== "configured" &&
|
|
327
|
+
ownerIdentity.governance.authenticationMode === "no_auth" && (_jsx("div", { className: "text-ink-4 text-[12px] mb-3", "data-testid": "owner-governance-next-action", children: t("pages.settings.ownerIdentity.governanceNextActionTokenAuth") })), ownerIdentity.resolved.error !== undefined && (_jsx("div", { className: "text-danger text-[12px] mb-3", "data-testid": "owner-identity-error", children: ownerIdentity.resolved.error })), ownerIdentity.resolved.source === "invalid_env" && (_jsx("div", { className: "text-ink-4 text-[12px] mb-3", "data-testid": "owner-identity-invalid-env-hint", children: t("pages.settings.ownerIdentity.invalidEnvHint") })), ownerIdentity.resolved.source === "file" && ownerIdentity.fileRecord !== null && (_jsxs("div", { className: "text-ink-4 text-[12px] mb-3 font-mono", children: [t("pages.settings.ownerIdentity.ownerIdLabel"), ": ", ownerIdentity.fileRecord.ownerId, " \u00B7", " ", t("pages.settings.ownerIdentity.registeredAt"), " ", ownerIdentity.fileRecord.registeredAt.slice(0, 10)] })), ownerIdentity.fileError !== undefined && (_jsx("div", { className: "text-danger text-[12px] mb-3", "data-testid": "owner-identity-file-error", children: ownerIdentity.fileError })), ownerIdentity.resolved.source === "env" ? (_jsx("div", { className: "text-ink-4 text-[12px]", children: t("pages.settings.ownerIdentity.envHint") })) : (_jsxs("div", { className: "mt-3", children: [_jsx("label", { htmlFor: "owner-id-input", className: "block text-sm font-medium text-ink mb-1", children: t("pages.settings.ownerIdentity.ownerIdLabel") }), _jsx("input", { id: "owner-id-input", type: "text", value: ownerIdInput, onChange: (e) => setOwnerIdInput(e.target.value), disabled: ownerActionPending, placeholder: "owner-alice", className: "w-full border border-line bg-surface rounded-[3px] px-3 py-2 text-sm text-ink focus:outline-none focus:border-gov focus:ring-1 focus:ring-gov disabled:opacity-50" }), _jsx("label", { htmlFor: "credential-id-input", className: "block text-sm font-medium text-ink mt-3 mb-1", children: t("pages.settings.ownerIdentity.credentialIdLabel") }), _jsx("input", { id: "credential-id-input", type: "text", value: credentialIdInput, onChange: (e) => setCredentialIdInput(e.target.value), disabled: ownerActionPending, placeholder: "cred-...", className: "w-full border border-line bg-surface rounded-[3px] px-3 py-2 text-sm text-ink focus:outline-none focus:border-gov focus:ring-1 focus:ring-gov disabled:opacity-50" }), _jsxs("div", { className: "flex items-center gap-2 mt-3", children: [_jsx("button", { type: "button", onClick: handleRegisterOwner, disabled: ownerActionPending, className: "border border-gov bg-gov text-paper rounded-[3px] px-[14px] py-[6px] text-[12.5px] font-medium hover:bg-gov-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.settings.ownerIdentity.register") }), ownerIdentity.resolved.source === "file" && (_jsx("button", { type: "button", onClick: handleUnregisterOwner, disabled: ownerActionPending, className: "border border-line text-ink-3 rounded-[3px] px-[14px] py-[6px] text-[12.5px] font-medium hover:bg-surface transition-colors disabled:opacity-50 disabled:cursor-not-allowed", children: t("pages.settings.ownerIdentity.unregister") }))] })] }))] }))] })] }), _jsxs("section", { className: "mb-8", "aria-labelledby": "section-principle-language", children: [_jsx(SectionTitle, { id: "section-principle-language", children: t("pages.settings.principleLanguage") }), _jsxs("div", { className: "bg-panel border border-line rounded-[6px] p-5", children: [_jsx("p", { className: "text-ink-3 text-[13px] leading-relaxed mb-3", children: t("pages.settings.principleLanguageDescription") }), _jsxs("div", { className: "flex items-center gap-3", children: [_jsxs("label", { htmlFor: "output-language-select", className: "text-sm font-medium text-ink", children: [t("pages.settings.principleLanguage"), ":"] }), _jsxs("select", { id: "output-language-select", value: outputLanguage, onChange: (e) => handleOutputLanguageChange(e.target.value), className: "border border-line bg-surface rounded-[3px] px-3 py-2 text-sm text-ink focus:outline-none focus:border-gov focus:ring-1 focus:ring-gov", children: [_jsx("option", { value: "zh-CN", children: t("pages.settings.languageZhCN") }), _jsx("option", { value: "en", children: t("pages.settings.languageEn") })] })] })] })] }), _jsxs("section", { className: "mb-8", "aria-labelledby": "section-sound-alerts", children: [_jsx(SectionTitle, { id: "section-sound-alerts", children: t("pages.settings.notifications") }), _jsx("div", { className: "bg-panel border border-line rounded-[6px] p-5", children: _jsxs("div", { className: "flex items-center justify-between gap-4", children: [_jsxs("div", { children: [_jsx("label", { htmlFor: "sound-alerts-toggle", className: "block text-sm font-medium text-ink", children: t("pages.settings.soundAlerts") }), _jsx("p", { className: "text-ink-3 text-[13px] leading-relaxed mt-1", children: t("pages.settings.soundAlertsDescription") })] }), _jsx("button", { id: "sound-alerts-toggle", type: "button", role: "switch", "aria-checked": soundEnabled, onClick: () => setSoundEnabled(!soundEnabled), className: cn("relative inline-flex h-6 w-11 items-center rounded-full transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", soundEnabled ? "bg-gov" : "bg-line"), children: _jsx("span", { className: cn("inline-block h-4 w-4 transform rounded-full bg-paper transition-transform", soundEnabled ? "translate-x-6" : "translate-x-1") }) })] }) })] }), _jsxs("section", { className: "mb-8", "aria-labelledby": "section-workspaces", children: [_jsx(SectionTitle, { id: "section-workspaces", children: t("pages.settings.workspace") }), workspaces.length > 0 ? (_jsx("div", { className: "space-y-[10px] mb-5", children: workspaces.map((ws) => (_jsx("article", { className: "bg-panel border border-line rounded-[6px] p-5", children: _jsxs("div", { className: "flex items-start justify-between gap-4", children: [_jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("div", { className: "font-medium text-ink text-sm", children: ws.name }), _jsx("div", { className: "text-ink-3 text-[13px] mt-1 font-mono break-all", children: ws.path }), _jsxs("div", { className: "text-ink-4 text-[12px] mt-1", children: [t("pages.settings.lastSync"), ":", " ", ws.lastSync ?? "—"] })] }), _jsx("div", { className: "flex items-center gap-2 shrink-0", children: confirmRemove?.workspaceName === ws.name ? (_jsxs(_Fragment, { children: [_jsx("span", { className: "text-ink-2 text-[12px]", children: t("pages.settings.confirmDeleteDescription", {
|
|
263
328
|
name: ws.name,
|
|
264
329
|
}) }), _jsx("button", { onClick: () => handleRemoveWorkspace(ws.name), className: "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", children: t("common.confirm") }), _jsx("button", { onClick: () => setConfirmRemove(null), className: "border border-line bg-surface text-ink rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:border-line-2 transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("common.cancel") })] })) : (_jsxs(_Fragment, { children: [_jsx("button", { onClick: () => handleSyncWorkspace(ws.name), className: "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.settings.syncWorkspace") }), _jsx("button", { onClick: () => setConfirmRemove({ workspaceName: ws.name }), className: "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.settings.removeWorkspace") })] })) })] }) }, ws.name))) })) : (_jsx("div", { className: "text-ink-3 text-[13px] leading-relaxed py-3 mb-5", children: "\u2014" })), _jsx("div", { className: "bg-panel border border-line rounded-[6px] p-5", children: _jsxs("div", { className: "flex items-end gap-3", children: [_jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("label", { htmlFor: "add-workspace-name", className: "block text-sm font-medium text-ink mb-2", children: t("pages.settings.name") }), _jsx("input", { id: "add-workspace-name", type: "text", value: addName, onChange: (e) => setAddName(e.target.value), placeholder: t("pages.settings.addNamePlaceholder"), className: "w-full border border-line bg-surface rounded-[3px] px-3 py-2 text-sm text-ink focus:outline-none focus:border-gov focus:ring-1 focus:ring-gov" })] }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("label", { htmlFor: "add-workspace-path", className: "block text-sm font-medium text-ink mb-2", children: t("pages.settings.path") }), _jsx("input", { id: "add-workspace-path", type: "text", value: addPath, onChange: (e) => setAddPath(e.target.value), placeholder: t("pages.settings.addPathPlaceholder"), className: "w-full border border-line bg-surface rounded-[3px] px-3 py-2 text-sm text-ink focus:outline-none focus:border-gov focus:ring-1 focus:ring-gov" })] }), _jsx("button", { onClick: handleAddWorkspace, disabled: addName.trim().length === 0 || addPath.trim().length === 0, className: "border border-gov bg-gov text-paper rounded-[3px] px-[14px] py-[6px] text-[12.5px] font-medium hover:bg-gov-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed shrink-0 focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.settings.addWorkspace") })] }) })] }), _jsxs("section", { className: "mb-8", "aria-labelledby": "section-onboarding-flag", children: [_jsx(SectionTitle, { id: "section-onboarding-flag", children: t("components.onboardingFlag.title") }), _jsx("div", { className: "bg-panel border border-line rounded-[6px] p-5", children: _jsxs("div", { className: "flex items-center justify-between gap-4", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("label", { htmlFor: "onboarding-flag-toggle", className: "block text-sm font-medium text-ink", children: t("components.onboardingFlag.label") }), _jsx("p", { className: "text-ink-3 text-[13px] leading-relaxed mt-1", children: t("components.onboardingFlag.description") })] }), _jsx("button", { id: "onboarding-flag-toggle", type: "button", role: "switch", "aria-checked": onboardingFlagEnabled ?? false, "aria-label": t("components.onboardingFlag.toggleAriaLabel"), onClick: handleToggleOnboardingFlag, disabled: onboardingFlagEnabled === null, className: cn("relative inline-flex h-6 w-11 shrink-0 items-center rounded-full transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2 disabled:opacity-50 disabled:cursor-not-allowed", onboardingFlagEnabled ? "bg-gov" : "bg-line"), children: _jsx("span", { className: cn("inline-block h-4 w-4 transform rounded-full bg-paper transition-transform", onboardingFlagEnabled ? "translate-x-6" : "translate-x-1") }) })] }) })] }), _jsxs("section", { "aria-labelledby": "section-onboarding-reset", children: [_jsx(SectionTitle, { id: "section-onboarding-reset", children: t("components.onboardingReset.title") }), _jsx("div", { className: "bg-panel border border-line rounded-[6px] p-5", children: _jsx("button", { onClick: handleResetOnboarding, className: "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("components.onboardingReset.resetButton") }) })] })] }) }));
|
|
265
330
|
}
|