@soleri/core 2.10.0 → 2.11.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/dist/agency/agency-manager.d.ts +47 -0
- package/dist/agency/agency-manager.d.ts.map +1 -0
- package/dist/agency/agency-manager.js +281 -0
- package/dist/agency/agency-manager.js.map +1 -0
- package/dist/agency/index.d.ts +3 -0
- package/dist/agency/index.d.ts.map +1 -0
- package/dist/agency/index.js +2 -0
- package/dist/agency/index.js.map +1 -0
- package/dist/agency/types.d.ts +69 -0
- package/dist/agency/types.d.ts.map +1 -0
- package/dist/agency/types.js +5 -0
- package/dist/agency/types.js.map +1 -0
- package/dist/brain/brain.d.ts +0 -1
- package/dist/brain/brain.d.ts.map +1 -1
- package/dist/brain/brain.js +14 -0
- package/dist/brain/brain.js.map +1 -1
- package/dist/brain/intelligence.d.ts +5 -1
- package/dist/brain/intelligence.d.ts.map +1 -1
- package/dist/brain/intelligence.js +83 -0
- package/dist/brain/intelligence.js.map +1 -1
- package/dist/brain/types.d.ts +21 -0
- package/dist/brain/types.d.ts.map +1 -1
- package/dist/chat/agent-loop-types.d.ts +82 -0
- package/dist/chat/agent-loop-types.d.ts.map +1 -0
- package/dist/chat/agent-loop-types.js +8 -0
- package/dist/chat/agent-loop-types.js.map +1 -0
- package/dist/chat/agent-loop.d.ts +19 -0
- package/dist/chat/agent-loop.d.ts.map +1 -0
- package/dist/chat/agent-loop.js +261 -0
- package/dist/chat/agent-loop.js.map +1 -0
- package/dist/chat/auth-manager.d.ts +49 -0
- package/dist/chat/auth-manager.d.ts.map +1 -0
- package/dist/chat/auth-manager.js +152 -0
- package/dist/chat/auth-manager.js.map +1 -0
- package/dist/chat/browser-session.d.ts +86 -0
- package/dist/chat/browser-session.d.ts.map +1 -0
- package/dist/chat/browser-session.js +143 -0
- package/dist/chat/browser-session.js.map +1 -0
- package/dist/chat/cancellation.d.ts +54 -0
- package/dist/chat/cancellation.d.ts.map +1 -0
- package/dist/chat/cancellation.js +80 -0
- package/dist/chat/cancellation.js.map +1 -0
- package/dist/chat/chat-session.d.ts +86 -0
- package/dist/chat/chat-session.d.ts.map +1 -0
- package/dist/chat/chat-session.js +252 -0
- package/dist/chat/chat-session.js.map +1 -0
- package/dist/chat/file-handler.d.ts +63 -0
- package/dist/chat/file-handler.d.ts.map +1 -0
- package/dist/chat/file-handler.js +182 -0
- package/dist/chat/file-handler.js.map +1 -0
- package/dist/chat/fragment-buffer.d.ts +49 -0
- package/dist/chat/fragment-buffer.d.ts.map +1 -0
- package/dist/chat/fragment-buffer.js +130 -0
- package/dist/chat/fragment-buffer.js.map +1 -0
- package/dist/chat/index.d.ts +24 -0
- package/dist/chat/index.d.ts.map +1 -0
- package/dist/chat/index.js +15 -0
- package/dist/chat/index.js.map +1 -0
- package/dist/chat/mcp-bridge.d.ts +60 -0
- package/dist/chat/mcp-bridge.d.ts.map +1 -0
- package/dist/chat/mcp-bridge.js +111 -0
- package/dist/chat/mcp-bridge.js.map +1 -0
- package/dist/chat/notifications.d.ts +82 -0
- package/dist/chat/notifications.d.ts.map +1 -0
- package/dist/chat/notifications.js +119 -0
- package/dist/chat/notifications.js.map +1 -0
- package/dist/chat/output-compressor.d.ts +30 -0
- package/dist/chat/output-compressor.d.ts.map +1 -0
- package/dist/chat/output-compressor.js +95 -0
- package/dist/chat/output-compressor.js.map +1 -0
- package/dist/chat/queue.d.ts +91 -0
- package/dist/chat/queue.d.ts.map +1 -0
- package/dist/chat/queue.js +146 -0
- package/dist/chat/queue.js.map +1 -0
- package/dist/chat/response-chunker.d.ts +29 -0
- package/dist/chat/response-chunker.d.ts.map +1 -0
- package/dist/chat/response-chunker.js +163 -0
- package/dist/chat/response-chunker.js.map +1 -0
- package/dist/chat/self-update.d.ts +62 -0
- package/dist/chat/self-update.d.ts.map +1 -0
- package/dist/chat/self-update.js +90 -0
- package/dist/chat/self-update.js.map +1 -0
- package/dist/chat/types.d.ts +105 -0
- package/dist/chat/types.d.ts.map +1 -0
- package/dist/chat/types.js +8 -0
- package/dist/chat/types.js.map +1 -0
- package/dist/chat/voice.d.ts +39 -0
- package/dist/chat/voice.d.ts.map +1 -0
- package/dist/chat/voice.js +80 -0
- package/dist/chat/voice.js.map +1 -0
- package/dist/claudemd/compose.d.ts +31 -0
- package/dist/claudemd/compose.d.ts.map +1 -0
- package/dist/claudemd/compose.js +105 -0
- package/dist/claudemd/compose.js.map +1 -0
- package/dist/claudemd/index.d.ts +5 -0
- package/dist/claudemd/index.d.ts.map +1 -0
- package/dist/claudemd/index.js +3 -0
- package/dist/claudemd/index.js.map +1 -0
- package/dist/claudemd/inject.d.ts +31 -0
- package/dist/claudemd/inject.d.ts.map +1 -0
- package/dist/claudemd/inject.js +157 -0
- package/dist/claudemd/inject.js.map +1 -0
- package/dist/claudemd/types.d.ts +41 -0
- package/dist/claudemd/types.d.ts.map +1 -0
- package/dist/claudemd/types.js +5 -0
- package/dist/claudemd/types.js.map +1 -0
- package/dist/context/context-engine.d.ts +31 -0
- package/dist/context/context-engine.d.ts.map +1 -0
- package/dist/context/context-engine.js +245 -0
- package/dist/context/context-engine.js.map +1 -0
- package/dist/context/index.d.ts +3 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +2 -0
- package/dist/context/index.js.map +1 -0
- package/dist/context/types.d.ts +54 -0
- package/dist/context/types.d.ts.map +1 -0
- package/dist/context/types.js +5 -0
- package/dist/context/types.js.map +1 -0
- package/dist/enforcement/adapters/claude-code.d.ts +18 -0
- package/dist/enforcement/adapters/claude-code.d.ts.map +1 -0
- package/dist/enforcement/adapters/claude-code.js +106 -0
- package/dist/enforcement/adapters/claude-code.js.map +1 -0
- package/dist/enforcement/adapters/index.d.ts +2 -0
- package/dist/enforcement/adapters/index.d.ts.map +1 -0
- package/dist/enforcement/adapters/index.js +2 -0
- package/dist/enforcement/adapters/index.js.map +1 -0
- package/dist/enforcement/index.d.ts +4 -0
- package/dist/enforcement/index.d.ts.map +1 -0
- package/dist/enforcement/index.js +3 -0
- package/dist/enforcement/index.js.map +1 -0
- package/dist/enforcement/registry.d.ts +23 -0
- package/dist/enforcement/registry.d.ts.map +1 -0
- package/dist/enforcement/registry.js +63 -0
- package/dist/enforcement/registry.js.map +1 -0
- package/dist/enforcement/types.d.ts +51 -0
- package/dist/enforcement/types.d.ts.map +1 -0
- package/dist/enforcement/types.js +8 -0
- package/dist/enforcement/types.js.map +1 -0
- package/dist/facades/facade-factory.d.ts +10 -3
- package/dist/facades/facade-factory.d.ts.map +1 -1
- package/dist/facades/facade-factory.js +94 -5
- package/dist/facades/facade-factory.js.map +1 -1
- package/dist/facades/types.d.ts +15 -1
- package/dist/facades/types.d.ts.map +1 -1
- package/dist/facades/types.js +6 -0
- package/dist/facades/types.js.map +1 -1
- package/dist/health/health-registry.d.ts +40 -0
- package/dist/health/health-registry.d.ts.map +1 -0
- package/dist/health/health-registry.js +134 -0
- package/dist/health/health-registry.js.map +1 -0
- package/dist/health/index.d.ts +5 -0
- package/dist/health/index.d.ts.map +1 -0
- package/dist/health/index.js +3 -0
- package/dist/health/index.js.map +1 -0
- package/dist/health/vault-integrity.d.ts +13 -0
- package/dist/health/vault-integrity.d.ts.map +1 -0
- package/dist/health/vault-integrity.js +49 -0
- package/dist/health/vault-integrity.js.map +1 -0
- package/dist/index.d.ts +67 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +51 -3
- package/dist/index.js.map +1 -1
- package/dist/intake/intake-pipeline.d.ts +0 -7
- package/dist/intake/intake-pipeline.d.ts.map +1 -1
- package/dist/intake/intake-pipeline.js +1 -1
- package/dist/intake/intake-pipeline.js.map +1 -1
- package/dist/intelligence/types.d.ts +1 -0
- package/dist/intelligence/types.d.ts.map +1 -1
- package/dist/migrations/index.d.ts +6 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/index.js +5 -0
- package/dist/migrations/index.js.map +1 -0
- package/dist/migrations/migration-runner.d.ts +51 -0
- package/dist/migrations/migration-runner.d.ts.map +1 -0
- package/dist/migrations/migration-runner.js +141 -0
- package/dist/migrations/migration-runner.js.map +1 -0
- package/dist/packs/index.d.ts +10 -0
- package/dist/packs/index.d.ts.map +1 -0
- package/dist/packs/index.js +8 -0
- package/dist/packs/index.js.map +1 -0
- package/dist/packs/lockfile.d.ts +97 -0
- package/dist/packs/lockfile.d.ts.map +1 -0
- package/dist/packs/lockfile.js +129 -0
- package/dist/packs/lockfile.js.map +1 -0
- package/dist/packs/pack-installer.d.ts +41 -0
- package/dist/packs/pack-installer.d.ts.map +1 -0
- package/dist/packs/pack-installer.js +253 -0
- package/dist/packs/pack-installer.js.map +1 -0
- package/dist/packs/resolver.d.ts +51 -0
- package/dist/packs/resolver.d.ts.map +1 -0
- package/dist/packs/resolver.js +195 -0
- package/dist/packs/resolver.js.map +1 -0
- package/dist/packs/types.d.ts +186 -0
- package/dist/packs/types.d.ts.map +1 -0
- package/dist/packs/types.js +69 -0
- package/dist/packs/types.js.map +1 -0
- package/dist/persistence/postgres-provider.d.ts +42 -7
- package/dist/persistence/postgres-provider.d.ts.map +1 -1
- package/dist/persistence/postgres-provider.js +187 -46
- package/dist/persistence/postgres-provider.js.map +1 -1
- package/dist/playbooks/index.d.ts +2 -0
- package/dist/playbooks/index.d.ts.map +1 -1
- package/dist/playbooks/index.js +2 -0
- package/dist/playbooks/index.js.map +1 -1
- package/dist/playbooks/playbook-executor.d.ts +100 -0
- package/dist/playbooks/playbook-executor.d.ts.map +1 -0
- package/dist/playbooks/playbook-executor.js +207 -0
- package/dist/playbooks/playbook-executor.js.map +1 -0
- package/dist/plugins/index.d.ts +7 -0
- package/dist/plugins/index.d.ts.map +1 -0
- package/dist/plugins/index.js +7 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/plugin-loader.d.ts +28 -0
- package/dist/plugins/plugin-loader.d.ts.map +1 -0
- package/dist/plugins/plugin-loader.js +150 -0
- package/dist/plugins/plugin-loader.js.map +1 -0
- package/dist/plugins/plugin-registry.d.ts +58 -0
- package/dist/plugins/plugin-registry.d.ts.map +1 -0
- package/dist/plugins/plugin-registry.js +157 -0
- package/dist/plugins/plugin-registry.js.map +1 -0
- package/dist/plugins/types.d.ts +180 -0
- package/dist/plugins/types.d.ts.map +1 -0
- package/dist/plugins/types.js +48 -0
- package/dist/plugins/types.js.map +1 -0
- package/dist/runtime/admin-extra-ops.d.ts.map +1 -1
- package/dist/runtime/admin-extra-ops.js +181 -8
- package/dist/runtime/admin-extra-ops.js.map +1 -1
- package/dist/runtime/capture-ops.d.ts.map +1 -1
- package/dist/runtime/capture-ops.js +106 -7
- package/dist/runtime/capture-ops.js.map +1 -1
- package/dist/runtime/deprecation.d.ts +33 -0
- package/dist/runtime/deprecation.d.ts.map +1 -0
- package/dist/runtime/deprecation.js +41 -0
- package/dist/runtime/deprecation.js.map +1 -0
- package/dist/runtime/facades/admin-facade.d.ts.map +1 -1
- package/dist/runtime/facades/admin-facade.js +12 -1
- package/dist/runtime/facades/admin-facade.js.map +1 -1
- package/dist/runtime/facades/agency-facade.d.ts +7 -0
- package/dist/runtime/facades/agency-facade.d.ts.map +1 -0
- package/dist/runtime/facades/agency-facade.js +103 -0
- package/dist/runtime/facades/agency-facade.js.map +1 -0
- package/dist/runtime/facades/brain-facade.d.ts.map +1 -1
- package/dist/runtime/facades/brain-facade.js +58 -0
- package/dist/runtime/facades/brain-facade.js.map +1 -1
- package/dist/runtime/facades/chat-facade.d.ts +7 -0
- package/dist/runtime/facades/chat-facade.d.ts.map +1 -0
- package/dist/runtime/facades/chat-facade.js +808 -0
- package/dist/runtime/facades/chat-facade.js.map +1 -0
- package/dist/runtime/facades/context-facade.d.ts +7 -0
- package/dist/runtime/facades/context-facade.d.ts.map +1 -0
- package/dist/runtime/facades/context-facade.js +45 -0
- package/dist/runtime/facades/context-facade.js.map +1 -0
- package/dist/runtime/facades/index.d.ts.map +1 -1
- package/dist/runtime/facades/index.js +18 -0
- package/dist/runtime/facades/index.js.map +1 -1
- package/dist/runtime/facades/vault-facade.d.ts.map +1 -1
- package/dist/runtime/facades/vault-facade.js +247 -1
- package/dist/runtime/facades/vault-facade.js.map +1 -1
- package/dist/runtime/feature-flags.d.ts +18 -0
- package/dist/runtime/feature-flags.d.ts.map +1 -0
- package/dist/runtime/feature-flags.js +90 -0
- package/dist/runtime/feature-flags.js.map +1 -0
- package/dist/runtime/pack-ops.d.ts +9 -0
- package/dist/runtime/pack-ops.d.ts.map +1 -0
- package/dist/runtime/pack-ops.js +76 -0
- package/dist/runtime/pack-ops.js.map +1 -0
- package/dist/runtime/playbook-ops.d.ts +3 -7
- package/dist/runtime/playbook-ops.d.ts.map +1 -1
- package/dist/runtime/playbook-ops.js +101 -10
- package/dist/runtime/playbook-ops.js.map +1 -1
- package/dist/runtime/plugin-ops.d.ts +9 -0
- package/dist/runtime/plugin-ops.d.ts.map +1 -0
- package/dist/runtime/plugin-ops.js +235 -0
- package/dist/runtime/plugin-ops.js.map +1 -0
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +72 -5
- package/dist/runtime/runtime.js.map +1 -1
- package/dist/runtime/telemetry-ops.d.ts +10 -0
- package/dist/runtime/telemetry-ops.d.ts.map +1 -0
- package/dist/runtime/telemetry-ops.js +53 -0
- package/dist/runtime/telemetry-ops.js.map +1 -0
- package/dist/runtime/types.d.ts +35 -0
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/vault-sharing-ops.d.ts +13 -0
- package/dist/runtime/vault-sharing-ops.d.ts.map +1 -0
- package/dist/runtime/vault-sharing-ops.js +345 -0
- package/dist/runtime/vault-sharing-ops.js.map +1 -0
- package/dist/streams/index.d.ts +1 -1
- package/dist/streams/index.d.ts.map +1 -1
- package/dist/streams/index.js +1 -1
- package/dist/streams/index.js.map +1 -1
- package/dist/streams/replayable-stream.d.ts +13 -1
- package/dist/streams/replayable-stream.d.ts.map +1 -1
- package/dist/streams/replayable-stream.js +27 -3
- package/dist/streams/replayable-stream.js.map +1 -1
- package/dist/text/similarity.d.ts +0 -1
- package/dist/text/similarity.d.ts.map +1 -1
- package/dist/text/similarity.js +1 -1
- package/dist/text/similarity.js.map +1 -1
- package/dist/transport/http-server.d.ts +56 -0
- package/dist/transport/http-server.d.ts.map +1 -0
- package/dist/transport/http-server.js +210 -0
- package/dist/transport/http-server.js.map +1 -0
- package/dist/transport/index.d.ts +11 -0
- package/dist/transport/index.d.ts.map +1 -0
- package/dist/transport/index.js +10 -0
- package/dist/transport/index.js.map +1 -0
- package/dist/transport/lsp-server.d.ts +140 -0
- package/dist/transport/lsp-server.d.ts.map +1 -0
- package/dist/transport/lsp-server.js +239 -0
- package/dist/transport/lsp-server.js.map +1 -0
- package/dist/transport/rate-limiter.d.ts +35 -0
- package/dist/transport/rate-limiter.d.ts.map +1 -0
- package/dist/transport/rate-limiter.js +72 -0
- package/dist/transport/rate-limiter.js.map +1 -0
- package/dist/transport/session-manager.d.ts +49 -0
- package/dist/transport/session-manager.d.ts.map +1 -0
- package/dist/transport/session-manager.js +83 -0
- package/dist/transport/session-manager.js.map +1 -0
- package/dist/transport/token-auth.d.ts +29 -0
- package/dist/transport/token-auth.d.ts.map +1 -0
- package/dist/transport/token-auth.js +84 -0
- package/dist/transport/token-auth.js.map +1 -0
- package/dist/transport/types.d.ts +61 -0
- package/dist/transport/types.d.ts.map +1 -0
- package/dist/transport/types.js +5 -0
- package/dist/transport/types.js.map +1 -0
- package/dist/transport/ws-server.d.ts +78 -0
- package/dist/transport/ws-server.d.ts.map +1 -0
- package/dist/transport/ws-server.js +342 -0
- package/dist/transport/ws-server.js.map +1 -0
- package/dist/vault/git-vault-sync.d.ts +107 -0
- package/dist/vault/git-vault-sync.d.ts.map +1 -0
- package/dist/vault/git-vault-sync.js +251 -0
- package/dist/vault/git-vault-sync.js.map +1 -0
- package/dist/vault/knowledge-review.d.ts +67 -0
- package/dist/vault/knowledge-review.d.ts.map +1 -0
- package/dist/vault/knowledge-review.js +133 -0
- package/dist/vault/knowledge-review.js.map +1 -0
- package/dist/vault/obsidian-sync.d.ts +94 -0
- package/dist/vault/obsidian-sync.d.ts.map +1 -0
- package/dist/vault/obsidian-sync.js +247 -0
- package/dist/vault/obsidian-sync.js.map +1 -0
- package/dist/vault/scope-detector.d.ts +31 -0
- package/dist/vault/scope-detector.d.ts.map +1 -0
- package/dist/vault/scope-detector.js +182 -0
- package/dist/vault/scope-detector.js.map +1 -0
- package/dist/vault/vault-branching.d.ts +71 -0
- package/dist/vault/vault-branching.d.ts.map +1 -0
- package/dist/vault/vault-branching.js +180 -0
- package/dist/vault/vault-branching.js.map +1 -0
- package/dist/vault/vault-manager.d.ts +89 -0
- package/dist/vault/vault-manager.d.ts.map +1 -0
- package/dist/vault/vault-manager.js +199 -0
- package/dist/vault/vault-manager.js.map +1 -0
- package/dist/vault/vault-types.d.ts +30 -0
- package/dist/vault/vault-types.d.ts.map +1 -0
- package/dist/vault/vault-types.js +10 -0
- package/dist/vault/vault-types.js.map +1 -0
- package/dist/vault/vault.d.ts +10 -0
- package/dist/vault/vault.d.ts.map +1 -1
- package/dist/vault/vault.js +36 -3
- package/dist/vault/vault.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/admin-extra-ops.test.ts +31 -11
- package/src/__tests__/agency-manager.test.ts +374 -0
- package/src/__tests__/agent-loop.test.ts +256 -0
- package/src/__tests__/capture-ops.test.ts +275 -0
- package/src/__tests__/chat-differentiators.test.ts +251 -0
- package/src/__tests__/chat-enhanced.test.ts +390 -0
- package/src/__tests__/chat-transport.test.ts +665 -0
- package/src/__tests__/claudemd.test.ts +282 -0
- package/src/__tests__/context-engine.test.ts +256 -0
- package/src/__tests__/core-ops.test.ts +97 -5
- package/src/__tests__/deprecation.test.ts +78 -0
- package/src/__tests__/enforcement.test.ts +153 -0
- package/src/__tests__/facade-factory.test.ts +271 -0
- package/src/__tests__/feature-flags.test.ts +138 -0
- package/src/__tests__/git-vault-sync.test.ts +230 -0
- package/src/__tests__/health-registry.test.ts +173 -0
- package/src/__tests__/knowledge-review.test.ts +104 -0
- package/src/__tests__/lsp-transport.test.ts +442 -0
- package/src/__tests__/migration-runner.test.ts +170 -0
- package/src/__tests__/normalize.test.ts +10 -0
- package/src/__tests__/obsidian-sync.test.ts +354 -0
- package/src/__tests__/pack-lockfile.test.ts +261 -0
- package/src/__tests__/pack-ops.test.ts +146 -0
- package/src/__tests__/pack-system.test.ts +423 -0
- package/src/__tests__/playbook-executor.test.ts +249 -0
- package/src/__tests__/playbook-ops-execution.test.ts +189 -0
- package/src/__tests__/plugin-ops.test.ts +411 -0
- package/src/__tests__/plugin-system.test.ts +509 -0
- package/src/__tests__/postgres-provider.test.ts +64 -6
- package/src/__tests__/replayable-stream.test.ts +112 -1
- package/src/__tests__/scope-detector.test.ts +121 -0
- package/src/__tests__/session-lifecycle.test.ts +259 -0
- package/src/__tests__/transport.test.ts +758 -0
- package/src/__tests__/vault-branching.test.ts +274 -0
- package/src/__tests__/vault-connect.test.ts +179 -0
- package/src/__tests__/vault-integrity.test.ts +71 -0
- package/src/__tests__/vault-manager.test.ts +238 -0
- package/src/__tests__/vault-scaling.test.ts +281 -0
- package/src/__tests__/vault-sharing.test.ts +270 -0
- package/src/__tests__/ws-transport.test.ts +479 -0
- package/src/agency/agency-manager.ts +326 -0
- package/src/agency/index.ts +13 -0
- package/src/agency/types.ts +88 -0
- package/src/brain/brain.ts +15 -11
- package/src/brain/intelligence.ts +103 -0
- package/src/brain/types.ts +26 -0
- package/src/chat/agent-loop-types.ts +99 -0
- package/src/chat/agent-loop.ts +357 -0
- package/src/chat/auth-manager.ts +171 -0
- package/src/chat/browser-session.ts +188 -0
- package/src/chat/cancellation.ts +99 -0
- package/src/chat/chat-session.ts +283 -0
- package/src/chat/file-handler.ts +230 -0
- package/src/chat/fragment-buffer.ts +160 -0
- package/src/chat/index.ts +72 -0
- package/src/chat/mcp-bridge.ts +135 -0
- package/src/chat/notifications.ts +164 -0
- package/src/chat/output-compressor.ts +116 -0
- package/src/chat/queue.ts +208 -0
- package/src/chat/response-chunker.ts +200 -0
- package/src/chat/self-update.ts +117 -0
- package/src/chat/types.ts +126 -0
- package/src/chat/voice.ts +134 -0
- package/src/claudemd/compose.ts +142 -0
- package/src/claudemd/index.ts +17 -0
- package/src/claudemd/inject.ts +170 -0
- package/src/claudemd/types.ts +45 -0
- package/src/context/context-engine.ts +302 -0
- package/src/context/index.ts +11 -0
- package/src/context/types.ts +69 -0
- package/src/enforcement/adapters/claude-code.ts +135 -0
- package/src/enforcement/adapters/index.ts +1 -0
- package/src/enforcement/index.ts +10 -0
- package/src/enforcement/registry.ts +82 -0
- package/src/enforcement/types.ts +56 -0
- package/src/facades/facade-factory.ts +138 -5
- package/src/facades/types.ts +21 -0
- package/src/health/health-registry.ts +165 -0
- package/src/health/index.ts +11 -0
- package/src/health/vault-integrity.ts +66 -0
- package/src/index.ts +294 -2
- package/src/intake/intake-pipeline.ts +1 -1
- package/src/intelligence/types.ts +1 -0
- package/src/migrations/index.ts +6 -0
- package/src/migrations/migration-runner.ts +185 -0
- package/src/packs/index.ts +20 -0
- package/src/packs/lockfile.ts +180 -0
- package/src/packs/pack-installer.ts +289 -0
- package/src/packs/resolver.ts +237 -0
- package/src/packs/types.ts +125 -0
- package/src/persistence/postgres-provider.ts +211 -58
- package/src/playbooks/index.ts +11 -0
- package/src/playbooks/playbook-executor.ts +301 -0
- package/src/plugins/index.ts +19 -0
- package/src/plugins/plugin-loader.ts +183 -0
- package/src/plugins/plugin-registry.ts +187 -0
- package/src/plugins/types.ts +119 -0
- package/src/runtime/admin-extra-ops.ts +193 -8
- package/src/runtime/capture-ops.ts +113 -8
- package/src/runtime/deprecation.ts +58 -0
- package/src/runtime/facades/admin-facade.ts +16 -1
- package/src/runtime/facades/agency-facade.ts +111 -0
- package/src/runtime/facades/brain-facade.ts +60 -0
- package/src/runtime/facades/chat-facade.ts +918 -0
- package/src/runtime/facades/context-facade.ts +55 -0
- package/src/runtime/facades/index.ts +22 -1
- package/src/runtime/facades/vault-facade.ts +261 -1
- package/src/runtime/feature-flags.ts +101 -0
- package/src/runtime/pack-ops.ts +85 -0
- package/src/runtime/playbook-ops.ts +113 -9
- package/src/runtime/plugin-ops.ts +258 -0
- package/src/runtime/runtime.ts +84 -5
- package/src/runtime/telemetry-ops.ts +57 -0
- package/src/runtime/types.ts +35 -0
- package/src/runtime/vault-sharing-ops.ts +372 -0
- package/src/streams/index.ts +1 -1
- package/src/streams/replayable-stream.ts +34 -3
- package/src/text/similarity.ts +1 -1
- package/src/transport/http-server.ts +269 -0
- package/src/transport/index.ts +48 -0
- package/src/transport/lsp-server.ts +401 -0
- package/src/transport/rate-limiter.ts +97 -0
- package/src/transport/session-manager.ts +120 -0
- package/src/transport/token-auth.ts +96 -0
- package/src/transport/types.ts +66 -0
- package/src/transport/ws-server.ts +415 -0
- package/src/vault/git-vault-sync.ts +318 -0
- package/src/vault/knowledge-review.ts +221 -0
- package/src/vault/obsidian-sync.ts +346 -0
- package/src/vault/scope-detector.ts +219 -0
- package/src/vault/vault-branching.ts +264 -0
- package/src/vault/vault-manager.ts +237 -0
- package/src/vault/vault-types.ts +50 -0
- package/src/vault/vault.ts +41 -3
- package/src/governance/index.ts +0 -18
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Loop Tests — MCP bridge, output compressor, message sanitization.
|
|
3
|
+
*
|
|
4
|
+
* Note: The actual agent loop (runAgentLoop) requires a live Anthropic API key,
|
|
5
|
+
* so we test the surrounding infrastructure in isolation.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { describe, test, expect, beforeEach } from 'vitest';
|
|
9
|
+
import { McpToolBridge } from '../chat/mcp-bridge.js';
|
|
10
|
+
import {
|
|
11
|
+
createOutputCompressor,
|
|
12
|
+
registerCompressor,
|
|
13
|
+
clearCompressors,
|
|
14
|
+
} from '../chat/output-compressor.js';
|
|
15
|
+
import type { McpToolRegistration } from '../chat/agent-loop-types.js';
|
|
16
|
+
|
|
17
|
+
// ─── MCP Tool Bridge ────────────────────────────────────────────────
|
|
18
|
+
|
|
19
|
+
describe('McpToolBridge', () => {
|
|
20
|
+
let bridge: McpToolBridge;
|
|
21
|
+
|
|
22
|
+
beforeEach(() => {
|
|
23
|
+
bridge = new McpToolBridge();
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
describe('registration', () => {
|
|
27
|
+
test('registers a tool', () => {
|
|
28
|
+
bridge.register(makeTool('test_tool'));
|
|
29
|
+
expect(bridge.has('test_tool')).toBe(true);
|
|
30
|
+
expect(bridge.size).toBe(1);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test('registerAll registers multiple tools', () => {
|
|
34
|
+
bridge.registerAll([makeTool('tool_a'), makeTool('tool_b'), makeTool('tool_c')]);
|
|
35
|
+
expect(bridge.size).toBe(3);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test('listTools returns names', () => {
|
|
39
|
+
bridge.registerAll([makeTool('alpha'), makeTool('beta')]);
|
|
40
|
+
const names = bridge.listTools();
|
|
41
|
+
expect(names).toContain('alpha');
|
|
42
|
+
expect(names).toContain('beta');
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test('getTools returns AgentTool format', () => {
|
|
46
|
+
bridge.register(makeTool('my_tool'));
|
|
47
|
+
const tools = bridge.getTools();
|
|
48
|
+
expect(tools.length).toBe(1);
|
|
49
|
+
expect(tools[0].name).toBe('my_tool');
|
|
50
|
+
expect(tools[0].description).toBeDefined();
|
|
51
|
+
expect(tools[0].inputSchema).toBeDefined();
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test('clear removes all tools', () => {
|
|
55
|
+
bridge.registerAll([makeTool('a'), makeTool('b')]);
|
|
56
|
+
bridge.clear();
|
|
57
|
+
expect(bridge.size).toBe(0);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
describe('allowlist', () => {
|
|
62
|
+
test('filters tools by allowlist', () => {
|
|
63
|
+
const filtered = new McpToolBridge({ allowlist: ['allowed_tool'] });
|
|
64
|
+
filtered.register(makeTool('allowed_tool'));
|
|
65
|
+
filtered.register(makeTool('blocked_tool'));
|
|
66
|
+
expect(filtered.size).toBe(1);
|
|
67
|
+
expect(filtered.has('allowed_tool')).toBe(true);
|
|
68
|
+
expect(filtered.has('blocked_tool')).toBe(false);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test('no allowlist allows all', () => {
|
|
72
|
+
bridge.register(makeTool('any_tool'));
|
|
73
|
+
expect(bridge.has('any_tool')).toBe(true);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
describe('execution', () => {
|
|
78
|
+
test('executes a registered tool', async () => {
|
|
79
|
+
bridge.register({
|
|
80
|
+
name: 'greet',
|
|
81
|
+
description: 'Greet someone',
|
|
82
|
+
inputSchema: { type: 'object', properties: { name: { type: 'string' } } },
|
|
83
|
+
handler: async (input) => ({ message: `Hello, ${input.name}!` }),
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const result = await bridge.execute('greet', { name: 'World' });
|
|
87
|
+
expect(result.isError).toBe(false);
|
|
88
|
+
expect(result.output).toContain('Hello, World!');
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test('returns error for unknown tool', async () => {
|
|
92
|
+
const result = await bridge.execute('nonexistent', {});
|
|
93
|
+
expect(result.isError).toBe(true);
|
|
94
|
+
expect(result.output).toContain('Unknown tool');
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test('handles tool execution errors', async () => {
|
|
98
|
+
bridge.register({
|
|
99
|
+
name: 'failing',
|
|
100
|
+
description: 'Always fails',
|
|
101
|
+
inputSchema: { type: 'object' },
|
|
102
|
+
handler: async () => {
|
|
103
|
+
throw new Error('Intentional failure');
|
|
104
|
+
},
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const result = await bridge.execute('failing', {});
|
|
108
|
+
expect(result.isError).toBe(true);
|
|
109
|
+
expect(result.output).toContain('Intentional failure');
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test('truncates long output', async () => {
|
|
113
|
+
const longBridge = new McpToolBridge({ maxOutput: 100 });
|
|
114
|
+
longBridge.register({
|
|
115
|
+
name: 'verbose',
|
|
116
|
+
description: 'Returns long output',
|
|
117
|
+
inputSchema: { type: 'object' },
|
|
118
|
+
handler: async () => 'x'.repeat(500),
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
const result = await longBridge.execute('verbose', {});
|
|
122
|
+
expect(result.output.length).toBeLessThanOrEqual(150); // 100 + truncation message
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test('createExecutor returns function', async () => {
|
|
126
|
+
bridge.register({
|
|
127
|
+
name: 'echo',
|
|
128
|
+
description: 'Echo input',
|
|
129
|
+
inputSchema: { type: 'object' },
|
|
130
|
+
handler: async (input) => input,
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const executor = bridge.createExecutor();
|
|
134
|
+
const result = await executor('echo', { msg: 'hi' });
|
|
135
|
+
expect(result.isError).toBe(false);
|
|
136
|
+
expect(result.output).toContain('hi');
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
describe('with compressor', () => {
|
|
141
|
+
test('applies compressor to output', async () => {
|
|
142
|
+
const compressor = createOutputCompressor({ maxLength: 50 });
|
|
143
|
+
const compBridge = new McpToolBridge({ compressor });
|
|
144
|
+
compBridge.register({
|
|
145
|
+
name: 'big_json',
|
|
146
|
+
description: 'Returns big JSON',
|
|
147
|
+
inputSchema: { type: 'object' },
|
|
148
|
+
handler: async () => ({ data: Array.from({ length: 20 }, (_, i) => `item-${i}`) }),
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
const result = await compBridge.execute('big_json', {});
|
|
152
|
+
// Compressor truncates arrays and strings; output should be shorter than raw JSON
|
|
153
|
+
expect(result.output.length).toBeLessThanOrEqual(200);
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// ─── Output Compressor ──────────────────────────────────────────────
|
|
159
|
+
|
|
160
|
+
describe('Output Compressor', () => {
|
|
161
|
+
beforeEach(() => {
|
|
162
|
+
clearCompressors();
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
test('short output passes through', () => {
|
|
166
|
+
const compressor = createOutputCompressor();
|
|
167
|
+
const result = compressor('tool', 'short text');
|
|
168
|
+
expect(result).toBe('short text');
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
test('long text gets truncated', () => {
|
|
172
|
+
const compressor = createOutputCompressor({ maxLength: 50 });
|
|
173
|
+
const result = compressor('tool', 'x'.repeat(200));
|
|
174
|
+
expect(result.length).toBeLessThanOrEqual(70); // 50 + truncation message
|
|
175
|
+
expect(result).toContain('truncated');
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
test('JSON arrays get compressed', () => {
|
|
179
|
+
const compressor = createOutputCompressor({ maxLength: 200, maxArrayItems: 3 });
|
|
180
|
+
const bigJson = JSON.stringify({ items: Array.from({ length: 20 }, (_, i) => `item-${i}`) });
|
|
181
|
+
const result = compressor('tool', bigJson);
|
|
182
|
+
expect(result).toContain('item-0');
|
|
183
|
+
expect(result).toContain('+17 more');
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
test('JSON strings get truncated when output exceeds max', () => {
|
|
187
|
+
// maxLength must be less than the input so compression kicks in
|
|
188
|
+
const compressor = createOutputCompressor({ maxStringLength: 20, maxLength: 50 });
|
|
189
|
+
const json = JSON.stringify({ content: 'x'.repeat(100) });
|
|
190
|
+
const result = compressor('tool', json);
|
|
191
|
+
// The compressed output should be shorter than the original
|
|
192
|
+
expect(result.length).toBeLessThan(json.length);
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
test('registered compressor takes priority', () => {
|
|
196
|
+
registerCompressor('special_tool', (output) => `COMPRESSED: ${output.length} chars`);
|
|
197
|
+
const compressor = createOutputCompressor();
|
|
198
|
+
const result = compressor('special_tool', 'x'.repeat(5000));
|
|
199
|
+
expect(result).toBe('COMPRESSED: 5000 chars');
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
test('prefix matching works', () => {
|
|
203
|
+
registerCompressor('vault_', (_output) => 'vault compressed');
|
|
204
|
+
const compressor = createOutputCompressor();
|
|
205
|
+
expect(compressor('vault_search', 'data')).toBe('vault compressed');
|
|
206
|
+
expect(compressor('vault_list', 'data')).toBe('vault compressed');
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
test('clearCompressors removes all', () => {
|
|
210
|
+
registerCompressor('test', () => 'custom');
|
|
211
|
+
clearCompressors();
|
|
212
|
+
const compressor = createOutputCompressor();
|
|
213
|
+
const result = compressor('test', 'short');
|
|
214
|
+
expect(result).toBe('short'); // Falls through to default
|
|
215
|
+
});
|
|
216
|
+
|
|
217
|
+
test('handles non-JSON gracefully', () => {
|
|
218
|
+
const compressor = createOutputCompressor({ maxLength: 20 });
|
|
219
|
+
const result = compressor('tool', 'not { valid json }'.repeat(10));
|
|
220
|
+
expect(result.length).toBeLessThanOrEqual(40);
|
|
221
|
+
expect(result).toContain('truncated');
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
test('preserves numbers and booleans', () => {
|
|
225
|
+
const compressor = createOutputCompressor();
|
|
226
|
+
const json = JSON.stringify({ count: 42, active: true, name: 'test' });
|
|
227
|
+
const result = compressor('tool', json);
|
|
228
|
+
const parsed = JSON.parse(result);
|
|
229
|
+
expect(parsed.count).toBe(42);
|
|
230
|
+
expect(parsed.active).toBe(true);
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
test('handles nested objects when compression triggers', () => {
|
|
234
|
+
// maxLength must be small enough to trigger JSON compression
|
|
235
|
+
const compressor = createOutputCompressor({ maxArrayItems: 2, maxLength: 30 });
|
|
236
|
+
const json = JSON.stringify({
|
|
237
|
+
outer: {
|
|
238
|
+
inner: { items: [1, 2, 3, 4, 5] },
|
|
239
|
+
},
|
|
240
|
+
});
|
|
241
|
+
const result = compressor('tool', json);
|
|
242
|
+
// Output should be truncated/compressed
|
|
243
|
+
expect(result.length).toBeLessThanOrEqual(60); // 30 + truncation message
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
// ─── Helpers ────────────────────────────────────────────────────────
|
|
248
|
+
|
|
249
|
+
function makeTool(name: string): McpToolRegistration {
|
|
250
|
+
return {
|
|
251
|
+
name,
|
|
252
|
+
description: `Test tool: ${name}`,
|
|
253
|
+
inputSchema: { type: 'object', properties: {} },
|
|
254
|
+
handler: async (input) => ({ name, input }),
|
|
255
|
+
};
|
|
256
|
+
}
|
|
@@ -197,6 +197,79 @@ describe('createCaptureOps', () => {
|
|
|
197
197
|
});
|
|
198
198
|
});
|
|
199
199
|
|
|
200
|
+
// ─── capture_knowledge content-hash dedup ──────────────────────
|
|
201
|
+
|
|
202
|
+
describe('capture_knowledge content-hash dedup', () => {
|
|
203
|
+
it('should skip duplicate entries with identical content', async () => {
|
|
204
|
+
setup();
|
|
205
|
+
const entry = {
|
|
206
|
+
type: 'pattern',
|
|
207
|
+
domain: 'testing',
|
|
208
|
+
title: 'Dedup test',
|
|
209
|
+
description: 'Should only be captured once.',
|
|
210
|
+
tags: ['dedup'],
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
// First capture succeeds
|
|
214
|
+
const first = (await findOp('capture_knowledge').handler({
|
|
215
|
+
entries: [entry],
|
|
216
|
+
})) as { captured: number; duplicated: number; results: Array<{ action: string }> };
|
|
217
|
+
expect(first.captured).toBe(1);
|
|
218
|
+
expect(first.duplicated).toBe(0);
|
|
219
|
+
|
|
220
|
+
// Second capture of same content is skipped
|
|
221
|
+
const second = (await findOp('capture_knowledge').handler({
|
|
222
|
+
entries: [entry],
|
|
223
|
+
})) as {
|
|
224
|
+
captured: number;
|
|
225
|
+
duplicated: number;
|
|
226
|
+
results: Array<{ id: string; action: string }>;
|
|
227
|
+
};
|
|
228
|
+
expect(second.captured).toBe(0);
|
|
229
|
+
expect(second.duplicated).toBe(1);
|
|
230
|
+
expect(second.results[0].action).toBe('duplicate');
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
it('should not flag entries with different content as duplicates', async () => {
|
|
234
|
+
setup();
|
|
235
|
+
const result = (await findOp('capture_knowledge').handler({
|
|
236
|
+
entries: [
|
|
237
|
+
{ type: 'pattern', domain: 'a', title: 'One', description: 'First.' },
|
|
238
|
+
{ type: 'pattern', domain: 'a', title: 'Two', description: 'Second.' },
|
|
239
|
+
],
|
|
240
|
+
})) as { captured: number; duplicated: number };
|
|
241
|
+
expect(result.captured).toBe(2);
|
|
242
|
+
expect(result.duplicated).toBe(0);
|
|
243
|
+
});
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
// ─── capture_quick content-hash dedup ─────────────────────────
|
|
247
|
+
|
|
248
|
+
describe('capture_quick content-hash dedup', () => {
|
|
249
|
+
it('should skip duplicate on second quick capture', async () => {
|
|
250
|
+
setup();
|
|
251
|
+
const params = {
|
|
252
|
+
type: 'rule',
|
|
253
|
+
domain: 'testing',
|
|
254
|
+
title: 'Quick dedup',
|
|
255
|
+
description: 'Should only be captured once.',
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
const first = (await findOp('capture_quick').handler(params)) as {
|
|
259
|
+
captured: boolean;
|
|
260
|
+
governance: { action: string };
|
|
261
|
+
};
|
|
262
|
+
expect(first.captured).toBe(true);
|
|
263
|
+
|
|
264
|
+
const second = (await findOp('capture_quick').handler(params)) as {
|
|
265
|
+
captured: boolean;
|
|
266
|
+
governance: { action: string };
|
|
267
|
+
};
|
|
268
|
+
expect(second.captured).toBe(false);
|
|
269
|
+
expect(second.governance.action).toBe('duplicate');
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
|
|
200
273
|
// ─── capture_knowledge with governance gating ───────────────────
|
|
201
274
|
|
|
202
275
|
describe('capture_knowledge governance gating', () => {
|
|
@@ -491,6 +564,208 @@ describe('createCaptureOps', () => {
|
|
|
491
564
|
});
|
|
492
565
|
});
|
|
493
566
|
|
|
567
|
+
// ─── Scope detection integration ────────────────────────────────
|
|
568
|
+
|
|
569
|
+
describe('capture_knowledge scope detection', () => {
|
|
570
|
+
it('should auto-detect team tier for universal patterns', async () => {
|
|
571
|
+
setup();
|
|
572
|
+
const result = (await findOp('capture_knowledge').handler({
|
|
573
|
+
entries: [
|
|
574
|
+
{
|
|
575
|
+
type: 'pattern',
|
|
576
|
+
domain: 'accessibility',
|
|
577
|
+
title: 'WCAG contrast requirements',
|
|
578
|
+
description:
|
|
579
|
+
'All text must meet WCAG AA contrast ratio of 4.5:1 for accessibility compliance.',
|
|
580
|
+
tags: ['a11y', 'wcag'],
|
|
581
|
+
},
|
|
582
|
+
],
|
|
583
|
+
})) as {
|
|
584
|
+
captured: number;
|
|
585
|
+
results: Array<{ scope?: { tier: string; confidence: string } }>;
|
|
586
|
+
};
|
|
587
|
+
|
|
588
|
+
expect(result.captured).toBe(1);
|
|
589
|
+
expect(result.results[0].scope).toBeDefined();
|
|
590
|
+
expect(result.results[0].scope!.tier).toBe('team');
|
|
591
|
+
expect(result.results[0].scope!.confidence).toBe('HIGH');
|
|
592
|
+
});
|
|
593
|
+
|
|
594
|
+
it('should auto-detect project tier for project-specific content', async () => {
|
|
595
|
+
setup();
|
|
596
|
+
const result = (await findOp('capture_knowledge').handler({
|
|
597
|
+
entries: [
|
|
598
|
+
{
|
|
599
|
+
type: 'pattern',
|
|
600
|
+
domain: 'architecture',
|
|
601
|
+
title: 'Package imports',
|
|
602
|
+
description: 'Use @soleri/core for all vault operations in packages/core/src/vault.ts.',
|
|
603
|
+
tags: ['project-specific'],
|
|
604
|
+
},
|
|
605
|
+
],
|
|
606
|
+
})) as {
|
|
607
|
+
captured: number;
|
|
608
|
+
results: Array<{ scope?: { tier: string; confidence: string } }>;
|
|
609
|
+
};
|
|
610
|
+
|
|
611
|
+
expect(result.captured).toBe(1);
|
|
612
|
+
expect(result.results[0].scope!.tier).toBe('project');
|
|
613
|
+
});
|
|
614
|
+
|
|
615
|
+
it('should auto-detect agent tier for personal preferences', async () => {
|
|
616
|
+
setup();
|
|
617
|
+
const result = (await findOp('capture_knowledge').handler({
|
|
618
|
+
entries: [
|
|
619
|
+
{
|
|
620
|
+
type: 'rule',
|
|
621
|
+
domain: 'workflow',
|
|
622
|
+
title: 'My editor preference',
|
|
623
|
+
description: 'I prefer using vim keybindings. My workflow involves ~/projects.',
|
|
624
|
+
tags: ['preference'],
|
|
625
|
+
},
|
|
626
|
+
],
|
|
627
|
+
})) as {
|
|
628
|
+
captured: number;
|
|
629
|
+
results: Array<{ scope?: { tier: string } }>;
|
|
630
|
+
};
|
|
631
|
+
|
|
632
|
+
expect(result.captured).toBe(1);
|
|
633
|
+
expect(result.results[0].scope!.tier).toBe('agent');
|
|
634
|
+
});
|
|
635
|
+
|
|
636
|
+
it('should use top-level tier override when provided', async () => {
|
|
637
|
+
setup();
|
|
638
|
+
const result = (await findOp('capture_knowledge').handler({
|
|
639
|
+
tier: 'team',
|
|
640
|
+
entries: [
|
|
641
|
+
{
|
|
642
|
+
type: 'pattern',
|
|
643
|
+
domain: 'testing',
|
|
644
|
+
title: 'Random note',
|
|
645
|
+
description: 'Something generic.',
|
|
646
|
+
},
|
|
647
|
+
],
|
|
648
|
+
})) as {
|
|
649
|
+
captured: number;
|
|
650
|
+
results: Array<{ scope?: { tier: string; confidence: string } }>;
|
|
651
|
+
};
|
|
652
|
+
|
|
653
|
+
expect(result.captured).toBe(1);
|
|
654
|
+
expect(result.results[0].scope!.tier).toBe('team');
|
|
655
|
+
expect(result.results[0].scope!.confidence).toBe('MANUAL');
|
|
656
|
+
});
|
|
657
|
+
|
|
658
|
+
it('should use per-entry tier override over top-level', async () => {
|
|
659
|
+
setup();
|
|
660
|
+
const result = (await findOp('capture_knowledge').handler({
|
|
661
|
+
tier: 'team',
|
|
662
|
+
entries: [
|
|
663
|
+
{
|
|
664
|
+
type: 'pattern',
|
|
665
|
+
domain: 'testing',
|
|
666
|
+
title: 'Override test',
|
|
667
|
+
description: 'Per-entry override.',
|
|
668
|
+
tier: 'agent',
|
|
669
|
+
},
|
|
670
|
+
],
|
|
671
|
+
})) as {
|
|
672
|
+
captured: number;
|
|
673
|
+
results: Array<{ scope?: { tier: string; confidence: string } }>;
|
|
674
|
+
};
|
|
675
|
+
|
|
676
|
+
expect(result.captured).toBe(1);
|
|
677
|
+
expect(result.results[0].scope!.tier).toBe('agent');
|
|
678
|
+
expect(result.results[0].scope!.confidence).toBe('MANUAL');
|
|
679
|
+
});
|
|
680
|
+
|
|
681
|
+
it('should include review note for LOW confidence detections', async () => {
|
|
682
|
+
setup();
|
|
683
|
+
const result = (await findOp('capture_knowledge').handler({
|
|
684
|
+
entries: [
|
|
685
|
+
{
|
|
686
|
+
type: 'pattern',
|
|
687
|
+
domain: 'other',
|
|
688
|
+
title: 'Ambiguous entry',
|
|
689
|
+
description: 'Something happened today.',
|
|
690
|
+
},
|
|
691
|
+
],
|
|
692
|
+
})) as {
|
|
693
|
+
captured: number;
|
|
694
|
+
results: Array<{ scope?: { tier: string; confidence: string }; reason?: string }>;
|
|
695
|
+
};
|
|
696
|
+
|
|
697
|
+
expect(result.captured).toBe(1);
|
|
698
|
+
expect(result.results[0].scope!.confidence).toBe('LOW');
|
|
699
|
+
expect(result.results[0].reason).toContain('Low confidence');
|
|
700
|
+
});
|
|
701
|
+
|
|
702
|
+
it('should persist tier to vault entry', async () => {
|
|
703
|
+
setup();
|
|
704
|
+
const result = (await findOp('capture_knowledge').handler({
|
|
705
|
+
entries: [
|
|
706
|
+
{
|
|
707
|
+
id: 'tier-persist-1',
|
|
708
|
+
type: 'pattern',
|
|
709
|
+
domain: 'security',
|
|
710
|
+
title: 'XSS prevention rule',
|
|
711
|
+
description: 'Sanitize user input to prevent XSS injection attacks.',
|
|
712
|
+
tags: ['security'],
|
|
713
|
+
},
|
|
714
|
+
],
|
|
715
|
+
})) as { captured: number };
|
|
716
|
+
|
|
717
|
+
expect(result.captured).toBe(1);
|
|
718
|
+
const entry = runtime.vault.get('tier-persist-1');
|
|
719
|
+
expect(entry).not.toBeNull();
|
|
720
|
+
expect(entry!.tier).toBe('team');
|
|
721
|
+
});
|
|
722
|
+
});
|
|
723
|
+
|
|
724
|
+
describe('capture_quick scope detection', () => {
|
|
725
|
+
it('should auto-detect tier', async () => {
|
|
726
|
+
setup();
|
|
727
|
+
const result = (await findOp('capture_quick').handler({
|
|
728
|
+
type: 'pattern',
|
|
729
|
+
domain: 'security',
|
|
730
|
+
title: 'Input sanitization',
|
|
731
|
+
description: 'Always sanitize user input to prevent XSS attacks.',
|
|
732
|
+
tags: ['security'],
|
|
733
|
+
})) as { captured: boolean; scope?: { tier: string; confidence: string } };
|
|
734
|
+
|
|
735
|
+
expect(result.captured).toBe(true);
|
|
736
|
+
expect(result.scope).toBeDefined();
|
|
737
|
+
expect(result.scope!.tier).toBe('team');
|
|
738
|
+
});
|
|
739
|
+
|
|
740
|
+
it('should accept manual tier override', async () => {
|
|
741
|
+
setup();
|
|
742
|
+
const result = (await findOp('capture_quick').handler({
|
|
743
|
+
type: 'rule',
|
|
744
|
+
domain: 'testing',
|
|
745
|
+
title: 'Generic note',
|
|
746
|
+
description: 'Something.',
|
|
747
|
+
tier: 'project',
|
|
748
|
+
})) as { captured: boolean; scope?: { tier: string; confidence: string } };
|
|
749
|
+
|
|
750
|
+
expect(result.captured).toBe(true);
|
|
751
|
+
expect(result.scope!.tier).toBe('project');
|
|
752
|
+
expect(result.scope!.confidence).toBe('MANUAL');
|
|
753
|
+
});
|
|
754
|
+
|
|
755
|
+
it('should include reviewNote for LOW confidence', async () => {
|
|
756
|
+
setup();
|
|
757
|
+
const result = (await findOp('capture_quick').handler({
|
|
758
|
+
type: 'rule',
|
|
759
|
+
domain: 'other',
|
|
760
|
+
title: 'Vague thing',
|
|
761
|
+
description: 'Not much context here.',
|
|
762
|
+
})) as { captured: boolean; reviewNote?: string };
|
|
763
|
+
|
|
764
|
+
expect(result.captured).toBe(true);
|
|
765
|
+
expect(result.reviewNote).toContain('Low confidence');
|
|
766
|
+
});
|
|
767
|
+
});
|
|
768
|
+
|
|
494
769
|
// ─── Auth levels ───────────────────────────────────────────────
|
|
495
770
|
|
|
496
771
|
describe('auth levels', () => {
|