create-principles-disciple 1.144.26 → 1.145.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_release/product-identity.json +2 -2
- package/codex-adapter/dist/codex-evidence-recorder.js +8 -2
- package/codex-adapter/dist/index.d.ts +2 -2
- package/codex-adapter/dist/index.js +1 -1
- package/codex-adapter/dist/ingestion/admission.js +16 -0
- package/codex-adapter/dist/ingestion/codex-version.d.ts +10 -4
- package/codex-adapter/dist/ingestion/codex-version.js +10 -4
- package/codex-adapter/dist/ingestion/explicit-owner-statement.d.ts +48 -0
- package/codex-adapter/dist/ingestion/explicit-owner-statement.js +123 -0
- package/codex-adapter/dist/ingestion/ingestion.js +50 -1
- package/codex-adapter/dist/pd-hook.js +66 -3
- package/codex-adapter/dist/worker/workspace-worker.d.ts +14 -0
- package/codex-adapter/dist/worker/workspace-worker.js +194 -11
- package/codex-adapter/package.json +2 -2
- package/console/dist/server/models/ApprovalsConsoleModel.d.ts +2 -2
- package/console/dist/server/models/ApprovalsConsoleModel.js +1 -1
- package/console/dist/server/models/ApprovalsGroupedConsoleModel.js +1 -1
- package/console/dist/server/models/PrinciplesConsoleModel.d.ts +26 -1
- package/console/dist/server/models/PrinciplesConsoleModel.js +18 -1
- package/console/dist/server/routes/activations.js +4 -4
- package/console/dist/server/routes/approvals.js +2 -2
- package/console/dist/server/routes/failed-tasks.d.ts +9 -0
- package/console/dist/server/routes/failed-tasks.js +116 -7
- package/console/dist/server/routes/principles.js +73 -1
- package/console/dist/shared/prompt-injection-contract.d.ts +1 -1
- package/console/dist/ui/api.d.ts +5 -5
- package/console/dist/ui/i18n/en.json +13 -2
- package/console/dist/ui/i18n/zh-CN.json +13 -2
- package/console/dist/ui/pages/activation/ActivationPage.js +2 -1
- package/console/dist/ui/pages/failed-tasks/FailedTasksPage.js +42 -4
- package/console/dist/ui/pages/focus/FocusPage.js +3 -3
- package/console/dist/ui/pages/principles/PrinciplesPage.js +7 -2
- package/console/dist/ui/utils/validators.d.ts +6 -2
- package/console/dist/ui/utils/validators.js +19 -4
- package/console/dist/web/assets/app.css +26 -0
- package/console/dist/web/assets/app.js +24 -24
- package/console/package.json +4 -4
- package/core/dist/host/host-installer.d.ts +3 -1
- package/core/dist/host/host-installer.d.ts.map +1 -1
- package/core/dist/host/host-installer.js.map +1 -1
- package/core/dist/runtime-v2/admission-gate.d.ts +8 -0
- package/core/dist/runtime-v2/admission-gate.d.ts.map +1 -1
- package/core/dist/runtime-v2/admission-gate.js +3 -2
- package/core/dist/runtime-v2/admission-gate.js.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-defaults.d.ts.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-defaults.js +16 -1
- package/core/dist/runtime-v2/config/pd-config-defaults.js.map +1 -1
- package/core/dist/runtime-v2/context-payload.d.ts +43 -3
- package/core/dist/runtime-v2/context-payload.d.ts.map +1 -1
- package/core/dist/runtime-v2/context-payload.js +15 -1
- package/core/dist/runtime-v2/context-payload.js.map +1 -1
- package/core/dist/runtime-v2/evidence-guards.d.ts +6 -0
- package/core/dist/runtime-v2/evidence-guards.d.ts.map +1 -1
- package/core/dist/runtime-v2/evidence-guards.js +11 -0
- package/core/dist/runtime-v2/evidence-guards.js.map +1 -1
- package/core/dist/runtime-v2/evolution/evolution-types.d.ts +4 -4
- package/core/dist/runtime-v2/evolution/evolution-types.d.ts.map +1 -1
- package/core/dist/runtime-v2/evolution/evolution-types.js +1 -1
- package/core/dist/runtime-v2/evolution/evolution-types.js.map +1 -1
- package/core/dist/runtime-v2/feature-flags/feature-flag-contract.d.ts.map +1 -1
- package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js +6 -0
- 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.map +1 -1
- package/core/dist/runtime-v2/feature-flags/feature-flag-lifecycle.js +8 -0
- package/core/dist/runtime-v2/feature-flags/feature-flag-lifecycle.js.map +1 -1
- package/core/dist/runtime-v2/index.d.ts +5 -2
- package/core/dist/runtime-v2/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/index.js +3 -1
- package/core/dist/runtime-v2/index.js.map +1 -1
- package/core/dist/runtime-v2/internalization/adversarial-feedback.d.ts +3 -1
- package/core/dist/runtime-v2/internalization/adversarial-feedback.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/adversarial-feedback.js +10 -1
- package/core/dist/runtime-v2/internalization/adversarial-feedback.js.map +1 -1
- package/core/dist/runtime-v2/internalization/evaluator-output.d.ts +11 -0
- package/core/dist/runtime-v2/internalization/evaluator-output.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/evaluator-output.js +10 -0
- package/core/dist/runtime-v2/internalization/evaluator-output.js.map +1 -1
- package/core/dist/runtime-v2/internalization/evaluator-prompt-builder.d.ts +3 -3
- package/core/dist/runtime-v2/internalization/evaluator-prompt-builder.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/evaluator-prompt-builder.js +49 -5
- package/core/dist/runtime-v2/internalization/evaluator-prompt-builder.js.map +1 -1
- package/core/dist/runtime-v2/internalization/evaluator-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/evaluator-runner.js +13 -16
- package/core/dist/runtime-v2/internalization/evaluator-runner.js.map +1 -1
- package/core/dist/runtime-v2/internalization/owner-decision-review.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/owner-decision-review.js +5 -1
- package/core/dist/runtime-v2/internalization/owner-decision-review.js.map +1 -1
- package/core/dist/runtime-v2/internalization/owner-review.d.ts +2 -2
- package/core/dist/runtime-v2/internalization/owner-review.js +2 -2
- package/core/dist/runtime-v2/internalization/scribe-output.d.ts +12 -0
- package/core/dist/runtime-v2/internalization/scribe-output.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/scribe-output.js +20 -0
- package/core/dist/runtime-v2/internalization/scribe-output.js.map +1 -1
- package/core/dist/runtime-v2/internalization/scribe-prompt-builder.d.ts +32 -1
- package/core/dist/runtime-v2/internalization/scribe-prompt-builder.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/scribe-prompt-builder.js +38 -1
- package/core/dist/runtime-v2/internalization/scribe-prompt-builder.js.map +1 -1
- package/core/dist/runtime-v2/internalization-queue-read-model.d.ts +6 -0
- package/core/dist/runtime-v2/internalization-queue-read-model.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization-queue-read-model.js +8 -1
- package/core/dist/runtime-v2/internalization-queue-read-model.js.map +1 -1
- package/core/dist/runtime-v2/intervention-evidence-normalizer.d.ts.map +1 -1
- package/core/dist/runtime-v2/intervention-evidence-normalizer.js +10 -3
- package/core/dist/runtime-v2/intervention-evidence-normalizer.js.map +1 -1
- package/core/dist/runtime-v2/pain-ingress.d.ts +1 -1
- package/core/dist/runtime-v2/pain-ingress.d.ts.map +1 -1
- package/core/dist/runtime-v2/pain-signal-bridge.d.ts +68 -2
- package/core/dist/runtime-v2/pain-signal-bridge.d.ts.map +1 -1
- package/core/dist/runtime-v2/pain-signal-bridge.js +541 -18
- package/core/dist/runtime-v2/pain-signal-bridge.js.map +1 -1
- package/core/dist/runtime-v2/pain-signal-runtime-factory.d.ts.map +1 -1
- package/core/dist/runtime-v2/pain-signal-runtime-factory.js +4 -0
- package/core/dist/runtime-v2/pain-signal-runtime-factory.js.map +1 -1
- package/core/dist/runtime-v2/product-telemetry/snapshot-contract.d.ts +2 -2
- package/core/dist/runtime-v2/product-telemetry/snapshot-contract.d.ts.map +1 -1
- package/core/dist/runtime-v2/product-telemetry/snapshot-contract.js +2 -2
- package/core/dist/runtime-v2/product-telemetry/snapshot-contract.js.map +1 -1
- package/core/dist/runtime-v2/store/candidate/admission-document.d.ts +90 -0
- package/core/dist/runtime-v2/store/candidate/admission-document.d.ts.map +1 -0
- package/core/dist/runtime-v2/store/candidate/admission-document.js +142 -0
- package/core/dist/runtime-v2/store/candidate/admission-document.js.map +1 -0
- package/core/dist/runtime-v2/store/candidate/candidate-store.d.ts +53 -0
- package/core/dist/runtime-v2/store/candidate/candidate-store.d.ts.map +1 -1
- package/core/dist/runtime-v2/store/candidate/memory-candidate-store.d.ts +35 -0
- package/core/dist/runtime-v2/store/candidate/memory-candidate-store.d.ts.map +1 -1
- package/core/dist/runtime-v2/store/candidate/memory-candidate-store.js +48 -0
- package/core/dist/runtime-v2/store/candidate/memory-candidate-store.js.map +1 -1
- package/core/dist/runtime-v2/store/candidate/sqlite-candidate-store.d.ts +44 -0
- package/core/dist/runtime-v2/store/candidate/sqlite-candidate-store.d.ts.map +1 -1
- package/core/dist/runtime-v2/store/candidate/sqlite-candidate-store.js +136 -0
- package/core/dist/runtime-v2/store/candidate/sqlite-candidate-store.js.map +1 -1
- package/core/dist/runtime-v2/store/context/sqlite-context-assembler.js.map +1 -1
- package/core/dist/runtime-v2/store/intervention-evidence-schema.js +1 -1
- package/core/dist/runtime-v2/store/runtime-state-manager.d.ts +65 -0
- package/core/dist/runtime-v2/store/runtime-state-manager.d.ts.map +1 -1
- package/core/dist/runtime-v2/store/runtime-state-manager.js +46 -0
- package/core/dist/runtime-v2/store/runtime-state-manager.js.map +1 -1
- package/core/dist/runtime-v2/store/sqlite-connection.d.ts.map +1 -1
- package/core/dist/runtime-v2/store/sqlite-connection.js +42 -0
- package/core/dist/runtime-v2/store/sqlite-connection.js.map +1 -1
- package/core/dist/runtime-v2/store/sqlite-intervention-evidence-store.d.ts +1 -1
- package/core/dist/runtime-v2/store/sqlite-intervention-evidence-store.d.ts.map +1 -1
- package/core/dist/runtime-v2/store/sqlite-intervention-evidence-store.js.map +1 -1
- package/core/dist/runtime-v2/store/task/sqlite-family-reopen.d.ts +19 -0
- package/core/dist/runtime-v2/store/task/sqlite-family-reopen.d.ts.map +1 -0
- package/core/dist/runtime-v2/store/task/sqlite-family-reopen.js +36 -0
- package/core/dist/runtime-v2/store/task/sqlite-family-reopen.js.map +1 -0
- package/core/dist/runtime-v2/store/task/sqlite-task-store.d.ts +23 -0
- 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 +50 -0
- package/core/dist/runtime-v2/store/task/sqlite-task-store.js.map +1 -1
- package/core/dist/runtime-v2/task-status.d.ts +3 -1
- package/core/dist/runtime-v2/task-status.d.ts.map +1 -1
- package/core/dist/runtime-v2/task-status.js +1 -1
- package/core/dist/runtime-v2/task-status.js.map +1 -1
- package/core/dist/runtime-v2/trajectory-schema.d.ts.map +1 -1
- package/core/dist/runtime-v2/trajectory-schema.js +11 -0
- package/core/dist/runtime-v2/trajectory-schema.js.map +1 -1
- package/core/dist/runtime-v2/types/event-types.d.ts +2 -2
- package/core/dist/runtime-v2/types/event-types.d.ts.map +1 -1
- package/core/dist/runtime-v2/types/event-types.js +1 -1
- package/core/dist/runtime-v2/types/event-types.js.map +1 -1
- package/core/dist/runtime-v2/types/evidence-chain-contract.d.ts +1 -1
- package/core/dist/runtime-v2/types/evidence-chain-contract.d.ts.map +1 -1
- package/core/dist/runtime-v2/types/evidence-chain-contract.js +2 -2
- package/core/dist/runtime-v2/types/evidence-chain-contract.js.map +1 -1
- package/core/dist/runtime-v2/types/intervention-evidence-contract.d.ts +3 -3
- package/core/dist/runtime-v2/types/intervention-evidence-contract.d.ts.map +1 -1
- package/core/dist/runtime-v2/types/intervention-evidence-contract.js +1 -0
- package/core/dist/runtime-v2/types/intervention-evidence-contract.js.map +1 -1
- package/core/dist/telemetry-event.d.ts +2 -2
- package/core/dist/telemetry-event.d.ts.map +1 -1
- package/core/dist/telemetry-event.js +4 -0
- package/core/dist/telemetry-event.js.map +1 -1
- package/core/dist/trajectory-types.d.ts +2 -2
- package/core/dist/trajectory-types.d.ts.map +1 -1
- package/core/package.json +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +84 -8
- package/dist/index.js.map +1 -1
- package/dist/installer.d.ts +42 -11
- package/dist/installer.d.ts.map +1 -1
- package/dist/installer.js +140 -36
- package/dist/installer.js.map +1 -1
- package/dist/installers/index.d.ts +18 -7
- package/dist/installers/index.d.ts.map +1 -1
- package/dist/installers/index.js +13 -4
- package/dist/installers/index.js.map +1 -1
- package/dist/installers/workbuddy-host-installer.d.ts +246 -0
- package/dist/installers/workbuddy-host-installer.d.ts.map +1 -0
- package/dist/installers/workbuddy-host-installer.js +1419 -0
- package/dist/installers/workbuddy-host-installer.js.map +1 -0
- package/dist/mvp-config.d.ts +24 -0
- package/dist/mvp-config.d.ts.map +1 -1
- package/dist/mvp-config.js +36 -0
- package/dist/mvp-config.js.map +1 -1
- package/dist/prompts.d.ts +13 -0
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +45 -8
- package/dist/prompts.js.map +1 -1
- package/dist/uninstaller.d.ts +1 -1
- package/dist/uninstaller.d.ts.map +1 -1
- package/dist/uninstaller.js +29 -4
- package/dist/uninstaller.js.map +1 -1
- package/host-runtime/dist/governance-signal-admission.d.ts +63 -0
- package/host-runtime/dist/governance-signal-admission.js +322 -53
- package/host-runtime/dist/host-liveness-contract.js +7 -1
- package/host-runtime/dist/index.d.ts +1 -0
- package/host-runtime/dist/index.js +5 -1
- package/host-runtime/dist/internalization-consumer-cycle.d.ts +12 -0
- package/host-runtime/dist/internalization-consumer-cycle.js +43 -1
- package/host-runtime/dist/intervention-evidence-ingress.d.ts +1 -1
- package/host-runtime/dist/product-telemetry/service.js +1 -1
- package/host-runtime/dist/production-pain-evidence.d.ts +59 -1
- package/host-runtime/dist/production-pain-evidence.js +200 -17
- package/host-runtime/dist/prompt-activation-deliverability.js +5 -4
- package/host-runtime/dist/prompt-injection-event-evidence.d.ts +1 -1
- package/host-runtime/dist/prompt-injection-event-evidence.js +5 -1
- package/host-runtime/dist/prompt-injection-projection.d.ts +14 -5
- package/host-runtime/dist/prompt-injection-projection.js +30 -16
- package/host-runtime/dist/workbuddy-worker-status.d.ts +24 -0
- package/host-runtime/dist/workbuddy-worker-status.js +52 -0
- package/host-runtime/package.json +3 -3
- package/install-layout/dist/index.d.ts +18 -1
- package/install-layout/dist/index.js +15 -2
- package/install-layout/package.json +1 -1
- package/package.json +6 -5
- package/pd-cli/dist/commands/candidate.d.ts.map +1 -1
- package/pd-cli/dist/commands/candidate.js +44 -4
- package/pd-cli/dist/commands/candidate.js.map +1 -1
- package/pd-cli/dist/commands/codex-worker.d.ts.map +1 -1
- package/pd-cli/dist/commands/codex-worker.js +30 -1
- package/pd-cli/dist/commands/codex-worker.js.map +1 -1
- package/pd-cli/dist/commands/config-doctor.d.ts.map +1 -1
- package/pd-cli/dist/commands/config-doctor.js +19 -4
- package/pd-cli/dist/commands/config-doctor.js.map +1 -1
- package/pd-cli/dist/commands/diagnose.d.ts.map +1 -1
- package/pd-cli/dist/commands/diagnose.js +4 -1
- package/pd-cli/dist/commands/diagnose.js.map +1 -1
- package/pd-cli/dist/commands/health-codex-install.d.ts +85 -0
- package/pd-cli/dist/commands/health-codex-install.d.ts.map +1 -0
- package/pd-cli/dist/commands/health-codex-install.js +207 -0
- package/pd-cli/dist/commands/health-codex-install.js.map +1 -0
- package/pd-cli/dist/commands/health-codex.d.ts.map +1 -1
- package/pd-cli/dist/commands/health-codex.js +78 -0
- package/pd-cli/dist/commands/health-codex.js.map +1 -1
- package/pd-cli/dist/commands/pain-list.d.ts +3 -2
- package/pd-cli/dist/commands/pain-list.d.ts.map +1 -1
- package/pd-cli/dist/commands/pain-list.js +10 -10
- package/pd-cli/dist/commands/pain-list.js.map +1 -1
- package/pd-cli/dist/commands/pain-record.d.ts +2 -0
- package/pd-cli/dist/commands/pain-record.d.ts.map +1 -1
- package/pd-cli/dist/commands/pain-record.js +36 -0
- package/pd-cli/dist/commands/pain-record.js.map +1 -1
- package/pd-cli/dist/commands/pain-retry.d.ts +6 -0
- package/pd-cli/dist/commands/pain-retry.d.ts.map +1 -1
- package/pd-cli/dist/commands/pain-retry.js +152 -5
- package/pd-cli/dist/commands/pain-retry.js.map +1 -1
- package/pd-cli/dist/commands/runtime-activation.d.ts +1 -1
- package/pd-cli/dist/commands/runtime-activation.d.ts.map +1 -1
- package/pd-cli/dist/commands/runtime-activation.js +3 -3
- package/pd-cli/dist/commands/runtime-activation.js.map +1 -1
- package/pd-cli/dist/commands/workbuddy-worker.d.ts +19 -0
- package/pd-cli/dist/commands/workbuddy-worker.d.ts.map +1 -0
- package/pd-cli/dist/commands/workbuddy-worker.js +168 -0
- package/pd-cli/dist/commands/workbuddy-worker.js.map +1 -0
- package/pd-cli/dist/index.js +29 -1
- package/pd-cli/dist/index.js.map +1 -1
- package/pd-cli/dist/resolve-workspace.d.ts +14 -2
- package/pd-cli/dist/resolve-workspace.d.ts.map +1 -1
- package/pd-cli/dist/resolve-workspace.js +88 -21
- package/pd-cli/dist/resolve-workspace.js.map +1 -1
- package/pd-cli/dist/services/admission-write-gate.d.ts +24 -0
- package/pd-cli/dist/services/admission-write-gate.d.ts.map +1 -0
- package/pd-cli/dist/services/admission-write-gate.js +41 -0
- package/pd-cli/dist/services/admission-write-gate.js.map +1 -0
- package/pd-cli/dist/services/pd-config-loader.d.ts +39 -7
- package/pd-cli/dist/services/pd-config-loader.d.ts.map +1 -1
- package/pd-cli/dist/services/pd-config-loader.js +111 -18
- package/pd-cli/dist/services/pd-config-loader.js.map +1 -1
- package/pd-cli/dist/services/rulehost-pipeline-runner.d.ts +10 -0
- package/pd-cli/dist/services/rulehost-pipeline-runner.d.ts.map +1 -1
- package/pd-cli/dist/services/rulehost-pipeline-runner.js +59 -4
- package/pd-cli/dist/services/rulehost-pipeline-runner.js.map +1 -1
- package/pd-cli/package.json +4 -3
- package/plugin/dist/bundle.js +564 -509
- package/plugin/dist/governance-audit.js +1 -1
- package/plugin/dist/openclaw.plugin.json +1 -1
- package/plugin/dist/rulehost-evidence.js +1 -1
- package/plugin/openclaw.plugin.json +1 -1
- package/plugin/package.json +3 -3
- package/release-manager/dist/index.d.ts.map +1 -1
- package/release-manager/dist/index.js +84 -8
- package/release-manager/dist/index.js.map +1 -1
- package/release-manager/dist/installer.d.ts +42 -11
- package/release-manager/dist/installer.d.ts.map +1 -1
- package/release-manager/dist/installer.js +140 -36
- package/release-manager/dist/installer.js.map +1 -1
- package/release-manager/dist/installers/index.d.ts +18 -7
- package/release-manager/dist/installers/index.d.ts.map +1 -1
- package/release-manager/dist/installers/index.js +13 -4
- package/release-manager/dist/installers/index.js.map +1 -1
- package/release-manager/dist/installers/workbuddy-host-installer.d.ts +246 -0
- package/release-manager/dist/installers/workbuddy-host-installer.d.ts.map +1 -0
- package/release-manager/dist/installers/workbuddy-host-installer.js +1419 -0
- package/release-manager/dist/installers/workbuddy-host-installer.js.map +1 -0
- package/release-manager/dist/mvp-config.d.ts +24 -0
- package/release-manager/dist/mvp-config.d.ts.map +1 -1
- package/release-manager/dist/mvp-config.js +36 -0
- package/release-manager/dist/mvp-config.js.map +1 -1
- package/release-manager/dist/prompts.d.ts +13 -0
- package/release-manager/dist/prompts.d.ts.map +1 -1
- package/release-manager/dist/prompts.js +45 -8
- package/release-manager/dist/prompts.js.map +1 -1
- package/release-manager/dist/uninstaller.d.ts +1 -1
- package/release-manager/dist/uninstaller.d.ts.map +1 -1
- package/release-manager/dist/uninstaller.js +29 -4
- package/release-manager/dist/uninstaller.js.map +1 -1
- package/release-manager/package.json +5 -4
- package/workbuddy-adapter/dist/codec/index.d.ts +2 -0
- package/workbuddy-adapter/dist/codec/index.js +2 -0
- package/workbuddy-adapter/dist/codec/input-decoder.d.ts +30 -0
- package/workbuddy-adapter/dist/codec/input-decoder.js +232 -0
- package/workbuddy-adapter/dist/codec/output-encoder.d.ts +62 -0
- package/workbuddy-adapter/dist/codec/output-encoder.js +75 -0
- package/workbuddy-adapter/dist/host-adapter.d.ts +33 -0
- package/workbuddy-adapter/dist/host-adapter.js +23 -0
- package/workbuddy-adapter/dist/index.d.ts +16 -0
- package/workbuddy-adapter/dist/index.js +16 -0
- package/workbuddy-adapter/dist/pd-hook.d.ts +17 -0
- package/workbuddy-adapter/dist/pd-hook.js +505 -0
- package/workbuddy-adapter/dist/tool-semantics.d.ts +22 -0
- package/workbuddy-adapter/dist/tool-semantics.js +33 -0
- package/workbuddy-adapter/dist/workbuddy-evidence-recorder.d.ts +50 -0
- package/workbuddy-adapter/dist/workbuddy-evidence-recorder.js +238 -0
- package/workbuddy-adapter/dist/worker/workspace-worker.d.ts +41 -0
- package/workbuddy-adapter/dist/worker/workspace-worker.js +219 -0
- package/workbuddy-adapter/dist/workspace-resolution.d.ts +15 -0
- package/workbuddy-adapter/dist/workspace-resolution.js +53 -0
- package/workbuddy-adapter/package.json +62 -0
- package/workbuddy-adapter/plugin/.codebuddy-plugin/plugin.json +6 -0
- package/workbuddy-adapter/plugin/hooks/hooks.json +62 -0
- package/workbuddy-adapter/plugin/scripts/wrapper.cjs +79 -0
|
@@ -110,6 +110,69 @@ async function getDecidedPrincipleIds(workspaceDir) {
|
|
|
110
110
|
closeFn?.();
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* PRI-956 (F15, R1 merge-readiness D1/D2): principle ids whose runtime
|
|
115
|
+
* authority is CURRENTLY revoked.
|
|
116
|
+
*
|
|
117
|
+
* The runtime authority is the activations table. A principle counts as
|
|
118
|
+
* revoked only when it has AT LEAST ONE activation AND NO activation in a
|
|
119
|
+
* still-active state (`deactivated_at` NULL/empty). This correctly handles:
|
|
120
|
+
* - deactivate (all activations deactivated → revoked),
|
|
121
|
+
* - deactivate then RE-ACTIVATE (a new/updated active activation exists →
|
|
122
|
+
* NOT revoked),
|
|
123
|
+
* - SUPERSEDE (old activation deactivated, newer active one exists → NOT
|
|
124
|
+
* revoked),
|
|
125
|
+
* - per-CHANNEL independence is preserved at the row level: a principle with
|
|
126
|
+
* an active prompt activation but a deactivated hook activation (or vice
|
|
127
|
+
* versa) still has an active row, so the global "runtime revoked" badge is
|
|
128
|
+
* NOT shown (D2: no global claim while any channel authority survives).
|
|
129
|
+
*
|
|
130
|
+
* "Ever deactivated but currently active" is deliberately NOT reported — the
|
|
131
|
+
* original query proved history, not current state.
|
|
132
|
+
*
|
|
133
|
+
* Read-only; degrades with a reason like the decided-ids query (D3: the
|
|
134
|
+
* unavailableReason is propagated to the API/UI — status cannot be confirmed
|
|
135
|
+
* and must not default to either active or revoked).
|
|
136
|
+
*/
|
|
137
|
+
async function getDeactivatedPrincipleIds(workspaceDir) {
|
|
138
|
+
const dbPath = path.join(workspaceDir, '.pd', 'state.db');
|
|
139
|
+
if (!fs.existsSync(dbPath)) {
|
|
140
|
+
return { ids: new Set(), unavailableReason: 'activation_db_not_found' };
|
|
141
|
+
}
|
|
142
|
+
let closeFn = null;
|
|
143
|
+
try {
|
|
144
|
+
const { SqliteConnection } = await import('@principles/core/runtime-v2');
|
|
145
|
+
const conn = new SqliteConnection({ workspaceDir, readonly: true });
|
|
146
|
+
closeFn = () => conn.close();
|
|
147
|
+
const db = conn.getDb();
|
|
148
|
+
const rows = db.prepare("SELECT target_ref, " +
|
|
149
|
+
"SUM(CASE WHEN deactivated_at IS NULL OR deactivated_at = '' THEN 1 ELSE 0 END) AS active_count, " +
|
|
150
|
+
"COUNT(*) AS total " +
|
|
151
|
+
"FROM activations WHERE target_ref LIKE 'ledger://%' " +
|
|
152
|
+
"GROUP BY target_ref"
|
|
153
|
+
// runtime-contract-exempt: ERR-001 better-sqlite3 .all() returns unknown[]; narrowing to Record<string, unknown>[] is type-only (fields validated below via typeof checks)
|
|
154
|
+
).all();
|
|
155
|
+
const ids = new Set();
|
|
156
|
+
for (const row of rows) {
|
|
157
|
+
const ref = getOwnStringField(row, 'target_ref');
|
|
158
|
+
const { total } = row;
|
|
159
|
+
const activeCount = row.active_count;
|
|
160
|
+
if (ref === undefined || typeof total !== 'number' || typeof activeCount !== 'number')
|
|
161
|
+
continue;
|
|
162
|
+
if (total > 0 && activeCount === 0) {
|
|
163
|
+
ids.add(ref.slice('ledger://'.length));
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return { ids };
|
|
167
|
+
}
|
|
168
|
+
catch (err) {
|
|
169
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
170
|
+
return { ids: new Set(), unavailableReason: `activation_query_failed: ${message}` };
|
|
171
|
+
}
|
|
172
|
+
finally {
|
|
173
|
+
closeFn?.();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
113
176
|
export async function handlePrinciplesRoute({ req, res, workspaceDir, subPath, featureFlags, now = () => new Date().toISOString(), }) {
|
|
114
177
|
// GET /api/v1/principles/:id/governance. Gate before constructing any
|
|
115
178
|
// Console model or projection reader so flag-off is a true no-read path.
|
|
@@ -244,7 +307,16 @@ export async function handlePrinciplesRoute({ req, res, workspaceDir, subPath, f
|
|
|
244
307
|
const VALID_FILTERS = new Set(['all', 'actionable']);
|
|
245
308
|
const filter = (filterRaw !== null && VALID_FILTERS.has(filterRaw) ? filterRaw : 'actionable');
|
|
246
309
|
const decidedResult = await getDecidedPrincipleIds(workspaceDir);
|
|
247
|
-
const
|
|
310
|
+
const deactivatedResult = await getDeactivatedPrincipleIds(workspaceDir);
|
|
311
|
+
const result = await model.listPrinciples(filter, {
|
|
312
|
+
decided: decidedResult.ids,
|
|
313
|
+
pendingApproval: decidedResult.pendingIds,
|
|
314
|
+
deactivated: deactivatedResult.ids,
|
|
315
|
+
});
|
|
316
|
+
// D3: revocation status must be observable when it cannot be confirmed
|
|
317
|
+
if (deactivatedResult.unavailableReason) {
|
|
318
|
+
result.revocationCheckUnavailable = deactivatedResult.unavailableReason;
|
|
319
|
+
}
|
|
248
320
|
// Surface approval cross-check unavailability to the UI (ERR-002)
|
|
249
321
|
if (decidedResult.unavailableReason) {
|
|
250
322
|
result.approvalCrossCheckUnavailable = decidedResult.unavailableReason;
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* If fields are ever extended and validation rules added, follow the
|
|
13
13
|
* feedback-contract pilot (TypeBox schema + schema-vs-validator equivalence test).
|
|
14
14
|
*/
|
|
15
|
-
export type PromptInjectionTargetHostName = 'openclaw' | 'codex';
|
|
15
|
+
export type PromptInjectionTargetHostName = 'openclaw' | 'codex' | 'workbuddy';
|
|
16
16
|
export type PromptInjectionRouteName = 'legacy_trim' | 'shared_render';
|
|
17
17
|
export type PromptInjectionBudgetScopeName = 'selected_lines' | 'full_directive_context';
|
|
18
18
|
export interface PromptInjectionPerHostForecast {
|
package/console/dist/ui/api.d.ts
CHANGED
|
@@ -134,7 +134,7 @@ export interface EvidenceAuditRecordData {
|
|
|
134
134
|
detail: string;
|
|
135
135
|
}
|
|
136
136
|
export interface EvidenceAuditCapabilityData {
|
|
137
|
-
hostKind: "openclaw" | "codex";
|
|
137
|
+
hostKind: "openclaw" | "codex" | "workbuddy";
|
|
138
138
|
capability: string;
|
|
139
139
|
status: "supported" | "unsupported" | "unknown";
|
|
140
140
|
adapterVersion: string;
|
|
@@ -173,7 +173,7 @@ declare function fetchEvidenceAudit(selectorType: "principle" | "activation" | "
|
|
|
173
173
|
};
|
|
174
174
|
}): Promise<ApiResponse<EvidenceAuditData>>;
|
|
175
175
|
declare function approveApproval(approvalId: string, note?: string, options?: {
|
|
176
|
-
targetHost?: 'openclaw' | 'codex';
|
|
176
|
+
targetHost?: 'openclaw' | 'codex' | 'workbuddy';
|
|
177
177
|
intentReviewed?: boolean;
|
|
178
178
|
reviewedArtifactId?: string;
|
|
179
179
|
}): Promise<ApiResponse<ApprovalRecordData>>;
|
|
@@ -263,8 +263,8 @@ declare function resolveOwnerDecision(taskId: string, body: {
|
|
|
263
263
|
};
|
|
264
264
|
ownerInstruction?: string | null;
|
|
265
265
|
}): Promise<ApiResponse<OwnerResolutionResultData>>;
|
|
266
|
-
declare function fetchApprovalsGrouped(targetHost?: 'openclaw' | 'codex'): Promise<ApiResponse<ApprovalsGroupedData>>;
|
|
267
|
-
declare function fetchAllActivations(targetHost?: 'openclaw' | 'codex'): Promise<ApiResponse<ActivationsData>>;
|
|
266
|
+
declare function fetchApprovalsGrouped(targetHost?: 'openclaw' | 'codex' | 'workbuddy'): Promise<ApiResponse<ApprovalsGroupedData>>;
|
|
267
|
+
declare function fetchAllActivations(targetHost?: 'openclaw' | 'codex' | 'workbuddy'): Promise<ApiResponse<ActivationsData>>;
|
|
268
268
|
declare function disableActivation(activationId: string): Promise<ApiResponse<DisableActivationData>>;
|
|
269
269
|
declare function fetchRuleCodeOwnerReview(activationId: string): Promise<ApiResponse<RuleCodeOwnerReviewData>>;
|
|
270
270
|
export interface ProposeRevisionData {
|
|
@@ -280,7 +280,7 @@ export interface ProposeRevisionData {
|
|
|
280
280
|
nextAction?: string;
|
|
281
281
|
error?: string;
|
|
282
282
|
}
|
|
283
|
-
declare function proposePromptRevision(activationId: string, statement: string, targetHost?: 'openclaw' | 'codex'): Promise<ApiResponse<ProposeRevisionData>>;
|
|
283
|
+
declare function proposePromptRevision(activationId: string, statement: string, targetHost?: 'openclaw' | 'codex' | 'workbuddy'): Promise<ApiResponse<ProposeRevisionData>>;
|
|
284
284
|
declare function ruleCodeDecision(activationId: string, action: 'continue-observing' | 'reject-after-shadow' | 'emergency-deactivate' | 'promote' | 'recover-to-shadow', body: Record<string, unknown>): Promise<ApiResponse<RuleCodeMutationData>>;
|
|
285
285
|
declare function pauseAllRuleCode(body: Record<string, unknown>): Promise<ApiResponse<RuleCodeMutationData>>;
|
|
286
286
|
declare function releaseRuleCodePause(pauseId: string, body: Record<string, unknown>): Promise<ApiResponse<RuleCodeMutationData>>;
|
|
@@ -642,6 +642,8 @@
|
|
|
642
642
|
"blockBehavior": "Behavior Change",
|
|
643
643
|
"blockBehaviorFallback": "No deterministic behavior rule recorded; the principle guides subsequent similar scenarios as a behavioral policy.",
|
|
644
644
|
"govDecision": "Governance Decision",
|
|
645
|
+
"revocationStatusUnknown": "Runtime revocation status cannot be confirmed — activation query failed. Awaiting recovery.",
|
|
646
|
+
"runtimeDeactivated": "Runtime Revoked",
|
|
645
647
|
"govApproved": "Owner Approved",
|
|
646
648
|
"govPending": "Pending Review",
|
|
647
649
|
"loading": "Loading…",
|
|
@@ -1033,7 +1035,7 @@
|
|
|
1033
1035
|
"injectionWindowFifo": "Out of window this turn: fits alone ({{cost}}/{{budget}} chars); this route does not rotate, capacity must free up first",
|
|
1034
1036
|
"injectionOversized": "Oversized, not injectable: {{cost}} chars alone > {{budget}} cap — rotation cannot help; shorten the statement",
|
|
1035
1037
|
"injectionResolutionFailed": "Cannot determine: {{reason}}",
|
|
1036
|
-
"injectionRouteUnconfirmed": "Host capacity unconfirmed: OpenClaw {{oc}} / Codex {{cx}}",
|
|
1038
|
+
"injectionRouteUnconfirmed": "Host capacity unconfirmed: OpenClaw {{oc}} / Codex {{cx}} / WorkBuddy {{wb}}",
|
|
1037
1039
|
"revisionOpen": "Modify to injectable version",
|
|
1038
1040
|
"revisionPlaceholder": "Enter the new principle statement (keep trigger, required action, and necessary exception; be concise)",
|
|
1039
1041
|
"revisionSubmit": "Create pending new version",
|
|
@@ -1871,7 +1873,16 @@
|
|
|
1871
1873
|
"failedTasks": {
|
|
1872
1874
|
"title": "Failed Tasks",
|
|
1873
1875
|
"subtitle": "Pipeline tasks that failed or need human review",
|
|
1874
|
-
"empty": "No failed tasks.
|
|
1876
|
+
"empty": "No failed tasks in the queried range. This does not mean the pipeline is healthy — check the learning-queue status below.",
|
|
1877
|
+
"pipeline": {
|
|
1878
|
+
"title": "Learning queue status",
|
|
1879
|
+
"statusHealthy": "Progressing",
|
|
1880
|
+
"statusBacklogged": "Backlogged (still progressing)",
|
|
1881
|
+
"statusStalled": "Possibly stalled",
|
|
1882
|
+
"statusDisabled": "Consumer disabled",
|
|
1883
|
+
"statusUnknown": "Status unknown",
|
|
1884
|
+
"nextActionPrefix": "Suggested: "
|
|
1885
|
+
},
|
|
1875
1886
|
"error": "Failed to load failed tasks",
|
|
1876
1887
|
"disabled": "Failed tasks observability is disabled. Enable 'failed_tasks_observability' in .pd/config.yaml to view.",
|
|
1877
1888
|
"createDraft": "Create Feedback Draft",
|
|
@@ -642,6 +642,8 @@
|
|
|
642
642
|
"blockBehavior": "行为改变",
|
|
643
643
|
"blockBehaviorFallback": "暂无确定性行为规则记录;该原则作为行为准则影响后续同类场景。",
|
|
644
644
|
"govDecision": "治理决策",
|
|
645
|
+
"revocationStatusUnknown": "运行时停用状态无法确认——激活查询失败,状态未知。",
|
|
646
|
+
"runtimeDeactivated": "运行时已停用",
|
|
645
647
|
"govApproved": "拥有者已批准",
|
|
646
648
|
"govPending": "等待拥有者审查",
|
|
647
649
|
"loading": "加载中…",
|
|
@@ -1033,7 +1035,7 @@
|
|
|
1033
1035
|
"injectionWindowFifo": "本轮未入窗口:单条可装入({{cost}}/{{budget}} 字符),当前路由不轮转,需腾出容量才会注入",
|
|
1034
1036
|
"injectionOversized": "超长不可注入:单条已 {{cost}} 字符 > 上限 {{budget}} 字符,轮转也救不了——需精简正文",
|
|
1035
1037
|
"injectionResolutionFailed": "无法判定:{{reason}}",
|
|
1036
|
-
"injectionRouteUnconfirmed": "当前宿主容量未确认:OpenClaw {{oc}} / Codex {{cx}}",
|
|
1038
|
+
"injectionRouteUnconfirmed": "当前宿主容量未确认:OpenClaw {{oc}} / Codex {{cx}} / WorkBuddy {{wb}}",
|
|
1037
1039
|
"revisionOpen": "修改为可注入版本",
|
|
1038
1040
|
"revisionPlaceholder": "输入新的原则正文(保留触发条件、必须动作和必要例外,尽量精简)",
|
|
1039
1041
|
"revisionSubmit": "创建待审批的新版本",
|
|
@@ -1871,7 +1873,16 @@
|
|
|
1871
1873
|
"failedTasks": {
|
|
1872
1874
|
"title": "失败任务",
|
|
1873
1875
|
"subtitle": "管道中失败或需要人工审查的任务",
|
|
1874
|
-
"empty": "
|
|
1876
|
+
"empty": "当前查询范围内没有失败任务。这不等于管道健康——请结合下方学习队列状态判断。",
|
|
1877
|
+
"pipeline": {
|
|
1878
|
+
"title": "学习队列状态",
|
|
1879
|
+
"statusHealthy": "正常推进",
|
|
1880
|
+
"statusBacklogged": "有积压(仍在推进)",
|
|
1881
|
+
"statusStalled": "疑似停滞",
|
|
1882
|
+
"statusDisabled": "消费者已禁用",
|
|
1883
|
+
"statusUnknown": "状态未知",
|
|
1884
|
+
"nextActionPrefix": "建议:"
|
|
1885
|
+
},
|
|
1875
1886
|
"error": "加载失败任务失败",
|
|
1876
1887
|
"disabled": "失败任务可观测性已禁用。请在 .pd/config.yaml 中启用 'failed_tasks_observability' 以查看。",
|
|
1877
1888
|
"createDraft": "创建反馈草稿",
|
|
@@ -179,9 +179,10 @@ function ActivationFactCard({ record, lifecycleData, receiptCount, onDisable, di
|
|
|
179
179
|
defaultValue: "无法判定:{{reason}}",
|
|
180
180
|
reason: record.promptInjection.reason ?? "unknown",
|
|
181
181
|
}), record.promptInjection.status === "route_unconfirmed" && (_jsxs(_Fragment, { children: [t("pages.activation.injectionRouteUnconfirmed", {
|
|
182
|
-
defaultValue: "当前宿主容量未确认:OpenClaw {{oc}} / Codex {{cx}}",
|
|
182
|
+
defaultValue: "当前宿主容量未确认:OpenClaw {{oc}} / Codex {{cx}} / WorkBuddy {{wb}}",
|
|
183
183
|
oc: record.promptInjection.perHostFits?.find((f) => f.hostKind === "openclaw")?.fits === undefined ? t("pages.activation.fitUnknown", { defaultValue: "未知" }) : record.promptInjection.perHostFits?.find((f) => f.hostKind === "openclaw")?.fits ? t("pages.activation.fitYes", { defaultValue: "可装入" }) : t("pages.activation.fitNo", { defaultValue: "超长" }),
|
|
184
184
|
cx: record.promptInjection.perHostFits?.find((f) => f.hostKind === "codex")?.fits === undefined ? t("pages.activation.fitUnknown", { defaultValue: "未知" }) : record.promptInjection.perHostFits?.find((f) => f.hostKind === "codex")?.fits ? t("pages.activation.fitYes", { defaultValue: "可装入" }) : t("pages.activation.fitNo", { defaultValue: "超长" }),
|
|
185
|
+
wb: record.promptInjection.perHostFits?.find((f) => f.hostKind === "workbuddy")?.fits === undefined ? t("pages.activation.fitUnknown", { defaultValue: "未知" }) : record.promptInjection.perHostFits?.find((f) => f.hostKind === "workbuddy")?.fits ? t("pages.activation.fitYes", { defaultValue: "可装入" }) : t("pages.activation.fitNo", { defaultValue: "超长" }),
|
|
185
186
|
}), record.promptInjection.reason !== undefined && (_jsx("span", { className: "block text-ink-4 text-[11.5px]", children: record.promptInjection.reason }))] }))] })] })), canProposeRevision && (_jsxs("div", { className: "mt-2", "data-testid": `activation-revision-${record.activationId}`, children: [!showRevisionInput && revisionResult === null && (_jsx("button", { type: "button", onClick: () => { setShowRevisionInput(true); setRevisionText(""); }, "data-testid": `activation-revision-open-${record.activationId}`, className: "inline-flex items-center border border-line rounded-[3px] px-[10px] py-[4px] text-[12px] hover:border-line-2", children: t("pages.activation.revisionOpen", { defaultValue: "修改为可注入版本" }) })), showRevisionInput && (_jsxs("div", { className: "rounded-[3px] border border-line bg-surface/60 p-2", children: [_jsx("textarea", { value: revisionText, onChange: (e) => setRevisionText(e.target.value), rows: 3, className: "w-full rounded-[2px] border border-line bg-panel px-2 py-1 text-[12.5px]", placeholder: t("pages.activation.revisionPlaceholder", { defaultValue: "输入新的原则正文(保留触发条件、必须动作和必要例外,尽量精简)" }), "data-testid": `activation-revision-input-${record.activationId}` }), _jsxs("div", { className: "mt-1 flex gap-2", children: [_jsx(Button, { variant: "ghost", size: "sm", onClick: handleProposeRevision, disabled: revisionSubmitting || revisionText.trim().length === 0, "data-testid": `activation-revision-submit-${record.activationId}`, children: revisionSubmitting ? t("common.loading") + "…" : t("pages.activation.revisionSubmit", { defaultValue: "创建待审批的新版本" }) }), _jsx(Button, { variant: "ghost", size: "sm", onClick: () => setShowRevisionInput(false), children: t("common.cancel", { defaultValue: "取消" }) })] })] })), revisionResult !== null && (_jsxs("div", { className: "rounded-[3px] border border-gov/40 bg-gov/5 p-2 text-[12px] leading-relaxed", "data-testid": `activation-revision-result-${record.activationId}`, children: [_jsx("p", { children: t("pages.activation.revisionResultNote", {
|
|
186
187
|
defaultValue: "新版本已进入待审批(审批号 {{approvalId}})。批准后旧版本自动停用并由新版本替换;拒绝则旧版本继续生效。",
|
|
187
188
|
approvalId: revisionResult.approvalId ?? "",
|
|
@@ -144,7 +144,28 @@ function validateFailedTasksData(v) {
|
|
|
144
144
|
if (total === null)
|
|
145
145
|
return null;
|
|
146
146
|
const nextAction = readNullableString(v, "nextAction");
|
|
147
|
-
|
|
147
|
+
// PRI-955 (F11): optional pipeline health block — an invalid block is
|
|
148
|
+
// omitted (never fails the whole payload), the page then renders nothing.
|
|
149
|
+
let pipeline;
|
|
150
|
+
if (Object.hasOwn(v, "pipeline") && isObject(v.pipeline)) {
|
|
151
|
+
const p = v.pipeline;
|
|
152
|
+
const status = readString(p, "status");
|
|
153
|
+
const note = readString(p, "note");
|
|
154
|
+
if (status === "healthy" || status === "backlogged" || status === "stalled" || status === "disabled" || status === "unknown") {
|
|
155
|
+
if (note !== null) {
|
|
156
|
+
pipeline = {
|
|
157
|
+
status,
|
|
158
|
+
pendingCount: readNumber(p, "pendingCount"),
|
|
159
|
+
oldestPendingTaskKind: readNullableString(p, "oldestPendingTaskKind"),
|
|
160
|
+
oldestPendingAgeMinutes: readNumber(p, "oldestPendingAgeMinutes"),
|
|
161
|
+
lastProgressAt: readNullableString(p, "lastProgressAt"),
|
|
162
|
+
note,
|
|
163
|
+
nextAction: readNullableString(p, "nextAction") ?? undefined,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return { tasks, total, nextAction: nextAction ?? undefined, ...(pipeline ? { pipeline } : {}) };
|
|
148
169
|
}
|
|
149
170
|
// ── Helpers ──────────────────────────────────────────────────────────────────
|
|
150
171
|
function truncateId(id) {
|
|
@@ -287,15 +308,32 @@ export function FailedTasksPage() {
|
|
|
287
308
|
void handleRecoverConfirmed();
|
|
288
309
|
}, children: recoverConfirmLabel })] })] }) })] }));
|
|
289
310
|
}
|
|
311
|
+
/** PRI-955 (F11): derived learning-queue health block — never claims health
|
|
312
|
+
* from the failed-task count alone. Facts come from the server projection. */
|
|
313
|
+
function PipelineHealthCard({ pipeline, t }) {
|
|
314
|
+
const statusLabel = pipeline.status === "healthy" ? t("pages.failedTasks.pipeline.statusHealthy")
|
|
315
|
+
: pipeline.status === "backlogged" ? t("pages.failedTasks.pipeline.statusBacklogged")
|
|
316
|
+
: pipeline.status === "stalled" ? t("pages.failedTasks.pipeline.statusStalled")
|
|
317
|
+
: t("pages.failedTasks.pipeline.statusUnknown");
|
|
318
|
+
const variant = pipeline.status === "healthy" ? "default"
|
|
319
|
+
: pipeline.status === "stalled" ? "destructive"
|
|
320
|
+
: pipeline.status === "backlogged" ? "amber"
|
|
321
|
+
: "default";
|
|
322
|
+
return (_jsxs("div", { className: "p-5 bg-panel border border-line rounded-[var(--radius-md)] mb-4", children: [_jsxs("div", { className: "flex items-center gap-3 mb-2", children: [_jsx("span", { className: "text-[15px] font-semibold text-ink", children: t("pages.failedTasks.pipeline.title") }), _jsx("span", { className: `text-xs px-2 py-0.5 rounded-full border ${variant === "destructive" ? "border-red-300 text-red-700 bg-red-50"
|
|
323
|
+
: variant === "amber" ? "border-amber-300 text-amber-700 bg-amber-50"
|
|
324
|
+
: "border-line text-ink-3 bg-canvas"}`, children: statusLabel })] }), _jsx("p", { className: "text-ink-3 text-sm leading-relaxed", children: pipeline.note }), pipeline.nextAction && (_jsxs("p", { className: "text-ink-3 text-sm leading-relaxed mt-1", children: [t("pages.failedTasks.pipeline.nextActionPrefix"), pipeline.nextAction] }))] }));
|
|
325
|
+
}
|
|
290
326
|
function LoadedContent({ data, onCreateDraft, onRecover, initialExpandedTaskId, t }) {
|
|
291
327
|
const hasTasks = data.tasks.length > 0;
|
|
292
|
-
// Empty state — surface nextAction from the API (rc-9: no silent fallback)
|
|
328
|
+
// Empty state — surface nextAction from the API (rc-9: no silent fallback).
|
|
329
|
+
// PRI-955: the empty copy no longer claims the pipeline is healthy; the
|
|
330
|
+
// derived queue-health block carries that judgment with facts.
|
|
293
331
|
if (!hasTasks) {
|
|
294
|
-
return (
|
|
332
|
+
return (_jsxs("div", { className: "py-8", children: [_jsxs("div", { className: "p-5 bg-panel border border-line rounded-[var(--radius-md)]", children: [_jsx("h3", { className: "text-[17px] font-semibold text-ink mb-2", children: t("pages.failedTasks.empty") }), data.nextAction && (_jsx("p", { className: "text-ink-3 text-sm leading-relaxed", children: data.nextAction }))] }), data.pipeline && _jsx(PipelineHealthCard, { pipeline: data.pipeline, t: t })] }));
|
|
295
333
|
}
|
|
296
334
|
const grouped = groupTasksByKind(data.tasks);
|
|
297
335
|
const sortedKinds = Array.from(grouped.keys()).sort();
|
|
298
|
-
return (_jsxs(_Fragment, { children: [_jsx("div", { className: "space-y-6", children: sortedKinds.map((kind) => {
|
|
336
|
+
return (_jsxs(_Fragment, { children: [data.pipeline && _jsx(PipelineHealthCard, { pipeline: data.pipeline, t: t }), _jsx("div", { className: "space-y-6", children: sortedKinds.map((kind) => {
|
|
299
337
|
const tasks = grouped.get(kind);
|
|
300
338
|
if (!tasks || tasks.length === 0)
|
|
301
339
|
return null;
|
|
@@ -420,7 +420,7 @@ function PendingReviewCard({ group, actionsLockedReason, onDecisionApplied, prom
|
|
|
420
420
|
full: promptInjection.fullRenderChars !== undefined
|
|
421
421
|
? t("pages.focus.promptScopeFullRender", { count: promptInjection.fullRenderChars })
|
|
422
422
|
: "",
|
|
423
|
-
}), promptInjection.hostKind !== undefined ? ` · ${promptInjection.hostKind === "openclaw" ? "OpenClaw" : "Codex"}` : ""] })] })), group.revisionReviewUnavailable === true && _jsx("p", { role: "alert", className: "mt-3 text-danger", children: t("pages.focus.revisionReviewUnavailable") }), group.revisionReview !== undefined && (_jsxs("div", { className: "mt-3 border border-line p-3 text-[12.5px]", "data-testid": `revision-intent-review-${group.principleId}`, children: [_jsx("p", { children: t("pages.focus.revisionIntentReview", { defaultValue: "修订复核:确认新正文保留触发条件、行动要求和必要例外,并与沿用意图一致。" }) }), _jsx("pre", { className: "mt-2 max-h-32 overflow-auto whitespace-pre-wrap", children: group.revisionReview.oldStatement }), _jsx("pre", { className: "mt-2 max-h-32 overflow-auto whitespace-pre-wrap", children: group.revisionReview.newStatement }), _jsx("dl", { className: "mt-2", children: Object.entries(group.revisionReview.intentFields).map(([key, value]) => _jsxs("div", { children: [_jsx("dt", { children: t(`pages.focus.intentField.${key}`, { defaultValue: key }) }), _jsx("dd", { children: value })] }, key)) }), _jsxs("label", { className: "mt-2 flex gap-2", children: [_jsx("input", { type: "checkbox", checked: intentReviewed, onChange: (event) => setIntentReviewed(event.target.checked) }), t("pages.focus.revisionIntentConfirmed", { defaultValue: "我已核对上述意图与新正文一致" })] })] })), _jsxs("div", { className: "flex gap-2 mt-4 flex-wrap items-center", children: [_jsx("button", { type: "button", onClick: handleApprove, disabled: decisionDisabled || (group.revisionReviewUnavailable === true || (group.revisionReview !== undefined && !intentReviewed)), "data-testid": `approve-btn-${group.principleId}`, className: "inline-flex items-center border border-gov bg-gov text-paper rounded-[3px] px-[14px] py-[6px] text-[12.5px] font-medium hover:bg-gov-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: actionLoading ? t("common.loading") + "…" : t("pages.focus.approveAction", { defaultValue: "批准" }) }), _jsx("button", { type: "button", onClick: () => { setShowEditInput((v) => !v); setShowRejectInput(false); }, disabled: decisionDisabled, "data-testid": `edit-btn-${group.principleId}`, className: "inline-flex items-center border border-line bg-surface text-ink rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:border-line-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.focus.editAction", { defaultValue: "编辑" }) }), _jsx("button", { type: "button", onClick: () => { setShowRejectInput((v) => !v); setShowEditInput(false); }, disabled: decisionDisabled, "data-testid": `reject-btn-${group.principleId}`, className: "inline-flex items-center border border-line bg-surface text-ink rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:border-line-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.focus.rejectAction", { defaultValue: "拒绝" }) }), _jsx(Link, { to: "/pain", className: "inline-flex items-center text-gov text-[12.5px] hover:underline focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.focus.viewFullChain") })] }), showRejectInput && (_jsxs("div", { className: "mt-3 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("pages.focus.rejectReasonLabel", { defaultValue: "拒绝原因(必填)" }) }), _jsx("textarea", { value: rejectReason, onChange: (e) => setRejectReason(e.target.value), "data-testid": `reject-reason-${group.principleId}`, placeholder: t("pages.focus.rejectReasonPlaceholder", { 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", { type: "button", onClick: handleReject, disabled: !rejectReason.trim() || actionLoading, "data-testid": `confirm-reject-${group.principleId}`, className: "inline-flex items-center border border-danger text-danger bg-surface rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:bg-danger/5 transition-colors disabled:opacity-50 disabled:cursor-not-allowed", children: t("pages.focus.confirmReject", { defaultValue: "确认拒绝" }) }), _jsx("button", { type: "button", onClick: () => { setShowRejectInput(false); setRejectReason(""); }, className: "inline-flex items-center border border-line bg-surface text-ink rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:border-line-2 transition-colors", children: t("pages.focus.cancelAction", { defaultValue: "取消" }) })] })] })), showEditInput && (_jsxs("div", { className: "mt-3 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("pages.focus.editReasonLabel", { defaultValue: "编辑原因(必填)" }) }), _jsxs("div", { className: "mb-2 text-ink-4 text-[12px] font-mono", children: [t("pages.focus.currentArtifactLabel", { defaultValue: "当前工件" }), ": ", currentArtifactId] }), _jsx("input", { type: "text", value: newArtifactId, onChange: (e) => setNewArtifactId(e.target.value), "data-testid": `edit-new-artifact-${group.principleId}`, placeholder: t("pages.focus.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("pages.focus.editNewArtifactPlaceholder", { defaultValue: "输入新的已验证工件 ID" }) }), _jsx("textarea", { value: editReason, onChange: (e) => setEditReason(e.target.value), "data-testid": `edit-reason-${group.principleId}`, placeholder: t("pages.focus.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", { type: "button", onClick: handleEdit, disabled: !editReason.trim() || !newArtifactId.trim() || actionLoading, "data-testid": `confirm-edit-${group.principleId}`, className: "inline-flex items-center border border-gov text-gov bg-surface rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:bg-gov/5 transition-colors disabled:opacity-50 disabled:cursor-not-allowed", children: t("pages.focus.confirmEdit", { defaultValue: "确认编辑" }) }), _jsx("button", { type: "button", onClick: () => { setShowEditInput(false); setEditReason(""); setNewArtifactId(""); }, className: "inline-flex items-center border border-line bg-surface text-ink rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:border-line-2 transition-colors", children: t("pages.focus.cancelAction", { defaultValue: "取消" }) })] })] }))] }));
|
|
423
|
+
}), promptInjection.hostKind !== undefined ? ` · ${promptInjection.hostKind === "openclaw" ? "OpenClaw" : promptInjection.hostKind === "workbuddy" ? "WorkBuddy" : "Codex"}` : ""] })] })), group.revisionReviewUnavailable === true && _jsx("p", { role: "alert", className: "mt-3 text-danger", children: t("pages.focus.revisionReviewUnavailable") }), group.revisionReview !== undefined && (_jsxs("div", { className: "mt-3 border border-line p-3 text-[12.5px]", "data-testid": `revision-intent-review-${group.principleId}`, children: [_jsx("p", { children: t("pages.focus.revisionIntentReview", { defaultValue: "修订复核:确认新正文保留触发条件、行动要求和必要例外,并与沿用意图一致。" }) }), _jsx("pre", { className: "mt-2 max-h-32 overflow-auto whitespace-pre-wrap", children: group.revisionReview.oldStatement }), _jsx("pre", { className: "mt-2 max-h-32 overflow-auto whitespace-pre-wrap", children: group.revisionReview.newStatement }), _jsx("dl", { className: "mt-2", children: Object.entries(group.revisionReview.intentFields).map(([key, value]) => _jsxs("div", { children: [_jsx("dt", { children: t(`pages.focus.intentField.${key}`, { defaultValue: key }) }), _jsx("dd", { children: value })] }, key)) }), _jsxs("label", { className: "mt-2 flex gap-2", children: [_jsx("input", { type: "checkbox", checked: intentReviewed, onChange: (event) => setIntentReviewed(event.target.checked) }), t("pages.focus.revisionIntentConfirmed", { defaultValue: "我已核对上述意图与新正文一致" })] })] })), _jsxs("div", { className: "flex gap-2 mt-4 flex-wrap items-center", children: [_jsx("button", { type: "button", onClick: handleApprove, disabled: decisionDisabled || (group.revisionReviewUnavailable === true || (group.revisionReview !== undefined && !intentReviewed)), "data-testid": `approve-btn-${group.principleId}`, className: "inline-flex items-center border border-gov bg-gov text-paper rounded-[3px] px-[14px] py-[6px] text-[12.5px] font-medium hover:bg-gov-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: actionLoading ? t("common.loading") + "…" : t("pages.focus.approveAction", { defaultValue: "批准" }) }), _jsx("button", { type: "button", onClick: () => { setShowEditInput((v) => !v); setShowRejectInput(false); }, disabled: decisionDisabled, "data-testid": `edit-btn-${group.principleId}`, className: "inline-flex items-center border border-line bg-surface text-ink rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:border-line-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.focus.editAction", { defaultValue: "编辑" }) }), _jsx("button", { type: "button", onClick: () => { setShowRejectInput((v) => !v); setShowEditInput(false); }, disabled: decisionDisabled, "data-testid": `reject-btn-${group.principleId}`, className: "inline-flex items-center border border-line bg-surface text-ink rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:border-line-2 transition-colors disabled:opacity-50 disabled:cursor-not-allowed focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.focus.rejectAction", { defaultValue: "拒绝" }) }), _jsx(Link, { to: "/pain", className: "inline-flex items-center text-gov text-[12.5px] hover:underline focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.focus.viewFullChain") })] }), showRejectInput && (_jsxs("div", { className: "mt-3 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("pages.focus.rejectReasonLabel", { defaultValue: "拒绝原因(必填)" }) }), _jsx("textarea", { value: rejectReason, onChange: (e) => setRejectReason(e.target.value), "data-testid": `reject-reason-${group.principleId}`, placeholder: t("pages.focus.rejectReasonPlaceholder", { 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", { type: "button", onClick: handleReject, disabled: !rejectReason.trim() || actionLoading, "data-testid": `confirm-reject-${group.principleId}`, className: "inline-flex items-center border border-danger text-danger bg-surface rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:bg-danger/5 transition-colors disabled:opacity-50 disabled:cursor-not-allowed", children: t("pages.focus.confirmReject", { defaultValue: "确认拒绝" }) }), _jsx("button", { type: "button", onClick: () => { setShowRejectInput(false); setRejectReason(""); }, className: "inline-flex items-center border border-line bg-surface text-ink rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:border-line-2 transition-colors", children: t("pages.focus.cancelAction", { defaultValue: "取消" }) })] })] })), showEditInput && (_jsxs("div", { className: "mt-3 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("pages.focus.editReasonLabel", { defaultValue: "编辑原因(必填)" }) }), _jsxs("div", { className: "mb-2 text-ink-4 text-[12px] font-mono", children: [t("pages.focus.currentArtifactLabel", { defaultValue: "当前工件" }), ": ", currentArtifactId] }), _jsx("input", { type: "text", value: newArtifactId, onChange: (e) => setNewArtifactId(e.target.value), "data-testid": `edit-new-artifact-${group.principleId}`, placeholder: t("pages.focus.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("pages.focus.editNewArtifactPlaceholder", { defaultValue: "输入新的已验证工件 ID" }) }), _jsx("textarea", { value: editReason, onChange: (e) => setEditReason(e.target.value), "data-testid": `edit-reason-${group.principleId}`, placeholder: t("pages.focus.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", { type: "button", onClick: handleEdit, disabled: !editReason.trim() || !newArtifactId.trim() || actionLoading, "data-testid": `confirm-edit-${group.principleId}`, className: "inline-flex items-center border border-gov text-gov bg-surface rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:bg-gov/5 transition-colors disabled:opacity-50 disabled:cursor-not-allowed", children: t("pages.focus.confirmEdit", { defaultValue: "确认编辑" }) }), _jsx("button", { type: "button", onClick: () => { setShowEditInput(false); setEditReason(""); setNewArtifactId(""); }, className: "inline-flex items-center border border-line bg-surface text-ink rounded-[3px] px-[14px] py-[6px] text-[12.5px] hover:border-line-2 transition-colors", children: t("pages.focus.cancelAction", { defaultValue: "取消" }) })] })] }))] }));
|
|
424
424
|
}
|
|
425
425
|
function StagnationSignalCard({ signal }) {
|
|
426
426
|
const { t } = useTranslation();
|
|
@@ -748,14 +748,14 @@ export function FocusPage({ featureFlags }) {
|
|
|
748
748
|
return (_jsxs("div", { className: "mb-4 rounded-[3px] border border-amber/40 bg-amber/5 px-3 py-2 text-[12.5px] leading-relaxed text-amber", "data-testid": "prompt-capacity-unconfirmed-banner", children: [_jsx("p", { children: t("pages.focus.promptCapacityUnconfirmed", {
|
|
749
749
|
defaultValue: "当前宿主容量未确认:本工作区适用的宿主会走不同的注入路由,以下数字未绑定具体宿主。",
|
|
750
750
|
}) }), _jsx("ul", { className: "mt-1 list-disc pl-5", children: (unconfirmed.perHost ?? []).map((entry) => (_jsx("li", { "data-testid": `prompt-capacity-perhost-${entry.hostKind}`, children: t("pages.focus.promptCapacityPerHostEntry", {
|
|
751
|
-
host: entry.hostKind === "openclaw" ? "OpenClaw" : "Codex",
|
|
751
|
+
host: entry.hostKind === "openclaw" ? "OpenClaw" : entry.hostKind === "workbuddy" ? "WorkBuddy" : "Codex",
|
|
752
752
|
billing: entry.route === "shared_render"
|
|
753
753
|
? t("pages.focus.promptCapacitySharedRoute")
|
|
754
754
|
: t("pages.focus.promptCapacityListRoute"),
|
|
755
755
|
used: entry.usedChars,
|
|
756
756
|
budget: unconfirmed.budget,
|
|
757
757
|
full: entry.truncated ? t("pages.focus.promptCapacityPerHostFull") : "",
|
|
758
|
-
}) }, entry.hostKind))) }), unconfirmed.nextAction !== undefined && (_jsx("p", { className: "mt-1 text-ink-2", children: unconfirmed.nextAction })), _jsxs("div", { className: "mt-2 flex gap-2", children: [["openclaw", "codex"].map((host) => (_jsx("button", { type: "button", onClick: () => setPromptTargetHost(host), "data-testid": `prompt-capacity-pick-${host}`, className: `inline-flex items-center border rounded-[3px] px-[10px] py-[4px] transition-colors ${promptTargetHost === host ? "border-amber bg-amber/10" : "border-line hover:border-line-2"}`, children: t("pages.focus.promptCapacityViewAsHost", { host: host === "openclaw" ? "OpenClaw" : "Codex" }) }, host))), promptTargetHost !== null && (_jsx("button", { type: "button", onClick: () => setPromptTargetHost(null), "data-testid": "prompt-capacity-pick-clear", className: "inline-flex items-center border border-line rounded-[3px] px-[10px] py-[4px] hover:border-line-2", children: t("pages.focus.promptCapacityClearHost", { defaultValue: "清除选择" }) }))] })] }));
|
|
758
|
+
}) }, entry.hostKind))) }), unconfirmed.nextAction !== undefined && (_jsx("p", { className: "mt-1 text-ink-2", children: unconfirmed.nextAction })), _jsxs("div", { className: "mt-2 flex gap-2", children: [["openclaw", "codex", "workbuddy"].map((host) => (_jsx("button", { type: "button", onClick: () => setPromptTargetHost(host), "data-testid": `prompt-capacity-pick-${host}`, className: `inline-flex items-center border rounded-[3px] px-[10px] py-[4px] transition-colors ${promptTargetHost === host ? "border-amber bg-amber/10" : "border-line hover:border-line-2"}`, children: t("pages.focus.promptCapacityViewAsHost", { host: host === "openclaw" ? "OpenClaw" : host === "workbuddy" ? "WorkBuddy" : "Codex" }) }, host))), promptTargetHost !== null && (_jsx("button", { type: "button", onClick: () => setPromptTargetHost(null), "data-testid": "prompt-capacity-pick-clear", className: "inline-flex items-center border border-line rounded-[3px] px-[10px] py-[4px] hover:border-line-2", children: t("pages.focus.promptCapacityClearHost", { defaultValue: "清除选择" }) }))] })] }));
|
|
759
759
|
})(), groupedAvailable && pendingGroups.map((group) => (_jsx(PendingReviewCard, { group: group, actionsLockedReason: ownerActionsLockedReason ?? undefined, promptInjection: groupedData.promptInjection, promptTargetHost: promptTargetHost ?? undefined, onDecisionApplied: () => { void loadData(); } }, group.principleId)))] }), _jsxs("section", { "aria-label": t("pages.focus.ownerAttention.sectionTitle"), className: "mb-7", "data-testid": "owner-attention-section", children: [_jsxs("div", { className: "flex items-baseline gap-2 mb-3", children: [_jsx(SectionTitle, { children: t("pages.focus.ownerAttention.sectionTitle") }), ownerInbox !== null && ownerInboxError === null && (_jsx("span", { className: "font-mono text-ink-4 text-[12px]", "data-testid": "owner-attention-counts", children: `· ${t("pages.focus.ownerAttention.blockedCount", { count: ownerInbox.groups.blocked.length })} · ${t("pages.focus.ownerAttention.recoveryCount", { count: inboxRecovery.length })}` }))] }), ownerInboxError !== null && (_jsx("p", { className: "text-ink-4 text-[12.5px]", children: t("pages.focus.ownerInbox.loadError") })), ownerInbox !== null && ownerInboxError === null && (_jsxs(_Fragment, { children: [ownerInbox.groups.blocked.length === 0
|
|
760
760
|
&& inboxRecovery.length === 0
|
|
761
761
|
&& unmatchedInboxDecisions.length === 0 && (_jsx("p", { className: "text-ink-4 text-[13px]", children: t("pages.focus.ownerAttention.empty") })), unmatchedInboxDecisions.length > 0 && (_jsx("p", { className: "mb-2 text-ink-4 text-[12px] leading-relaxed", "data-testid": "owner-attention-unmatched-note", children: t("pages.focus.ownerAttention.unmatchedTitle") })), unmatchedInboxDecisions.map((item) => (_jsx(InboxItem, { item: item, t: t, note: t("pages.focus.ownerAttention.unmatchedItemNote") }, item.principleId))), inboxBlockedIndividual.map((item) => (_jsx(InboxItem, { item: item, t: t }, item.principleId))), inboxRecovery.map((item) => (_jsx(InboxItem, { item: item, t: t }, item.principleId))), inboxBlockedAggregate.length > 0 && (_jsxs("p", { className: "mt-2 text-ink-4 text-[12.5px] leading-relaxed", "data-testid": "owner-attention-aggregate-notice", children: [t("pages.focus.ownerAttention.blockedAggregate", { count: inboxBlockedAggregate.length }), " ", _jsx(Link, { to: "/principles", className: "text-gov hover:underline", children: t("pages.focus.ownerInbox.viewLibrary") })] })), ownerInbox.historicalUnknown.count > 0 && (_jsxs("p", { className: "text-ink-4 text-[12.5px] leading-relaxed mt-2", "data-testid": "owner-inbox-aggregate-notice", children: [ownerInbox.historicalUnknown.reasonText, " ", _jsx(Link, { to: "/principles", className: "text-gov hover:underline", children: t("pages.focus.ownerInbox.viewLibrary") })] }))] }))] }), 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" ? "bg-gov/10 text-gov border border-gov/20"
|
|
@@ -158,6 +158,8 @@ export function PrinciplesPage() {
|
|
|
158
158
|
// Owner Decision Experience v1: backend semantic titles + decision states
|
|
159
159
|
// (display-only — the page never re-derives decision qualification).
|
|
160
160
|
const [ownerDecisionLibrary, setOwnerDecisionLibrary] = useState(null);
|
|
161
|
+
// PRI-956 (F15, D3): runtime status cannot be confirmed when set
|
|
162
|
+
const [revocationUnavailable, setRevocationUnavailable] = useState(null);
|
|
161
163
|
// Fetch data
|
|
162
164
|
const loadData = useCallback(async () => {
|
|
163
165
|
setLoading(true);
|
|
@@ -183,6 +185,8 @@ export function PrinciplesPage() {
|
|
|
183
185
|
setCategories(pData.categories);
|
|
184
186
|
// PRI-558: expose summary for the metrics bar
|
|
185
187
|
setSummary(pData.summary);
|
|
188
|
+
// PRI-956 (F15, D3): propagate revocation check unavailability
|
|
189
|
+
setRevocationUnavailable(pData.revocationCheckUnavailable ?? null);
|
|
186
190
|
const aData = aResult.success ? validateApprovalsGrouped(aResult.data) : null;
|
|
187
191
|
setApprovalGroups(aData?.groups ?? []);
|
|
188
192
|
}
|
|
@@ -241,6 +245,7 @@ export function PrinciplesPage() {
|
|
|
241
245
|
channels: uniqueChannels,
|
|
242
246
|
evaluability: p.evaluability,
|
|
243
247
|
decisionState: decision?.decisionState,
|
|
248
|
+
runtimeDeactivated: p.runtimeDeactivated === true,
|
|
244
249
|
updatedAt: p.updatedAt,
|
|
245
250
|
createdAt: p.createdAt,
|
|
246
251
|
priority: p.priority,
|
|
@@ -273,7 +278,7 @@ export function PrinciplesPage() {
|
|
|
273
278
|
];
|
|
274
279
|
// PRI-558: most recent update across loaded principles (drives "Last Updated" metric)
|
|
275
280
|
const latestUpdatedAt = principles.reduce((max, p) => (new Date(p.updatedAt).getTime() > new Date(max).getTime() ? p.updatedAt : max), principles[0]?.updatedAt ?? "");
|
|
276
|
-
return (_jsxs(PageShell, { children: [_jsx(SectionTitle, { children: t("principles.reviewTitle") }), _jsx(ShinyText, { as: "h1", className: "text-[29px] font-semibold tracking-tight text-ink mb-2", duration: 4.5, brightness: 0.5, disabled: !(filterMode === 'actionable' && (categories?.owner_actionable ?? 0) > 0), children: t("principles.reviewSubtitle") }), _jsx("p", { className: "text-ink-3 text-[14px] leading-relaxed mb-6", children: t("principles.reviewDescription") }), _jsx(PrinciplesViewNav, { view: "workspace" }), _jsxs("div", { className: "flex flex-wrap items-center gap-3 mb-6", children: [_jsxs("div", { className: "flex gap-1", role: "group", "aria-label": "Filter mode", children: [_jsxs("button", { onClick: () => setFilterMode('actionable'), className: "font-mono text-[11px] uppercase tracking-[0.02em] border rounded-[2px] px-2 py-1 transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gov " +
|
|
281
|
+
return (_jsxs(PageShell, { children: [revocationUnavailable && (_jsx("div", { className: "mb-4 p-3 bg-amber-50 border border-amber-300 rounded-[var(--radius-md)] text-sm text-amber-800", children: t("principles.revocationStatusUnknown") })), _jsx(SectionTitle, { children: t("principles.reviewTitle") }), _jsx(ShinyText, { as: "h1", className: "text-[29px] font-semibold tracking-tight text-ink mb-2", duration: 4.5, brightness: 0.5, disabled: !(filterMode === 'actionable' && (categories?.owner_actionable ?? 0) > 0), children: t("principles.reviewSubtitle") }), _jsx("p", { className: "text-ink-3 text-[14px] leading-relaxed mb-6", children: t("principles.reviewDescription") }), _jsx(PrinciplesViewNav, { view: "workspace" }), _jsxs("div", { className: "flex flex-wrap items-center gap-3 mb-6", children: [_jsxs("div", { className: "flex gap-1", role: "group", "aria-label": "Filter mode", children: [_jsxs("button", { onClick: () => setFilterMode('actionable'), className: "font-mono text-[11px] uppercase tracking-[0.02em] border rounded-[2px] px-2 py-1 transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gov " +
|
|
277
282
|
(filterMode === 'actionable'
|
|
278
283
|
? "bg-gov text-paper border-gov"
|
|
279
284
|
: "bg-surface text-ink-3 border-line hover:border-line-2"), children: [t("principles.filterActionable", { defaultValue: "Actionable" }), categories?.owner_actionable ? ` (${categories.owner_actionable})` : ''] }), _jsxs("button", { onClick: () => setFilterMode('all'), className: "font-mono text-[11px] uppercase tracking-[0.02em] border rounded-[2px] px-2 py-1 transition-colors focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-gov " +
|
|
@@ -308,6 +313,6 @@ export function PrinciplesPage() {
|
|
|
308
313
|
? t("principles.blockImpactSeeDecisionView", { defaultValue: "以详情页「当前实际执行」为准(本卡片不据此判断影响)。" })
|
|
309
314
|
: t(BLOCK_IMPACT_KEY[card.status]) }), _jsx(EvolutionBlock, { label: t("principles.blockBehavior"), children: card.action ? card.action : t("principles.blockBehaviorFallback") }), _jsx("div", { className: "mt-3 pt-3 border-t border-line/60", children: _jsxs("div", { className: "flex items-center justify-between gap-3 bg-gov/5 border border-line rounded-[3px] px-3 py-2", children: [_jsxs("div", { className: "flex items-center gap-2 flex-wrap", children: [_jsx("span", { className: "font-mono text-[11px] uppercase tracking-[0.02em] text-ink-4", children: t("principles.govDecision") }), _jsxs("span", { className: "font-mono text-[11px] uppercase tracking-[0.02em] border rounded-[2px] px-2 py-0.5 " +
|
|
310
315
|
STATUS_TEXT[card.status] +
|
|
311
|
-
" border-current/20", children: [decision.glyph, " ", t(decision.labelKey)] })] }), decisionDate && (_jsx("span", { className: "font-mono text-[11px] text-ink-4 whitespace-nowrap", children: formatDate(decisionDate, i18n.language) }))] }) })] }, card.principleId));
|
|
316
|
+
" border-current/20", children: [decision.glyph, " ", t(decision.labelKey)] }), card.runtimeDeactivated === true && (_jsx("span", { className: "font-mono text-[11px] uppercase tracking-[0.02em] border rounded-[2px] px-2 py-0.5 border-amber-300 text-amber-700 bg-amber-50", children: t("principles.runtimeDeactivated") }))] }), decisionDate && (_jsx("span", { className: "font-mono text-[11px] text-ink-4 whitespace-nowrap", children: formatDate(decisionDate, i18n.language) }))] }) })] }, card.principleId));
|
|
312
317
|
})] }))] }));
|
|
313
318
|
}
|
|
@@ -594,6 +594,8 @@ export interface PrincipleListItemData {
|
|
|
594
594
|
conflictsWithCount: number;
|
|
595
595
|
createdAt: string;
|
|
596
596
|
updatedAt: string;
|
|
597
|
+
/** PRI-956 (F15): runtime authority revoked (activations deactivated). */
|
|
598
|
+
runtimeDeactivated?: boolean;
|
|
597
599
|
/** PRI-332: Detected language of the principle text */
|
|
598
600
|
detectedLanguage: string;
|
|
599
601
|
/** PRI-332 P1-5: Structured readability warning code */
|
|
@@ -612,6 +614,8 @@ export interface PrinciplesListData {
|
|
|
612
614
|
categories?: Record<string, number>;
|
|
613
615
|
/** If the approval cross-check was unavailable, this explains why (ERR-002) */
|
|
614
616
|
approvalCrossCheckUnavailable?: string;
|
|
617
|
+
/** PRI-956 (F15, D3): if the activations-table query was unavailable, this explains why — runtime status cannot be confirmed */
|
|
618
|
+
revocationCheckUnavailable?: string;
|
|
615
619
|
}
|
|
616
620
|
export type CorePrincipleLayerData = 'foundational' | 'operating';
|
|
617
621
|
export interface CorePrincipleData {
|
|
@@ -696,8 +700,8 @@ export interface EvidenceChainRecordData {
|
|
|
696
700
|
dreamerTaskStatus?: string;
|
|
697
701
|
/** PRI-469: optional intent tension from diagnostician artifact (SPEC §16). */
|
|
698
702
|
intentTension?: IntentTensionData;
|
|
699
|
-
/** PRI-625 Slice D: evidence host attribution — openclaw | codex | unknown. */
|
|
700
|
-
hostKind?: 'openclaw' | 'codex' | 'unknown';
|
|
703
|
+
/** PRI-625 Slice D: evidence host attribution — openclaw | codex | workbuddy | unknown. */
|
|
704
|
+
hostKind?: 'openclaw' | 'codex' | 'workbuddy' | 'unknown';
|
|
701
705
|
}
|
|
702
706
|
export interface IntentTensionData {
|
|
703
707
|
source: string;
|
|
@@ -1089,7 +1089,7 @@ function validatePromptActivationInjectionStatus(v) {
|
|
|
1089
1089
|
for (const entry of v.perHostFits) {
|
|
1090
1090
|
if (!isObject(entry))
|
|
1091
1091
|
return null;
|
|
1092
|
-
if ((entry.hostKind !== 'openclaw' && entry.hostKind !== 'codex') || typeof entry.fits !== 'boolean')
|
|
1092
|
+
if ((entry.hostKind !== 'openclaw' && entry.hostKind !== 'codex' && entry.hostKind !== 'workbuddy') || typeof entry.fits !== 'boolean')
|
|
1093
1093
|
return null;
|
|
1094
1094
|
perHostFits.push({ hostKind: entry.hostKind, fits: entry.fits });
|
|
1095
1095
|
}
|
|
@@ -1152,7 +1152,7 @@ export function validateActivations(v) {
|
|
|
1152
1152
|
const route = v.promptInjectionRoute;
|
|
1153
1153
|
if ((route.status === 'confirmed' || route.status === 'unconfirmed') && typeof route.flagEnabled === 'boolean') {
|
|
1154
1154
|
const summary = { status: route.status, flagEnabled: route.flagEnabled };
|
|
1155
|
-
if (Object.hasOwn(route, 'hostKind') && (route.hostKind === 'openclaw' || route.hostKind === 'codex'))
|
|
1155
|
+
if (Object.hasOwn(route, 'hostKind') && (route.hostKind === 'openclaw' || route.hostKind === 'codex' || route.hostKind === 'workbuddy'))
|
|
1156
1156
|
summary.hostKind = route.hostKind;
|
|
1157
1157
|
if (Object.hasOwn(route, 'route') && (route.route === 'legacy_trim' || route.route === 'shared_render'))
|
|
1158
1158
|
summary.route = route.route;
|
|
@@ -1587,6 +1587,13 @@ function validatePrincipleListItem(v) {
|
|
|
1587
1587
|
return null;
|
|
1588
1588
|
result.readabilityWarningCode = v.readabilityWarningCode;
|
|
1589
1589
|
}
|
|
1590
|
+
// PRI-956 (F15): optional runtime-revocation disclosure — present only when
|
|
1591
|
+
// the activations table reports a deactivated prompt activation.
|
|
1592
|
+
if (Object.hasOwn(v, 'runtimeDeactivated')) {
|
|
1593
|
+
if (v.runtimeDeactivated !== true)
|
|
1594
|
+
return null;
|
|
1595
|
+
result.runtimeDeactivated = true;
|
|
1596
|
+
}
|
|
1590
1597
|
return result;
|
|
1591
1598
|
}
|
|
1592
1599
|
function validateCorePrinciple(v) {
|
|
@@ -1662,11 +1669,19 @@ export function validatePrinciplesList(v) {
|
|
|
1662
1669
|
const approvalCrossCheckUnavailable = isString(v.approvalCrossCheckUnavailable)
|
|
1663
1670
|
? v.approvalCrossCheckUnavailable
|
|
1664
1671
|
: undefined;
|
|
1672
|
+
// PRI-956 (F15, D3): revocationCheckUnavailable — optional string
|
|
1673
|
+
if (Object.hasOwn(v, 'revocationCheckUnavailable') && !isString(v.revocationCheckUnavailable)) {
|
|
1674
|
+
return null;
|
|
1675
|
+
}
|
|
1676
|
+
const revocationCheckUnavailable = isString(v.revocationCheckUnavailable)
|
|
1677
|
+
? v.revocationCheckUnavailable
|
|
1678
|
+
: undefined;
|
|
1665
1679
|
return {
|
|
1666
1680
|
principles,
|
|
1667
1681
|
summary: { candidate, probation, active, deprecated, archived, total },
|
|
1668
1682
|
...(categories !== undefined ? { categories } : {}),
|
|
1669
1683
|
...(approvalCrossCheckUnavailable !== undefined ? { approvalCrossCheckUnavailable } : {}),
|
|
1684
|
+
...(revocationCheckUnavailable !== undefined ? { revocationCheckUnavailable } : {}),
|
|
1670
1685
|
};
|
|
1671
1686
|
}
|
|
1672
1687
|
function validateApprovalGroupRecord(v) {
|
|
@@ -1764,7 +1779,7 @@ export function validatePromptInjectionBudgetStatus(v) {
|
|
|
1764
1779
|
if (Object.hasOwn(v, 'capacityStatus') && (v.capacityStatus === 'confirmed' || v.capacityStatus === 'unconfirmed')) {
|
|
1765
1780
|
result.capacityStatus = v.capacityStatus;
|
|
1766
1781
|
}
|
|
1767
|
-
if (Object.hasOwn(v, 'hostKind') && (v.hostKind === 'openclaw' || v.hostKind === 'codex')) {
|
|
1782
|
+
if (Object.hasOwn(v, 'hostKind') && (v.hostKind === 'openclaw' || v.hostKind === 'codex' || v.hostKind === 'workbuddy')) {
|
|
1768
1783
|
result.hostKind = v.hostKind;
|
|
1769
1784
|
}
|
|
1770
1785
|
if (Object.hasOwn(v, 'route') && (v.route === 'legacy_trim' || v.route === 'shared_render')) {
|
|
@@ -1798,7 +1813,7 @@ export function validatePromptInjectionBudgetStatus(v) {
|
|
|
1798
1813
|
if (!isObject(entry))
|
|
1799
1814
|
return null;
|
|
1800
1815
|
const { hostKind, route, usedChars: hostUsed, truncated: hostTruncated } = entry;
|
|
1801
|
-
if ((hostKind !== 'openclaw' && hostKind !== 'codex')
|
|
1816
|
+
if ((hostKind !== 'openclaw' && hostKind !== 'codex' && hostKind !== 'workbuddy')
|
|
1802
1817
|
|| (route !== 'legacy_trim' && route !== 'shared_render')
|
|
1803
1818
|
|| typeof hostUsed !== 'number' || !Number.isInteger(hostUsed) || hostUsed < 0
|
|
1804
1819
|
|| typeof hostTruncated !== 'boolean') {
|
|
@@ -7,13 +7,18 @@
|
|
|
7
7
|
--font-mono: "JetBrains Mono", "SFMono-Regular", "Cascadia Mono", Consolas, monospace;
|
|
8
8
|
--color-red-50: oklch(97.1% 0.013 17.38);
|
|
9
9
|
--color-red-200: oklch(88.5% 0.062 18.334);
|
|
10
|
+
--color-red-300: oklch(80.8% 0.114 19.571);
|
|
10
11
|
--color-red-400: oklch(70.4% 0.191 22.216);
|
|
11
12
|
--color-red-500: oklch(63.7% 0.237 25.331);
|
|
12
13
|
--color-red-600: oklch(57.7% 0.245 27.325);
|
|
13
14
|
--color-red-700: oklch(50.5% 0.213 27.518);
|
|
15
|
+
--color-amber-50: oklch(98.7% 0.022 95.277);
|
|
16
|
+
--color-amber-300: oklch(87.9% 0.169 91.605);
|
|
14
17
|
--color-amber-400: oklch(82.8% 0.189 84.429);
|
|
15
18
|
--color-amber-500: oklch(76.9% 0.188 70.08);
|
|
16
19
|
--color-amber-600: oklch(66.6% 0.179 58.318);
|
|
20
|
+
--color-amber-700: oklch(55.5% 0.163 48.998);
|
|
21
|
+
--color-amber-800: oklch(47.3% 0.137 46.201);
|
|
17
22
|
--color-green-50: oklch(98.2% 0.018 155.826);
|
|
18
23
|
--color-green-200: oklch(92.5% 0.084 155.995);
|
|
19
24
|
--color-green-400: oklch(79.2% 0.209 151.711);
|
|
@@ -1211,6 +1216,9 @@
|
|
|
1211
1216
|
.border-amber {
|
|
1212
1217
|
border-color: var(--color-amber);
|
|
1213
1218
|
}
|
|
1219
|
+
.border-amber-300 {
|
|
1220
|
+
border-color: var(--color-amber-300);
|
|
1221
|
+
}
|
|
1214
1222
|
.border-amber-400\/50 {
|
|
1215
1223
|
border-color: color-mix(in srgb, oklch(82.8% 0.189 84.429) 50%, transparent);
|
|
1216
1224
|
@supports (color: color-mix(in lab, red, red)) {
|
|
@@ -1406,6 +1414,9 @@
|
|
|
1406
1414
|
.border-red-200 {
|
|
1407
1415
|
border-color: var(--color-red-200);
|
|
1408
1416
|
}
|
|
1417
|
+
.border-red-300 {
|
|
1418
|
+
border-color: var(--color-red-300);
|
|
1419
|
+
}
|
|
1409
1420
|
.border-red-400 {
|
|
1410
1421
|
border-color: var(--color-red-400);
|
|
1411
1422
|
}
|
|
@@ -1442,6 +1453,9 @@
|
|
|
1442
1453
|
.bg-amber {
|
|
1443
1454
|
background-color: var(--color-amber);
|
|
1444
1455
|
}
|
|
1456
|
+
.bg-amber-50 {
|
|
1457
|
+
background-color: var(--color-amber-50);
|
|
1458
|
+
}
|
|
1445
1459
|
.bg-amber-400\/15 {
|
|
1446
1460
|
background-color: color-mix(in srgb, oklch(82.8% 0.189 84.429) 15%, transparent);
|
|
1447
1461
|
@supports (color: color-mix(in lab, red, red)) {
|
|
@@ -1607,6 +1621,9 @@
|
|
|
1607
1621
|
background-color: color-mix(in oklab, var(--color-primary) 70%, transparent);
|
|
1608
1622
|
}
|
|
1609
1623
|
}
|
|
1624
|
+
.bg-red-50 {
|
|
1625
|
+
background-color: var(--color-red-50);
|
|
1626
|
+
}
|
|
1610
1627
|
.bg-red-500 {
|
|
1611
1628
|
background-color: var(--color-red-500);
|
|
1612
1629
|
}
|
|
@@ -2098,6 +2115,12 @@
|
|
|
2098
2115
|
.text-amber-600 {
|
|
2099
2116
|
color: var(--color-amber-600);
|
|
2100
2117
|
}
|
|
2118
|
+
.text-amber-700 {
|
|
2119
|
+
color: var(--color-amber-700);
|
|
2120
|
+
}
|
|
2121
|
+
.text-amber-800 {
|
|
2122
|
+
color: var(--color-amber-800);
|
|
2123
|
+
}
|
|
2101
2124
|
.text-amber\/80 {
|
|
2102
2125
|
color: color-mix(in srgb, #a66a2a 80%, transparent);
|
|
2103
2126
|
@supports (color: color-mix(in lab, red, red)) {
|
|
@@ -2170,6 +2193,9 @@
|
|
|
2170
2193
|
.text-red-600 {
|
|
2171
2194
|
color: var(--color-red-600);
|
|
2172
2195
|
}
|
|
2196
|
+
.text-red-700 {
|
|
2197
|
+
color: var(--color-red-700);
|
|
2198
|
+
}
|
|
2173
2199
|
.text-teal-600 {
|
|
2174
2200
|
color: var(--color-teal-600);
|
|
2175
2201
|
}
|