@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,372 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vault Sharing Ops — knowledge scoping, export, sync, and review ops.
|
|
3
|
+
*
|
|
4
|
+
* Covers:
|
|
5
|
+
* - #105: Knowledge scoping (detect_scope, set_scope, scope-aware filtering)
|
|
6
|
+
* - #104: Vault export to shareable packs
|
|
7
|
+
* - #67: Vault push/pull git sync with conflict resolution
|
|
8
|
+
* - #65: Team review workflows (submit/approve/reject)
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { z } from 'zod';
|
|
12
|
+
import type { OpDefinition } from '../facades/types.js';
|
|
13
|
+
import type { AgentRuntime } from './types.js';
|
|
14
|
+
import { detectScope, type ScopeInput } from '../vault/scope-detector.js';
|
|
15
|
+
import { GitVaultSync, type GitVaultSyncConfig } from '../vault/git-vault-sync.js';
|
|
16
|
+
import type { IntelligenceEntry, IntelligenceBundle } from '../intelligence/types.js';
|
|
17
|
+
|
|
18
|
+
export function createVaultSharingOps(runtime: AgentRuntime): OpDefinition[] {
|
|
19
|
+
const { vault, knowledgeReview } = runtime;
|
|
20
|
+
|
|
21
|
+
return [
|
|
22
|
+
// ─── Scoping (#105) ───────────────────────────────────────────
|
|
23
|
+
{
|
|
24
|
+
name: 'vault_detect_scope',
|
|
25
|
+
description:
|
|
26
|
+
'Auto-detect the appropriate scope tier (agent/project/team) for a knowledge entry using weighted heuristics on content, category, tags, and title.',
|
|
27
|
+
auth: 'read' as const,
|
|
28
|
+
schema: z.object({
|
|
29
|
+
title: z.string().describe('Entry title'),
|
|
30
|
+
description: z.string().describe('Entry description'),
|
|
31
|
+
category: z.string().optional().describe('Entry category/domain'),
|
|
32
|
+
tags: z.array(z.string()).optional().describe('Entry tags'),
|
|
33
|
+
}),
|
|
34
|
+
handler: async (params) => {
|
|
35
|
+
const input: ScopeInput = {
|
|
36
|
+
title: params.title as string,
|
|
37
|
+
description: params.description as string,
|
|
38
|
+
category: params.category as string | undefined,
|
|
39
|
+
tags: params.tags as string[] | undefined,
|
|
40
|
+
};
|
|
41
|
+
return detectScope(input);
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: 'vault_set_scope',
|
|
46
|
+
description: 'Manually set the scope tier for a vault entry. Overrides auto-detection.',
|
|
47
|
+
auth: 'write' as const,
|
|
48
|
+
schema: z.object({
|
|
49
|
+
id: z.string().describe('Entry ID'),
|
|
50
|
+
tier: z.enum(['agent', 'project', 'team']).describe('Scope tier'),
|
|
51
|
+
}),
|
|
52
|
+
handler: async (params) => {
|
|
53
|
+
const id = params.id as string;
|
|
54
|
+
const tier = params.tier as 'agent' | 'project' | 'team';
|
|
55
|
+
const entry = vault.get(id);
|
|
56
|
+
if (!entry) return { error: `Entry '${id}' not found` };
|
|
57
|
+
vault.seed([{ ...entry, tier }]);
|
|
58
|
+
return { updated: true, id, tier };
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
name: 'vault_list_by_scope',
|
|
63
|
+
description: 'List vault entries filtered by scope tier, with optional domain/type filters.',
|
|
64
|
+
auth: 'read' as const,
|
|
65
|
+
schema: z.object({
|
|
66
|
+
tier: z.enum(['agent', 'project', 'team']).describe('Scope tier to filter by'),
|
|
67
|
+
domain: z.string().optional(),
|
|
68
|
+
type: z.enum(['pattern', 'anti-pattern', 'rule', 'playbook']).optional(),
|
|
69
|
+
limit: z.number().optional(),
|
|
70
|
+
offset: z.number().optional(),
|
|
71
|
+
}),
|
|
72
|
+
handler: async (params) => {
|
|
73
|
+
const tier = params.tier as string;
|
|
74
|
+
const filters: string[] = ['tier = @tier'];
|
|
75
|
+
const fp: Record<string, unknown> = { tier };
|
|
76
|
+
if (params.domain) {
|
|
77
|
+
filters.push('domain = @domain');
|
|
78
|
+
fp.domain = params.domain;
|
|
79
|
+
}
|
|
80
|
+
if (params.type) {
|
|
81
|
+
filters.push('type = @type');
|
|
82
|
+
fp.type = params.type;
|
|
83
|
+
}
|
|
84
|
+
const limit = (params.limit as number) ?? 50;
|
|
85
|
+
const offset = (params.offset as number) ?? 0;
|
|
86
|
+
fp.limit = limit;
|
|
87
|
+
fp.offset = offset;
|
|
88
|
+
const wc = `WHERE ${filters.join(' AND ')}`;
|
|
89
|
+
const provider = vault.getProvider();
|
|
90
|
+
const rows = provider.all<Record<string, unknown>>(
|
|
91
|
+
`SELECT * FROM entries ${wc} ORDER BY domain, title LIMIT @limit OFFSET @offset`,
|
|
92
|
+
fp,
|
|
93
|
+
);
|
|
94
|
+
// Map to entries using the same logic as vault.list
|
|
95
|
+
const entries = rows.map((row) => ({
|
|
96
|
+
id: row.id as string,
|
|
97
|
+
type: row.type as string,
|
|
98
|
+
domain: row.domain as string,
|
|
99
|
+
title: row.title as string,
|
|
100
|
+
severity: row.severity as string,
|
|
101
|
+
description: row.description as string,
|
|
102
|
+
tier: (row.tier as string) ?? 'agent',
|
|
103
|
+
tags: JSON.parse((row.tags as string) || '[]'),
|
|
104
|
+
}));
|
|
105
|
+
return { entries, count: entries.length, tier };
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
// ─── Export to Pack (#104) ─────────────────────────────────────
|
|
110
|
+
{
|
|
111
|
+
name: 'vault_export_pack',
|
|
112
|
+
description:
|
|
113
|
+
'Export vault entries as a shareable intelligence pack. Filters by tier, domain, or tags. Returns IntelligenceBundle format.',
|
|
114
|
+
auth: 'read' as const,
|
|
115
|
+
schema: z.object({
|
|
116
|
+
name: z.string().optional().describe('Pack name (default: agent ID)'),
|
|
117
|
+
version: z.string().optional().describe('Pack version (default: 1.0.0)'),
|
|
118
|
+
tier: z.enum(['agent', 'project', 'team']).optional().describe('Filter by scope tier'),
|
|
119
|
+
domain: z.string().optional().describe('Filter by domain'),
|
|
120
|
+
tags: z.array(z.string()).optional().describe('Filter by tags (OR match)'),
|
|
121
|
+
excludeIds: z.array(z.string()).optional().describe('Entry IDs to exclude'),
|
|
122
|
+
}),
|
|
123
|
+
handler: async (params) => {
|
|
124
|
+
const tier = params.tier as string | undefined;
|
|
125
|
+
const domain = params.domain as string | undefined;
|
|
126
|
+
const tags = params.tags as string[] | undefined;
|
|
127
|
+
const excludeIds = new Set((params.excludeIds as string[] | undefined) ?? []);
|
|
128
|
+
|
|
129
|
+
// Get all matching entries
|
|
130
|
+
let entries = vault.list({ domain, tags, limit: 10000 });
|
|
131
|
+
|
|
132
|
+
// Filter by tier if specified
|
|
133
|
+
if (tier) {
|
|
134
|
+
entries = entries.filter((e) => e.tier === tier);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Exclude specified IDs
|
|
138
|
+
if (excludeIds.size > 0) {
|
|
139
|
+
entries = entries.filter((e) => !excludeIds.has(e.id));
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Group by domain into bundles
|
|
143
|
+
const byDomain = new Map<string, IntelligenceEntry[]>();
|
|
144
|
+
for (const entry of entries) {
|
|
145
|
+
const d = entry.domain;
|
|
146
|
+
if (!byDomain.has(d)) byDomain.set(d, []);
|
|
147
|
+
byDomain.get(d)!.push(entry);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
const version = (params.version as string) ?? '1.0.0';
|
|
151
|
+
const bundles: IntelligenceBundle[] = [];
|
|
152
|
+
for (const [d, domainEntries] of byDomain) {
|
|
153
|
+
bundles.push({ domain: d, version, entries: domainEntries });
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
return {
|
|
157
|
+
name: (params.name as string) ?? runtime.config.agentId,
|
|
158
|
+
version,
|
|
159
|
+
bundles,
|
|
160
|
+
totalEntries: entries.length,
|
|
161
|
+
domains: [...byDomain.keys()],
|
|
162
|
+
};
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
{
|
|
166
|
+
name: 'vault_import_pack',
|
|
167
|
+
description:
|
|
168
|
+
'Import an intelligence pack into the vault with content-hash dedup. Entries with duplicate content are skipped.',
|
|
169
|
+
auth: 'write' as const,
|
|
170
|
+
schema: z.object({
|
|
171
|
+
bundles: z
|
|
172
|
+
.array(
|
|
173
|
+
z.object({
|
|
174
|
+
domain: z.string(),
|
|
175
|
+
version: z.string(),
|
|
176
|
+
entries: z.array(z.record(z.unknown())),
|
|
177
|
+
}),
|
|
178
|
+
)
|
|
179
|
+
.describe('Array of IntelligenceBundle objects to import'),
|
|
180
|
+
tier: z
|
|
181
|
+
.enum(['agent', 'project', 'team'])
|
|
182
|
+
.optional()
|
|
183
|
+
.describe('Force all imported entries to this tier'),
|
|
184
|
+
}),
|
|
185
|
+
handler: async (params) => {
|
|
186
|
+
const bundles = params.bundles as Array<{
|
|
187
|
+
domain: string;
|
|
188
|
+
version: string;
|
|
189
|
+
entries: IntelligenceEntry[];
|
|
190
|
+
}>;
|
|
191
|
+
const forceTier = params.tier as 'agent' | 'project' | 'team' | undefined;
|
|
192
|
+
let imported = 0;
|
|
193
|
+
let duplicates = 0;
|
|
194
|
+
|
|
195
|
+
for (const bundle of bundles) {
|
|
196
|
+
const entries = bundle.entries.map((e) => ({
|
|
197
|
+
...e,
|
|
198
|
+
tier: forceTier ?? e.tier ?? 'project',
|
|
199
|
+
}));
|
|
200
|
+
const results = vault.seedDedup(entries);
|
|
201
|
+
for (const r of results) {
|
|
202
|
+
if (r.action === 'inserted') imported++;
|
|
203
|
+
else duplicates++;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return { imported, duplicates, total: imported + duplicates };
|
|
208
|
+
},
|
|
209
|
+
},
|
|
210
|
+
|
|
211
|
+
// ─── Git Sync (#67) ───────────────────────────────────────────
|
|
212
|
+
{
|
|
213
|
+
name: 'vault_git_push',
|
|
214
|
+
description:
|
|
215
|
+
'Push all vault entries to a git-tracked directory. Each entry becomes a JSON file under domain subdirectories.',
|
|
216
|
+
auth: 'write' as const,
|
|
217
|
+
schema: z.object({
|
|
218
|
+
repoDir: z.string().describe('Path to git-tracked vault directory'),
|
|
219
|
+
authorName: z.string().optional().describe('Git author name'),
|
|
220
|
+
authorEmail: z.string().optional().describe('Git author email'),
|
|
221
|
+
}),
|
|
222
|
+
handler: async (params) => {
|
|
223
|
+
const config: GitVaultSyncConfig = {
|
|
224
|
+
repoDir: params.repoDir as string,
|
|
225
|
+
authorName: params.authorName as string | undefined,
|
|
226
|
+
authorEmail: params.authorEmail as string | undefined,
|
|
227
|
+
};
|
|
228
|
+
const sync = new GitVaultSync(config);
|
|
229
|
+
await sync.init();
|
|
230
|
+
const { entries } = vault.exportAll();
|
|
231
|
+
return sync.syncAll(entries);
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
name: 'vault_git_pull',
|
|
236
|
+
description:
|
|
237
|
+
'Pull entries from a git-tracked directory into the vault. Reads JSON files and imports with conflict resolution.',
|
|
238
|
+
auth: 'write' as const,
|
|
239
|
+
schema: z.object({
|
|
240
|
+
repoDir: z.string().describe('Path to git-tracked vault directory'),
|
|
241
|
+
onConflict: z
|
|
242
|
+
.enum(['git', 'vault'])
|
|
243
|
+
.optional()
|
|
244
|
+
.describe(
|
|
245
|
+
'Conflict resolution: "git" (default) overwrites vault, "vault" keeps existing',
|
|
246
|
+
),
|
|
247
|
+
}),
|
|
248
|
+
handler: async (params) => {
|
|
249
|
+
const config: GitVaultSyncConfig = {
|
|
250
|
+
repoDir: params.repoDir as string,
|
|
251
|
+
autoCommit: false,
|
|
252
|
+
};
|
|
253
|
+
const sync = new GitVaultSync(config);
|
|
254
|
+
await sync.init();
|
|
255
|
+
return sync.pull(vault, {
|
|
256
|
+
onConflict: params.onConflict as 'git' | 'vault' | undefined,
|
|
257
|
+
});
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
name: 'vault_git_sync',
|
|
262
|
+
description:
|
|
263
|
+
'Bidirectional sync between vault and git directory. Pushes vault entries to git and pulls git-only entries into vault.',
|
|
264
|
+
auth: 'write' as const,
|
|
265
|
+
schema: z.object({
|
|
266
|
+
repoDir: z.string().describe('Path to git-tracked vault directory'),
|
|
267
|
+
onConflict: z
|
|
268
|
+
.enum(['git', 'vault'])
|
|
269
|
+
.optional()
|
|
270
|
+
.describe('Conflict resolution for entries that exist in both'),
|
|
271
|
+
authorName: z.string().optional(),
|
|
272
|
+
authorEmail: z.string().optional(),
|
|
273
|
+
}),
|
|
274
|
+
handler: async (params) => {
|
|
275
|
+
const config: GitVaultSyncConfig = {
|
|
276
|
+
repoDir: params.repoDir as string,
|
|
277
|
+
authorName: params.authorName as string | undefined,
|
|
278
|
+
authorEmail: params.authorEmail as string | undefined,
|
|
279
|
+
};
|
|
280
|
+
const sync = new GitVaultSync(config);
|
|
281
|
+
await sync.init();
|
|
282
|
+
return sync.sync(vault, {
|
|
283
|
+
onConflict: params.onConflict as 'git' | 'vault' | undefined,
|
|
284
|
+
});
|
|
285
|
+
},
|
|
286
|
+
},
|
|
287
|
+
|
|
288
|
+
// ─── Review Workflows (#65) ───────────────────────────────────
|
|
289
|
+
{
|
|
290
|
+
name: 'vault_submit_review',
|
|
291
|
+
description:
|
|
292
|
+
'Submit a vault entry for team review. Transitions entry from draft → pending_review.',
|
|
293
|
+
auth: 'write' as const,
|
|
294
|
+
schema: z.object({
|
|
295
|
+
entryId: z.string().describe('Entry ID to submit for review'),
|
|
296
|
+
submittedBy: z.string().optional().describe('Name/ID of the submitter'),
|
|
297
|
+
}),
|
|
298
|
+
handler: async (params) => {
|
|
299
|
+
try {
|
|
300
|
+
return knowledgeReview.submit({
|
|
301
|
+
entryId: params.entryId as string,
|
|
302
|
+
submittedBy: params.submittedBy as string | undefined,
|
|
303
|
+
});
|
|
304
|
+
} catch (err) {
|
|
305
|
+
return { error: (err as Error).message };
|
|
306
|
+
}
|
|
307
|
+
},
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
name: 'vault_approve',
|
|
311
|
+
description: 'Approve a pending vault entry. Transitions from pending_review → approved.',
|
|
312
|
+
auth: 'admin' as const,
|
|
313
|
+
schema: z.object({
|
|
314
|
+
entryId: z.string().describe('Entry ID to approve'),
|
|
315
|
+
reviewedBy: z.string().optional().describe('Name/ID of the reviewer'),
|
|
316
|
+
comment: z.string().optional().describe('Review comment'),
|
|
317
|
+
}),
|
|
318
|
+
handler: async (params) => {
|
|
319
|
+
try {
|
|
320
|
+
return knowledgeReview.approve({
|
|
321
|
+
entryId: params.entryId as string,
|
|
322
|
+
reviewedBy: params.reviewedBy as string | undefined,
|
|
323
|
+
comment: params.comment as string | undefined,
|
|
324
|
+
});
|
|
325
|
+
} catch (err) {
|
|
326
|
+
return { error: (err as Error).message };
|
|
327
|
+
}
|
|
328
|
+
},
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
name: 'vault_reject',
|
|
332
|
+
description: 'Reject a pending vault entry. Transitions from pending_review → rejected.',
|
|
333
|
+
auth: 'admin' as const,
|
|
334
|
+
schema: z.object({
|
|
335
|
+
entryId: z.string().describe('Entry ID to reject'),
|
|
336
|
+
reviewedBy: z.string().optional().describe('Name/ID of the reviewer'),
|
|
337
|
+
comment: z.string().optional().describe('Reason for rejection'),
|
|
338
|
+
}),
|
|
339
|
+
handler: async (params) => {
|
|
340
|
+
try {
|
|
341
|
+
return knowledgeReview.reject({
|
|
342
|
+
entryId: params.entryId as string,
|
|
343
|
+
reviewedBy: params.reviewedBy as string | undefined,
|
|
344
|
+
comment: params.comment as string | undefined,
|
|
345
|
+
});
|
|
346
|
+
} catch (err) {
|
|
347
|
+
return { error: (err as Error).message };
|
|
348
|
+
}
|
|
349
|
+
},
|
|
350
|
+
},
|
|
351
|
+
{
|
|
352
|
+
name: 'vault_pending_reviews',
|
|
353
|
+
description: 'List all vault entries pending team review.',
|
|
354
|
+
auth: 'read' as const,
|
|
355
|
+
schema: z.object({
|
|
356
|
+
limit: z.number().optional().describe('Max entries to return'),
|
|
357
|
+
}),
|
|
358
|
+
handler: async (params) => {
|
|
359
|
+
const pending = knowledgeReview.listPending((params.limit as number) ?? 50);
|
|
360
|
+
return { pending, count: pending.length };
|
|
361
|
+
},
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
name: 'vault_review_stats',
|
|
365
|
+
description: 'Get review workflow statistics — counts by status.',
|
|
366
|
+
auth: 'read' as const,
|
|
367
|
+
handler: async () => {
|
|
368
|
+
return knowledgeReview.stats();
|
|
369
|
+
},
|
|
370
|
+
},
|
|
371
|
+
];
|
|
372
|
+
}
|
package/src/streams/index.ts
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feed a single async source to multiple consumer functions in parallel.
|
|
3
|
+
* Each consumer gets its own independent iterator via ReplayableStream.
|
|
4
|
+
* Source executes exactly once regardless of consumer count.
|
|
5
|
+
*/
|
|
6
|
+
export async function fanOut<T>(
|
|
7
|
+
source: AsyncIterable<T>,
|
|
8
|
+
consumers: Array<(items: AsyncIterable<T>) => Promise<void>>,
|
|
9
|
+
options?: { maxBuffer?: number },
|
|
10
|
+
): Promise<void> {
|
|
11
|
+
const stream = new ReplayableStream(source, options);
|
|
12
|
+
await Promise.all(consumers.map((fn) => fn(stream)));
|
|
13
|
+
}
|
|
14
|
+
|
|
1
15
|
/**
|
|
2
16
|
* Multi-consumer async stream that replays from a buffer.
|
|
3
17
|
* Source executes exactly once — new iterators replay from buffer[0].
|
|
@@ -12,9 +26,12 @@ export class ReplayableStream<T> implements AsyncIterable<T> {
|
|
|
12
26
|
reject: (err: unknown) => void;
|
|
13
27
|
}> = [];
|
|
14
28
|
private advancing = false;
|
|
29
|
+
private readonly maxBuffer: number | undefined;
|
|
30
|
+
private evictedCount = 0;
|
|
15
31
|
|
|
16
|
-
constructor(source: AsyncIterable<T
|
|
32
|
+
constructor(source: AsyncIterable<T>, options?: { maxBuffer?: number }) {
|
|
17
33
|
this.source = source[Symbol.asyncIterator]();
|
|
34
|
+
this.maxBuffer = options?.maxBuffer;
|
|
18
35
|
}
|
|
19
36
|
|
|
20
37
|
private async advance(): Promise<void> {
|
|
@@ -30,6 +47,11 @@ export class ReplayableStream<T> implements AsyncIterable<T> {
|
|
|
30
47
|
this.waiters.length = 0;
|
|
31
48
|
} else {
|
|
32
49
|
this.buffer.push(result.value);
|
|
50
|
+
// Evict oldest entry if buffer exceeds max
|
|
51
|
+
if (this.maxBuffer !== undefined && this.buffer.length > this.maxBuffer) {
|
|
52
|
+
this.buffer.shift();
|
|
53
|
+
this.evictedCount++;
|
|
54
|
+
}
|
|
33
55
|
for (const waiter of this.waiters) {
|
|
34
56
|
waiter.resolve({ value: result.value, done: false });
|
|
35
57
|
}
|
|
@@ -51,8 +73,17 @@ export class ReplayableStream<T> implements AsyncIterable<T> {
|
|
|
51
73
|
let index = 0;
|
|
52
74
|
return {
|
|
53
75
|
next: async (): Promise<IteratorResult<T>> => {
|
|
54
|
-
|
|
55
|
-
|
|
76
|
+
// Translate absolute index to buffer-relative position
|
|
77
|
+
const bufferStart = this.evictedCount;
|
|
78
|
+
const relativeIndex = index - bufferStart;
|
|
79
|
+
if (relativeIndex < 0) {
|
|
80
|
+
throw new Error(
|
|
81
|
+
`ReplayableStream: consumer fell behind — ${-relativeIndex} items were evicted (maxBuffer: ${this.maxBuffer})`,
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
if (relativeIndex < this.buffer.length) {
|
|
85
|
+
index++;
|
|
86
|
+
return { value: this.buffer[relativeIndex], done: false };
|
|
56
87
|
}
|
|
57
88
|
if (this.done) {
|
|
58
89
|
if (this.error) throw this.error;
|