@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
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import {
|
|
3
|
+
resolveToken,
|
|
4
|
+
listProjectTokens,
|
|
5
|
+
buildReverseIndex,
|
|
6
|
+
} from '../domain-packs/token-resolver.js';
|
|
7
|
+
import type { PackProjectContext } from '../domain-packs/pack-runtime.js';
|
|
8
|
+
|
|
9
|
+
const mockProject: PackProjectContext = {
|
|
10
|
+
id: 'test-project',
|
|
11
|
+
name: 'Test Project',
|
|
12
|
+
path: '/test',
|
|
13
|
+
colors: {
|
|
14
|
+
primary: {
|
|
15
|
+
base: '#3B82F6',
|
|
16
|
+
scale: { '50': '#EFF6FF', '100': '#DBEAFE', '500': '#3B82F6', '900': '#1E3A5F' },
|
|
17
|
+
},
|
|
18
|
+
neutral: {
|
|
19
|
+
base: '#6B7280',
|
|
20
|
+
scale: { '50': '#F9FAFB', '100': '#F3F4F6', '500': '#6B7280', '900': '#111827' },
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
semanticTokens: {
|
|
24
|
+
'text-inverse': '#FFFFFF',
|
|
25
|
+
'bg-surface': '#F9FAFB',
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
describe('resolveToken', () => {
|
|
30
|
+
it('should pass through hex values', () => {
|
|
31
|
+
expect(resolveToken('#FF0000', mockProject)).toBe('#FF0000');
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
it('should resolve named colors', () => {
|
|
35
|
+
expect(resolveToken('white', mockProject)).toBe('#FFFFFF');
|
|
36
|
+
expect(resolveToken('black', mockProject)).toBe('#000000');
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
it('should resolve semantic tokens', () => {
|
|
40
|
+
expect(resolveToken('text-inverse', mockProject)).toBe('#FFFFFF');
|
|
41
|
+
expect(resolveToken('bg-surface', mockProject)).toBe('#F9FAFB');
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('should resolve SCALE[SHADE] format', () => {
|
|
45
|
+
expect(resolveToken('PRIMARY[500]', mockProject)).toBe('#3B82F6');
|
|
46
|
+
expect(resolveToken('neutral[900]', mockProject)).toBe('#111827');
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
it('should resolve Tailwind-style tokens', () => {
|
|
50
|
+
expect(resolveToken('bg-primary-500', mockProject)).toBe('#3B82F6');
|
|
51
|
+
expect(resolveToken('text-neutral-900', mockProject)).toBe('#111827');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('should throw for unknown tokens', () => {
|
|
55
|
+
expect(() => resolveToken('unknown-token', mockProject)).toThrow('Cannot resolve');
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('should throw for unknown scales', () => {
|
|
59
|
+
expect(() => resolveToken('ACCENT[500]', mockProject)).toThrow('Unknown color scale');
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
describe('listProjectTokens', () => {
|
|
64
|
+
it('should list all scale and semantic tokens', () => {
|
|
65
|
+
const tokens = listProjectTokens(mockProject);
|
|
66
|
+
expect(tokens.length).toBeGreaterThan(0);
|
|
67
|
+
expect(tokens.some((t) => t.token === 'primary-500')).toBe(true);
|
|
68
|
+
expect(tokens.some((t) => t.token === 'text-inverse')).toBe(true);
|
|
69
|
+
expect(tokens.some((t) => t.scale === 'semantic')).toBe(true);
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
describe('buildReverseIndex', () => {
|
|
74
|
+
it('should map hex to token name', () => {
|
|
75
|
+
const index = buildReverseIndex(mockProject);
|
|
76
|
+
expect(index.get('#3B82F6')).toBe('primary-500');
|
|
77
|
+
expect(index.get('#FFFFFF')).toBe('text-inverse');
|
|
78
|
+
});
|
|
79
|
+
});
|
|
@@ -15,6 +15,7 @@ import { watch, readFileSync, existsSync } from 'node:fs';
|
|
|
15
15
|
import { join, extname } from 'node:path';
|
|
16
16
|
import type { FSWatcher } from 'node:fs';
|
|
17
17
|
import type { Vault } from '../vault/vault.js';
|
|
18
|
+
import { DEFAULT_SUGGESTION_RULES } from './default-rules.js';
|
|
18
19
|
import type {
|
|
19
20
|
AgencyConfig,
|
|
20
21
|
AgencyStatus,
|
|
@@ -24,6 +25,11 @@ import type {
|
|
|
24
25
|
WarningDetector,
|
|
25
26
|
SurfacedPattern,
|
|
26
27
|
ClarificationQuestion,
|
|
28
|
+
SuggestionRule,
|
|
29
|
+
SuggestionContext,
|
|
30
|
+
ProactiveSuggestion,
|
|
31
|
+
RichClarificationQuestion,
|
|
32
|
+
Notification,
|
|
27
33
|
} from './types.js';
|
|
28
34
|
|
|
29
35
|
// ─── Defaults ──────────────────────────────────────────────────────
|
|
@@ -57,6 +63,14 @@ export class AgencyManager {
|
|
|
57
63
|
private cooldownMap = new Map<string, number>();
|
|
58
64
|
private debounceTimers = new Map<string, ReturnType<typeof setTimeout>>();
|
|
59
65
|
|
|
66
|
+
// Proactive intelligence (#211)
|
|
67
|
+
private suggestionRules: SuggestionRule[] = [];
|
|
68
|
+
private recentFiles: FileChange[] = [];
|
|
69
|
+
private suppressedWarningIds = new Set<string>();
|
|
70
|
+
private dismissedPatterns = new Map<string, number>(); // entryId → dismissedAt timestamp
|
|
71
|
+
private dismissalTtlMs = 24 * 60 * 60 * 1000; // 24 hours
|
|
72
|
+
private notificationQueue: Notification[] = [];
|
|
73
|
+
|
|
60
74
|
constructor(vault: Vault, config?: AgencyConfig) {
|
|
61
75
|
this.vault = vault;
|
|
62
76
|
this.config = {
|
|
@@ -68,6 +82,11 @@ export class AgencyManager {
|
|
|
68
82
|
minPatternConfidence: config?.minPatternConfidence ?? DEFAULT_MIN_CONFIDENCE,
|
|
69
83
|
cooldownMs: config?.cooldownMs ?? DEFAULT_COOLDOWN_MS,
|
|
70
84
|
};
|
|
85
|
+
|
|
86
|
+
// Register built-in suggestion rules
|
|
87
|
+
for (const rule of DEFAULT_SUGGESTION_RULES) {
|
|
88
|
+
this.suggestionRules.push(rule);
|
|
89
|
+
}
|
|
71
90
|
}
|
|
72
91
|
|
|
73
92
|
// ─── Lifecycle ──────────────────────────────────────────────────
|
|
@@ -84,15 +103,7 @@ export class AgencyManager {
|
|
|
84
103
|
}
|
|
85
104
|
|
|
86
105
|
getStatus(): AgencyStatus {
|
|
87
|
-
return
|
|
88
|
-
enabled: this.config.enabled,
|
|
89
|
-
watching: this.watchers.length > 0,
|
|
90
|
-
watchPaths: this.config.watchPaths,
|
|
91
|
-
detectorCount: this.detectors.length,
|
|
92
|
-
pendingWarnings: this.pendingWarnings.length,
|
|
93
|
-
surfacedPatterns: this.surfacedPatterns.length,
|
|
94
|
-
fileChangesProcessed: this.changesProcessed,
|
|
95
|
-
};
|
|
106
|
+
return this.getFullStatus();
|
|
96
107
|
}
|
|
97
108
|
|
|
98
109
|
updateConfig(config: Partial<AgencyConfig>): void {
|
|
@@ -323,4 +334,201 @@ export class AgencyManager {
|
|
|
323
334
|
const ext = extname(filePath);
|
|
324
335
|
return this.config.extensions.includes(ext);
|
|
325
336
|
}
|
|
337
|
+
|
|
338
|
+
// ─── Proactive Suggestions (#211) ──────────────────────────────────
|
|
339
|
+
|
|
340
|
+
registerSuggestionRule(rule: SuggestionRule): void {
|
|
341
|
+
this.suggestionRules.push(rule);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Evaluate all suggestion rules and return triggered suggestions.
|
|
346
|
+
*/
|
|
347
|
+
generateSuggestions(): ProactiveSuggestion[] {
|
|
348
|
+
const context: SuggestionContext = {
|
|
349
|
+
recentFiles: this.recentFiles.slice(-20),
|
|
350
|
+
pendingWarnings: this.pendingWarnings,
|
|
351
|
+
surfacedPatterns: this.surfacedPatterns,
|
|
352
|
+
fileChangesProcessed: this.changesProcessed,
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
const suggestions: ProactiveSuggestion[] = [];
|
|
356
|
+
for (const rule of this.suggestionRules) {
|
|
357
|
+
try {
|
|
358
|
+
if (rule.condition(context)) {
|
|
359
|
+
suggestions.push(rule.generate(context));
|
|
360
|
+
}
|
|
361
|
+
} catch {
|
|
362
|
+
// Rule failure is non-critical
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// Create notifications for suggestions
|
|
367
|
+
for (const s of suggestions) {
|
|
368
|
+
this.pushNotification('suggestion', s.title, s.description, s.priority);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
return suggestions.sort((a, b) => {
|
|
372
|
+
const prio = { high: 0, medium: 1, low: 2 };
|
|
373
|
+
return prio[a.priority] - prio[b.priority];
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
// ─── Rich Clarification (#211) ─────────────────────────────────────
|
|
378
|
+
|
|
379
|
+
generateRichClarification(prompt: string): RichClarificationQuestion[] {
|
|
380
|
+
const questions: RichClarificationQuestion[] = [];
|
|
381
|
+
|
|
382
|
+
// Ambiguous scope detection
|
|
383
|
+
const scopeWords = ['everything', 'all', 'the whole', 'entire'];
|
|
384
|
+
if (scopeWords.some((w) => prompt.toLowerCase().includes(w))) {
|
|
385
|
+
questions.push({
|
|
386
|
+
question: 'That sounds like a broad scope. Can you narrow it down?',
|
|
387
|
+
reason: 'Broad requests often lead to unfocused work',
|
|
388
|
+
urgency: 'recommended',
|
|
389
|
+
options: [
|
|
390
|
+
{ label: 'Just the current file', description: 'Focus on what I have open' },
|
|
391
|
+
{ label: 'This module/directory', description: 'Scope to the current package' },
|
|
392
|
+
{
|
|
393
|
+
label: 'The full project',
|
|
394
|
+
description: 'I really mean everything',
|
|
395
|
+
implications: 'This may take significantly longer',
|
|
396
|
+
},
|
|
397
|
+
],
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// Missing context detection
|
|
402
|
+
const vagueVerbs = ['fix', 'improve', 'update', 'change'];
|
|
403
|
+
const hasVagueVerb = vagueVerbs.some((v) => prompt.toLowerCase().startsWith(v));
|
|
404
|
+
const isShort = prompt.split(/\s+/).length < 5;
|
|
405
|
+
if (hasVagueVerb && isShort) {
|
|
406
|
+
questions.push({
|
|
407
|
+
question: 'Could you describe the specific problem or desired outcome?',
|
|
408
|
+
reason: `"${prompt}" is ambiguous — different interpretations lead to different solutions`,
|
|
409
|
+
urgency: 'blocking',
|
|
410
|
+
options: [
|
|
411
|
+
{ label: "There's an error/bug", description: 'Something is broken' },
|
|
412
|
+
{ label: 'It works but needs improvement', description: 'Refactoring or enhancement' },
|
|
413
|
+
{ label: 'Add new behavior', description: 'Feature addition' },
|
|
414
|
+
],
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
// Destructive operation detection
|
|
419
|
+
const destructiveWords = ['delete', 'remove', 'drop', 'reset', 'wipe', 'purge'];
|
|
420
|
+
if (destructiveWords.some((w) => prompt.toLowerCase().includes(w))) {
|
|
421
|
+
questions.push({
|
|
422
|
+
question: 'This sounds like a destructive operation. Are you sure?',
|
|
423
|
+
reason: 'Destructive actions are hard to undo',
|
|
424
|
+
urgency: 'blocking',
|
|
425
|
+
options: [
|
|
426
|
+
{
|
|
427
|
+
label: 'Yes, proceed',
|
|
428
|
+
description: 'I understand the consequences',
|
|
429
|
+
recommended: false,
|
|
430
|
+
},
|
|
431
|
+
{
|
|
432
|
+
label: 'Let me reconsider',
|
|
433
|
+
description: 'Show me what would be affected first',
|
|
434
|
+
recommended: true,
|
|
435
|
+
},
|
|
436
|
+
],
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
return questions;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// ─── Warning Suppression (#211) ────────────────────────────────────
|
|
444
|
+
|
|
445
|
+
suppressWarning(warningId: string): void {
|
|
446
|
+
this.suppressedWarningIds.add(warningId);
|
|
447
|
+
this.pendingWarnings = this.pendingWarnings.filter((w) => w.id !== warningId);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
unsuppressWarning(warningId: string): void {
|
|
451
|
+
this.suppressedWarningIds.delete(warningId);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
getSuppressedWarnings(): string[] {
|
|
455
|
+
return [...this.suppressedWarningIds];
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Override getPendingWarnings to filter out suppressed.
|
|
460
|
+
*/
|
|
461
|
+
getFilteredWarnings(): Warning[] {
|
|
462
|
+
return this.pendingWarnings.filter((w) => !this.suppressedWarningIds.has(w.id));
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// ─── Pattern Dismissal (#211) ──────────────────────────────────────
|
|
466
|
+
|
|
467
|
+
dismissPattern(entryId: string): void {
|
|
468
|
+
this.dismissedPatterns.set(entryId, Date.now());
|
|
469
|
+
this.surfacedPatterns = this.surfacedPatterns.filter((p) => p.entryId !== entryId);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
isDismissed(entryId: string): boolean {
|
|
473
|
+
const dismissedAt = this.dismissedPatterns.get(entryId);
|
|
474
|
+
if (!dismissedAt) return false;
|
|
475
|
+
if (Date.now() - dismissedAt > this.dismissalTtlMs) {
|
|
476
|
+
this.dismissedPatterns.delete(entryId);
|
|
477
|
+
return false;
|
|
478
|
+
}
|
|
479
|
+
return true;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
getActiveSurfacedPatterns(): SurfacedPattern[] {
|
|
483
|
+
return this.surfacedPatterns.filter((p) => !this.isDismissed(p.entryId));
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
// ─── Notification Queue (#211) ─────────────────────────────────────
|
|
487
|
+
|
|
488
|
+
pushNotification(
|
|
489
|
+
type: Notification['type'],
|
|
490
|
+
title: string,
|
|
491
|
+
message: string,
|
|
492
|
+
priority: Notification['priority'] = 'medium',
|
|
493
|
+
): void {
|
|
494
|
+
this.notificationQueue.push({
|
|
495
|
+
id: `notif-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
|
496
|
+
type,
|
|
497
|
+
title,
|
|
498
|
+
message,
|
|
499
|
+
priority,
|
|
500
|
+
createdAt: Date.now(),
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
drainNotifications(): Notification[] {
|
|
505
|
+
const notifications = [...this.notificationQueue];
|
|
506
|
+
this.notificationQueue = [];
|
|
507
|
+
return notifications.sort((a, b) => {
|
|
508
|
+
const prio = { high: 0, medium: 1, low: 2 };
|
|
509
|
+
return prio[a.priority] - prio[b.priority];
|
|
510
|
+
});
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
getPendingNotificationCount(): number {
|
|
514
|
+
return this.notificationQueue.length;
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
// ─── Extended Status (#211) ────────────────────────────────────────
|
|
518
|
+
|
|
519
|
+
getFullStatus(): AgencyStatus {
|
|
520
|
+
return {
|
|
521
|
+
enabled: this.config.enabled,
|
|
522
|
+
watching: this.watchers.length > 0,
|
|
523
|
+
watchPaths: this.config.watchPaths,
|
|
524
|
+
detectorCount: this.detectors.length,
|
|
525
|
+
pendingWarnings: this.getFilteredWarnings().length,
|
|
526
|
+
surfacedPatterns: this.getActiveSurfacedPatterns().length,
|
|
527
|
+
fileChangesProcessed: this.changesProcessed,
|
|
528
|
+
suggestionRuleCount: this.suggestionRules.length,
|
|
529
|
+
suppressedWarnings: this.suppressedWarningIds.size,
|
|
530
|
+
dismissedPatterns: this.dismissedPatterns.size,
|
|
531
|
+
pendingNotifications: this.notificationQueue.length,
|
|
532
|
+
};
|
|
533
|
+
}
|
|
326
534
|
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default suggestion rules — 6 built-in rules that work for any agent.
|
|
3
|
+
* Registered on agent startup so agency_suggestions works out of the box.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { SuggestionRule } from './types.js';
|
|
7
|
+
|
|
8
|
+
export const DEFAULT_SUGGESTION_RULES: SuggestionRule[] = [
|
|
9
|
+
{
|
|
10
|
+
name: 'many-warnings',
|
|
11
|
+
description: 'Fires when 5+ warnings are pending',
|
|
12
|
+
condition: (ctx) => ctx.pendingWarnings.length >= 5,
|
|
13
|
+
generate: (ctx) => ({
|
|
14
|
+
rule: 'many-warnings',
|
|
15
|
+
title: `${ctx.pendingWarnings.length} warnings pending`,
|
|
16
|
+
description: `You have ${ctx.pendingWarnings.length} unresolved warnings — consider running a scan or addressing the critical ones.`,
|
|
17
|
+
priority: 'high',
|
|
18
|
+
action: 'Run agency_warnings to review',
|
|
19
|
+
}),
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: 'stale-patterns',
|
|
23
|
+
description: 'Fires when surfaced patterns suggest stale knowledge',
|
|
24
|
+
condition: (ctx) => ctx.surfacedPatterns.length === 0 && ctx.fileChangesProcessed > 20,
|
|
25
|
+
generate: () => ({
|
|
26
|
+
rule: 'stale-patterns',
|
|
27
|
+
title: 'Knowledge base maintenance recommended',
|
|
28
|
+
description:
|
|
29
|
+
'No patterns surfaced despite significant file activity — vault may need grooming or new knowledge.',
|
|
30
|
+
priority: 'medium',
|
|
31
|
+
action: 'Run curator_health_audit',
|
|
32
|
+
}),
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: 'high-activity-no-capture',
|
|
36
|
+
description: 'Fires when many files changed but no patterns captured',
|
|
37
|
+
condition: (ctx) => ctx.fileChangesProcessed > 50 && ctx.surfacedPatterns.length === 0,
|
|
38
|
+
generate: (ctx) => ({
|
|
39
|
+
rule: 'high-activity-no-capture',
|
|
40
|
+
title: 'Long session without knowledge capture',
|
|
41
|
+
description: `${ctx.fileChangesProcessed} file changes processed — consider capturing what you've learned.`,
|
|
42
|
+
priority: 'medium',
|
|
43
|
+
action: 'Run smart_capture or radar_analyze',
|
|
44
|
+
}),
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: 'critical-warnings',
|
|
48
|
+
description: 'Fires when critical-severity warnings exist',
|
|
49
|
+
condition: (ctx) => ctx.pendingWarnings.some((w) => w.severity === 'critical'),
|
|
50
|
+
generate: (ctx) => {
|
|
51
|
+
const critical = ctx.pendingWarnings.filter((w) => w.severity === 'critical');
|
|
52
|
+
return {
|
|
53
|
+
rule: 'critical-warnings',
|
|
54
|
+
title: `${critical.length} critical warning(s) need attention`,
|
|
55
|
+
description: critical.map((w) => w.message).join('; '),
|
|
56
|
+
priority: 'high',
|
|
57
|
+
};
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: 'pattern-surfaced',
|
|
62
|
+
description: 'Fires when relevant vault patterns were found for changed files',
|
|
63
|
+
condition: (ctx) => ctx.surfacedPatterns.length > 0,
|
|
64
|
+
generate: (ctx) => ({
|
|
65
|
+
rule: 'pattern-surfaced',
|
|
66
|
+
title: `${ctx.surfacedPatterns.length} relevant pattern(s) found`,
|
|
67
|
+
description: ctx.surfacedPatterns.map((p) => `${p.title} (${p.domain})`).join(', '),
|
|
68
|
+
priority: 'low',
|
|
69
|
+
}),
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: 'first-session',
|
|
73
|
+
description: 'Fires on first use when no file changes have been processed',
|
|
74
|
+
condition: (ctx) => ctx.fileChangesProcessed === 0 && ctx.pendingWarnings.length === 0,
|
|
75
|
+
generate: () => ({
|
|
76
|
+
rule: 'first-session',
|
|
77
|
+
title: 'Agency mode ready',
|
|
78
|
+
description:
|
|
79
|
+
'File watching and proactive suggestions are enabled. Start editing files to see patterns and warnings.',
|
|
80
|
+
priority: 'low',
|
|
81
|
+
}),
|
|
82
|
+
},
|
|
83
|
+
];
|
package/src/agency/types.ts
CHANGED
|
@@ -85,4 +85,65 @@ export interface AgencyStatus {
|
|
|
85
85
|
pendingWarnings: number;
|
|
86
86
|
surfacedPatterns: number;
|
|
87
87
|
fileChangesProcessed: number;
|
|
88
|
+
suggestionRuleCount: number;
|
|
89
|
+
suppressedWarnings: number;
|
|
90
|
+
dismissedPatterns: number;
|
|
91
|
+
pendingNotifications: number;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// ─── Proactive Suggestions (#211) ────────────────────────────────────
|
|
95
|
+
|
|
96
|
+
export interface SuggestionRule {
|
|
97
|
+
/** Unique name for this rule. */
|
|
98
|
+
name: string;
|
|
99
|
+
/** Human description of what this rule detects. */
|
|
100
|
+
description: string;
|
|
101
|
+
/** Condition: returns true if this rule should fire. */
|
|
102
|
+
condition(context: SuggestionContext): boolean;
|
|
103
|
+
/** Generate a suggestion when condition is true. */
|
|
104
|
+
generate(context: SuggestionContext): ProactiveSuggestion;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface SuggestionContext {
|
|
108
|
+
recentFiles: FileChange[];
|
|
109
|
+
pendingWarnings: Warning[];
|
|
110
|
+
surfacedPatterns: SurfacedPattern[];
|
|
111
|
+
fileChangesProcessed: number;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export interface ProactiveSuggestion {
|
|
115
|
+
rule: string;
|
|
116
|
+
title: string;
|
|
117
|
+
description: string;
|
|
118
|
+
priority: 'high' | 'medium' | 'low';
|
|
119
|
+
action?: string;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// ─── Rich Clarification (#211) ───────────────────────────────────────
|
|
123
|
+
|
|
124
|
+
export type ClarificationUrgency = 'blocking' | 'recommended' | 'optional';
|
|
125
|
+
|
|
126
|
+
export interface ClarificationOption {
|
|
127
|
+
label: string;
|
|
128
|
+
description?: string;
|
|
129
|
+
implications?: string;
|
|
130
|
+
recommended?: boolean;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export interface RichClarificationQuestion {
|
|
134
|
+
question: string;
|
|
135
|
+
reason: string;
|
|
136
|
+
urgency: ClarificationUrgency;
|
|
137
|
+
options?: ClarificationOption[];
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// ─── Notifications (#211) ────────────────────────────────────────────
|
|
141
|
+
|
|
142
|
+
export interface Notification {
|
|
143
|
+
id: string;
|
|
144
|
+
type: 'suggestion' | 'warning' | 'pattern';
|
|
145
|
+
title: string;
|
|
146
|
+
message: string;
|
|
147
|
+
priority: 'high' | 'medium' | 'low';
|
|
148
|
+
createdAt: number;
|
|
88
149
|
}
|
package/src/brain/brain.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Vault } from '../vault/vault.js';
|
|
2
2
|
import type { SearchResult } from '../vault/vault.js';
|
|
3
|
+
import type { VaultManager } from '../vault/vault-manager.js';
|
|
3
4
|
import type { IntelligenceEntry } from '../intelligence/types.js';
|
|
4
5
|
import { computeContentHash } from '../vault/content-hash.js';
|
|
5
6
|
import {
|
|
@@ -14,6 +15,7 @@ import type {
|
|
|
14
15
|
ScoringWeights,
|
|
15
16
|
ScoreBreakdown,
|
|
16
17
|
RankedResult,
|
|
18
|
+
ScanResult,
|
|
17
19
|
SearchOptions,
|
|
18
20
|
CaptureResult,
|
|
19
21
|
BrainStats,
|
|
@@ -59,12 +61,14 @@ const RECENCY_HALF_LIFE_DAYS = 365;
|
|
|
59
61
|
|
|
60
62
|
export class Brain {
|
|
61
63
|
private vault: Vault;
|
|
64
|
+
private vaultManager: VaultManager | undefined;
|
|
62
65
|
private cognee: CogneeClient | undefined;
|
|
63
66
|
private vocabulary: Map<string, number> = new Map();
|
|
64
67
|
private weights: ScoringWeights = { ...DEFAULT_WEIGHTS };
|
|
65
68
|
|
|
66
|
-
constructor(vault: Vault, cognee?: CogneeClient) {
|
|
69
|
+
constructor(vault: Vault, cognee?: CogneeClient, vaultManager?: VaultManager) {
|
|
67
70
|
this.vault = vault;
|
|
71
|
+
this.vaultManager = vaultManager;
|
|
68
72
|
this.cognee = cognee;
|
|
69
73
|
this.rebuildVocabulary();
|
|
70
74
|
this.recomputeWeights();
|
|
@@ -72,12 +76,31 @@ export class Brain {
|
|
|
72
76
|
|
|
73
77
|
async intelligentSearch(query: string, options?: SearchOptions): Promise<RankedResult[]> {
|
|
74
78
|
const limit = options?.limit ?? 10;
|
|
75
|
-
const
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
79
|
+
const fetchLimit = Math.max(limit * 3, 30);
|
|
80
|
+
|
|
81
|
+
// Use VaultManager when available to search across all connected sources
|
|
82
|
+
// (agent tier + shared vault + dynamically connected external vaults).
|
|
83
|
+
// Falls back to single vault search when no manager is present.
|
|
84
|
+
let rawResults: SearchResult[];
|
|
85
|
+
if (this.vaultManager) {
|
|
86
|
+
rawResults = this.vaultManager.search(query, fetchLimit);
|
|
87
|
+
// Apply domain/type/severity filters that VaultManager.search() doesn't support
|
|
88
|
+
if (options?.domain || options?.type || options?.severity) {
|
|
89
|
+
rawResults = rawResults.filter((r) => {
|
|
90
|
+
if (options.domain && r.entry.domain !== options.domain) return false;
|
|
91
|
+
if (options.type && r.entry.type !== options.type) return false;
|
|
92
|
+
if (options.severity && r.entry.severity !== options.severity) return false;
|
|
93
|
+
return true;
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
} else {
|
|
97
|
+
rawResults = this.vault.search(query, {
|
|
98
|
+
domain: options?.domain,
|
|
99
|
+
type: options?.type,
|
|
100
|
+
severity: options?.severity,
|
|
101
|
+
limit: fetchLimit,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
81
104
|
|
|
82
105
|
// Cognee vector search (parallel, with timeout fallback)
|
|
83
106
|
let cogneeScoreMap: Map<string, number> = new Map();
|
|
@@ -212,6 +235,49 @@ export class Brain {
|
|
|
212
235
|
return ranked.slice(0, limit);
|
|
213
236
|
}
|
|
214
237
|
|
|
238
|
+
/**
|
|
239
|
+
* Two-pass retrieval — Pass 1: Scan.
|
|
240
|
+
* Returns lightweight results (title, score, snippet) without full entry bodies.
|
|
241
|
+
* Use `loadEntries()` for Pass 2 to fetch full content for selected entries.
|
|
242
|
+
*/
|
|
243
|
+
async scanSearch(query: string, options?: Omit<SearchOptions, 'mode'>): Promise<ScanResult[]> {
|
|
244
|
+
const fullResults = await this.intelligentSearch(query, { ...options, mode: 'full' });
|
|
245
|
+
return fullResults.map((r) => ({
|
|
246
|
+
id: r.entry.id,
|
|
247
|
+
title: r.entry.title,
|
|
248
|
+
score: r.score,
|
|
249
|
+
type: r.entry.type,
|
|
250
|
+
domain: r.entry.domain,
|
|
251
|
+
severity: r.entry.severity,
|
|
252
|
+
tags: r.entry.tags,
|
|
253
|
+
snippet: r.entry.description.slice(0, 120) + (r.entry.description.length > 120 ? '...' : ''),
|
|
254
|
+
tokenEstimate: this.estimateTokens(r.entry),
|
|
255
|
+
}));
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Two-pass retrieval — Pass 2: Load.
|
|
260
|
+
* Returns full entries for specific IDs (from a previous scan).
|
|
261
|
+
*/
|
|
262
|
+
loadEntries(ids: string[]): IntelligenceEntry[] {
|
|
263
|
+
const results: IntelligenceEntry[] = [];
|
|
264
|
+
for (const id of ids) {
|
|
265
|
+
const entry = this.vault.get(id);
|
|
266
|
+
if (entry) results.push(entry);
|
|
267
|
+
}
|
|
268
|
+
return results;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/** Rough token estimate for an entry (chars / 4). */
|
|
272
|
+
private estimateTokens(entry: IntelligenceEntry): number {
|
|
273
|
+
let chars = entry.title.length + entry.description.length;
|
|
274
|
+
if (entry.context) chars += entry.context.length;
|
|
275
|
+
if (entry.example) chars += entry.example.length;
|
|
276
|
+
if (entry.counterExample) chars += entry.counterExample.length;
|
|
277
|
+
if (entry.why) chars += entry.why.length;
|
|
278
|
+
return Math.ceil(chars / 4);
|
|
279
|
+
}
|
|
280
|
+
|
|
215
281
|
enrichAndCapture(
|
|
216
282
|
entry: Partial<IntelligenceEntry> & {
|
|
217
283
|
id: string;
|
|
@@ -426,7 +492,43 @@ export class Brain {
|
|
|
426
492
|
}
|
|
427
493
|
|
|
428
494
|
rebuildVocabulary(): void {
|
|
429
|
-
|
|
495
|
+
// Collect entries from all connected sources when VaultManager is available
|
|
496
|
+
let entries: IntelligenceEntry[];
|
|
497
|
+
if (this.vaultManager) {
|
|
498
|
+
const seen = new Set<string>();
|
|
499
|
+
entries = [];
|
|
500
|
+
// Gather entries from all tier vaults and connected sources via manager
|
|
501
|
+
for (const tierInfo of this.vaultManager.listTiers()) {
|
|
502
|
+
if (!tierInfo.connected) continue;
|
|
503
|
+
try {
|
|
504
|
+
const tierVault = this.vaultManager.getTier(tierInfo.tier);
|
|
505
|
+
for (const e of tierVault.list({ limit: 100000 })) {
|
|
506
|
+
if (!seen.has(e.id)) {
|
|
507
|
+
seen.add(e.id);
|
|
508
|
+
entries.push(e);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
} catch {
|
|
512
|
+
/* tier not connected */
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
for (const { name } of this.vaultManager.listConnected()) {
|
|
516
|
+
const cv = this.vaultManager.getConnected(name);
|
|
517
|
+
if (!cv) continue;
|
|
518
|
+
try {
|
|
519
|
+
for (const e of cv.vault.list({ limit: 100000 })) {
|
|
520
|
+
if (!seen.has(e.id)) {
|
|
521
|
+
seen.add(e.id);
|
|
522
|
+
entries.push(e);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
} catch {
|
|
526
|
+
/* source not accessible */
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
} else {
|
|
530
|
+
entries = this.vault.list({ limit: 100000 });
|
|
531
|
+
}
|
|
430
532
|
const docCount = entries.length;
|
|
431
533
|
if (docCount === 0) {
|
|
432
534
|
this.vocabulary.clear();
|
|
@@ -497,12 +497,31 @@ export class BrainIntelligence {
|
|
|
497
497
|
limit?: number;
|
|
498
498
|
}): PatternStrength[] {
|
|
499
499
|
const limit = context.limit ?? 5;
|
|
500
|
-
|
|
500
|
+
|
|
501
|
+
// Try domain-filtered first, fall back to all domains if too few results
|
|
502
|
+
let strengths = this.getStrengths({
|
|
501
503
|
domain: context.domain,
|
|
502
|
-
minStrength: 30
|
|
504
|
+
minStrength: 20, // lowered from 30 — small corpus needs lower threshold
|
|
503
505
|
limit: limit * 3,
|
|
504
506
|
});
|
|
505
507
|
|
|
508
|
+
// If domain-filtered returns too few, try without domain filter
|
|
509
|
+
// This handles cases where domain was stored as 'unknown' due to
|
|
510
|
+
// vault.get() returning null during computeStrengths
|
|
511
|
+
if (strengths.length < limit && context.domain) {
|
|
512
|
+
const allStrengths = this.getStrengths({
|
|
513
|
+
minStrength: 20,
|
|
514
|
+
limit: limit * 5,
|
|
515
|
+
});
|
|
516
|
+
// Include domain-matching AND entries where domain lookup failed
|
|
517
|
+
const additional = allStrengths.filter(
|
|
518
|
+
(s) =>
|
|
519
|
+
!strengths.some((existing) => existing.pattern === s.pattern) &&
|
|
520
|
+
(s.domain === context.domain || s.domain === 'unknown'),
|
|
521
|
+
);
|
|
522
|
+
strengths = [...strengths, ...additional];
|
|
523
|
+
}
|
|
524
|
+
|
|
506
525
|
// If task context provided, boost patterns with matching terms
|
|
507
526
|
if (context.task) {
|
|
508
527
|
const taskTerms = new Set(context.task.toLowerCase().split(/\W+/).filter(Boolean));
|