@soleri/core 2.12.0 → 8.0.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/data/flows/build.flow.yaml +128 -0
- package/data/flows/deliver.flow.yaml +110 -0
- package/data/flows/design.flow.yaml +108 -0
- package/data/flows/enhance.flow.yaml +90 -0
- package/data/flows/explore.flow.yaml +84 -0
- package/data/flows/fix.flow.yaml +90 -0
- package/data/flows/plan.flow.yaml +87 -0
- package/data/flows/review.flow.yaml +90 -0
- package/dist/agency/agency-manager.d.ts +27 -1
- package/dist/agency/agency-manager.d.ts.map +1 -1
- package/dist/agency/agency-manager.js +180 -9
- package/dist/agency/agency-manager.js.map +1 -1
- package/dist/agency/default-rules.d.ts +7 -0
- package/dist/agency/default-rules.d.ts.map +1 -0
- package/dist/agency/default-rules.js +79 -0
- package/dist/agency/default-rules.js.map +1 -0
- package/dist/agency/types.d.ts +48 -0
- package/dist/agency/types.d.ts.map +1 -1
- package/dist/brain/brain.d.ts +17 -2
- package/dist/brain/brain.d.ts.map +1 -1
- package/dist/brain/brain.js +118 -8
- package/dist/brain/brain.js.map +1 -1
- package/dist/brain/intelligence.d.ts.map +1 -1
- package/dist/brain/intelligence.js +16 -2
- package/dist/brain/intelligence.js.map +1 -1
- package/dist/brain/knowledge-synthesizer.d.ts +37 -0
- package/dist/brain/knowledge-synthesizer.d.ts.map +1 -0
- package/dist/brain/knowledge-synthesizer.js +161 -0
- package/dist/brain/knowledge-synthesizer.js.map +1 -0
- package/dist/brain/learning-radar.d.ts +96 -0
- package/dist/brain/learning-radar.d.ts.map +1 -0
- package/dist/brain/learning-radar.js +202 -0
- package/dist/brain/learning-radar.js.map +1 -0
- package/dist/brain/types.d.ts +15 -0
- package/dist/brain/types.d.ts.map +1 -1
- package/dist/capabilities/chain-mapping.d.ts +21 -0
- package/dist/capabilities/chain-mapping.d.ts.map +1 -0
- package/dist/capabilities/chain-mapping.js +86 -0
- package/dist/capabilities/chain-mapping.js.map +1 -0
- package/dist/capabilities/index.d.ts +10 -0
- package/dist/capabilities/index.d.ts.map +1 -0
- package/dist/capabilities/index.js +8 -0
- package/dist/capabilities/index.js.map +1 -0
- package/dist/capabilities/registry.d.ts +95 -0
- package/dist/capabilities/registry.d.ts.map +1 -0
- package/dist/capabilities/registry.js +227 -0
- package/dist/capabilities/registry.js.map +1 -0
- package/dist/capabilities/types.d.ts +106 -0
- package/dist/capabilities/types.d.ts.map +1 -0
- package/dist/capabilities/types.js +12 -0
- package/dist/capabilities/types.js.map +1 -0
- package/dist/context/context-engine.d.ts.map +1 -1
- package/dist/context/context-engine.js +82 -17
- package/dist/context/context-engine.js.map +1 -1
- package/dist/context/types.d.ts +5 -0
- package/dist/context/types.d.ts.map +1 -1
- package/dist/control/intent-router.d.ts +12 -1
- package/dist/control/intent-router.d.ts.map +1 -1
- package/dist/control/intent-router.js +126 -2
- package/dist/control/intent-router.js.map +1 -1
- package/dist/control/types.d.ts +17 -0
- package/dist/control/types.d.ts.map +1 -1
- package/dist/curator/classifier.d.ts +18 -0
- package/dist/curator/classifier.d.ts.map +1 -0
- package/dist/curator/classifier.js +61 -0
- package/dist/curator/classifier.js.map +1 -0
- package/dist/curator/quality-gate.d.ts +29 -0
- package/dist/curator/quality-gate.d.ts.map +1 -0
- package/dist/curator/quality-gate.js +88 -0
- package/dist/curator/quality-gate.js.map +1 -0
- package/dist/domain-packs/index.d.ts +8 -0
- package/dist/domain-packs/index.d.ts.map +1 -0
- package/dist/domain-packs/index.js +8 -0
- package/dist/domain-packs/index.js.map +1 -0
- package/dist/domain-packs/inject-rules.d.ts +24 -0
- package/dist/domain-packs/inject-rules.d.ts.map +1 -0
- package/dist/domain-packs/inject-rules.js +65 -0
- package/dist/domain-packs/inject-rules.js.map +1 -0
- package/dist/domain-packs/knowledge-installer.d.ts +27 -0
- package/dist/domain-packs/knowledge-installer.d.ts.map +1 -0
- package/dist/domain-packs/knowledge-installer.js +89 -0
- package/dist/domain-packs/knowledge-installer.js.map +1 -0
- package/dist/domain-packs/loader.d.ts +28 -0
- package/dist/domain-packs/loader.d.ts.map +1 -0
- package/dist/domain-packs/loader.js +105 -0
- package/dist/domain-packs/loader.js.map +1 -0
- package/dist/domain-packs/pack-runtime.d.ts +80 -0
- package/dist/domain-packs/pack-runtime.d.ts.map +1 -0
- package/dist/domain-packs/pack-runtime.js +36 -0
- package/dist/domain-packs/pack-runtime.js.map +1 -0
- package/dist/domain-packs/skills-installer.d.ts +21 -0
- package/dist/domain-packs/skills-installer.d.ts.map +1 -0
- package/dist/domain-packs/skills-installer.js +38 -0
- package/dist/domain-packs/skills-installer.js.map +1 -0
- package/dist/domain-packs/token-resolver.d.ts +37 -0
- package/dist/domain-packs/token-resolver.d.ts.map +1 -0
- package/dist/domain-packs/token-resolver.js +109 -0
- package/dist/domain-packs/token-resolver.js.map +1 -0
- package/dist/domain-packs/types.d.ts +91 -0
- package/dist/domain-packs/types.d.ts.map +1 -0
- package/dist/domain-packs/types.js +122 -0
- package/dist/domain-packs/types.js.map +1 -0
- package/dist/engine/bin/soleri-engine.d.ts +12 -0
- package/dist/engine/bin/soleri-engine.d.ts.map +1 -0
- package/dist/engine/bin/soleri-engine.js +184 -0
- package/dist/engine/bin/soleri-engine.js.map +1 -0
- package/dist/engine/core-ops.d.ts +27 -0
- package/dist/engine/core-ops.d.ts.map +1 -0
- package/dist/engine/core-ops.js +159 -0
- package/dist/engine/core-ops.js.map +1 -0
- package/dist/engine/index.d.ts +19 -0
- package/dist/engine/index.d.ts.map +1 -0
- package/dist/engine/index.js +17 -0
- package/dist/engine/index.js.map +1 -0
- package/dist/engine/register-engine.d.ts +54 -0
- package/dist/engine/register-engine.d.ts.map +1 -0
- package/dist/engine/register-engine.js +270 -0
- package/dist/engine/register-engine.js.map +1 -0
- package/dist/engine/test-helpers.d.ts +30 -0
- package/dist/engine/test-helpers.d.ts.map +1 -0
- package/dist/engine/test-helpers.js +59 -0
- package/dist/engine/test-helpers.js.map +1 -0
- package/dist/events/event-bus.d.ts +30 -0
- package/dist/events/event-bus.d.ts.map +1 -0
- package/dist/events/event-bus.js +51 -0
- package/dist/events/event-bus.js.map +1 -0
- package/dist/flows/chain-runner.d.ts +46 -0
- package/dist/flows/chain-runner.d.ts.map +1 -0
- package/dist/flows/chain-runner.js +271 -0
- package/dist/flows/chain-runner.js.map +1 -0
- package/dist/flows/chain-types.d.ts +103 -0
- package/dist/flows/chain-types.d.ts.map +1 -0
- package/dist/flows/chain-types.js +23 -0
- package/dist/flows/chain-types.js.map +1 -0
- package/dist/flows/context-router.d.ts +39 -0
- package/dist/flows/context-router.d.ts.map +1 -0
- package/dist/flows/context-router.js +206 -0
- package/dist/flows/context-router.js.map +1 -0
- package/dist/flows/dispatch-registry.d.ts +24 -0
- package/dist/flows/dispatch-registry.d.ts.map +1 -0
- package/dist/flows/dispatch-registry.js +70 -0
- package/dist/flows/dispatch-registry.js.map +1 -0
- package/dist/flows/epilogue.d.ts +24 -0
- package/dist/flows/epilogue.d.ts.map +1 -0
- package/dist/flows/epilogue.js +52 -0
- package/dist/flows/epilogue.js.map +1 -0
- package/dist/flows/executor.d.ts +25 -0
- package/dist/flows/executor.d.ts.map +1 -0
- package/dist/flows/executor.js +153 -0
- package/dist/flows/executor.js.map +1 -0
- package/dist/flows/gate-evaluator.d.ts +26 -0
- package/dist/flows/gate-evaluator.d.ts.map +1 -0
- package/dist/flows/gate-evaluator.js +162 -0
- package/dist/flows/gate-evaluator.js.map +1 -0
- package/dist/flows/index.d.ts +14 -0
- package/dist/flows/index.d.ts.map +1 -0
- package/dist/flows/index.js +20 -0
- package/dist/flows/index.js.map +1 -0
- package/dist/flows/loader.d.ts +17 -0
- package/dist/flows/loader.d.ts.map +1 -0
- package/dist/flows/loader.js +61 -0
- package/dist/flows/loader.js.map +1 -0
- package/dist/flows/plan-builder.d.ts +40 -0
- package/dist/flows/plan-builder.d.ts.map +1 -0
- package/dist/flows/plan-builder.js +213 -0
- package/dist/flows/plan-builder.js.map +1 -0
- package/dist/flows/probes.d.ts +11 -0
- package/dist/flows/probes.d.ts.map +1 -0
- package/dist/flows/probes.js +62 -0
- package/dist/flows/probes.js.map +1 -0
- package/dist/flows/types.d.ts +950 -0
- package/dist/flows/types.d.ts.map +1 -0
- package/dist/flows/types.js +105 -0
- package/dist/flows/types.js.map +1 -0
- package/dist/health/doctor-checks.d.ts +15 -0
- package/dist/health/doctor-checks.d.ts.map +1 -0
- package/dist/health/doctor-checks.js +98 -0
- package/dist/health/doctor-checks.js.map +1 -0
- package/dist/index.d.ts +11 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -1
- package/dist/index.js.map +1 -1
- package/dist/intake/text-ingester.d.ts +52 -0
- package/dist/intake/text-ingester.d.ts.map +1 -0
- package/dist/intake/text-ingester.js +181 -0
- package/dist/intake/text-ingester.js.map +1 -0
- package/dist/intelligence/loader.d.ts +19 -0
- package/dist/intelligence/loader.d.ts.map +1 -1
- package/dist/intelligence/loader.js +35 -0
- package/dist/intelligence/loader.js.map +1 -1
- package/dist/intelligence/types.d.ts +1 -0
- package/dist/intelligence/types.d.ts.map +1 -1
- package/dist/llm/llm-client.d.ts.map +1 -1
- package/dist/llm/llm-client.js +37 -1
- package/dist/llm/llm-client.js.map +1 -1
- package/dist/llm/oauth-discovery.d.ts +26 -0
- package/dist/llm/oauth-discovery.d.ts.map +1 -0
- package/dist/llm/oauth-discovery.js +149 -0
- package/dist/llm/oauth-discovery.js.map +1 -0
- package/dist/packs/types.d.ts +58 -19
- package/dist/packs/types.d.ts.map +1 -1
- package/dist/packs/types.js +14 -0
- package/dist/packs/types.js.map +1 -1
- package/dist/planning/evidence-collector.d.ts +41 -0
- package/dist/planning/evidence-collector.d.ts.map +1 -0
- package/dist/planning/evidence-collector.js +194 -0
- package/dist/planning/evidence-collector.js.map +1 -0
- package/dist/planning/planner.d.ts +4 -0
- package/dist/planning/planner.d.ts.map +1 -1
- package/dist/planning/planner.js +11 -0
- package/dist/planning/planner.js.map +1 -1
- package/dist/playbooks/generic/onboarding.d.ts +9 -0
- package/dist/playbooks/generic/onboarding.d.ts.map +1 -0
- package/dist/playbooks/generic/onboarding.js +74 -0
- package/dist/playbooks/generic/onboarding.js.map +1 -0
- package/dist/playbooks/playbook-registry.d.ts.map +1 -1
- package/dist/playbooks/playbook-registry.js +2 -0
- package/dist/playbooks/playbook-registry.js.map +1 -1
- package/dist/queue/job-queue.d.ts +92 -0
- package/dist/queue/job-queue.d.ts.map +1 -0
- package/dist/queue/job-queue.js +180 -0
- package/dist/queue/job-queue.js.map +1 -0
- package/dist/queue/pipeline-runner.d.ts +62 -0
- package/dist/queue/pipeline-runner.d.ts.map +1 -0
- package/dist/queue/pipeline-runner.js +126 -0
- package/dist/queue/pipeline-runner.js.map +1 -0
- package/dist/runtime/admin-extra-ops.d.ts.map +1 -1
- package/dist/runtime/admin-extra-ops.js +15 -9
- package/dist/runtime/admin-extra-ops.js.map +1 -1
- package/dist/runtime/admin-ops.js +4 -4
- package/dist/runtime/admin-ops.js.map +1 -1
- package/dist/runtime/admin-setup-ops.d.ts +20 -0
- package/dist/runtime/admin-setup-ops.d.ts.map +1 -0
- package/dist/runtime/admin-setup-ops.js +583 -0
- package/dist/runtime/admin-setup-ops.js.map +1 -0
- package/dist/runtime/capture-ops.d.ts.map +1 -1
- package/dist/runtime/capture-ops.js +33 -1
- package/dist/runtime/capture-ops.js.map +1 -1
- package/dist/runtime/chain-ops.d.ts +9 -0
- package/dist/runtime/chain-ops.d.ts.map +1 -0
- package/dist/runtime/chain-ops.js +107 -0
- package/dist/runtime/chain-ops.js.map +1 -0
- package/dist/runtime/claude-md-helpers.d.ts +65 -0
- package/dist/runtime/claude-md-helpers.d.ts.map +1 -0
- package/dist/runtime/claude-md-helpers.js +173 -0
- package/dist/runtime/claude-md-helpers.js.map +1 -0
- package/dist/runtime/curator-extra-ops.d.ts +3 -2
- package/dist/runtime/curator-extra-ops.d.ts.map +1 -1
- package/dist/runtime/curator-extra-ops.js +81 -3
- package/dist/runtime/curator-extra-ops.js.map +1 -1
- package/dist/runtime/domain-ops.d.ts +21 -5
- package/dist/runtime/domain-ops.d.ts.map +1 -1
- package/dist/runtime/domain-ops.js +64 -6
- package/dist/runtime/domain-ops.js.map +1 -1
- package/dist/runtime/facades/admin-facade.d.ts.map +1 -1
- package/dist/runtime/facades/admin-facade.js +4 -0
- package/dist/runtime/facades/admin-facade.js.map +1 -1
- package/dist/runtime/facades/agency-facade.d.ts.map +1 -1
- package/dist/runtime/facades/agency-facade.js +64 -0
- package/dist/runtime/facades/agency-facade.js.map +1 -1
- package/dist/runtime/facades/brain-facade.d.ts.map +1 -1
- package/dist/runtime/facades/brain-facade.js +122 -1
- package/dist/runtime/facades/brain-facade.js.map +1 -1
- package/dist/runtime/facades/cognee-facade.d.ts.map +1 -1
- package/dist/runtime/facades/cognee-facade.js +3 -1
- package/dist/runtime/facades/cognee-facade.js.map +1 -1
- package/dist/runtime/facades/control-facade.d.ts.map +1 -1
- package/dist/runtime/facades/control-facade.js +42 -0
- package/dist/runtime/facades/control-facade.js.map +1 -1
- package/dist/runtime/facades/index.d.ts.map +1 -1
- package/dist/runtime/facades/index.js +10 -6
- package/dist/runtime/facades/index.js.map +1 -1
- package/dist/runtime/facades/memory-facade.d.ts.map +1 -1
- package/dist/runtime/facades/memory-facade.js +20 -2
- package/dist/runtime/facades/memory-facade.js.map +1 -1
- package/dist/runtime/facades/plan-facade.d.ts.map +1 -1
- package/dist/runtime/facades/plan-facade.js +2 -0
- package/dist/runtime/facades/plan-facade.js.map +1 -1
- package/dist/runtime/facades/vault-facade.d.ts.map +1 -1
- package/dist/runtime/facades/vault-facade.js +27 -5
- package/dist/runtime/facades/vault-facade.js.map +1 -1
- package/dist/runtime/intake-ops.d.ts +7 -5
- package/dist/runtime/intake-ops.d.ts.map +1 -1
- package/dist/runtime/intake-ops.js +98 -5
- package/dist/runtime/intake-ops.js.map +1 -1
- package/dist/runtime/memory-extra-ops.d.ts +6 -3
- package/dist/runtime/memory-extra-ops.d.ts.map +1 -1
- package/dist/runtime/memory-extra-ops.js +292 -4
- package/dist/runtime/memory-extra-ops.js.map +1 -1
- package/dist/runtime/orchestrate-ops.d.ts +8 -7
- package/dist/runtime/orchestrate-ops.d.ts.map +1 -1
- package/dist/runtime/orchestrate-ops.js +217 -61
- package/dist/runtime/orchestrate-ops.js.map +1 -1
- package/dist/runtime/planning-extra-ops.d.ts.map +1 -1
- package/dist/runtime/planning-extra-ops.js +85 -0
- package/dist/runtime/planning-extra-ops.js.map +1 -1
- package/dist/runtime/playbook-ops.js +1 -1
- package/dist/runtime/playbook-ops.js.map +1 -1
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +165 -18
- package/dist/runtime/runtime.js.map +1 -1
- package/dist/runtime/session-briefing.d.ts +23 -0
- package/dist/runtime/session-briefing.d.ts.map +1 -0
- package/dist/runtime/session-briefing.js +140 -0
- package/dist/runtime/session-briefing.js.map +1 -0
- package/dist/runtime/types.d.ts +29 -2
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/vault-linking-ops.d.ts +13 -0
- package/dist/runtime/vault-linking-ops.d.ts.map +1 -0
- package/dist/runtime/vault-linking-ops.js +365 -0
- package/dist/runtime/vault-linking-ops.js.map +1 -0
- package/dist/vault/linking.d.ts +46 -0
- package/dist/vault/linking.d.ts.map +1 -0
- package/dist/vault/linking.js +275 -0
- package/dist/vault/linking.js.map +1 -0
- package/dist/vault/vault-types.d.ts +37 -0
- package/dist/vault/vault-types.d.ts.map +1 -1
- package/dist/vault/vault.d.ts +37 -0
- package/dist/vault/vault.d.ts.map +1 -1
- package/dist/vault/vault.js +152 -9
- package/dist/vault/vault.js.map +1 -1
- package/package.json +4 -1
- package/src/__tests__/admin-extra-ops.test.ts +1 -1
- package/src/__tests__/admin-ops.test.ts +2 -1
- package/src/__tests__/admin-setup-ops.test.ts +355 -0
- package/src/__tests__/async-infrastructure.test.ts +307 -0
- package/src/__tests__/cognee-client-gaps.test.ts +474 -0
- package/src/__tests__/cognee-hybrid-search.test.ts +492 -0
- package/src/__tests__/cognee-sync-manager-deep.test.ts +654 -0
- package/src/__tests__/cognee-sync-manager.test.ts +1 -0
- package/src/__tests__/core-ops.test.ts +9 -61
- package/src/__tests__/curator-extra-ops.test.ts +6 -2
- package/src/__tests__/curator-pipeline-e2e.test.ts +358 -0
- package/src/__tests__/domain-packs.test.ts +421 -0
- package/src/__tests__/flows.test.ts +604 -0
- package/src/__tests__/memory-extra-ops.test.ts +2 -2
- package/src/__tests__/planning-extra-ops.test.ts +2 -2
- package/src/__tests__/playbook-registry.test.ts +2 -2
- package/src/__tests__/playbook-seeder.test.ts +8 -8
- package/src/__tests__/playbook.test.ts +5 -5
- package/src/__tests__/second-brain-features.test.ts +583 -0
- package/src/__tests__/token-resolver.test.ts +79 -0
- package/src/agency/agency-manager.ts +217 -9
- package/src/agency/default-rules.ts +83 -0
- package/src/agency/types.ts +61 -0
- package/src/brain/brain.ts +110 -8
- package/src/brain/intelligence.ts +21 -2
- package/src/brain/knowledge-synthesizer.ts +218 -0
- package/src/brain/learning-radar.ts +340 -0
- package/src/brain/types.ts +16 -0
- package/src/capabilities/chain-mapping.ts +93 -0
- package/src/capabilities/index.ts +21 -0
- package/src/capabilities/registry.ts +290 -0
- package/src/capabilities/types.ts +143 -0
- package/src/context/context-engine.ts +114 -15
- package/src/context/types.ts +5 -0
- package/src/control/intent-router.ts +153 -2
- package/src/control/types.ts +10 -0
- package/src/curator/classifier.ts +88 -0
- package/src/curator/quality-gate.ts +129 -0
- package/src/domain-packs/index.ts +27 -0
- package/src/domain-packs/inject-rules.ts +74 -0
- package/src/domain-packs/knowledge-installer.ts +116 -0
- package/src/domain-packs/loader.ts +124 -0
- package/src/domain-packs/pack-runtime.ts +99 -0
- package/src/domain-packs/skills-installer.ts +56 -0
- package/src/domain-packs/token-resolver.ts +126 -0
- package/src/domain-packs/types.ts +229 -0
- package/src/engine/__tests__/register-engine.test.ts +104 -0
- package/src/engine/bin/soleri-engine.ts +218 -0
- package/src/engine/core-ops.ts +178 -0
- package/src/engine/index.ts +19 -0
- package/src/engine/register-engine.ts +385 -0
- package/src/engine/test-helpers.ts +83 -0
- package/src/events/event-bus.ts +58 -0
- package/src/flows/chain-runner.ts +369 -0
- package/src/flows/chain-types.ts +57 -0
- package/src/flows/context-router.ts +257 -0
- package/src/flows/dispatch-registry.ts +80 -0
- package/src/flows/epilogue.ts +65 -0
- package/src/flows/executor.ts +182 -0
- package/src/flows/gate-evaluator.ts +171 -0
- package/src/flows/index.ts +52 -0
- package/src/flows/loader.ts +63 -0
- package/src/flows/plan-builder.ts +250 -0
- package/src/flows/probes.ts +70 -0
- package/src/flows/types.ts +217 -0
- package/src/health/doctor-checks.ts +115 -0
- package/src/index.ts +68 -1
- package/src/intake/text-ingester.ts +234 -0
- package/src/intelligence/loader.ts +38 -0
- package/src/intelligence/types.ts +1 -0
- package/src/llm/llm-client.ts +38 -1
- package/src/llm/oauth-discovery.ts +169 -0
- package/src/packs/types.ts +19 -0
- package/src/planning/evidence-collector.ts +247 -0
- package/src/planning/planner.ts +11 -0
- package/src/playbooks/generic/onboarding.ts +79 -0
- package/src/playbooks/playbook-registry.ts +2 -0
- package/src/queue/job-queue.ts +281 -0
- package/src/queue/pipeline-runner.ts +149 -0
- package/src/runtime/admin-extra-ops.ts +14 -8
- package/src/runtime/admin-ops.ts +4 -4
- package/src/runtime/admin-setup-ops.ts +664 -0
- package/src/runtime/capture-ops.ts +40 -1
- package/src/runtime/chain-ops.ts +121 -0
- package/src/runtime/claude-md-helpers.ts +236 -0
- package/src/runtime/curator-extra-ops.ts +86 -3
- package/src/runtime/domain-ops.ts +71 -5
- package/src/runtime/facades/admin-facade.ts +4 -0
- package/src/runtime/facades/agency-facade.ts +68 -0
- package/src/runtime/facades/brain-facade.ts +142 -1
- package/src/runtime/facades/cognee-facade.ts +3 -1
- package/src/runtime/facades/control-facade.ts +45 -0
- package/src/runtime/facades/index.ts +12 -6
- package/src/runtime/facades/memory-facade.ts +20 -2
- package/src/runtime/facades/plan-facade.ts +2 -0
- package/src/runtime/facades/vault-facade.ts +30 -5
- package/src/runtime/intake-ops.ts +107 -5
- package/src/runtime/memory-extra-ops.ts +312 -4
- package/src/runtime/orchestrate-ops.ts +261 -65
- package/src/runtime/planning-extra-ops.ts +94 -0
- package/src/runtime/playbook-ops.ts +1 -1
- package/src/runtime/runtime.ts +164 -19
- package/src/runtime/session-briefing.ts +161 -0
- package/src/runtime/types.ts +29 -2
- package/src/runtime/vault-linking-ops.ts +452 -0
- package/src/vault/linking.ts +333 -0
- package/src/vault/vault-types.ts +46 -0
- package/src/vault/vault.ts +173 -11
|
@@ -34,8 +34,9 @@ describe('createSemanticFacades', () => {
|
|
|
34
34
|
return op;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
-
it('should return
|
|
38
|
-
|
|
37
|
+
it('should return ops from all semantic facades (without cognee)', () => {
|
|
38
|
+
// Op count varies as new ops are added. Just verify a reasonable minimum.
|
|
39
|
+
expect(ops.length).toBeGreaterThan(250);
|
|
39
40
|
});
|
|
40
41
|
|
|
41
42
|
it('should have all expected op names', () => {
|
|
@@ -103,12 +104,8 @@ describe('createSemanticFacades', () => {
|
|
|
103
104
|
expect(names).toContain('route_intent');
|
|
104
105
|
expect(names).toContain('morph');
|
|
105
106
|
expect(names).toContain('get_behavior_rules');
|
|
106
|
-
// Cognee
|
|
107
|
-
|
|
108
|
-
expect(names).toContain('cognee_search');
|
|
109
|
-
expect(names).toContain('cognee_add');
|
|
110
|
-
expect(names).toContain('cognee_cognify');
|
|
111
|
-
expect(names).toContain('cognee_config');
|
|
107
|
+
// Cognee — only present when cognee is enabled in runtime
|
|
108
|
+
// (this test creates runtime without cognee: true)
|
|
112
109
|
// Context Engine (#172)
|
|
113
110
|
expect(names).toContain('context_extract_entities');
|
|
114
111
|
expect(names).toContain('context_retrieve_knowledge');
|
|
@@ -324,10 +321,7 @@ describe('createSemanticFacades', () => {
|
|
|
324
321
|
// Prompt templates
|
|
325
322
|
expect(names).toContain('render_prompt');
|
|
326
323
|
expect(names).toContain('list_templates');
|
|
327
|
-
// Cognee Sync ops
|
|
328
|
-
expect(names).toContain('cognee_sync_status');
|
|
329
|
-
expect(names).toContain('cognee_sync_drain');
|
|
330
|
-
expect(names).toContain('cognee_sync_reconcile');
|
|
324
|
+
// Cognee Sync ops — only present when cognee is enabled
|
|
331
325
|
// Intake ops
|
|
332
326
|
expect(names).toContain('intake_ingest_book');
|
|
333
327
|
expect(names).toContain('intake_process');
|
|
@@ -515,55 +509,9 @@ describe('createSemanticFacades', () => {
|
|
|
515
509
|
expect(result.totalEntries).toBe(1);
|
|
516
510
|
});
|
|
517
511
|
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
available: boolean;
|
|
522
|
-
url: string;
|
|
523
|
-
};
|
|
524
|
-
expect(typeof result.available).toBe('boolean');
|
|
525
|
-
expect(typeof result.url).toBe('string');
|
|
526
|
-
});
|
|
527
|
-
|
|
528
|
-
it('cognee_search should return empty when unavailable', async () => {
|
|
529
|
-
const results = (await findOp('cognee_search').handler({
|
|
530
|
-
query: 'test pattern',
|
|
531
|
-
})) as unknown[];
|
|
532
|
-
expect(results).toEqual([]);
|
|
533
|
-
});
|
|
534
|
-
|
|
535
|
-
it('cognee_add should return 0 when unavailable', async () => {
|
|
536
|
-
runtime.vault.seed([
|
|
537
|
-
{
|
|
538
|
-
id: 'cog-1',
|
|
539
|
-
type: 'pattern',
|
|
540
|
-
domain: 'testing',
|
|
541
|
-
title: 'Cognee test',
|
|
542
|
-
severity: 'warning',
|
|
543
|
-
description: 'Test.',
|
|
544
|
-
tags: ['test'],
|
|
545
|
-
},
|
|
546
|
-
]);
|
|
547
|
-
const result = (await findOp('cognee_add').handler({
|
|
548
|
-
entryIds: ['cog-1'],
|
|
549
|
-
})) as { added: number };
|
|
550
|
-
expect(result.added).toBe(0);
|
|
551
|
-
});
|
|
552
|
-
|
|
553
|
-
it('cognee_cognify should return unavailable when Cognee is down', async () => {
|
|
554
|
-
const result = (await findOp('cognee_cognify').handler({})) as { status: string };
|
|
555
|
-
expect(result.status).toBe('unavailable');
|
|
556
|
-
});
|
|
557
|
-
|
|
558
|
-
it('cognee_config should return config and null status', async () => {
|
|
559
|
-
const result = (await findOp('cognee_config').handler({})) as {
|
|
560
|
-
config: { baseUrl: string; dataset: string };
|
|
561
|
-
cachedStatus: null;
|
|
562
|
-
};
|
|
563
|
-
expect(result.config.baseUrl).toBe('http://localhost:8000');
|
|
564
|
-
expect(result.config.dataset).toBe('test-core-ops');
|
|
565
|
-
expect(result.cachedStatus).toBeNull();
|
|
566
|
-
});
|
|
512
|
+
// Cognee ops are only registered when runtime has cognee enabled.
|
|
513
|
+
// This test creates runtime without cognee: true, so these ops are not present.
|
|
514
|
+
// See e2e/full-pipeline.test.ts for cognee facade tests with cognee enabled.
|
|
567
515
|
|
|
568
516
|
it('llm_rotate should return rotation status', async () => {
|
|
569
517
|
const result = (await findOp('llm_rotate').handler({ provider: 'openai' })) as {
|
|
@@ -26,9 +26,9 @@ describe('createCuratorExtraOps', () => {
|
|
|
26
26
|
ops = createCuratorExtraOps(runtime);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
it('should return
|
|
29
|
+
it('should return 9 ops', () => {
|
|
30
30
|
setup();
|
|
31
|
-
expect(ops).toHaveLength(
|
|
31
|
+
expect(ops).toHaveLength(9);
|
|
32
32
|
const names = ops.map((o) => o.name);
|
|
33
33
|
expect(names).toEqual([
|
|
34
34
|
'curator_entry_history',
|
|
@@ -36,6 +36,10 @@ describe('createCuratorExtraOps', () => {
|
|
|
36
36
|
'curator_queue_stats',
|
|
37
37
|
'curator_enrich',
|
|
38
38
|
'curator_hybrid_contradictions',
|
|
39
|
+
'curator_pipeline_status',
|
|
40
|
+
'curator_enqueue_pipeline',
|
|
41
|
+
'curator_schedule_start',
|
|
42
|
+
'curator_schedule_stop',
|
|
39
43
|
]);
|
|
40
44
|
});
|
|
41
45
|
|
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* E2E tests for curator async infrastructure (#210).
|
|
3
|
+
*
|
|
4
|
+
* Tests the full pipeline: enqueue → DAG resolution → handler dispatch → completion.
|
|
5
|
+
* Also tests quality gate and classifier graceful degradation (no LLM).
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
|
9
|
+
import { Vault } from '../vault/vault.js';
|
|
10
|
+
import { Brain } from '../brain/brain.js';
|
|
11
|
+
import { Curator } from '../curator/curator.js';
|
|
12
|
+
import { JobQueue } from '../queue/job-queue.js';
|
|
13
|
+
import { PipelineRunner } from '../queue/pipeline-runner.js';
|
|
14
|
+
import { TypedEventBus } from '../events/event-bus.js';
|
|
15
|
+
import { LinkManager } from '../vault/linking.js';
|
|
16
|
+
import { evaluateQuality } from '../curator/quality-gate.js';
|
|
17
|
+
import { classifyEntry } from '../curator/classifier.js';
|
|
18
|
+
import type { IntelligenceEntry } from '../intelligence/types.js';
|
|
19
|
+
|
|
20
|
+
// ─── Shared Setup ────────────────────────────────────────────────────
|
|
21
|
+
|
|
22
|
+
let vault: Vault;
|
|
23
|
+
let brain: Brain;
|
|
24
|
+
let curator: Curator;
|
|
25
|
+
let queue: JobQueue;
|
|
26
|
+
let runner: PipelineRunner;
|
|
27
|
+
let linkManager: LinkManager;
|
|
28
|
+
|
|
29
|
+
const SEED: IntelligenceEntry[] = [
|
|
30
|
+
{
|
|
31
|
+
id: 'pattern-circuit-breaker',
|
|
32
|
+
type: 'pattern',
|
|
33
|
+
domain: 'architecture',
|
|
34
|
+
title: 'Circuit Breaker for External Services',
|
|
35
|
+
severity: 'critical',
|
|
36
|
+
description: 'Wrap external service calls in a circuit breaker to prevent cascade failures.',
|
|
37
|
+
tags: ['networking', 'resilience', 'microservices'],
|
|
38
|
+
why: 'Prevents one failing service from taking down the entire system.',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
id: 'anti-pattern-no-timeout',
|
|
42
|
+
type: 'anti-pattern',
|
|
43
|
+
domain: 'architecture',
|
|
44
|
+
title: 'HTTP Calls Without Timeout',
|
|
45
|
+
severity: 'critical',
|
|
46
|
+
description: 'Never make HTTP calls without a timeout. Can hang indefinitely.',
|
|
47
|
+
tags: ['networking', 'timeout', 'http'],
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
id: 'pattern-semantic-tokens',
|
|
51
|
+
type: 'pattern',
|
|
52
|
+
domain: 'design',
|
|
53
|
+
title: 'Use Semantic Tokens',
|
|
54
|
+
severity: 'warning',
|
|
55
|
+
description: 'Prefer semantic tokens over primitive color values for maintainability.',
|
|
56
|
+
tags: ['tokens', 'design-system'],
|
|
57
|
+
},
|
|
58
|
+
];
|
|
59
|
+
|
|
60
|
+
beforeAll(() => {
|
|
61
|
+
vault = new Vault(':memory:');
|
|
62
|
+
vault.seed(SEED);
|
|
63
|
+
brain = new Brain(vault);
|
|
64
|
+
curator = new Curator(vault);
|
|
65
|
+
queue = new JobQueue(vault.getProvider());
|
|
66
|
+
linkManager = new LinkManager(vault.getProvider());
|
|
67
|
+
runner = new PipelineRunner(queue);
|
|
68
|
+
|
|
69
|
+
// Register handlers matching the runtime setup
|
|
70
|
+
runner.registerHandler('tag-normalize', async (job) => {
|
|
71
|
+
const entry = vault.get(job.entryId ?? '');
|
|
72
|
+
if (!entry) return { skipped: true, reason: 'entry not found' };
|
|
73
|
+
return curator.normalizeTag(entry.tags[0] ?? '');
|
|
74
|
+
});
|
|
75
|
+
runner.registerHandler('dedup-check', async (job) => {
|
|
76
|
+
const entry = vault.get(job.entryId ?? '');
|
|
77
|
+
if (!entry) return { skipped: true, reason: 'entry not found' };
|
|
78
|
+
return curator.detectDuplicates(entry.id);
|
|
79
|
+
});
|
|
80
|
+
runner.registerHandler('auto-link', async (job) => {
|
|
81
|
+
const suggestions = linkManager.suggestLinks(job.entryId ?? '', 3);
|
|
82
|
+
for (const s of suggestions) {
|
|
83
|
+
linkManager.addLink(job.entryId ?? '', s.entryId, s.suggestedType, `pipeline: ${s.reason}`);
|
|
84
|
+
}
|
|
85
|
+
return { linked: suggestions.length };
|
|
86
|
+
});
|
|
87
|
+
runner.registerHandler('quality-gate', async (job) => {
|
|
88
|
+
const entry = vault.get(job.entryId ?? '');
|
|
89
|
+
if (!entry) return { skipped: true, reason: 'entry not found' };
|
|
90
|
+
return evaluateQuality(entry, null); // No LLM in tests
|
|
91
|
+
});
|
|
92
|
+
runner.registerHandler('classify', async (job) => {
|
|
93
|
+
const entry = vault.get(job.entryId ?? '');
|
|
94
|
+
if (!entry) return { skipped: true, reason: 'entry not found' };
|
|
95
|
+
return classifyEntry(entry, null); // No LLM in tests
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
afterAll(() => {
|
|
100
|
+
runner.stop();
|
|
101
|
+
vault.close();
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
// ─── Job Queue Integration ──────────────────────────────────────────
|
|
105
|
+
|
|
106
|
+
describe('Job Queue — curator pipeline', () => {
|
|
107
|
+
it('enqueues a 3-step DAG pipeline for an entry', () => {
|
|
108
|
+
const pipelineId = 'pipe-test-1';
|
|
109
|
+
const entryId = 'pattern-circuit-breaker';
|
|
110
|
+
|
|
111
|
+
const step1 = queue.enqueue('tag-normalize', { entryId, pipelineId });
|
|
112
|
+
const step2 = queue.enqueue('dedup-check', { entryId, pipelineId, dependsOn: [step1] });
|
|
113
|
+
const step3 = queue.enqueue('auto-link', { entryId, pipelineId, dependsOn: [step2] });
|
|
114
|
+
|
|
115
|
+
const jobs = queue.getByPipeline(pipelineId);
|
|
116
|
+
expect(jobs.length).toBe(3);
|
|
117
|
+
expect(jobs[0].type).toBe('tag-normalize');
|
|
118
|
+
expect(jobs[1].dependsOn).toContain(step1);
|
|
119
|
+
expect(jobs[2].dependsOn).toContain(step2);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it('dequeueReady only returns jobs with completed deps', () => {
|
|
123
|
+
const pipelineId = 'pipe-test-dag';
|
|
124
|
+
const step1 = queue.enqueue('tag-normalize', {
|
|
125
|
+
entryId: 'pattern-circuit-breaker',
|
|
126
|
+
pipelineId,
|
|
127
|
+
});
|
|
128
|
+
const step2 = queue.enqueue('dedup-check', {
|
|
129
|
+
entryId: 'pattern-circuit-breaker',
|
|
130
|
+
pipelineId,
|
|
131
|
+
dependsOn: [step1],
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
// Only step1 should be ready
|
|
135
|
+
const ready = queue.dequeueReady(10);
|
|
136
|
+
const readyIds = ready.map((j) => j.id);
|
|
137
|
+
expect(readyIds).toContain(step1);
|
|
138
|
+
expect(readyIds).not.toContain(step2);
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
// ─── Pipeline Runner Integration ────────────────────────────────────
|
|
143
|
+
|
|
144
|
+
describe('Pipeline Runner — full pipeline execution', () => {
|
|
145
|
+
it('executes a 3-step pipeline in DAG order', async () => {
|
|
146
|
+
const pipelineId = 'pipe-runner-test';
|
|
147
|
+
const entryId = 'pattern-circuit-breaker';
|
|
148
|
+
|
|
149
|
+
const step1 = queue.enqueue('tag-normalize', { entryId, pipelineId });
|
|
150
|
+
const step2 = queue.enqueue('dedup-check', { entryId, pipelineId, dependsOn: [step1] });
|
|
151
|
+
const step3 = queue.enqueue('auto-link', { entryId, pipelineId, dependsOn: [step2] });
|
|
152
|
+
|
|
153
|
+
// Process step 1
|
|
154
|
+
const batch1 = await runner.processOnce(10);
|
|
155
|
+
expect(batch1).toBeGreaterThanOrEqual(1);
|
|
156
|
+
expect(queue.get(step1)!.status).toBe('completed');
|
|
157
|
+
|
|
158
|
+
// Process step 2
|
|
159
|
+
const batch2 = await runner.processOnce(10);
|
|
160
|
+
expect(batch2).toBeGreaterThanOrEqual(1);
|
|
161
|
+
expect(queue.get(step2)!.status).toBe('completed');
|
|
162
|
+
|
|
163
|
+
// Process step 3
|
|
164
|
+
const batch3 = await runner.processOnce(10);
|
|
165
|
+
expect(batch3).toBeGreaterThanOrEqual(1);
|
|
166
|
+
expect(queue.get(step3)!.status).toBe('completed');
|
|
167
|
+
|
|
168
|
+
// All jobs in pipeline should be completed
|
|
169
|
+
const jobs = queue.getByPipeline(pipelineId);
|
|
170
|
+
expect(jobs.every((j) => j.status === 'completed')).toBe(true);
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
it('tag-normalize handler returns normalization result', async () => {
|
|
174
|
+
const id = queue.enqueue('tag-normalize', { entryId: 'pattern-circuit-breaker' });
|
|
175
|
+
await runner.processOnce();
|
|
176
|
+
|
|
177
|
+
const job = queue.get(id);
|
|
178
|
+
expect(job!.status).toBe('completed');
|
|
179
|
+
expect(job!.result).toBeDefined();
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
it('dedup-check handler detects duplicates', async () => {
|
|
183
|
+
const id = queue.enqueue('dedup-check', { entryId: 'pattern-circuit-breaker' });
|
|
184
|
+
await runner.processOnce();
|
|
185
|
+
|
|
186
|
+
const job = queue.get(id);
|
|
187
|
+
expect(job!.status).toBe('completed');
|
|
188
|
+
expect(job!.result).toBeDefined();
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
it('auto-link handler creates Zettelkasten links', async () => {
|
|
192
|
+
const id = queue.enqueue('auto-link', { entryId: 'pattern-circuit-breaker' });
|
|
193
|
+
await runner.processOnce();
|
|
194
|
+
|
|
195
|
+
const job = queue.get(id);
|
|
196
|
+
expect(job!.status).toBe('completed');
|
|
197
|
+
const result = job!.result as { linked: number };
|
|
198
|
+
expect(typeof result.linked).toBe('number');
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it('handles missing entry gracefully', async () => {
|
|
202
|
+
const id = queue.enqueue('tag-normalize', { entryId: 'nonexistent-entry' });
|
|
203
|
+
await runner.processOnce();
|
|
204
|
+
|
|
205
|
+
const job = queue.get(id);
|
|
206
|
+
expect(job!.status).toBe('completed');
|
|
207
|
+
expect((job!.result as Record<string, unknown>).skipped).toBe(true);
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
it('runner status tracks processed/failed counts', async () => {
|
|
211
|
+
const status = runner.getStatus();
|
|
212
|
+
expect(status.jobsProcessed).toBeGreaterThan(0);
|
|
213
|
+
expect(typeof status.jobsFailed).toBe('number');
|
|
214
|
+
expect(typeof status.jobsRetried).toBe('number');
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
// ─── Quality Gate (no LLM) ──────────────────────────────────────────
|
|
219
|
+
|
|
220
|
+
describe('Quality Gate — graceful degradation', () => {
|
|
221
|
+
it('returns ACCEPT with default scores when no LLM', async () => {
|
|
222
|
+
const entry = vault.get('pattern-circuit-breaker')!;
|
|
223
|
+
const result = await evaluateQuality(entry, null);
|
|
224
|
+
|
|
225
|
+
expect(result.evaluated).toBe(false);
|
|
226
|
+
expect(result.verdict).toBe('ACCEPT');
|
|
227
|
+
expect(result.overallScore).toBe(50);
|
|
228
|
+
expect(result.scores.novelty).toBe(50);
|
|
229
|
+
expect(result.scores.actionability).toBe(50);
|
|
230
|
+
expect(result.reasoning).toContain('unavailable');
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
it('quality-gate job handler works via pipeline', async () => {
|
|
234
|
+
const id = queue.enqueue('quality-gate', { entryId: 'pattern-circuit-breaker' });
|
|
235
|
+
await runner.processOnce();
|
|
236
|
+
|
|
237
|
+
const job = queue.get(id);
|
|
238
|
+
expect(job!.status).toBe('completed');
|
|
239
|
+
const result = job!.result as { evaluated: boolean; verdict: string };
|
|
240
|
+
expect(result.verdict).toBe('ACCEPT');
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
// ─── Classifier (no LLM) ────────────────────────────────────────────
|
|
245
|
+
|
|
246
|
+
describe('Classifier — graceful degradation', () => {
|
|
247
|
+
it('returns empty classification when no LLM', async () => {
|
|
248
|
+
const entry = vault.get('pattern-circuit-breaker')!;
|
|
249
|
+
const result = await classifyEntry(entry, null);
|
|
250
|
+
|
|
251
|
+
expect(result.classified).toBe(false);
|
|
252
|
+
expect(result.suggestedDomain).toBeNull();
|
|
253
|
+
expect(result.suggestedSeverity).toBeNull();
|
|
254
|
+
expect(result.suggestedTags).toEqual([]);
|
|
255
|
+
expect(result.confidence).toBe(0);
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
it('classify job handler works via pipeline', async () => {
|
|
259
|
+
const id = queue.enqueue('classify', { entryId: 'anti-pattern-no-timeout' });
|
|
260
|
+
await runner.processOnce();
|
|
261
|
+
|
|
262
|
+
const job = queue.get(id);
|
|
263
|
+
expect(job!.status).toBe('completed');
|
|
264
|
+
const result = job!.result as { classified: boolean };
|
|
265
|
+
expect(result.classified).toBe(false); // No LLM
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
// ─── Event Bus Integration ──────────────────────────────────────────
|
|
270
|
+
|
|
271
|
+
describe('Event Bus — curator events', () => {
|
|
272
|
+
type CuratorEvents = {
|
|
273
|
+
'entry:captured': { id: string; title: string };
|
|
274
|
+
'pipeline:started': { pipelineId: string; entryId: string };
|
|
275
|
+
'pipeline:completed': { pipelineId: string; jobsCompleted: number };
|
|
276
|
+
'quality:rejected': { entryId: string; score: number; reasons: string[] };
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
it('fires entry:captured event and listeners receive it', () => {
|
|
280
|
+
const bus = new TypedEventBus<CuratorEvents>();
|
|
281
|
+
let received: CuratorEvents['entry:captured'] | null = null;
|
|
282
|
+
|
|
283
|
+
bus.on('entry:captured', (payload) => {
|
|
284
|
+
received = payload;
|
|
285
|
+
});
|
|
286
|
+
bus.emit('entry:captured', { id: 'test-1', title: 'Test Entry' });
|
|
287
|
+
|
|
288
|
+
expect(received).toEqual({ id: 'test-1', title: 'Test Entry' });
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
it('fires pipeline events in sequence', () => {
|
|
292
|
+
const bus = new TypedEventBus<CuratorEvents>();
|
|
293
|
+
const events: string[] = [];
|
|
294
|
+
|
|
295
|
+
bus.on('pipeline:started', () => events.push('started'));
|
|
296
|
+
bus.on('pipeline:completed', () => events.push('completed'));
|
|
297
|
+
|
|
298
|
+
bus.emit('pipeline:started', { pipelineId: 'p1', entryId: 'e1' });
|
|
299
|
+
bus.emit('pipeline:completed', { pipelineId: 'p1', jobsCompleted: 3 });
|
|
300
|
+
|
|
301
|
+
expect(events).toEqual(['started', 'completed']);
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
it('fires quality:rejected for low-scoring entries', () => {
|
|
305
|
+
const bus = new TypedEventBus<CuratorEvents>();
|
|
306
|
+
let rejected: CuratorEvents['quality:rejected'] | null = null;
|
|
307
|
+
|
|
308
|
+
bus.on('quality:rejected', (payload) => {
|
|
309
|
+
rejected = payload;
|
|
310
|
+
});
|
|
311
|
+
bus.emit('quality:rejected', {
|
|
312
|
+
entryId: 'junk-1',
|
|
313
|
+
score: 25,
|
|
314
|
+
reasons: ['too vague', 'no actionability'],
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
expect(rejected!.score).toBe(25);
|
|
318
|
+
expect(rejected!.reasons).toContain('too vague');
|
|
319
|
+
});
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
// ─── Full Pipeline E2E ──────────────────────────────────────────────
|
|
323
|
+
|
|
324
|
+
describe('Full pipeline E2E — capture to completion', () => {
|
|
325
|
+
it('processes a 5-step pipeline: quality-gate → tag-normalize → dedup → classify → auto-link', async () => {
|
|
326
|
+
const entryId = 'anti-pattern-no-timeout';
|
|
327
|
+
const pipelineId = 'full-e2e';
|
|
328
|
+
|
|
329
|
+
const step1 = queue.enqueue('quality-gate', { entryId, pipelineId });
|
|
330
|
+
const step2 = queue.enqueue('tag-normalize', { entryId, pipelineId, dependsOn: [step1] });
|
|
331
|
+
const step3 = queue.enqueue('dedup-check', { entryId, pipelineId, dependsOn: [step2] });
|
|
332
|
+
const step4 = queue.enqueue('classify', { entryId, pipelineId, dependsOn: [step3] });
|
|
333
|
+
const step5 = queue.enqueue('auto-link', { entryId, pipelineId, dependsOn: [step4] });
|
|
334
|
+
|
|
335
|
+
// Process all steps — run enough batches to drain DAG
|
|
336
|
+
// (earlier tests may have left pending jobs, so process generously)
|
|
337
|
+
for (let i = 0; i < 10; i++) {
|
|
338
|
+
await runner.processOnce(20);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
const jobs = queue.getByPipeline(pipelineId);
|
|
342
|
+
const statuses = jobs.map((j) => `${j.type}:${j.status}`);
|
|
343
|
+
|
|
344
|
+
expect(statuses).toEqual([
|
|
345
|
+
'quality-gate:completed',
|
|
346
|
+
'tag-normalize:completed',
|
|
347
|
+
'dedup-check:completed',
|
|
348
|
+
'classify:completed',
|
|
349
|
+
'auto-link:completed',
|
|
350
|
+
]);
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
it('queue stats reflect pipeline completion', () => {
|
|
354
|
+
const stats = queue.getStats();
|
|
355
|
+
expect(stats.completed).toBeGreaterThan(5);
|
|
356
|
+
expect(stats.total).toBeGreaterThan(10);
|
|
357
|
+
});
|
|
358
|
+
});
|