@soleri/core 2.9.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/planning/gap-analysis.d.ts.map +1 -1
- package/dist/planning/gap-analysis.js +3 -1
- package/dist/planning/gap-analysis.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/planning/gap-analysis.ts +52 -7
- 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,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chat Session Manager — per-conversation history with disk persistence.
|
|
3
|
+
*
|
|
4
|
+
* Ported from Salvador's session-manager.ts with improvements:
|
|
5
|
+
* - Transport-agnostic (no Telegram coupling)
|
|
6
|
+
* - Synchronous persistence (matches Soleri's better-sqlite3 heritage)
|
|
7
|
+
* - Simpler compaction (no personality tracking)
|
|
8
|
+
* - TTL-based reaping with unref'd timer
|
|
9
|
+
*/
|
|
10
|
+
import type { ChatSession, ChatSessionConfig, ChatMessage } from './types.js';
|
|
11
|
+
export declare class ChatSessionManager {
|
|
12
|
+
private sessions;
|
|
13
|
+
private config;
|
|
14
|
+
private reaperTimer;
|
|
15
|
+
constructor(config: ChatSessionConfig);
|
|
16
|
+
/**
|
|
17
|
+
* Get or create a session. Loads from disk if not in memory.
|
|
18
|
+
*/
|
|
19
|
+
getOrCreate(sessionId: string): ChatSession;
|
|
20
|
+
/**
|
|
21
|
+
* Get a session without creating one.
|
|
22
|
+
*/
|
|
23
|
+
get(sessionId: string): ChatSession | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* Check if a session exists (memory or disk).
|
|
26
|
+
*/
|
|
27
|
+
has(sessionId: string): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Append a message and persist.
|
|
30
|
+
*/
|
|
31
|
+
appendMessage(sessionId: string, message: ChatMessage): void;
|
|
32
|
+
/**
|
|
33
|
+
* Append multiple messages (e.g. assistant response + tool blocks).
|
|
34
|
+
*/
|
|
35
|
+
appendMessages(sessionId: string, messages: ChatMessage[]): void;
|
|
36
|
+
/**
|
|
37
|
+
* Get message count for a session.
|
|
38
|
+
*/
|
|
39
|
+
messageCount(sessionId: string): number;
|
|
40
|
+
/**
|
|
41
|
+
* Clear session history (keep session alive, wipe messages).
|
|
42
|
+
*/
|
|
43
|
+
clear(sessionId: string): void;
|
|
44
|
+
/**
|
|
45
|
+
* Delete a session entirely (memory + disk).
|
|
46
|
+
*/
|
|
47
|
+
delete(sessionId: string): void;
|
|
48
|
+
/**
|
|
49
|
+
* List all active session IDs (memory only — disk sessions not loaded).
|
|
50
|
+
*/
|
|
51
|
+
listActive(): string[];
|
|
52
|
+
/**
|
|
53
|
+
* List all session IDs (memory + disk).
|
|
54
|
+
*/
|
|
55
|
+
listAll(): string[];
|
|
56
|
+
/**
|
|
57
|
+
* Number of active (in-memory) sessions.
|
|
58
|
+
*/
|
|
59
|
+
get size(): number;
|
|
60
|
+
/**
|
|
61
|
+
* Update session metadata.
|
|
62
|
+
*/
|
|
63
|
+
setMeta(sessionId: string, meta: Record<string, unknown>): void;
|
|
64
|
+
/**
|
|
65
|
+
* Start periodic TTL-based session cleanup.
|
|
66
|
+
*/
|
|
67
|
+
startReaper(): void;
|
|
68
|
+
/**
|
|
69
|
+
* Stop the reaper.
|
|
70
|
+
*/
|
|
71
|
+
stopReaper(): void;
|
|
72
|
+
/**
|
|
73
|
+
* Reap expired sessions. Returns number of sessions reaped.
|
|
74
|
+
*/
|
|
75
|
+
reap(): number;
|
|
76
|
+
/**
|
|
77
|
+
* Close all sessions and stop reaper.
|
|
78
|
+
*/
|
|
79
|
+
close(): void;
|
|
80
|
+
private compact;
|
|
81
|
+
private sessionPath;
|
|
82
|
+
private persistToDisk;
|
|
83
|
+
private loadFromDisk;
|
|
84
|
+
private removeFromDisk;
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=chat-session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-session.d.ts","sourceRoot":"","sources":["../../src/chat/chat-session.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAO9E,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,QAAQ,CAAkC;IAClD,OAAO,CAAC,MAAM,CAA8B;IAC5C,OAAO,CAAC,WAAW,CAA+C;gBAEtD,MAAM,EAAE,iBAAiB;IAarC;;OAEG;IACH,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW;IA4B3C;;OAEG;IACH,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAI/C;;OAEG;IACH,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAO/B;;OAEG;IACH,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI;IAa5D;;OAEG;IACH,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,IAAI;IAYhE;;OAEG;IACH,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM;IAOvC;;OAEG;IACH,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAY9B;;OAEG;IACH,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAK/B;;OAEG;IACH,UAAU,IAAI,MAAM,EAAE;IAItB;;OAEG;IACH,OAAO,IAAI,MAAM,EAAE;IAenB;;OAEG;IACH,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;OAEG;IACH,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAQ/D;;OAEG;IACH,WAAW,IAAI,IAAI;IAMnB;;OAEG;IACH,UAAU,IAAI,IAAI;IAOlB;;OAEG;IACH,IAAI,IAAI,MAAM;IAkBd;;OAEG;IACH,KAAK,IAAI,IAAI;IAOb,OAAO,CAAC,OAAO;IAMf,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,cAAc;CAQvB"}
|
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chat Session Manager — per-conversation history with disk persistence.
|
|
3
|
+
*
|
|
4
|
+
* Ported from Salvador's session-manager.ts with improvements:
|
|
5
|
+
* - Transport-agnostic (no Telegram coupling)
|
|
6
|
+
* - Synchronous persistence (matches Soleri's better-sqlite3 heritage)
|
|
7
|
+
* - Simpler compaction (no personality tracking)
|
|
8
|
+
* - TTL-based reaping with unref'd timer
|
|
9
|
+
*/
|
|
10
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync, rmSync, readdirSync } from 'node:fs';
|
|
11
|
+
import { join } from 'node:path';
|
|
12
|
+
const DEFAULT_TTL_MS = 7_200_000; // 2 hours
|
|
13
|
+
const DEFAULT_COMPACTION_THRESHOLD = 100;
|
|
14
|
+
const DEFAULT_COMPACTION_KEEP = 40;
|
|
15
|
+
const REAPER_INTERVAL_MS = 60_000; // 1 minute
|
|
16
|
+
export class ChatSessionManager {
|
|
17
|
+
sessions = new Map();
|
|
18
|
+
config;
|
|
19
|
+
reaperTimer = null;
|
|
20
|
+
constructor(config) {
|
|
21
|
+
this.config = {
|
|
22
|
+
storageDir: config.storageDir,
|
|
23
|
+
ttlMs: config.ttlMs ?? DEFAULT_TTL_MS,
|
|
24
|
+
compactionThreshold: config.compactionThreshold ?? DEFAULT_COMPACTION_THRESHOLD,
|
|
25
|
+
compactionKeep: config.compactionKeep ?? DEFAULT_COMPACTION_KEEP,
|
|
26
|
+
};
|
|
27
|
+
mkdirSync(this.config.storageDir, { recursive: true });
|
|
28
|
+
}
|
|
29
|
+
// ─── Lifecycle ──────────────────────────────────────────────────
|
|
30
|
+
/**
|
|
31
|
+
* Get or create a session. Loads from disk if not in memory.
|
|
32
|
+
*/
|
|
33
|
+
getOrCreate(sessionId) {
|
|
34
|
+
let session = this.sessions.get(sessionId);
|
|
35
|
+
if (session) {
|
|
36
|
+
session.lastActiveAt = Date.now();
|
|
37
|
+
return session;
|
|
38
|
+
}
|
|
39
|
+
// Try loading from disk
|
|
40
|
+
session = this.loadFromDisk(sessionId);
|
|
41
|
+
if (session) {
|
|
42
|
+
session.lastActiveAt = Date.now();
|
|
43
|
+
this.sessions.set(sessionId, session);
|
|
44
|
+
return session;
|
|
45
|
+
}
|
|
46
|
+
// Create new
|
|
47
|
+
const now = Date.now();
|
|
48
|
+
session = {
|
|
49
|
+
id: sessionId,
|
|
50
|
+
messages: [],
|
|
51
|
+
createdAt: now,
|
|
52
|
+
lastActiveAt: now,
|
|
53
|
+
};
|
|
54
|
+
this.sessions.set(sessionId, session);
|
|
55
|
+
this.persistToDisk(session);
|
|
56
|
+
return session;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Get a session without creating one.
|
|
60
|
+
*/
|
|
61
|
+
get(sessionId) {
|
|
62
|
+
return this.sessions.get(sessionId) ?? this.loadFromDisk(sessionId);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Check if a session exists (memory or disk).
|
|
66
|
+
*/
|
|
67
|
+
has(sessionId) {
|
|
68
|
+
if (this.sessions.has(sessionId))
|
|
69
|
+
return true;
|
|
70
|
+
return existsSync(this.sessionPath(sessionId));
|
|
71
|
+
}
|
|
72
|
+
// ─── Message Management ─────────────────────────────────────────
|
|
73
|
+
/**
|
|
74
|
+
* Append a message and persist.
|
|
75
|
+
*/
|
|
76
|
+
appendMessage(sessionId, message) {
|
|
77
|
+
const session = this.getOrCreate(sessionId);
|
|
78
|
+
session.messages.push(message);
|
|
79
|
+
session.lastActiveAt = Date.now();
|
|
80
|
+
// Auto-compact if threshold exceeded
|
|
81
|
+
if (session.messages.length > this.config.compactionThreshold) {
|
|
82
|
+
this.compact(session);
|
|
83
|
+
}
|
|
84
|
+
this.persistToDisk(session);
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Append multiple messages (e.g. assistant response + tool blocks).
|
|
88
|
+
*/
|
|
89
|
+
appendMessages(sessionId, messages) {
|
|
90
|
+
const session = this.getOrCreate(sessionId);
|
|
91
|
+
session.messages.push(...messages);
|
|
92
|
+
session.lastActiveAt = Date.now();
|
|
93
|
+
if (session.messages.length > this.config.compactionThreshold) {
|
|
94
|
+
this.compact(session);
|
|
95
|
+
}
|
|
96
|
+
this.persistToDisk(session);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Get message count for a session.
|
|
100
|
+
*/
|
|
101
|
+
messageCount(sessionId) {
|
|
102
|
+
const session = this.sessions.get(sessionId);
|
|
103
|
+
return session?.messages.length ?? 0;
|
|
104
|
+
}
|
|
105
|
+
// ─── Session Operations ─────────────────────────────────────────
|
|
106
|
+
/**
|
|
107
|
+
* Clear session history (keep session alive, wipe messages).
|
|
108
|
+
*/
|
|
109
|
+
clear(sessionId) {
|
|
110
|
+
const session = this.sessions.get(sessionId);
|
|
111
|
+
if (session) {
|
|
112
|
+
session.messages = [];
|
|
113
|
+
session.lastActiveAt = Date.now();
|
|
114
|
+
this.persistToDisk(session);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
// Remove from disk
|
|
118
|
+
this.removeFromDisk(sessionId);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Delete a session entirely (memory + disk).
|
|
123
|
+
*/
|
|
124
|
+
delete(sessionId) {
|
|
125
|
+
this.sessions.delete(sessionId);
|
|
126
|
+
this.removeFromDisk(sessionId);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* List all active session IDs (memory only — disk sessions not loaded).
|
|
130
|
+
*/
|
|
131
|
+
listActive() {
|
|
132
|
+
return [...this.sessions.keys()];
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* List all session IDs (memory + disk).
|
|
136
|
+
*/
|
|
137
|
+
listAll() {
|
|
138
|
+
const memoryIds = new Set(this.sessions.keys());
|
|
139
|
+
try {
|
|
140
|
+
const files = readdirSync(this.config.storageDir);
|
|
141
|
+
for (const f of files) {
|
|
142
|
+
if (f.endsWith('.json')) {
|
|
143
|
+
memoryIds.add(f.replace('.json', ''));
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
// Directory may not exist yet
|
|
149
|
+
}
|
|
150
|
+
return [...memoryIds];
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Number of active (in-memory) sessions.
|
|
154
|
+
*/
|
|
155
|
+
get size() {
|
|
156
|
+
return this.sessions.size;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Update session metadata.
|
|
160
|
+
*/
|
|
161
|
+
setMeta(sessionId, meta) {
|
|
162
|
+
const session = this.getOrCreate(sessionId);
|
|
163
|
+
session.meta = { ...session.meta, ...meta };
|
|
164
|
+
this.persistToDisk(session);
|
|
165
|
+
}
|
|
166
|
+
// ─── Reaping (TTL cleanup) ─────────────────────────────────────
|
|
167
|
+
/**
|
|
168
|
+
* Start periodic TTL-based session cleanup.
|
|
169
|
+
*/
|
|
170
|
+
startReaper() {
|
|
171
|
+
if (this.reaperTimer)
|
|
172
|
+
return;
|
|
173
|
+
this.reaperTimer = setInterval(() => this.reap(), REAPER_INTERVAL_MS);
|
|
174
|
+
this.reaperTimer.unref();
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Stop the reaper.
|
|
178
|
+
*/
|
|
179
|
+
stopReaper() {
|
|
180
|
+
if (this.reaperTimer) {
|
|
181
|
+
clearInterval(this.reaperTimer);
|
|
182
|
+
this.reaperTimer = null;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Reap expired sessions. Returns number of sessions reaped.
|
|
187
|
+
*/
|
|
188
|
+
reap() {
|
|
189
|
+
if (this.config.ttlMs <= 0)
|
|
190
|
+
return 0;
|
|
191
|
+
const now = Date.now();
|
|
192
|
+
const cutoff = now - this.config.ttlMs;
|
|
193
|
+
let reaped = 0;
|
|
194
|
+
for (const [id, session] of this.sessions) {
|
|
195
|
+
if (session.lastActiveAt < cutoff) {
|
|
196
|
+
this.sessions.delete(id);
|
|
197
|
+
this.removeFromDisk(id);
|
|
198
|
+
reaped++;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return reaped;
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Close all sessions and stop reaper.
|
|
205
|
+
*/
|
|
206
|
+
close() {
|
|
207
|
+
this.stopReaper();
|
|
208
|
+
this.sessions.clear();
|
|
209
|
+
}
|
|
210
|
+
// ─── Private ───────────────────────────────────────────────────
|
|
211
|
+
compact(session) {
|
|
212
|
+
const keep = this.config.compactionKeep;
|
|
213
|
+
if (session.messages.length <= keep)
|
|
214
|
+
return;
|
|
215
|
+
session.messages = session.messages.slice(-keep);
|
|
216
|
+
}
|
|
217
|
+
sessionPath(sessionId) {
|
|
218
|
+
// Sanitize ID for filesystem safety
|
|
219
|
+
const safe = sessionId.replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
220
|
+
return join(this.config.storageDir, `${safe}.json`);
|
|
221
|
+
}
|
|
222
|
+
persistToDisk(session) {
|
|
223
|
+
try {
|
|
224
|
+
writeFileSync(this.sessionPath(session.id), JSON.stringify(session), 'utf-8');
|
|
225
|
+
}
|
|
226
|
+
catch {
|
|
227
|
+
// Disk write failure is non-critical — session lives in memory
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
loadFromDisk(sessionId) {
|
|
231
|
+
const path = this.sessionPath(sessionId);
|
|
232
|
+
if (!existsSync(path))
|
|
233
|
+
return undefined;
|
|
234
|
+
try {
|
|
235
|
+
const data = readFileSync(path, 'utf-8');
|
|
236
|
+
return JSON.parse(data);
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
return undefined;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
removeFromDisk(sessionId) {
|
|
243
|
+
const path = this.sessionPath(sessionId);
|
|
244
|
+
try {
|
|
245
|
+
rmSync(path, { force: true });
|
|
246
|
+
}
|
|
247
|
+
catch {
|
|
248
|
+
// Removal failure is non-critical
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
//# sourceMappingURL=chat-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-session.js","sourceRoot":"","sources":["../../src/chat/chat-session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Handler — intent detection and multimodal message building for chat transports.
|
|
3
|
+
*
|
|
4
|
+
* Provides transport-agnostic utilities for handling files sent by users:
|
|
5
|
+
* - Intent detection: should this file be viewed (vision), read as text, or ingested?
|
|
6
|
+
* - Multimodal message building for Anthropic API (ImageBlock, DocumentBlock)
|
|
7
|
+
* - Temp file management
|
|
8
|
+
*
|
|
9
|
+
* The actual file download is transport-specific (Telegram, Discord, etc.)
|
|
10
|
+
* and belongs in forge templates.
|
|
11
|
+
*/
|
|
12
|
+
/** Maximum file size in bytes (Telegram limit). */
|
|
13
|
+
export declare const MAX_FILE_SIZE: number;
|
|
14
|
+
/** File extensions treated as readable text. */
|
|
15
|
+
export declare const TEXT_EXTENSIONS: Set<string>;
|
|
16
|
+
/** MIME types supported for vision (ImageBlock). */
|
|
17
|
+
export declare const IMAGE_MIME_TYPES: Set<string>;
|
|
18
|
+
/** Keywords that indicate the user wants to ingest/learn from the file. */
|
|
19
|
+
export declare const INTAKE_KEYWORDS: string[];
|
|
20
|
+
export type FileIntent = 'vision' | 'text' | 'intake';
|
|
21
|
+
export interface FileInfo {
|
|
22
|
+
/** Original filename. */
|
|
23
|
+
name: string;
|
|
24
|
+
/** MIME type. */
|
|
25
|
+
mimeType: string;
|
|
26
|
+
/** File size in bytes. */
|
|
27
|
+
size: number;
|
|
28
|
+
/** File content as Buffer. */
|
|
29
|
+
data: Buffer;
|
|
30
|
+
}
|
|
31
|
+
export interface MultimodalContent {
|
|
32
|
+
type: 'image' | 'document' | 'text';
|
|
33
|
+
/** For image: base64 data. For document: base64 data. For text: the text content. */
|
|
34
|
+
content: string;
|
|
35
|
+
/** MIME type (for image/document). */
|
|
36
|
+
mimeType?: string;
|
|
37
|
+
/** Source filename. */
|
|
38
|
+
filename?: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Detect what the user wants to do with a file based on its type and
|
|
42
|
+
* any accompanying text message.
|
|
43
|
+
*/
|
|
44
|
+
export declare function detectFileIntent(filename: string, mimeType: string, userText?: string): FileIntent;
|
|
45
|
+
/**
|
|
46
|
+
* Build multimodal content from a file for the Anthropic API.
|
|
47
|
+
*/
|
|
48
|
+
export declare function buildMultimodalContent(file: FileInfo, intent: FileIntent): MultimodalContent;
|
|
49
|
+
/**
|
|
50
|
+
* Save a file to a temp directory with timestamp prefix.
|
|
51
|
+
* Returns the full path.
|
|
52
|
+
*/
|
|
53
|
+
export declare function saveTempFile(uploadDir: string, filename: string, data: Buffer): string;
|
|
54
|
+
/**
|
|
55
|
+
* Clean up temp files older than maxAgeMs.
|
|
56
|
+
*/
|
|
57
|
+
export declare function cleanupTempFiles(uploadDir: string, maxAgeMs?: number): number;
|
|
58
|
+
/**
|
|
59
|
+
* Strip base64 data from multimodal content for session persistence.
|
|
60
|
+
* Replaces binary content with a size placeholder to prevent session bloat.
|
|
61
|
+
*/
|
|
62
|
+
export declare function sanitizeForPersistence(content: MultimodalContent): MultimodalContent;
|
|
63
|
+
//# sourceMappingURL=file-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-handler.d.ts","sourceRoot":"","sources":["../../src/chat/file-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,mDAAmD;AACnD,eAAO,MAAM,aAAa,QAAmB,CAAC;AAE9C,gDAAgD;AAChD,eAAO,MAAM,eAAe,aAuC1B,CAAC;AAEH,oDAAoD;AACpD,eAAO,MAAM,gBAAgB,aAAkE,CAAC;AAEhG,2EAA2E;AAC3E,eAAO,MAAM,eAAe,UAY3B,CAAC;AAIF,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAC;AAEtD,MAAM,WAAW,QAAQ;IACvB,yBAAyB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,iBAAiB;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,OAAO,GAAG,UAAU,GAAG,MAAM,CAAC;IACpC,qFAAqF;IACrF,OAAO,EAAE,MAAM,CAAC;IAChB,sCAAsC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uBAAuB;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAID;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,QAAQ,CAAC,EAAE,MAAM,GAChB,UAAU,CA0BZ;AAID;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,GAAG,iBAAiB,CA2B5F;AAID;;;GAGG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAMtF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAkB,GAAG,MAAM,CAqBxF;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,iBAAiB,GAAG,iBAAiB,CAQpF"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File Handler — intent detection and multimodal message building for chat transports.
|
|
3
|
+
*
|
|
4
|
+
* Provides transport-agnostic utilities for handling files sent by users:
|
|
5
|
+
* - Intent detection: should this file be viewed (vision), read as text, or ingested?
|
|
6
|
+
* - Multimodal message building for Anthropic API (ImageBlock, DocumentBlock)
|
|
7
|
+
* - Temp file management
|
|
8
|
+
*
|
|
9
|
+
* The actual file download is transport-specific (Telegram, Discord, etc.)
|
|
10
|
+
* and belongs in forge templates.
|
|
11
|
+
*/
|
|
12
|
+
import { mkdirSync, writeFileSync, readdirSync, rmSync, statSync } from 'node:fs';
|
|
13
|
+
import { join, extname } from 'node:path';
|
|
14
|
+
// ─── Constants ────────────────────────────────────────────────────────
|
|
15
|
+
/** Maximum file size in bytes (Telegram limit). */
|
|
16
|
+
export const MAX_FILE_SIZE = 20 * 1024 * 1024; // 20MB
|
|
17
|
+
/** File extensions treated as readable text. */
|
|
18
|
+
export const TEXT_EXTENSIONS = new Set([
|
|
19
|
+
'.ts',
|
|
20
|
+
'.tsx',
|
|
21
|
+
'.js',
|
|
22
|
+
'.jsx',
|
|
23
|
+
'.py',
|
|
24
|
+
'.rb',
|
|
25
|
+
'.rs',
|
|
26
|
+
'.go',
|
|
27
|
+
'.java',
|
|
28
|
+
'.kt',
|
|
29
|
+
'.swift',
|
|
30
|
+
'.c',
|
|
31
|
+
'.cpp',
|
|
32
|
+
'.h',
|
|
33
|
+
'.cs',
|
|
34
|
+
'.php',
|
|
35
|
+
'.sh',
|
|
36
|
+
'.bash',
|
|
37
|
+
'.zsh',
|
|
38
|
+
'.fish',
|
|
39
|
+
'.md',
|
|
40
|
+
'.txt',
|
|
41
|
+
'.json',
|
|
42
|
+
'.yaml',
|
|
43
|
+
'.yml',
|
|
44
|
+
'.toml',
|
|
45
|
+
'.xml',
|
|
46
|
+
'.html',
|
|
47
|
+
'.css',
|
|
48
|
+
'.scss',
|
|
49
|
+
'.sql',
|
|
50
|
+
'.graphql',
|
|
51
|
+
'.prisma',
|
|
52
|
+
'.env',
|
|
53
|
+
'.gitignore',
|
|
54
|
+
'.dockerfile',
|
|
55
|
+
'.csv',
|
|
56
|
+
'.log',
|
|
57
|
+
]);
|
|
58
|
+
/** MIME types supported for vision (ImageBlock). */
|
|
59
|
+
export const IMAGE_MIME_TYPES = new Set(['image/jpeg', 'image/png', 'image/gif', 'image/webp']);
|
|
60
|
+
/** Keywords that indicate the user wants to ingest/learn from the file. */
|
|
61
|
+
export const INTAKE_KEYWORDS = [
|
|
62
|
+
'learn',
|
|
63
|
+
'ingest',
|
|
64
|
+
'absorb',
|
|
65
|
+
'study',
|
|
66
|
+
'memorize',
|
|
67
|
+
'remember',
|
|
68
|
+
'read this',
|
|
69
|
+
'save this',
|
|
70
|
+
'store this',
|
|
71
|
+
'add to vault',
|
|
72
|
+
'add to knowledge',
|
|
73
|
+
];
|
|
74
|
+
// ─── Intent Detection ─────────────────────────────────────────────────
|
|
75
|
+
/**
|
|
76
|
+
* Detect what the user wants to do with a file based on its type and
|
|
77
|
+
* any accompanying text message.
|
|
78
|
+
*/
|
|
79
|
+
export function detectFileIntent(filename, mimeType, userText) {
|
|
80
|
+
const ext = extname(filename).toLowerCase();
|
|
81
|
+
const textLower = userText?.toLowerCase() ?? '';
|
|
82
|
+
// Check for intake keywords first
|
|
83
|
+
if (userText && INTAKE_KEYWORDS.some((kw) => textLower.includes(kw))) {
|
|
84
|
+
return 'intake';
|
|
85
|
+
}
|
|
86
|
+
// Text files → read as text
|
|
87
|
+
if (TEXT_EXTENSIONS.has(ext)) {
|
|
88
|
+
return 'text';
|
|
89
|
+
}
|
|
90
|
+
// Images → vision
|
|
91
|
+
if (IMAGE_MIME_TYPES.has(mimeType) || mimeType.startsWith('image/')) {
|
|
92
|
+
return 'vision';
|
|
93
|
+
}
|
|
94
|
+
// PDFs → vision (DocumentBlock)
|
|
95
|
+
if (mimeType === 'application/pdf' || ext === '.pdf') {
|
|
96
|
+
return 'vision';
|
|
97
|
+
}
|
|
98
|
+
// Default: try vision
|
|
99
|
+
return 'vision';
|
|
100
|
+
}
|
|
101
|
+
// ─── Multimodal Message Building ──────────────────────────────────────
|
|
102
|
+
/**
|
|
103
|
+
* Build multimodal content from a file for the Anthropic API.
|
|
104
|
+
*/
|
|
105
|
+
export function buildMultimodalContent(file, intent) {
|
|
106
|
+
const ext = extname(file.name).toLowerCase();
|
|
107
|
+
if (intent === 'text' || TEXT_EXTENSIONS.has(ext)) {
|
|
108
|
+
return {
|
|
109
|
+
type: 'text',
|
|
110
|
+
content: file.data.toString('utf-8'),
|
|
111
|
+
filename: file.name,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
if (IMAGE_MIME_TYPES.has(file.mimeType)) {
|
|
115
|
+
return {
|
|
116
|
+
type: 'image',
|
|
117
|
+
content: file.data.toString('base64'),
|
|
118
|
+
mimeType: file.mimeType,
|
|
119
|
+
filename: file.name,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
// PDF and other documents
|
|
123
|
+
return {
|
|
124
|
+
type: 'document',
|
|
125
|
+
content: file.data.toString('base64'),
|
|
126
|
+
mimeType: file.mimeType,
|
|
127
|
+
filename: file.name,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
// ─── Temp File Management ─────────────────────────────────────────────
|
|
131
|
+
/**
|
|
132
|
+
* Save a file to a temp directory with timestamp prefix.
|
|
133
|
+
* Returns the full path.
|
|
134
|
+
*/
|
|
135
|
+
export function saveTempFile(uploadDir, filename, data) {
|
|
136
|
+
mkdirSync(uploadDir, { recursive: true });
|
|
137
|
+
const safeName = filename.replace(/[^\w.-]/g, '_');
|
|
138
|
+
const path = join(uploadDir, `${Date.now()}-${safeName}`);
|
|
139
|
+
writeFileSync(path, data);
|
|
140
|
+
return path;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Clean up temp files older than maxAgeMs.
|
|
144
|
+
*/
|
|
145
|
+
export function cleanupTempFiles(uploadDir, maxAgeMs = 3_600_000) {
|
|
146
|
+
let removed = 0;
|
|
147
|
+
try {
|
|
148
|
+
const cutoff = Date.now() - maxAgeMs;
|
|
149
|
+
const files = readdirSync(uploadDir);
|
|
150
|
+
for (const file of files) {
|
|
151
|
+
const filePath = join(uploadDir, file);
|
|
152
|
+
try {
|
|
153
|
+
const stat = statSync(filePath);
|
|
154
|
+
if (stat.mtimeMs < cutoff) {
|
|
155
|
+
rmSync(filePath);
|
|
156
|
+
removed++;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
catch {
|
|
160
|
+
// Skip files we can't stat
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
catch {
|
|
165
|
+
// Directory doesn't exist or can't be read
|
|
166
|
+
}
|
|
167
|
+
return removed;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Strip base64 data from multimodal content for session persistence.
|
|
171
|
+
* Replaces binary content with a size placeholder to prevent session bloat.
|
|
172
|
+
*/
|
|
173
|
+
export function sanitizeForPersistence(content) {
|
|
174
|
+
if (content.type === 'text')
|
|
175
|
+
return content;
|
|
176
|
+
const sizeKb = Math.round(Buffer.byteLength(content.content, 'base64') / 1024);
|
|
177
|
+
return {
|
|
178
|
+
...content,
|
|
179
|
+
content: `[${content.type}: ${content.filename ?? 'file'}, ${sizeKb}KB]`,
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
//# sourceMappingURL=file-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-handler.js","sourceRoot":"","sources":["../../src/chat/file-handler.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fragment Buffer — merges split messages from chat platforms.
|
|
3
|
+
*
|
|
4
|
+
* Telegram, Discord, and other platforms split long pastes into multiple
|
|
5
|
+
* messages (e.g. Telegram's 4096 char limit). This buffer detects near-limit
|
|
6
|
+
* messages and waits briefly for follow-up parts before flushing as one unit.
|
|
7
|
+
*
|
|
8
|
+
* Ported from Salvador's handler-messages.ts with improvements:
|
|
9
|
+
* - Transport-agnostic (works for any chat platform)
|
|
10
|
+
* - Callback-based flush (no transport dependency)
|
|
11
|
+
* - Configurable thresholds
|
|
12
|
+
*/
|
|
13
|
+
import type { Fragment, FragmentBufferConfig } from './types.js';
|
|
14
|
+
export declare class FragmentBuffer {
|
|
15
|
+
private buffers;
|
|
16
|
+
private config;
|
|
17
|
+
private onFlush;
|
|
18
|
+
constructor(config: FragmentBufferConfig | undefined, onFlush: (key: string, merged: string) => void);
|
|
19
|
+
/**
|
|
20
|
+
* Receive a message. Returns true if the message was buffered (caller should wait),
|
|
21
|
+
* false if the message should be processed immediately.
|
|
22
|
+
*/
|
|
23
|
+
receive(key: string, fragment: Fragment): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Force-flush a specific buffer. Returns the merged text or null if no buffer.
|
|
26
|
+
*/
|
|
27
|
+
flush(key: string): string | null;
|
|
28
|
+
/**
|
|
29
|
+
* Force-flush all pending buffers.
|
|
30
|
+
*/
|
|
31
|
+
flushAll(): void;
|
|
32
|
+
/**
|
|
33
|
+
* Number of keys with pending fragments.
|
|
34
|
+
*/
|
|
35
|
+
get pendingCount(): number;
|
|
36
|
+
/**
|
|
37
|
+
* Check if a key has pending fragments.
|
|
38
|
+
*/
|
|
39
|
+
hasPending(key: string): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Close the buffer — flush all and clean up timers.
|
|
42
|
+
*/
|
|
43
|
+
close(): void;
|
|
44
|
+
private startBuffer;
|
|
45
|
+
private appendToBuffer;
|
|
46
|
+
private autoFlush;
|
|
47
|
+
private mergeFragments;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=fragment-buffer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fragment-buffer.d.ts","sourceRoot":"","sources":["../../src/chat/fragment-buffer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAcjE,qBAAa,cAAc;IACzB,OAAO,CAAC,OAAO,CAAoC;IACnD,OAAO,CAAC,MAAM,CAAiC;IAC/C,OAAO,CAAC,OAAO,CAAwC;gBAGrD,MAAM,EAAE,oBAAoB,GAAG,SAAS,EACxC,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI;IAWhD;;;OAGG;IACH,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO;IAkBjD;;OAEG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAUjC;;OAEG;IACH,QAAQ,IAAI,IAAI;IAShB;;OAEG;IACH,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED;;OAEG;IACH,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIhC;;OAEG;IACH,KAAK,IAAI,IAAI;IASb,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,cAAc;IAkBtB,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,cAAc;CAGvB"}
|