create-principles-disciple 1.100.0 → 1.102.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/console/dist/server/index.js +9 -0
- package/console/dist/server/models/ActivationsConsoleModel.d.ts +37 -1
- package/console/dist/server/models/ActivationsConsoleModel.js +114 -13
- package/console/dist/server/routes/onboarding.d.ts +34 -0
- package/console/dist/server/routes/onboarding.js +324 -0
- package/console/dist/ui/App.js +74 -15
- package/console/dist/ui/api.d.ts +17 -1
- package/console/dist/ui/api.js +6 -1
- package/console/dist/ui/components/onboarding/CircuitDiagram.d.ts +8 -0
- package/console/dist/ui/components/onboarding/CircuitDiagram.js +18 -0
- package/console/dist/ui/components/onboarding/DemoResultView.d.ts +22 -0
- package/console/dist/ui/components/onboarding/DemoResultView.js +15 -0
- package/console/dist/ui/i18n/en.json +127 -0
- package/console/dist/ui/i18n/zh-CN.json +127 -0
- package/console/dist/ui/pages/activation/ActivationValidators.js +1 -1
- package/console/dist/ui/pages/control-center/AgentCard.js +10 -3
- package/console/dist/ui/pages/control-center/ControlCenterPage.js +1 -1
- package/console/dist/ui/pages/settings/SettingsPage.js +64 -5
- package/console/dist/ui/pages/signal-keywords/KeywordEditDialog.d.ts +12 -0
- package/console/dist/ui/pages/signal-keywords/KeywordEditDialog.js +41 -0
- package/console/dist/ui/pages/signal-keywords/KeywordListSection.d.ts +10 -0
- package/console/dist/ui/pages/signal-keywords/KeywordListSection.js +39 -0
- package/console/dist/ui/pages/signal-keywords/PendingTermsSection.d.ts +14 -0
- package/console/dist/ui/pages/signal-keywords/PendingTermsSection.js +35 -0
- package/console/dist/ui/pages/signal-keywords/SignalKeywordsPage.d.ts +1 -0
- package/console/dist/ui/pages/signal-keywords/SignalKeywordsPage.js +49 -0
- package/console/dist/ui/pages/welcome/WelcomePage.d.ts +5 -0
- package/console/dist/ui/pages/welcome/WelcomePage.js +185 -0
- package/console/dist/ui/utils/__tests__/onboarding-state.test.d.ts +1 -0
- package/console/dist/ui/utils/__tests__/onboarding-state.test.js +72 -0
- package/console/dist/ui/utils/agent-metadata.d.ts +13 -0
- package/console/dist/ui/utils/agent-metadata.js +26 -0
- package/console/dist/ui/utils/onboarding-state.d.ts +25 -0
- package/console/dist/ui/utils/onboarding-state.js +77 -0
- package/console/dist/ui/utils/signal-keywords-api.d.ts +68 -0
- package/console/dist/ui/utils/signal-keywords-api.js +121 -0
- package/console/dist/ui/utils/signal-keywords-types.d.ts +57 -0
- package/console/dist/ui/utils/signal-keywords-types.js +10 -0
- package/console/dist/ui/utils/signal-keywords-validators.d.ts +20 -0
- package/console/dist/ui/utils/signal-keywords-validators.js +114 -0
- package/console/dist/web/assets/app.css +401 -0
- package/console/dist/web/assets/app.js +6904 -1835
- package/core/dist/index.d.ts +2 -0
- package/core/dist/index.d.ts.map +1 -1
- package/core/dist/index.js +1 -0
- package/core/dist/index.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/admission-gate.test.js +63 -1
- package/core/dist/runtime-v2/__tests__/admission-gate.test.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/architecture-regression.test.js +21 -5
- package/core/dist/runtime-v2/__tests__/architecture-regression.test.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/chain-integrity-attack.test.js +17 -0
- package/core/dist/runtime-v2/__tests__/chain-integrity-attack.test.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/chain-integrity-real-path.test.js +12 -0
- package/core/dist/runtime-v2/__tests__/chain-integrity-real-path.test.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/evaluator-runner-vslice-v2.test.js +28 -0
- package/core/dist/runtime-v2/__tests__/evaluator-runner-vslice-v2.test.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/internalization-chain-integrity-read-model.test.js +168 -1
- package/core/dist/runtime-v2/__tests__/internalization-chain-integrity-read-model.test.js.map +1 -1
- package/core/dist/runtime-v2/__tests__/pain-to-principle-service.test.js +8 -0
- package/core/dist/runtime-v2/__tests__/pain-to-principle-service.test.js.map +1 -1
- package/core/dist/runtime-v2/activation/__tests__/activation-dispatcher.test.js +53 -0
- package/core/dist/runtime-v2/activation/__tests__/activation-dispatcher.test.js.map +1 -1
- package/core/dist/runtime-v2/activation/__tests__/helpers.d.ts +21 -0
- package/core/dist/runtime-v2/activation/__tests__/helpers.d.ts.map +1 -0
- package/core/dist/runtime-v2/activation/__tests__/helpers.js +132 -0
- package/core/dist/runtime-v2/activation/__tests__/helpers.js.map +1 -0
- package/core/dist/runtime-v2/activation/__tests__/story-a-acceptance.test.js +2 -117
- package/core/dist/runtime-v2/activation/__tests__/story-a-acceptance.test.js.map +1 -1
- package/core/dist/runtime-v2/activation/activation-dispatcher.d.ts.map +1 -1
- package/core/dist/runtime-v2/activation/activation-dispatcher.js +18 -2
- package/core/dist/runtime-v2/activation/activation-dispatcher.js.map +1 -1
- package/core/dist/runtime-v2/activation/index.d.ts +1 -1
- package/core/dist/runtime-v2/activation/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/activation/index.js +1 -1
- package/core/dist/runtime-v2/activation/index.js.map +1 -1
- package/core/dist/runtime-v2/activation/writers/__tests__/rule-host-writer.test.js +253 -6
- package/core/dist/runtime-v2/activation/writers/__tests__/rule-host-writer.test.js.map +1 -1
- package/core/dist/runtime-v2/activation/writers/rule-host-writer.d.ts +12 -0
- package/core/dist/runtime-v2/activation/writers/rule-host-writer.d.ts.map +1 -1
- package/core/dist/runtime-v2/activation/writers/rule-host-writer.js +96 -2
- package/core/dist/runtime-v2/activation/writers/rule-host-writer.js.map +1 -1
- package/core/dist/runtime-v2/admission-gate.d.ts +27 -0
- package/core/dist/runtime-v2/admission-gate.d.ts.map +1 -1
- package/core/dist/runtime-v2/admission-gate.js +55 -0
- package/core/dist/runtime-v2/admission-gate.js.map +1 -1
- package/core/dist/runtime-v2/cli/diagnose.d.ts +4 -0
- package/core/dist/runtime-v2/cli/diagnose.d.ts.map +1 -1
- package/core/dist/runtime-v2/cli/diagnose.js +25 -0
- package/core/dist/runtime-v2/cli/diagnose.js.map +1 -1
- package/core/dist/runtime-v2/config/__tests__/internal-agent-names.test.d.ts +2 -0
- package/core/dist/runtime-v2/config/__tests__/internal-agent-names.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/config/__tests__/internal-agent-names.test.js +15 -0
- package/core/dist/runtime-v2/config/__tests__/internal-agent-names.test.js.map +1 -0
- package/core/dist/runtime-v2/config/__tests__/pd-config-agent-binding.test.js +7 -0
- 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 +28 -0
- package/core/dist/runtime-v2/config/__tests__/pd-config-contract.test.js.map +1 -1
- package/core/dist/runtime-v2/config/__tests__/pd-config-redaction-deep.test.js +1 -0
- package/core/dist/runtime-v2/config/__tests__/pd-config-redaction-deep.test.js.map +1 -1
- package/core/dist/runtime-v2/config/__tests__/pd-config-validation-edge-cases.test.js +1 -0
- package/core/dist/runtime-v2/config/__tests__/pd-config-validation-edge-cases.test.js.map +1 -1
- package/core/dist/runtime-v2/config/index.d.ts +5 -3
- package/core/dist/runtime-v2/config/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/config/index.js +8 -2
- package/core/dist/runtime-v2/config/index.js.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-defaults.d.ts +2 -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 +12 -0
- package/core/dist/runtime-v2/config/pd-config-defaults.js.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-effective.d.ts.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-effective.js +25 -1
- 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 +6 -1
- package/core/dist/runtime-v2/config/pd-config-feature-flags.js.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-redaction.d.ts.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-redaction.js +9 -0
- package/core/dist/runtime-v2/config/pd-config-redaction.js.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-types.d.ts +110 -1
- package/core/dist/runtime-v2/config/pd-config-types.d.ts.map +1 -1
- package/core/dist/runtime-v2/config/pd-config-types.js +7 -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 +114 -1
- package/core/dist/runtime-v2/config/pd-config-validate.js.map +1 -1
- package/core/dist/runtime-v2/config/pd-profile-constants.d.ts +27 -0
- package/core/dist/runtime-v2/config/pd-profile-constants.d.ts.map +1 -0
- package/core/dist/runtime-v2/config/pd-profile-constants.js +145 -0
- package/core/dist/runtime-v2/config/pd-profile-constants.js.map +1 -0
- package/core/dist/runtime-v2/config/pd-validate-profile.d.ts +28 -0
- package/core/dist/runtime-v2/config/pd-validate-profile.d.ts.map +1 -0
- package/core/dist/runtime-v2/config/pd-validate-profile.js +482 -0
- package/core/dist/runtime-v2/config/pd-validate-profile.js.map +1 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js +26 -0
- package/core/dist/runtime-v2/feature-flags/__tests__/feature-flag-contract.test.js.map +1 -1
- package/core/dist/runtime-v2/feature-flags/__tests__/plugin-surface-registry.test.js +12 -1
- package/core/dist/runtime-v2/feature-flags/__tests__/plugin-surface-registry.test.js.map +1 -1
- package/core/dist/runtime-v2/feature-flags/feature-flag-contract.d.ts.map +1 -1
- package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js +8 -0
- package/core/dist/runtime-v2/feature-flags/feature-flag-contract.js.map +1 -1
- package/core/dist/runtime-v2/feature-flags/plugin-surface-registry.d.ts.map +1 -1
- package/core/dist/runtime-v2/feature-flags/plugin-surface-registry.js +8 -2
- package/core/dist/runtime-v2/feature-flags/plugin-surface-registry.js.map +1 -1
- package/core/dist/runtime-v2/index.d.ts +6 -4
- package/core/dist/runtime-v2/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/index.js +5 -3
- package/core/dist/runtime-v2/index.js.map +1 -1
- package/core/dist/runtime-v2/internalization/__tests__/artificer-prompt-builder-v2.test.js +25 -0
- package/core/dist/runtime-v2/internalization/__tests__/artificer-prompt-builder-v2.test.js.map +1 -1
- package/core/dist/runtime-v2/internalization/__tests__/artificer-rule-output.test.js +139 -0
- package/core/dist/runtime-v2/internalization/__tests__/artificer-rule-output.test.js.map +1 -1
- package/core/dist/runtime-v2/internalization/__tests__/diag-chain-e2e.test.js +20 -1
- package/core/dist/runtime-v2/internalization/__tests__/diag-chain-e2e.test.js.map +1 -1
- package/core/dist/runtime-v2/internalization/__tests__/diag-rootcause-intent-tension.test.js +7 -0
- package/core/dist/runtime-v2/internalization/__tests__/diag-rootcause-intent-tension.test.js.map +1 -1
- package/core/dist/runtime-v2/internalization/__tests__/diag-rootcause-runner.test.js +21 -0
- package/core/dist/runtime-v2/internalization/__tests__/diag-rootcause-runner.test.js.map +1 -1
- package/core/dist/runtime-v2/internalization/__tests__/rule-host-input-builder.test.js +23 -0
- package/core/dist/runtime-v2/internalization/__tests__/rule-host-input-builder.test.js.map +1 -1
- package/core/dist/runtime-v2/internalization/artificer-output.d.ts +7 -0
- package/core/dist/runtime-v2/internalization/artificer-output.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/artificer-output.js +22 -1
- package/core/dist/runtime-v2/internalization/artificer-output.js.map +1 -1
- package/core/dist/runtime-v2/internalization/artificer-prompt-builder.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/artificer-prompt-builder.js +2 -0
- package/core/dist/runtime-v2/internalization/artificer-prompt-builder.js.map +1 -1
- package/core/dist/runtime-v2/internalization/artificer-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/artificer-runner.js +13 -0
- package/core/dist/runtime-v2/internalization/artificer-runner.js.map +1 -1
- package/core/dist/runtime-v2/internalization/diag-distiller-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/diag-distiller-runner.js +4 -1
- package/core/dist/runtime-v2/internalization/diag-distiller-runner.js.map +1 -1
- package/core/dist/runtime-v2/internalization/diag-rootcause-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/diag-rootcause-runner.js +7 -1
- package/core/dist/runtime-v2/internalization/diag-rootcause-runner.js.map +1 -1
- package/core/dist/runtime-v2/internalization/diag-router-runner.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/diag-router-runner.js +4 -1
- package/core/dist/runtime-v2/internalization/diag-router-runner.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 +7 -1
- package/core/dist/runtime-v2/internalization/evaluator-runner.js.map +1 -1
- package/core/dist/runtime-v2/internalization/index.d.ts +1 -1
- package/core/dist/runtime-v2/internalization/index.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/index.js +1 -1
- package/core/dist/runtime-v2/internalization/index.js.map +1 -1
- package/core/dist/runtime-v2/internalization/internalization-task-guards.d.ts +7 -0
- package/core/dist/runtime-v2/internalization/internalization-task-guards.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization/internalization-task-guards.js +8 -0
- package/core/dist/runtime-v2/internalization/internalization-task-guards.js.map +1 -1
- package/core/dist/runtime-v2/internalization-chain-integrity-read-model.d.ts.map +1 -1
- package/core/dist/runtime-v2/internalization-chain-integrity-read-model.js +57 -1
- package/core/dist/runtime-v2/internalization-chain-integrity-read-model.js.map +1 -1
- package/core/dist/runtime-v2/proven-channel-baseline.js +1 -1
- package/core/dist/runtime-v2/proven-channel-baseline.js.map +1 -1
- package/core/dist/runtime-v2/runner/__tests__/diagnose.test.js +91 -1
- package/core/dist/runtime-v2/runner/__tests__/diagnose.test.js.map +1 -1
- package/core/dist/runtime-v2/signal-collector/__tests__/keyword-stage.test.d.ts +2 -0
- package/core/dist/runtime-v2/signal-collector/__tests__/keyword-stage.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/signal-collector/__tests__/keyword-stage.test.js +39 -0
- package/core/dist/runtime-v2/signal-collector/__tests__/keyword-stage.test.js.map +1 -0
- package/core/dist/runtime-v2/signal-collector/__tests__/llm-stage.test.d.ts +2 -0
- package/core/dist/runtime-v2/signal-collector/__tests__/llm-stage.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/signal-collector/__tests__/llm-stage.test.js +34 -0
- package/core/dist/runtime-v2/signal-collector/__tests__/llm-stage.test.js.map +1 -0
- package/core/dist/runtime-v2/signal-collector/__tests__/signal-collector.test.d.ts +2 -0
- package/core/dist/runtime-v2/signal-collector/__tests__/signal-collector.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/signal-collector/__tests__/signal-collector.test.js +222 -0
- package/core/dist/runtime-v2/signal-collector/__tests__/signal-collector.test.js.map +1 -0
- package/core/dist/runtime-v2/signal-collector/__tests__/types.test.d.ts +2 -0
- package/core/dist/runtime-v2/signal-collector/__tests__/types.test.d.ts.map +1 -0
- package/core/dist/runtime-v2/signal-collector/__tests__/types.test.js +35 -0
- package/core/dist/runtime-v2/signal-collector/__tests__/types.test.js.map +1 -0
- package/core/dist/runtime-v2/signal-collector/index.d.ts +5 -0
- package/core/dist/runtime-v2/signal-collector/index.d.ts.map +1 -0
- package/core/dist/runtime-v2/signal-collector/index.js +5 -0
- package/core/dist/runtime-v2/signal-collector/index.js.map +1 -0
- package/core/dist/runtime-v2/signal-collector/keyword-stage.d.ts +20 -0
- package/core/dist/runtime-v2/signal-collector/keyword-stage.d.ts.map +1 -0
- package/core/dist/runtime-v2/signal-collector/keyword-stage.js +61 -0
- package/core/dist/runtime-v2/signal-collector/keyword-stage.js.map +1 -0
- package/core/dist/runtime-v2/signal-collector/llm-stage.d.ts +16 -0
- package/core/dist/runtime-v2/signal-collector/llm-stage.d.ts.map +1 -0
- package/core/dist/runtime-v2/signal-collector/llm-stage.js +34 -0
- package/core/dist/runtime-v2/signal-collector/llm-stage.js.map +1 -0
- package/core/dist/runtime-v2/signal-collector/signal-collector.d.ts +16 -0
- package/core/dist/runtime-v2/signal-collector/signal-collector.d.ts.map +1 -0
- package/core/dist/runtime-v2/signal-collector/signal-collector.js +71 -0
- package/core/dist/runtime-v2/signal-collector/signal-collector.js.map +1 -0
- package/core/dist/runtime-v2/signal-collector/types.d.ts +61 -0
- package/core/dist/runtime-v2/signal-collector/types.d.ts.map +1 -0
- package/core/dist/runtime-v2/signal-collector/types.js +45 -0
- package/core/dist/runtime-v2/signal-collector/types.js.map +1 -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 +19 -0
- package/core/dist/runtime-v2/store/candidate/sqlite-candidate-store.js.map +1 -1
- package/core/dist/runtime-v2/store/schema-conformance.test.js +73 -0
- package/core/dist/runtime-v2/store/schema-conformance.test.js.map +1 -1
- package/core/dist/runtime-v2/store/sqlite-connection-schema-version.test.js +41 -7
- package/core/dist/runtime-v2/store/sqlite-connection-schema-version.test.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 +22 -1
- package/core/dist/runtime-v2/store/sqlite-connection.js.map +1 -1
- package/core/dist/runtime-v2/types/event-types.d.ts +40 -3
- package/core/dist/runtime-v2/types/event-types.d.ts.map +1 -1
- package/core/dist/runtime-v2/types/event-types.js +9 -0
- package/core/dist/runtime-v2/types/event-types.js.map +1 -1
- package/core/dist/runtime-v2/types/index.d.ts +2 -2
- 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/workflow-funnel-loader.js +1 -1
- package/core/dist/workflow-funnel-loader.js.map +1 -1
- package/dist/i18n.d.ts.map +1 -1
- package/dist/i18n.js +6 -0
- package/dist/i18n.js.map +1 -1
- package/dist/index.js +12 -3
- package/dist/index.js.map +1 -1
- package/dist/installer.d.ts +3 -0
- package/dist/installer.d.ts.map +1 -1
- package/dist/installer.js +167 -1
- package/dist/installer.js.map +1 -1
- package/dist/mvp-config.d.ts +8 -0
- package/dist/mvp-config.d.ts.map +1 -1
- package/dist/mvp-config.js +12 -2
- package/dist/mvp-config.js.map +1 -1
- package/package.json +1 -1
- package/pd-cli/dist/commands/candidate.d.ts.map +1 -1
- package/pd-cli/dist/commands/candidate.js +89 -7
- package/pd-cli/dist/commands/candidate.js.map +1 -1
- package/pd-cli/dist/commands/pain-retry.d.ts +3 -0
- package/pd-cli/dist/commands/pain-retry.d.ts.map +1 -1
- package/pd-cli/dist/commands/pain-retry.js +39 -14
- package/pd-cli/dist/commands/pain-retry.js.map +1 -1
- package/pd-cli/dist/commands/runtime-activation.d.ts +4 -0
- package/pd-cli/dist/commands/runtime-activation.d.ts.map +1 -1
- package/pd-cli/dist/commands/runtime-activation.js +244 -10
- package/pd-cli/dist/commands/runtime-activation.js.map +1 -1
- package/pd-cli/dist/index.js +7 -84
- package/pd-cli/dist/index.js.map +1 -1
- package/pd-cli/dist/services/rulehost-pipeline-runner.js +1 -1
- package/pd-cli/dist/services/rulehost-pipeline-runner.js.map +1 -1
- package/pd-cli/package.json +1 -1
- package/plugin/dist/commands/context.js +17 -11
- package/plugin/dist/commands/samples.js +25 -0
- package/plugin/dist/core/event-log.d.ts +11 -1
- package/plugin/dist/core/event-log.js +13 -0
- package/plugin/dist/core/init.js +3 -4
- package/plugin/dist/core/rule-host.d.ts +68 -0
- package/plugin/dist/core/rule-host.js +167 -28
- package/plugin/dist/core/signal-collector-host.d.ts +105 -0
- package/plugin/dist/core/signal-collector-host.js +337 -0
- package/plugin/dist/hooks/prompt.d.ts +3 -2
- package/plugin/dist/hooks/prompt.js +47 -571
- package/plugin/dist/types/event-types.d.ts +1 -1
- package/plugin/dist/types.d.ts +5 -25
- package/plugin/dist/types.js +4 -9
- package/plugin/dist/utils/hashing.js +1 -1
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useState, useEffect, useCallback, useRef } from 'react';
|
|
3
|
+
import { useNavigate } from 'react-router-dom';
|
|
4
|
+
import { useTranslation } from 'react-i18next';
|
|
5
|
+
import { CircuitDiagram } from '../../components/onboarding/CircuitDiagram.js';
|
|
6
|
+
import { DemoResultView } from '../../components/onboarding/DemoResultView.js';
|
|
7
|
+
import { getOnboardingState, setOnboardingState } from '../../utils/onboarding-state.js';
|
|
8
|
+
import { request } from '../../api.js';
|
|
9
|
+
// Polling configuration for step 3 evidence detection (spec 6.5.2).
|
|
10
|
+
const TWO_HOURS_MS = 2 * 60 * 60 * 1000;
|
|
11
|
+
const POLL_INTERVAL_MS = 30 * 1000;
|
|
12
|
+
// rc-1/rc-2/rc-4: validate the demo response shape before use.
|
|
13
|
+
// The backend owns this shape, but parsed JSON is treated as unknown.
|
|
14
|
+
function isDemoStage(value) {
|
|
15
|
+
if (typeof value !== 'object' || value === null)
|
|
16
|
+
return false;
|
|
17
|
+
const name = Object.hasOwn(value, 'name') ? Reflect.get(value, 'name') : undefined;
|
|
18
|
+
const status = Object.hasOwn(value, 'status') ? Reflect.get(value, 'status') : undefined;
|
|
19
|
+
if (typeof name !== 'string')
|
|
20
|
+
return false;
|
|
21
|
+
return status === 'passed' || status === 'failed' || status === 'degraded' || status === 'skipped';
|
|
22
|
+
}
|
|
23
|
+
function parseDemoResponse(value) {
|
|
24
|
+
if (typeof value !== 'object' || value === null)
|
|
25
|
+
return null;
|
|
26
|
+
const v = value;
|
|
27
|
+
if (typeof v.simulated !== 'boolean')
|
|
28
|
+
return null;
|
|
29
|
+
if (typeof v.demo !== 'object' || v.demo === null)
|
|
30
|
+
return null;
|
|
31
|
+
const d = v.demo;
|
|
32
|
+
if (typeof d.status !== 'string')
|
|
33
|
+
return null;
|
|
34
|
+
const demo = { status: d.status };
|
|
35
|
+
if (typeof d.generatedAt === 'string')
|
|
36
|
+
demo.generatedAt = d.generatedAt;
|
|
37
|
+
if (typeof d.narrative === 'string')
|
|
38
|
+
demo.narrative = d.narrative;
|
|
39
|
+
if (typeof d.storyDescription === 'string')
|
|
40
|
+
demo.storyDescription = d.storyDescription;
|
|
41
|
+
if (typeof d.simulated === 'boolean')
|
|
42
|
+
demo.simulated = d.simulated;
|
|
43
|
+
if (Object.hasOwn(d, 'stages')) {
|
|
44
|
+
if (!Array.isArray(d.stages) || !d.stages.every(isDemoStage))
|
|
45
|
+
return null;
|
|
46
|
+
demo.stages = d.stages;
|
|
47
|
+
}
|
|
48
|
+
return { demo, simulated: v.simulated };
|
|
49
|
+
}
|
|
50
|
+
export function WelcomePage({ workspaceId }) {
|
|
51
|
+
const { t } = useTranslation();
|
|
52
|
+
const navigate = useNavigate();
|
|
53
|
+
const [step, setStep] = useState(1);
|
|
54
|
+
const [demoStatus, setDemoStatus] = useState('idle');
|
|
55
|
+
const [demoResult, setDemoResult] = useState(null);
|
|
56
|
+
const [demoError, setDemoError] = useState(null);
|
|
57
|
+
const [stateError, setStateError] = useState(null);
|
|
58
|
+
const [pollingActive, setPollingActive] = useState(false);
|
|
59
|
+
const [pollingStatus, setPollingStatus] = useState('idle');
|
|
60
|
+
const [pollingError, setPollingError] = useState(null);
|
|
61
|
+
// Refs for polling cleanup (spec 6.5.2 test case 3: unmount clears timers).
|
|
62
|
+
const pollingIntervalRef = useRef(null);
|
|
63
|
+
const pollingTimeoutRef = useRef(null);
|
|
64
|
+
// P2-2B: track consecutive polling errors; after 3, stop polling and surface
|
|
65
|
+
// the failure (rc-9: no silent fallback). Reset to 0 on any successful poll.
|
|
66
|
+
const errorCountRef = useRef(0);
|
|
67
|
+
// P2-3: baseline record count captured when polling starts, so we only
|
|
68
|
+
// trigger evidence-found on NEW evidence (not pre-existing records).
|
|
69
|
+
const baselineCountRef = useRef(0);
|
|
70
|
+
// If onboarding was already completed for this workspace, skip the wizard.
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
const state = getOnboardingState(workspaceId);
|
|
73
|
+
if (state.completed) {
|
|
74
|
+
navigate('/focus', { replace: true });
|
|
75
|
+
}
|
|
76
|
+
}, [workspaceId, navigate]);
|
|
77
|
+
const completeOnboarding = useCallback((status) => {
|
|
78
|
+
if (!setOnboardingState(workspaceId, {
|
|
79
|
+
completed: true,
|
|
80
|
+
step: 3,
|
|
81
|
+
status,
|
|
82
|
+
completedAt: new Date().toISOString(),
|
|
83
|
+
})) {
|
|
84
|
+
setStateError(t('pages.welcome.stateSaveError'));
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
navigate('/focus', { replace: true });
|
|
88
|
+
}, [workspaceId, navigate, t]);
|
|
89
|
+
const runDemo = useCallback(async () => {
|
|
90
|
+
setDemoStatus('loading');
|
|
91
|
+
setDemoError(null);
|
|
92
|
+
try {
|
|
93
|
+
const response = await request('/api/v1/onboarding/run-demo', { method: 'POST' }, parseDemoResponse);
|
|
94
|
+
if (!response.success) {
|
|
95
|
+
throw new Error(response.error);
|
|
96
|
+
}
|
|
97
|
+
setDemoResult(response.data.demo);
|
|
98
|
+
setDemoStatus('success');
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
const message = err instanceof Error ? err.message : 'Demo failed to start';
|
|
102
|
+
setDemoError(message);
|
|
103
|
+
setDemoStatus('error');
|
|
104
|
+
}
|
|
105
|
+
}, []);
|
|
106
|
+
const skipOnboarding = useCallback(() => {
|
|
107
|
+
completeOnboarding('skipped');
|
|
108
|
+
}, [completeOnboarding]);
|
|
109
|
+
// EP-05 (Loop State Freshness): each poll fetches fresh evidence.
|
|
110
|
+
const stopPolling = useCallback(() => {
|
|
111
|
+
setPollingActive(false);
|
|
112
|
+
if (pollingIntervalRef.current) {
|
|
113
|
+
clearInterval(pollingIntervalRef.current);
|
|
114
|
+
pollingIntervalRef.current = null;
|
|
115
|
+
}
|
|
116
|
+
if (pollingTimeoutRef.current) {
|
|
117
|
+
clearTimeout(pollingTimeoutRef.current);
|
|
118
|
+
pollingTimeoutRef.current = null;
|
|
119
|
+
}
|
|
120
|
+
}, []);
|
|
121
|
+
const startPolling = useCallback(() => {
|
|
122
|
+
setPollingActive(true);
|
|
123
|
+
setPollingStatus('polling');
|
|
124
|
+
setPollingError(null);
|
|
125
|
+
errorCountRef.current = 0;
|
|
126
|
+
pollingTimeoutRef.current = setTimeout(() => {
|
|
127
|
+
setPollingStatus('timeout');
|
|
128
|
+
stopPolling();
|
|
129
|
+
}, TWO_HOURS_MS);
|
|
130
|
+
// P2-3: capture baseline count on first poll, then only trigger
|
|
131
|
+
// evidence-found when count exceeds baseline (NEW evidence appeared).
|
|
132
|
+
let baselineCaptured = false;
|
|
133
|
+
const checkForEvidence = async () => {
|
|
134
|
+
try {
|
|
135
|
+
const response = await request('/api/v1/evidence-chain');
|
|
136
|
+
// P2-A: request() returns { success: false, error } on HTTP/network
|
|
137
|
+
// errors instead of throwing. Convert non-success into a thrown error
|
|
138
|
+
// so the catch block (error counter + retry UI) actually fires.
|
|
139
|
+
if (!response.success) {
|
|
140
|
+
throw new Error(response.error || 'Failed to fetch evidence');
|
|
141
|
+
}
|
|
142
|
+
if (response.data) {
|
|
143
|
+
const data = response.data;
|
|
144
|
+
if (typeof data === 'object' && data !== null && Object.hasOwn(data, 'records')) {
|
|
145
|
+
const records = data.records;
|
|
146
|
+
if (Array.isArray(records)) {
|
|
147
|
+
// P2-2B: a successful poll with valid data resets the error streak.
|
|
148
|
+
errorCountRef.current = 0;
|
|
149
|
+
if (!baselineCaptured) {
|
|
150
|
+
// First poll: capture baseline count, do not trigger.
|
|
151
|
+
baselineCountRef.current = records.length;
|
|
152
|
+
baselineCaptured = true;
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
if (records.length > baselineCountRef.current) {
|
|
156
|
+
setPollingStatus('evidence-found');
|
|
157
|
+
stopPolling();
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
// P2-2B (rc-9: no silent fallback) — surface the failure instead of
|
|
165
|
+
// swallowing it. After 3 consecutive errors, stop polling and show the
|
|
166
|
+
// error UI so the user can retry rather than waiting up to 2 hours.
|
|
167
|
+
errorCountRef.current += 1;
|
|
168
|
+
setPollingError(t('pages.welcome.step3.pollingError'));
|
|
169
|
+
if (errorCountRef.current >= 3) {
|
|
170
|
+
setPollingStatus('error');
|
|
171
|
+
stopPolling();
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
checkForEvidence();
|
|
176
|
+
pollingIntervalRef.current = setInterval(checkForEvidence, POLL_INTERVAL_MS);
|
|
177
|
+
}, [stopPolling, t]);
|
|
178
|
+
// Cleanup on unmount (spec 6.5.2 test case 3: no memory leak).
|
|
179
|
+
useEffect(() => {
|
|
180
|
+
return () => {
|
|
181
|
+
stopPolling();
|
|
182
|
+
};
|
|
183
|
+
}, [stopPolling]);
|
|
184
|
+
return (_jsxs("div", { className: "welcome-page", role: "main", children: [_jsxs("header", { className: "welcome-header", children: [_jsx("h1", { children: t('pages.welcome.title') }), _jsx("p", { className: "welcome-subtitle", children: t('pages.welcome.subtitle') }), _jsx("div", { className: "welcome-step-indicator", role: "progressbar", "aria-valuetext": t('pages.welcome.stepIndicator', { current: step, total: 3 }), children: [1, 2, 3].map((s) => (_jsx("span", { className: `step-dot ${s === step ? 'active' : ''} ${s < step ? 'completed' : ''}` }, s))) })] }), stateError && _jsx("p", { className: "polling-error", role: "alert", children: stateError }), step === 1 && (_jsxs("section", { className: "welcome-step welcome-step-1", "aria-labelledby": "step1-title", children: [_jsx("h2", { id: "step1-title", children: t('pages.welcome.step1.title') }), _jsx("p", { children: t('pages.welcome.step1.description') }), _jsx(CircuitDiagram, {}), _jsxs("div", { className: "welcome-actions", children: [_jsx("button", { className: "pd-btn pd-btn-brand", onClick: () => setStep(2), children: t('pages.welcome.step1.startButton') }), _jsx("button", { className: "pd-btn pd-btn-alt", onClick: skipOnboarding, children: t('pages.welcome.step1.skipButton') })] })] })), step === 2 && (_jsxs("section", { className: "welcome-step welcome-step-2", "aria-labelledby": "step2-title", children: [_jsx("h2", { id: "step2-title", children: t('pages.welcome.step2.title') }), _jsx("p", { children: t('pages.welcome.step2.description') }), _jsx(DemoResultView, { result: demoResult, loading: demoStatus === 'loading', error: demoError }), _jsxs("div", { className: "welcome-actions", children: [demoStatus === 'idle' && (_jsx("button", { className: "pd-btn pd-btn-brand", onClick: runDemo, children: t('pages.welcome.step2.runDemoButton') })), (demoStatus === 'success' || demoStatus === 'error') && (_jsx("button", { className: "pd-btn pd-btn-alt", onClick: () => setStep(3), children: t('pages.welcome.step2.nextButton') }))] })] })), step === 3 && (_jsxs("section", { className: "welcome-step welcome-step-3", "aria-labelledby": "step3-title", children: [_jsx("h2", { id: "step3-title", children: t('pages.welcome.step3.title') }), _jsx("p", { children: t('pages.welcome.step3.description') }), _jsxs("div", { className: "example-prompt", role: "note", children: [_jsx("span", { className: "prompt-label", children: t('pages.welcome.step3.examplePrompt') }), _jsx("code", { className: "prompt-text", children: t('pages.welcome.step3.examplePromptText') })] }), pollingStatus === 'idle' && (_jsxs(_Fragment, { children: [_jsx("p", { className: "window-hint", children: t('pages.welcome.step3.windowHint') }), _jsxs("div", { className: "welcome-actions", children: [_jsx("button", { className: "pd-btn pd-btn-brand", onClick: () => { startPolling(); }, children: t('pages.welcome.step3.tryNowButton') }), _jsx("button", { className: "pd-btn pd-btn-alt", onClick: () => completeOnboarding('demo'), children: t('pages.welcome.step3.goToFocusButton') }), _jsx("button", { className: "pd-btn pd-btn-alt", onClick: skipOnboarding, children: t('pages.welcome.step3.skipButton') })] })] })), pollingStatus === 'polling' && (_jsxs("div", { className: "polling-active", role: "status", "aria-live": "polite", children: [_jsx("p", { children: t('pages.welcome.step3.pollingActive') }), _jsx("button", { className: "pd-btn pd-btn-alt", onClick: () => { stopPolling(); completeOnboarding('demo'); }, children: t('pages.welcome.step3.stopPollingButton') })] })), pollingStatus === 'evidence-found' && (_jsxs("div", { className: "polling-success", role: "status", children: [_jsx("p", { children: t('pages.welcome.step3.evidenceFound') }), _jsx("button", { className: "pd-btn pd-btn-brand", onClick: () => completeOnboarding('evidence_found'), children: t('pages.welcome.step3.goToFocusButton') })] })), pollingStatus === 'timeout' && (_jsxs("div", { className: "polling-timeout", role: "status", children: [_jsx("p", { children: t('pages.welcome.step3.timeoutHint') }), _jsx("button", { className: "pd-btn pd-btn-brand", onClick: () => completeOnboarding('demo'), children: t('pages.welcome.step3.goToFocusButton') }), _jsx("button", { className: "pd-btn pd-btn-alt", onClick: skipOnboarding, children: t('pages.welcome.step3.skipButton') })] })), pollingStatus === 'error' && (_jsxs("div", { className: "polling-error", role: "alert", children: [_jsx("p", { children: pollingError ?? t('pages.welcome.step3.pollingError') }), _jsxs("div", { className: "welcome-actions", children: [_jsx("button", { className: "pd-btn pd-btn-brand", onClick: () => { startPolling(); }, children: t('pages.welcome.step3.retryButton') }), _jsx("button", { className: "pd-btn pd-btn-alt", onClick: () => completeOnboarding('demo'), children: t('pages.welcome.step3.goToFocusButton') })] })] }))] }))] }));
|
|
185
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
2
|
+
// Mock localStorage
|
|
3
|
+
const localStorageMock = (() => {
|
|
4
|
+
let store = {};
|
|
5
|
+
return {
|
|
6
|
+
getItem: vi.fn((key) => store[key] ?? null),
|
|
7
|
+
setItem: vi.fn((key, value) => { store[key] = value; }),
|
|
8
|
+
removeItem: vi.fn((key) => { delete store[key]; }),
|
|
9
|
+
clear: vi.fn(() => { store = {}; }),
|
|
10
|
+
};
|
|
11
|
+
})();
|
|
12
|
+
Object.defineProperty(globalThis, 'localStorage', { value: localStorageMock });
|
|
13
|
+
import { getOnboardingState, setOnboardingState, resetOnboardingState, ONBOARDING_STORAGE_KEY_PREFIX } from '../onboarding-state.js';
|
|
14
|
+
describe('Onboarding state with workspaceId dimension', () => {
|
|
15
|
+
beforeEach(() => {
|
|
16
|
+
localStorageMock.clear();
|
|
17
|
+
localStorageMock.getItem.mockClear();
|
|
18
|
+
localStorageMock.setItem.mockClear();
|
|
19
|
+
localStorageMock.removeItem.mockClear();
|
|
20
|
+
});
|
|
21
|
+
it('reports write and reset failures so callers cannot show false success', () => {
|
|
22
|
+
localStorageMock.setItem.mockImplementationOnce(() => { throw new Error('quota'); });
|
|
23
|
+
expect(setOnboardingState('ws-full', { completed: true, step: 3, status: 'demo' })).toBe(false);
|
|
24
|
+
localStorageMock.removeItem.mockImplementationOnce(() => { throw new Error('blocked'); });
|
|
25
|
+
expect(resetOnboardingState('ws-full')).toBe(false);
|
|
26
|
+
});
|
|
27
|
+
it('Given new workspace, When getOnboardingState called, Then returns default incomplete state', () => {
|
|
28
|
+
const state = getOnboardingState('ws-123');
|
|
29
|
+
expect(state.completed).toBe(false);
|
|
30
|
+
expect(state.step).toBe(0);
|
|
31
|
+
expect(state.status).toBe('pending');
|
|
32
|
+
});
|
|
33
|
+
it('Given onboarding completed, When setOnboardingState called with demo status, Then state persisted with workspaceId key', () => {
|
|
34
|
+
setOnboardingState('ws-123', { completed: true, step: 3, status: 'demo' });
|
|
35
|
+
const state = getOnboardingState('ws-123');
|
|
36
|
+
expect(state.completed).toBe(true);
|
|
37
|
+
expect(state.status).toBe('demo');
|
|
38
|
+
expect(state.step).toBe(3);
|
|
39
|
+
});
|
|
40
|
+
it('Given two workspaces, When state set for ws-A, Then ws-B state is independent (no cross-workspace leakage)', () => {
|
|
41
|
+
setOnboardingState('ws-A', { completed: true, step: 3, status: 'demo' });
|
|
42
|
+
const stateB = getOnboardingState('ws-B');
|
|
43
|
+
expect(stateB.completed).toBe(false);
|
|
44
|
+
expect(stateB.status).toBe('pending');
|
|
45
|
+
});
|
|
46
|
+
it('Given completed onboarding, When resetOnboardingState called, Then state returns to default', () => {
|
|
47
|
+
setOnboardingState('ws-123', { completed: true, step: 3, status: 'skipped' });
|
|
48
|
+
resetOnboardingState('ws-123');
|
|
49
|
+
const state = getOnboardingState('ws-123');
|
|
50
|
+
expect(state.completed).toBe(false);
|
|
51
|
+
expect(state.step).toBe(0);
|
|
52
|
+
expect(state.status).toBe('pending');
|
|
53
|
+
});
|
|
54
|
+
it('Given malformed localStorage data, When getOnboardingState called, Then returns safe default (rc-1 treat as unknown)', () => {
|
|
55
|
+
localStorageMock.getItem.mockReturnValueOnce('not-json');
|
|
56
|
+
const state = getOnboardingState('ws-broken');
|
|
57
|
+
expect(state.completed).toBe(false);
|
|
58
|
+
expect(state.status).toBe('pending');
|
|
59
|
+
});
|
|
60
|
+
it('Given non-string completedAt, When state is loaded, Then rejects the malformed contract', () => {
|
|
61
|
+
localStorageMock.getItem.mockReturnValueOnce(JSON.stringify({
|
|
62
|
+
completed: true, step: 3, status: 'evidence_found', completedAt: 123,
|
|
63
|
+
}));
|
|
64
|
+
expect(getOnboardingState('ws-invalid-date')).toEqual({
|
|
65
|
+
completed: false, step: 0, status: 'pending',
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
it('Given localStorage key prefix, Then key format is pd_onboarding_<workspaceId>', () => {
|
|
69
|
+
setOnboardingState('ws-123', { completed: true, step: 3, status: 'demo' });
|
|
70
|
+
expect(localStorageMock.setItem).toHaveBeenCalledWith(`${ONBOARDING_STORAGE_KEY_PREFIX}_ws-123`, expect.any(String));
|
|
71
|
+
});
|
|
72
|
+
});
|
|
@@ -42,6 +42,19 @@ export interface AgentMeta {
|
|
|
42
42
|
/** MVP 状态说明(可选,仅 philosopher/rolloutReviewer 有) */
|
|
43
43
|
mvpNoteZh?: string;
|
|
44
44
|
mvpNoteEn?: string;
|
|
45
|
+
/** 操作入口(可选,仅侧链代理用于跳转管理页面) */
|
|
46
|
+
action?: ActionMeta;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* 操作入口(可选,仅侧链代理用于跳转管理页面)
|
|
50
|
+
*/
|
|
51
|
+
export interface ActionMeta {
|
|
52
|
+
/** 链接文本(中) */
|
|
53
|
+
linkTextZh: string;
|
|
54
|
+
/** 链接文本(英) */
|
|
55
|
+
linkTextEn: string;
|
|
56
|
+
/** 路由路径 */
|
|
57
|
+
to: string;
|
|
45
58
|
}
|
|
46
59
|
export interface AgentGroupMeta {
|
|
47
60
|
id: AgentGroup;
|
|
@@ -255,6 +255,11 @@ export const AGENT_METADATA = {
|
|
|
255
255
|
techDetailZh: {},
|
|
256
256
|
techDetailEn: {},
|
|
257
257
|
isCore: true,
|
|
258
|
+
action: {
|
|
259
|
+
linkTextZh: '管理关键词',
|
|
260
|
+
linkTextEn: 'Manage Keywords',
|
|
261
|
+
to: '/control-center/signal-keywords?category=correction',
|
|
262
|
+
},
|
|
258
263
|
},
|
|
259
264
|
empathyObserver: {
|
|
260
265
|
name: 'empathyObserver',
|
|
@@ -271,5 +276,26 @@ export const AGENT_METADATA = {
|
|
|
271
276
|
techDetailZh: {},
|
|
272
277
|
techDetailEn: {},
|
|
273
278
|
isCore: true,
|
|
279
|
+
action: {
|
|
280
|
+
linkTextZh: '管理关键词',
|
|
281
|
+
linkTextEn: 'Manage Keywords',
|
|
282
|
+
to: '/control-center/signal-keywords?category=empathy',
|
|
283
|
+
},
|
|
284
|
+
},
|
|
285
|
+
signalCollector: {
|
|
286
|
+
name: 'signalCollector',
|
|
287
|
+
group: 'sidechain',
|
|
288
|
+
displayNameZh: '信号采集器',
|
|
289
|
+
displayNameEn: 'Signal Collector',
|
|
290
|
+
roleZh: '统一捕捉用户纠正与情绪反馈(合并原 correction + empathy)',
|
|
291
|
+
roleEn: 'Unified capture of user corrections and emotional feedback (merges former correction + empathy)',
|
|
292
|
+
detailZh: '以前有两套并行的用户反馈检测:correction(抓"你错了")和 empathy(抓情绪挫败),词库重叠且各自维护。\n\n信号采集器把两者合并成一套:关键词快扫 + 本地 LLM 深度判断,按信号强度分流——明确纠错直接触发诊断,情绪推测走 GFI 累积。',
|
|
293
|
+
detailEn: 'Previously there were two parallel user-feedback detectors: correction (catching "you are wrong") and empathy (catching emotional frustration), with overlapping keyword stores maintained separately.\n\nThe Signal Collector merges them into one: keyword fast-scan + local LLM deep judgment, routed by signal strength — explicit corrections trigger diagnosis directly, emotional inference accumulates via GFI.',
|
|
294
|
+
impactLevel: 'amber',
|
|
295
|
+
impactZh: '退回纯关键词检测(高精度短语仍工作),LLM 深度判断关闭。歧义词和未命中场景召回率下降。',
|
|
296
|
+
impactEn: 'Falls back to keyword-only detection (high-precision phrases still work); LLM deep judgment disabled. Recall drops for ambiguous terms and missed cases.',
|
|
297
|
+
techDetailZh: {},
|
|
298
|
+
techDetailEn: {},
|
|
299
|
+
isCore: false,
|
|
274
300
|
},
|
|
275
301
|
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Onboarding state persistence with workspaceId dimension.
|
|
3
|
+
* Prevents cross-workspace state leakage (spec §6.3 改动 1).
|
|
4
|
+
* localStorage is the single source of truth (no cross-device sync — YAGNI).
|
|
5
|
+
*/
|
|
6
|
+
export interface OnboardingState {
|
|
7
|
+
completed: boolean;
|
|
8
|
+
step: number;
|
|
9
|
+
status: 'pending' | 'demo' | 'skipped' | 'evidence_found';
|
|
10
|
+
completedAt?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare const ONBOARDING_STORAGE_KEY_PREFIX = "pd_onboarding";
|
|
13
|
+
/**
|
|
14
|
+
* Get onboarding state for a specific workspace.
|
|
15
|
+
* Treats localStorage data as unknown (rc-1) — validates shape before use.
|
|
16
|
+
*/
|
|
17
|
+
export declare function getOnboardingState(workspaceId: string): OnboardingState;
|
|
18
|
+
/**
|
|
19
|
+
* Set onboarding state for a specific workspace.
|
|
20
|
+
*/
|
|
21
|
+
export declare function setOnboardingState(workspaceId: string, state: OnboardingState): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Reset onboarding state for a specific workspace (Settings page "reset" button).
|
|
24
|
+
*/
|
|
25
|
+
export declare function resetOnboardingState(workspaceId: string): boolean;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Onboarding state persistence with workspaceId dimension.
|
|
3
|
+
* Prevents cross-workspace state leakage (spec §6.3 改动 1).
|
|
4
|
+
* localStorage is the single source of truth (no cross-device sync — YAGNI).
|
|
5
|
+
*/
|
|
6
|
+
const DEFAULT_STATE = {
|
|
7
|
+
completed: false,
|
|
8
|
+
step: 0,
|
|
9
|
+
status: 'pending',
|
|
10
|
+
};
|
|
11
|
+
export const ONBOARDING_STORAGE_KEY_PREFIX = 'pd_onboarding';
|
|
12
|
+
function storageKey(workspaceId) {
|
|
13
|
+
return `${ONBOARDING_STORAGE_KEY_PREFIX}_${workspaceId}`;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Type guard for OnboardingState (rc-2: no `as` bypass).
|
|
17
|
+
*/
|
|
18
|
+
function isOnboardingState(value) {
|
|
19
|
+
if (typeof value !== 'object' || value === null)
|
|
20
|
+
return false;
|
|
21
|
+
const completed = Object.hasOwn(value, 'completed') ? Reflect.get(value, 'completed') : undefined;
|
|
22
|
+
const step = Object.hasOwn(value, 'step') ? Reflect.get(value, 'step') : undefined;
|
|
23
|
+
const status = Object.hasOwn(value, 'status') ? Reflect.get(value, 'status') : undefined;
|
|
24
|
+
const completedAt = Object.hasOwn(value, 'completedAt') ? Reflect.get(value, 'completedAt') : undefined;
|
|
25
|
+
return (typeof completed === 'boolean' &&
|
|
26
|
+
typeof step === 'number' &&
|
|
27
|
+
(status === 'pending' || status === 'demo' || status === 'skipped' || status === 'evidence_found') &&
|
|
28
|
+
(!Object.hasOwn(value, 'completedAt') || typeof completedAt === 'string'));
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get onboarding state for a specific workspace.
|
|
32
|
+
* Treats localStorage data as unknown (rc-1) — validates shape before use.
|
|
33
|
+
*/
|
|
34
|
+
export function getOnboardingState(workspaceId) {
|
|
35
|
+
try {
|
|
36
|
+
const raw = localStorage.getItem(storageKey(workspaceId));
|
|
37
|
+
if (!raw)
|
|
38
|
+
return DEFAULT_STATE;
|
|
39
|
+
// rc-1: treat parsed JSON as unknown, validate shape
|
|
40
|
+
const parsed = JSON.parse(raw);
|
|
41
|
+
if (!isOnboardingState(parsed))
|
|
42
|
+
return DEFAULT_STATE;
|
|
43
|
+
return parsed;
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
// rc-9: surface the failure — don't silently swallow.
|
|
47
|
+
console.error('[onboarding-state] Failed to read onboarding state:', err);
|
|
48
|
+
return DEFAULT_STATE;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Set onboarding state for a specific workspace.
|
|
53
|
+
*/
|
|
54
|
+
export function setOnboardingState(workspaceId, state) {
|
|
55
|
+
try {
|
|
56
|
+
localStorage.setItem(storageKey(workspaceId), JSON.stringify(state));
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
// rc-9: surface the failure — don't silently swallow.
|
|
61
|
+
console.error('[onboarding-state] Failed to save onboarding state:', err);
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Reset onboarding state for a specific workspace (Settings page "reset" button).
|
|
67
|
+
*/
|
|
68
|
+
export function resetOnboardingState(workspaceId) {
|
|
69
|
+
try {
|
|
70
|
+
localStorage.removeItem(storageKey(workspaceId));
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
console.error('[onboarding-state] Failed to reset onboarding state:', err);
|
|
75
|
+
return false;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* signal-keywords-api — 信号关键词 API 层
|
|
3
|
+
*
|
|
4
|
+
* 调用 OpenClaw 插件的信号关键词管理端点。
|
|
5
|
+
* 功能分阶段交付:
|
|
6
|
+
* - Phase 1:只读(fetch keywords + pending)
|
|
7
|
+
* - Phase 2:读写(update / admit / reject)
|
|
8
|
+
*
|
|
9
|
+
* 当前 Phase 1 实现;写方法为 stub,返回"未实现"错误。
|
|
10
|
+
*
|
|
11
|
+
* ERR entries:
|
|
12
|
+
* - rc-1: 所有响应经 validator 校验
|
|
13
|
+
* - rc-2: 无 `as` bypass
|
|
14
|
+
* - rc-9: 降级/失败路径含 reason
|
|
15
|
+
*/
|
|
16
|
+
import type { ApiResponse } from '../../types.js';
|
|
17
|
+
import type { UnifiedKeywordStore, PendingTermStore, UpdateKeywordStoreRequest, AdmitPendingTermRequest, SignalKeyword, PendingSignalTerm } from './signal-keywords-types.js';
|
|
18
|
+
/**
|
|
19
|
+
* 获取所有活跃关键词列表(SignalKeywordsPage 使用)
|
|
20
|
+
*
|
|
21
|
+
* 当前 Phase 1: 端点未实现,返回 stub 错误。
|
|
22
|
+
* Phase 2 需对接 /api/plugins/principles/signal-keywords 端点。
|
|
23
|
+
*/
|
|
24
|
+
export declare function listActiveSignalKeywords(_signal?: AbortSignal): Promise<ApiResponse<SignalKeyword[]>>;
|
|
25
|
+
/**
|
|
26
|
+
* 获取待确认信号词列表(SignalKeywordsPage 使用)
|
|
27
|
+
*
|
|
28
|
+
* 当前 Phase 1: 端点未实现,返回 stub 错误。
|
|
29
|
+
* Phase 2 需对接 /api/plugins/principles/signal-keywords/pending 端点。
|
|
30
|
+
*/
|
|
31
|
+
export declare function listPendingSignalTerms(_signal?: AbortSignal): Promise<ApiResponse<PendingSignalTerm[]>>;
|
|
32
|
+
/**
|
|
33
|
+
* 获取指定分类的信号词库
|
|
34
|
+
*
|
|
35
|
+
* @param category - 分类(correction | empathy)
|
|
36
|
+
* @param signal - 允许外部中止
|
|
37
|
+
*/
|
|
38
|
+
export declare function fetchKeywordStore(category: 'correction' | 'empathy', signal?: AbortSignal): Promise<ApiResponse<UnifiedKeywordStore>>;
|
|
39
|
+
/**
|
|
40
|
+
* 获取 PendingTerm 候选池
|
|
41
|
+
*
|
|
42
|
+
* @param signal - 允许外部中止
|
|
43
|
+
*/
|
|
44
|
+
export declare function fetchPendingTerms(signal?: AbortSignal): Promise<ApiResponse<PendingTermStore>>;
|
|
45
|
+
/**
|
|
46
|
+
* 更新信号词库
|
|
47
|
+
*
|
|
48
|
+
* Phase 2 实现,当前返回"未实现"。
|
|
49
|
+
*/
|
|
50
|
+
export declare function updateKeywordStore(_req: UpdateKeywordStoreRequest, _signal?: AbortSignal): Promise<ApiResponse<{
|
|
51
|
+
version: number;
|
|
52
|
+
}>>;
|
|
53
|
+
/**
|
|
54
|
+
* 审批一个 PendingTerm(移入词库)
|
|
55
|
+
*
|
|
56
|
+
* Phase 2 实现,当前返回"未实现"。
|
|
57
|
+
*/
|
|
58
|
+
export declare function admitPendingTerm(_req: AdmitPendingTermRequest, _signal?: AbortSignal): Promise<ApiResponse<{
|
|
59
|
+
version: number;
|
|
60
|
+
}>>;
|
|
61
|
+
/**
|
|
62
|
+
* 拒绝一个 PendingTerm(从候选池移除)
|
|
63
|
+
*
|
|
64
|
+
* Phase 2 实现,当前返回"未实现"。
|
|
65
|
+
*/
|
|
66
|
+
export declare function rejectPendingTerm(_term: string, _signal?: AbortSignal): Promise<ApiResponse<{
|
|
67
|
+
version: number;
|
|
68
|
+
}>>;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* signal-keywords-api — 信号关键词 API 层
|
|
3
|
+
*
|
|
4
|
+
* 调用 OpenClaw 插件的信号关键词管理端点。
|
|
5
|
+
* 功能分阶段交付:
|
|
6
|
+
* - Phase 1:只读(fetch keywords + pending)
|
|
7
|
+
* - Phase 2:读写(update / admit / reject)
|
|
8
|
+
*
|
|
9
|
+
* 当前 Phase 1 实现;写方法为 stub,返回"未实现"错误。
|
|
10
|
+
*
|
|
11
|
+
* ERR entries:
|
|
12
|
+
* - rc-1: 所有响应经 validator 校验
|
|
13
|
+
* - rc-2: 无 `as` bypass
|
|
14
|
+
* - rc-9: 降级/失败路径含 reason
|
|
15
|
+
*/
|
|
16
|
+
// ── 端点路径(当 plugin I/O 模块实现后启用) ──────────────────────────────────
|
|
17
|
+
// const KEYWORDS_BASE = '/api/plugins/principles/signal-keywords';
|
|
18
|
+
// ── SignalKeywordsPage 直接调用的列表函数 ──────────────────────────────────────
|
|
19
|
+
/**
|
|
20
|
+
* 获取所有活跃关键词列表(SignalKeywordsPage 使用)
|
|
21
|
+
*
|
|
22
|
+
* 当前 Phase 1: 端点未实现,返回 stub 错误。
|
|
23
|
+
* Phase 2 需对接 /api/plugins/principles/signal-keywords 端点。
|
|
24
|
+
*/
|
|
25
|
+
export async function listActiveSignalKeywords(_signal) {
|
|
26
|
+
void _signal;
|
|
27
|
+
return {
|
|
28
|
+
success: false,
|
|
29
|
+
error: '信号关键词管理端点在当前版本中尚未实现(server-side plugin I/O 模块未部署)',
|
|
30
|
+
reason: 'endpoint_not_implemented',
|
|
31
|
+
nextAction: '请等待后续版本更新后再使用此功能',
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* 获取待确认信号词列表(SignalKeywordsPage 使用)
|
|
36
|
+
*
|
|
37
|
+
* 当前 Phase 1: 端点未实现,返回 stub 错误。
|
|
38
|
+
* Phase 2 需对接 /api/plugins/principles/signal-keywords/pending 端点。
|
|
39
|
+
*/
|
|
40
|
+
export async function listPendingSignalTerms(_signal) {
|
|
41
|
+
void _signal;
|
|
42
|
+
return {
|
|
43
|
+
success: false,
|
|
44
|
+
error: '信号关键词管理端点在当前版本中尚未实现(server-side plugin I/O 模块未部署)',
|
|
45
|
+
reason: 'endpoint_not_implemented',
|
|
46
|
+
nextAction: '请等待后续版本更新后再使用此功能',
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
// ── Phase 1 读取词库(category 分类读取) ──────────────────────────────────────
|
|
50
|
+
/**
|
|
51
|
+
* 获取指定分类的信号词库
|
|
52
|
+
*
|
|
53
|
+
* @param category - 分类(correction | empathy)
|
|
54
|
+
* @param signal - 允许外部中止
|
|
55
|
+
*/
|
|
56
|
+
export async function fetchKeywordStore(category, signal) {
|
|
57
|
+
// Phase 1: 端点未实现,返回可识别的降级错误(rc-9)
|
|
58
|
+
// 见 Task 4 实施说明:server-side 端点不在本 PR 范围内
|
|
59
|
+
void category;
|
|
60
|
+
void signal;
|
|
61
|
+
return {
|
|
62
|
+
success: false,
|
|
63
|
+
error: '信号关键词管理端点在当前版本中尚未实现(server-side plugin I/O 模块未部署)',
|
|
64
|
+
reason: 'endpoint_not_implemented',
|
|
65
|
+
nextAction: '请等待后续版本更新后再使用此功能',
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* 获取 PendingTerm 候选池
|
|
70
|
+
*
|
|
71
|
+
* @param signal - 允许外部中止
|
|
72
|
+
*/
|
|
73
|
+
export async function fetchPendingTerms(signal) {
|
|
74
|
+
void signal;
|
|
75
|
+
return {
|
|
76
|
+
success: false,
|
|
77
|
+
error: '信号关键词管理端点在当前版本中尚未实现(server-side plugin I/O 模块未部署)',
|
|
78
|
+
reason: 'endpoint_not_implemented',
|
|
79
|
+
nextAction: '请等待后续版本更新后再使用此功能',
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
// ── 写操作(Phase 2 stubs) ───────────────────────────────────────────────────
|
|
83
|
+
/**
|
|
84
|
+
* 更新信号词库
|
|
85
|
+
*
|
|
86
|
+
* Phase 2 实现,当前返回"未实现"。
|
|
87
|
+
*/
|
|
88
|
+
export async function updateKeywordStore(_req, _signal) {
|
|
89
|
+
return {
|
|
90
|
+
success: false,
|
|
91
|
+
error: '写操作在当前版本中尚未实现',
|
|
92
|
+
reason: 'endpoint_not_implemented',
|
|
93
|
+
nextAction: '请等待后续版本更新后再使用此功能',
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* 审批一个 PendingTerm(移入词库)
|
|
98
|
+
*
|
|
99
|
+
* Phase 2 实现,当前返回"未实现"。
|
|
100
|
+
*/
|
|
101
|
+
export async function admitPendingTerm(_req, _signal) {
|
|
102
|
+
return {
|
|
103
|
+
success: false,
|
|
104
|
+
error: '写操作在当前版本中尚未实现',
|
|
105
|
+
reason: 'endpoint_not_implemented',
|
|
106
|
+
nextAction: '请等待后续版本更新后再使用此功能',
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* 拒绝一个 PendingTerm(从候选池移除)
|
|
111
|
+
*
|
|
112
|
+
* Phase 2 实现,当前返回"未实现"。
|
|
113
|
+
*/
|
|
114
|
+
export async function rejectPendingTerm(_term, _signal) {
|
|
115
|
+
return {
|
|
116
|
+
success: false,
|
|
117
|
+
error: '写操作在当前版本中尚未实现',
|
|
118
|
+
reason: 'endpoint_not_implemented',
|
|
119
|
+
nextAction: '请等待后续版本更新后再使用此功能',
|
|
120
|
+
};
|
|
121
|
+
}
|