comisai 1.0.34 → 1.0.36
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/node_modules/@comis/agent/dist/background/auto-background-middleware.d.ts +11 -1
- package/node_modules/@comis/agent/dist/background/auto-background-middleware.js +21 -4
- package/node_modules/@comis/agent/dist/background/background-task-manager.d.ts +2 -2
- package/node_modules/@comis/agent/dist/background/background-task-manager.js +61 -20
- package/node_modules/@comis/agent/dist/background/background-task-persistence.js +10 -3
- package/node_modules/@comis/agent/dist/background/background-task-types.d.ts +10 -3
- package/node_modules/@comis/agent/dist/background/background-task-types.js +1 -1
- package/node_modules/@comis/agent/dist/background/completion-formatter.d.ts +39 -0
- package/node_modules/@comis/agent/dist/background/completion-formatter.js +77 -0
- package/node_modules/@comis/agent/dist/background/completion-runner.d.ts +53 -0
- package/node_modules/@comis/agent/dist/background/completion-runner.js +151 -0
- package/node_modules/@comis/agent/dist/background/index.d.ts +4 -0
- package/node_modules/@comis/agent/dist/background/index.js +2 -0
- package/node_modules/@comis/agent/dist/bridge/bridge-metrics.d.ts +17 -2
- package/node_modules/@comis/agent/dist/bridge/bridge-metrics.js +14 -2
- package/node_modules/@comis/agent/dist/bridge/pi-event-bridge.d.ts +23 -23
- package/node_modules/@comis/agent/dist/bridge/pi-event-bridge.js +72 -60
- package/node_modules/@comis/agent/dist/bridge/thinking-block-hash-invariant.d.ts +6 -7
- package/node_modules/@comis/agent/dist/bridge/thinking-block-hash-invariant.js +24 -25
- package/node_modules/@comis/agent/dist/budget/cost-tracker.d.ts +1 -1
- package/node_modules/@comis/agent/dist/context-engine/constants.d.ts +5 -5
- package/node_modules/@comis/agent/dist/context-engine/constants.js +12 -12
- package/node_modules/@comis/agent/dist/context-engine/context-engine.js +13 -4
- package/node_modules/@comis/agent/dist/context-engine/dag-annotator.d.ts +1 -2
- package/node_modules/@comis/agent/dist/context-engine/dag-annotator.js +1 -2
- package/node_modules/@comis/agent/dist/context-engine/llm-compaction.js +20 -16
- package/node_modules/@comis/agent/dist/context-engine/rehydration.js +6 -6
- package/node_modules/@comis/agent/dist/context-engine/signature-replay-scrubber.d.ts +12 -12
- package/node_modules/@comis/agent/dist/context-engine/signature-replay-scrubber.js +36 -22
- package/node_modules/@comis/agent/dist/context-engine/types-core.d.ts +15 -0
- package/node_modules/@comis/agent/dist/executor/cache-break-detection.d.ts +6 -6
- package/node_modules/@comis/agent/dist/executor/cache-break-detection.js +8 -8
- package/node_modules/@comis/agent/dist/executor/executor-context-engine-setup.d.ts +16 -0
- package/node_modules/@comis/agent/dist/executor/executor-context-engine-setup.js +46 -5
- package/node_modules/@comis/agent/dist/executor/executor-post-execution.d.ts +30 -0
- package/node_modules/@comis/agent/dist/executor/executor-post-execution.js +17 -1
- package/node_modules/@comis/agent/dist/executor/executor-prompt-runner.js +1 -1
- package/node_modules/@comis/agent/dist/executor/executor-response-filter.d.ts +7 -6
- package/node_modules/@comis/agent/dist/executor/executor-response-filter.js +9 -42
- package/node_modules/@comis/agent/dist/executor/executor-tool-assembly.js +2 -3
- package/node_modules/@comis/agent/dist/executor/gemini-cache-injector.d.ts +2 -2
- package/node_modules/@comis/agent/dist/executor/gemini-cache-injector.js +4 -4
- package/node_modules/@comis/agent/dist/executor/phase-filter.d.ts +2 -2
- package/node_modules/@comis/agent/dist/executor/phase-filter.js +5 -7
- package/node_modules/@comis/agent/dist/executor/pi-executor.d.ts +13 -0
- package/node_modules/@comis/agent/dist/executor/pi-executor.js +71 -6
- package/node_modules/@comis/agent/dist/executor/post-batch-continuation.js +7 -7
- package/node_modules/@comis/agent/dist/executor/stream-wrappers/request-body-injector.d.ts +1 -1
- package/node_modules/@comis/agent/dist/executor/stream-wrappers/request-body-injector.js +1 -1
- package/node_modules/@comis/agent/dist/executor/tool-deferral.d.ts +2 -2
- package/node_modules/@comis/agent/dist/executor/tool-deferral.js +7 -7
- package/node_modules/@comis/agent/dist/index.d.ts +17 -0
- package/node_modules/@comis/agent/dist/index.js +32 -11
- package/node_modules/@comis/agent/dist/model/auth-provider.d.ts +25 -2
- package/node_modules/@comis/agent/dist/model/auth-provider.js +6 -0
- package/node_modules/@comis/agent/dist/model/compaction-model-resolver.d.ts +3 -3
- package/node_modules/@comis/agent/dist/model/compaction-model-resolver.js +3 -3
- package/node_modules/@comis/agent/dist/model/oauth-credential-store-file.d.ts +37 -0
- package/node_modules/@comis/agent/dist/model/oauth-credential-store-file.js +279 -0
- package/node_modules/@comis/agent/dist/model/oauth-credential-store-selector.d.ts +49 -0
- package/node_modules/@comis/agent/dist/model/oauth-credential-store-selector.js +50 -0
- package/node_modules/@comis/agent/dist/model/oauth-device-code.d.ts +57 -0
- package/node_modules/@comis/agent/dist/model/oauth-device-code.js +302 -0
- package/node_modules/@comis/agent/dist/model/oauth-env.d.ts +33 -0
- package/node_modules/@comis/agent/dist/model/oauth-env.js +38 -0
- package/node_modules/@comis/agent/dist/model/oauth-errors.d.ts +41 -0
- package/node_modules/@comis/agent/dist/model/oauth-errors.js +88 -0
- package/node_modules/@comis/agent/dist/model/oauth-identity.d.ts +53 -0
- package/node_modules/@comis/agent/dist/model/oauth-identity.js +141 -0
- package/node_modules/@comis/agent/dist/model/oauth-login-runner.d.ts +99 -0
- package/node_modules/@comis/agent/dist/model/oauth-login-runner.js +374 -0
- package/node_modules/@comis/agent/dist/model/oauth-tls-preflight.d.ts +58 -0
- package/node_modules/@comis/agent/dist/model/oauth-tls-preflight.js +82 -0
- package/node_modules/@comis/agent/dist/model/oauth-token-manager.d.ts +86 -16
- package/node_modules/@comis/agent/dist/model/oauth-token-manager.js +961 -66
- package/node_modules/@comis/agent/dist/model/operation-model-defaults.d.ts +9 -4
- package/node_modules/@comis/agent/dist/model/operation-model-defaults.js +36 -9
- package/node_modules/@comis/agent/dist/model/resolve-provider-api-key.d.ts +48 -0
- package/node_modules/@comis/agent/dist/model/resolve-provider-api-key.js +66 -0
- package/node_modules/@comis/agent/dist/provider/capabilities.d.ts +5 -5
- package/node_modules/@comis/agent/dist/provider/capabilities.js +10 -23
- package/node_modules/@comis/agent/dist/safety/tool-output-safety.js +3 -3
- package/node_modules/@comis/agent/dist/session/comis-session-manager.d.ts +1 -1
- package/node_modules/@comis/agent/dist/session/comis-session-manager.js +1 -1
- package/node_modules/@comis/agent/dist/spawn/narrative-caster.d.ts +10 -0
- package/node_modules/@comis/agent/dist/spawn/narrative-caster.js +5 -1
- package/node_modules/@comis/agent/package.json +1 -1
- package/node_modules/@comis/channels/dist/email/email-adapter.js +6 -6
- package/node_modules/@comis/channels/dist/email/imap-lifecycle.js +7 -7
- package/node_modules/@comis/channels/dist/shared/deliver-to-channel.js +12 -10
- package/node_modules/@comis/channels/dist/telegram/telegram-adapter.js +1 -1
- package/node_modules/@comis/channels/package.json +1 -1
- package/node_modules/@comis/cli/dist/cli.js +2 -0
- package/node_modules/@comis/cli/dist/commands/agent.d.ts +3 -3
- package/node_modules/@comis/cli/dist/commands/agent.js +46 -3
- package/node_modules/@comis/cli/dist/commands/auth.d.ts +37 -0
- package/node_modules/@comis/cli/dist/commands/auth.js +433 -0
- package/node_modules/@comis/cli/dist/commands/doctor.d.ts +4 -1
- package/node_modules/@comis/cli/dist/commands/doctor.js +20 -5
- package/node_modules/@comis/cli/dist/doctor/checks/oauth-health.d.ts +39 -0
- package/node_modules/@comis/cli/dist/doctor/checks/oauth-health.js +399 -0
- package/node_modules/@comis/cli/dist/doctor/types.d.ts +19 -0
- package/node_modules/@comis/cli/dist/index.d.ts +1 -0
- package/node_modules/@comis/cli/dist/index.js +10 -4
- package/node_modules/@comis/cli/dist/output/relative-time.d.ts +23 -0
- package/node_modules/@comis/cli/dist/output/relative-time.js +36 -0
- package/node_modules/@comis/cli/dist/wizard/non-interactive.js +17 -8
- package/node_modules/@comis/cli/dist/wizard/steps/03-provider.js +2 -1
- package/node_modules/@comis/cli/dist/wizard/steps/04-credentials.js +223 -34
- package/node_modules/@comis/cli/dist/wizard/steps/10-write-config.js +14 -0
- package/node_modules/@comis/cli/dist/wizard/steps/11-daemon-start.js +3 -3
- package/node_modules/@comis/cli/dist/wizard/types.d.ts +7 -0
- package/node_modules/@comis/cli/package.json +1 -1
- package/node_modules/@comis/core/dist/bootstrap.d.ts +1 -1
- package/node_modules/@comis/core/dist/config/env-substitution.d.ts +66 -0
- package/node_modules/@comis/core/dist/config/env-substitution.js +115 -0
- package/node_modules/@comis/core/dist/config/index.d.ts +3 -1
- package/node_modules/@comis/core/dist/config/index.js +2 -1
- package/node_modules/@comis/core/dist/config/loader.js +61 -0
- package/node_modules/@comis/core/dist/config/managed-sections.d.ts +3 -3
- package/node_modules/@comis/core/dist/config/managed-sections.js +10 -5
- package/node_modules/@comis/core/dist/config/schema-agent.d.ts +4 -0
- package/node_modules/@comis/core/dist/config/schema-agent.js +16 -1
- package/node_modules/@comis/core/dist/config/schema-background-tasks.d.ts +7 -0
- package/node_modules/@comis/core/dist/config/schema-background-tasks.js +7 -0
- package/node_modules/@comis/core/dist/config/schema-delivery.d.ts +2 -0
- package/node_modules/@comis/core/dist/config/schema-delivery.js +2 -0
- package/node_modules/@comis/core/dist/config/schema-gemini-cache.d.ts +0 -2
- package/node_modules/@comis/core/dist/config/schema-gemini-cache.js +0 -2
- package/node_modules/@comis/core/dist/config/schema-oauth.d.ts +23 -0
- package/node_modules/@comis/core/dist/config/schema-oauth.js +19 -0
- package/node_modules/@comis/core/dist/config/schema-skills.d.ts +6 -8
- package/node_modules/@comis/core/dist/config/schema-skills.js +3 -4
- package/node_modules/@comis/core/dist/config/schema.d.ts +10 -0
- package/node_modules/@comis/core/dist/config/schema.js +3 -0
- package/node_modules/@comis/core/dist/domain/background-task-origin.d.ts +39 -0
- package/node_modules/@comis/core/dist/domain/background-task-origin.js +39 -0
- package/node_modules/@comis/core/dist/event-bus/events-infra.d.ts +71 -2
- package/node_modules/@comis/core/dist/exports/config.d.ts +2 -2
- package/node_modules/@comis/core/dist/exports/config.js +1 -1
- package/node_modules/@comis/core/dist/exports/domain.d.ts +2 -0
- package/node_modules/@comis/core/dist/exports/domain.js +1 -0
- package/node_modules/@comis/core/dist/exports/ports.d.ts +2 -2
- package/node_modules/@comis/core/dist/exports/ports.js +1 -1
- package/node_modules/@comis/core/dist/ports/delivery-queue.d.ts +23 -0
- package/node_modules/@comis/core/dist/ports/delivery-queue.js +2 -0
- package/node_modules/@comis/core/dist/ports/index.d.ts +2 -0
- package/node_modules/@comis/core/dist/ports/index.js +1 -0
- package/node_modules/@comis/core/dist/ports/oauth-credential-store.d.ts +64 -0
- package/node_modules/@comis/core/dist/ports/oauth-credential-store.js +37 -0
- package/node_modules/@comis/core/dist/tool-metadata.d.ts +20 -0
- package/node_modules/@comis/core/package.json +1 -1
- package/node_modules/@comis/daemon/dist/daemon-types.d.ts +23 -3
- package/node_modules/@comis/daemon/dist/daemon.js +82 -19
- package/node_modules/@comis/daemon/dist/index.d.ts +2 -0
- package/node_modules/@comis/daemon/dist/index.js +5 -0
- package/node_modules/@comis/daemon/dist/observability/channel-health-logger.js +3 -3
- package/node_modules/@comis/daemon/dist/observability/delivery-queue-logger.js +1 -1
- package/node_modules/@comis/daemon/dist/rpc/agent-handlers.d.ts +22 -1
- package/node_modules/@comis/daemon/dist/rpc/agent-handlers.js +84 -21
- package/node_modules/@comis/daemon/dist/rpc/agent-inline-workspace.js +2 -2
- package/node_modules/@comis/daemon/dist/rpc/config-handlers.d.ts +9 -1
- package/node_modules/@comis/daemon/dist/rpc/config-handlers.js +104 -23
- package/node_modules/@comis/daemon/dist/rpc/credential-resolver.d.ts +30 -1
- package/node_modules/@comis/daemon/dist/rpc/credential-resolver.js +74 -11
- package/node_modules/@comis/daemon/dist/rpc/mcp-handlers.d.ts +8 -0
- package/node_modules/@comis/daemon/dist/rpc/mcp-handlers.js +22 -8
- package/node_modules/@comis/daemon/dist/rpc/provider-handlers.js +9 -12
- package/node_modules/@comis/daemon/dist/rpc/rpc-dispatch.d.ts +1 -0
- package/node_modules/@comis/daemon/dist/rpc/rpc-dispatch.js +27 -2
- package/node_modules/@comis/daemon/dist/setup-docker-restart-warn.js +0 -1
- package/node_modules/@comis/daemon/dist/wiring/index.d.ts +2 -0
- package/node_modules/@comis/daemon/dist/wiring/index.js +1 -0
- package/node_modules/@comis/daemon/dist/wiring/oauth-preflight.d.ts +21 -0
- package/node_modules/@comis/daemon/dist/wiring/oauth-preflight.js +134 -0
- package/node_modules/@comis/daemon/dist/wiring/setup-agents.d.ts +46 -1
- package/node_modules/@comis/daemon/dist/wiring/setup-agents.js +127 -3
- package/node_modules/@comis/daemon/dist/wiring/setup-background-completion-runner.d.ts +39 -0
- package/node_modules/@comis/daemon/dist/wiring/setup-background-completion-runner.js +32 -0
- package/node_modules/@comis/daemon/dist/wiring/setup-background-tasks.d.ts +10 -3
- package/node_modules/@comis/daemon/dist/wiring/setup-background-tasks.js +11 -5
- package/node_modules/@comis/daemon/dist/wiring/setup-channels.js +20 -1
- package/node_modules/@comis/daemon/dist/wiring/setup-cross-session.js +1 -1
- package/node_modules/@comis/daemon/dist/wiring/setup-delivery.d.ts +14 -5
- package/node_modules/@comis/daemon/dist/wiring/setup-delivery.js +52 -19
- package/node_modules/@comis/daemon/dist/wiring/setup-schedulers.js +4 -0
- package/node_modules/@comis/daemon/package.json +1 -1
- package/node_modules/@comis/gateway/dist/index.d.ts +2 -0
- package/node_modules/@comis/gateway/dist/index.js +2 -0
- package/node_modules/@comis/gateway/dist/oauth/oauth-callback-route.d.ts +66 -0
- package/node_modules/@comis/gateway/dist/oauth/oauth-callback-route.js +212 -0
- package/node_modules/@comis/gateway/dist/server/hono-server.d.ts +14 -0
- package/node_modules/@comis/gateway/dist/server/hono-server.js +10 -0
- package/node_modules/@comis/gateway/package.json +1 -1
- package/node_modules/@comis/infra/dist/logging/log-fields.d.ts +23 -0
- package/node_modules/@comis/infra/package.json +1 -1
- package/node_modules/@comis/memory/dist/compaction.d.ts +3 -5
- package/node_modules/@comis/memory/dist/compaction.js +2 -3
- package/node_modules/@comis/memory/dist/delivery-queue-adapter.d.ts +2 -2
- package/node_modules/@comis/memory/dist/delivery-queue-adapter.js +49 -1
- package/node_modules/@comis/memory/dist/index.d.ts +2 -0
- package/node_modules/@comis/memory/dist/index.js +3 -0
- package/node_modules/@comis/memory/dist/memory-api.d.ts +1 -1
- package/node_modules/@comis/memory/dist/memory-api.js +1 -1
- package/node_modules/@comis/memory/dist/oauth-profile-schema.d.ts +17 -0
- package/node_modules/@comis/memory/dist/oauth-profile-schema.js +33 -0
- package/node_modules/@comis/memory/dist/oauth-profile-store-encrypted.d.ts +27 -0
- package/node_modules/@comis/memory/dist/oauth-profile-store-encrypted.js +144 -0
- package/node_modules/@comis/memory/dist/session-store.d.ts +1 -1
- package/node_modules/@comis/memory/dist/session-store.js +1 -1
- package/node_modules/@comis/memory/dist/sqlite-secret-store.d.ts +29 -3
- package/node_modules/@comis/memory/dist/sqlite-secret-store.js +11 -3
- package/node_modules/@comis/memory/package.json +1 -1
- package/node_modules/@comis/scheduler/dist/execution/execution-lock.d.ts +13 -0
- package/node_modules/@comis/scheduler/dist/execution/execution-lock.js +1 -1
- package/node_modules/@comis/scheduler/dist/execution/index.d.ts +2 -0
- package/node_modules/@comis/scheduler/dist/execution/index.js +2 -0
- package/node_modules/@comis/scheduler/dist/heartbeat/agent-heartbeat-source.js +1 -1
- package/node_modules/@comis/scheduler/dist/index.d.ts +2 -0
- package/node_modules/@comis/scheduler/dist/index.js +2 -0
- package/node_modules/@comis/scheduler/package.json +1 -1
- package/node_modules/@comis/shared/package.json +1 -1
- package/node_modules/@comis/skills/dist/bridge/schema-validator.d.ts +38 -0
- package/node_modules/@comis/skills/dist/bridge/schema-validator.js +169 -0
- package/node_modules/@comis/skills/dist/bridge/tool-metadata-enforcement.js +12 -0
- package/node_modules/@comis/skills/dist/bridge/tool-metadata-registry.js +130 -0
- package/node_modules/@comis/skills/dist/builtin/exec-diagnostics.d.ts +32 -0
- package/node_modules/@comis/skills/dist/builtin/exec-diagnostics.js +127 -0
- package/node_modules/@comis/skills/dist/builtin/exec-security.js +38 -0
- package/node_modules/@comis/skills/dist/builtin/exec-tool.js +9 -0
- package/node_modules/@comis/skills/dist/builtin/file-tools/grep-tool.js +6 -6
- package/node_modules/@comis/skills/dist/builtin/platform/agents-manage-tool.d.ts +5 -4
- package/node_modules/@comis/skills/dist/builtin/platform/agents-manage-tool.js +38 -27
- package/node_modules/@comis/skills/dist/builtin/platform/background-tasks-tool.d.ts +4 -1
- package/node_modules/@comis/skills/dist/builtin/platform/background-tasks-tool.js +3 -3
- package/node_modules/@comis/skills/dist/builtin/platform/cron-tool.js +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/gateway-tool.js +6 -6
- package/node_modules/@comis/skills/dist/builtin/platform/mcp-manage-tool.d.ts +1 -1
- package/node_modules/@comis/skills/dist/builtin/platform/mcp-manage-tool.js +9 -9
- package/node_modules/@comis/skills/dist/builtin/sandbox/bwrap-provider.d.ts +11 -0
- package/node_modules/@comis/skills/dist/builtin/sandbox/bwrap-provider.js +114 -1
- package/node_modules/@comis/skills/dist/builtin/sandbox/detect-provider.js +40 -15
- package/node_modules/@comis/skills/dist/media/ssrf-fetcher.d.ts +7 -0
- package/node_modules/@comis/skills/dist/media/ssrf-fetcher.js +9 -2
- package/node_modules/@comis/skills/package.json +1 -1
- package/node_modules/@comis/web/dist/assets/{agent-detail-71BSbSfD.js → agent-detail-q8t1NB7w.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{agent-editor-CTSDZhwT.js → agent-editor-B46io5gv.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{agent-list-BEhni2ea.js → agent-list-DQ6g2Rcx.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{billing-view-DVP1IvVs.js → billing-view-IWPR8LgF.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{channel-detail-N_YK74xC.js → channel-detail-DlNNZuuC.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{channel-list-DRk6ZJaF.js → channel-list-DhGwxiMc.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{chat-console-Dm-GtSf9.js → chat-console-Nv6fM3Rc.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{config-editor-CIferYX6.js → config-editor-BYKuJF76.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{context-dag-browser-CL84rXXM.js → context-dag-browser-ClNEtzYE.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{context-engine-B1HOTEZv.js → context-engine-BZJ6HChd.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{delivery-view-Y6JKYVFw.js → delivery-view-Cb7I3vGu.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{diagnostics-view-DWV1UQjz.js → diagnostics-view-9u9Lyu5a.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{ic-chat-message-DfSERzzg.js → ic-chat-message-BFt3cVpx.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{ic-connection-dot-CXyhlJup.js → ic-connection-dot-y77LZ3Gu.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{ic-tool-call-DNmwTjek.js → ic-tool-call-qt6w1NQl.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{index-CBr0Tm9_.js → index-8Tg9oc-C.js} +2 -2
- package/node_modules/@comis/web/dist/assets/{mcp-management-BaH2-vox.js → mcp-management-69dtH_kY.js} +2 -2
- package/node_modules/@comis/web/dist/assets/{media-config-CZLshJoN.js → media-config-BdjLj5c1.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{media-test-C9NUWgo_.js → media-test-DuPqrixi.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{memory-inspector-D_fmTcRN.js → memory-inspector-B-Pepbq-.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{message-center-BBFlNCZn.js → message-center-B7l0yNYY.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{models-BytGLm99.js → models-JHFHuv5S.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{observe-view-VXtHqaqq.js → observe-view-r8mqhy4O.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{pipeline-builder-CfXczlfJ.js → pipeline-builder-XjkiZRcR.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{pipeline-history-CPmXFnbe.js → pipeline-history-CZqJv_Hj.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{pipeline-history-detail-DcueTMs9.js → pipeline-history-detail-BEFGMoDy.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{pipeline-list-B-xG5WZh.js → pipeline-list-B6q5LvO1.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{pipeline-monitor-pnIOYaSY.js → pipeline-monitor-BNomXjVL.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{scheduler-BtUIFHhA.js → scheduler-BJEjcGKA.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{security-C8mWRq2y.js → security-2G1jhBfV.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{session-detail-DgdkO5ka.js → session-detail-DmVPzFBR.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{session-list-DcylcfTn.js → session-list-CsqMQoHs.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{setup-wizard-BP5yjsuL.js → setup-wizard-CAdM-gSP.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{skills-DXt1bX8Z.js → skills-2ODqKaWr.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{subagents-C7YbUHXY.js → subagents-BFlwfTbD.js} +1 -1
- package/node_modules/@comis/web/dist/assets/{workspace-manager-DP6pW4wa.js → workspace-manager--CbOx_dI.js} +1 -1
- package/node_modules/@comis/web/dist/index.html +1 -1
- package/node_modules/@comis/web/package.json +1 -1
- package/package.json +17 -16
|
@@ -14,6 +14,7 @@ import { createRestApi, ActivityRingBuffer, subscribeActivityBuffer } from "../w
|
|
|
14
14
|
import { createSseEndpoint } from "../web/sse-endpoint.js";
|
|
15
15
|
import { createStaticMiddleware } from "../web/static-middleware.js";
|
|
16
16
|
import { createWebhookEndpoint } from "../webhook/webhook-endpoint.js";
|
|
17
|
+
import { createOAuthCallbackRoute, } from "../oauth/oauth-callback-route.js";
|
|
17
18
|
/**
|
|
18
19
|
* Create a gateway server with Hono.
|
|
19
20
|
*
|
|
@@ -123,6 +124,15 @@ export function createGatewayServer(deps) {
|
|
|
123
124
|
const webhookApp = createWebhookEndpoint(deps.webhookDeps);
|
|
124
125
|
app.route("/hooks", webhookApp);
|
|
125
126
|
}
|
|
127
|
+
// Mount OAuth callback at GET /oauth/callback/:provider
|
|
128
|
+
if (deps.oauthCallbackDeps) {
|
|
129
|
+
const oauthApp = createOAuthCallbackRoute({
|
|
130
|
+
...deps.oauthCallbackDeps,
|
|
131
|
+
logger,
|
|
132
|
+
});
|
|
133
|
+
app.route("/oauth", oauthApp);
|
|
134
|
+
logger.debug({ submodule: "oauth-callback" }, "OAuth callback route mounted at /oauth/callback/:provider");
|
|
135
|
+
}
|
|
126
136
|
// Mount web dashboard routes (if configured)
|
|
127
137
|
let unsubscribeActivity;
|
|
128
138
|
if (deps.webDeps) {
|
|
@@ -73,6 +73,29 @@ export interface LogFields {
|
|
|
73
73
|
* that produced it.
|
|
74
74
|
*/
|
|
75
75
|
module: string;
|
|
76
|
+
/**
|
|
77
|
+
* Finer-grained scope inside an existing `module` binding.
|
|
78
|
+
*
|
|
79
|
+
* Use at call sites instead of overriding `module:` in the payload.
|
|
80
|
+
* Pino concatenates parent-bound fields (pre-serialized JSON fragment)
|
|
81
|
+
* with the call-site object without deduplication, so passing
|
|
82
|
+
* `{ module: "agent.bridge.X" }` against a parent already bound with
|
|
83
|
+
* `module: "agent"` emits BOTH keys on the same line. JSON parsers
|
|
84
|
+
* keep the last, but the polluted output wastes bytes and confuses
|
|
85
|
+
* log consumers.
|
|
86
|
+
*
|
|
87
|
+
* `submodule` sidesteps the duplicate-key emission entirely:
|
|
88
|
+
* @example
|
|
89
|
+
* logger.info(
|
|
90
|
+
* { submodule: "bridge.hash-invariant", agentId, durationMs },
|
|
91
|
+
* "Hash invariant assertion ran",
|
|
92
|
+
* );
|
|
93
|
+
*
|
|
94
|
+
* Convention: omit any redundant parent-prefix from the value
|
|
95
|
+
* (e.g., under `module: "agent"`, prefer `submodule: "bridge.X"`
|
|
96
|
+
* over `submodule: "agent.bridge.X"`).
|
|
97
|
+
*/
|
|
98
|
+
submodule: string;
|
|
76
99
|
/**
|
|
77
100
|
* Pipeline step name.
|
|
78
101
|
* @example "response-filter" | "chunking" | "markdown-ir" | "media-compress"
|
|
@@ -5,9 +5,8 @@
|
|
|
5
5
|
* into semantic memories, keeping working memory bounded while preserving
|
|
6
6
|
* important information.
|
|
7
7
|
*
|
|
8
|
-
* The summarizer is pluggable --
|
|
9
|
-
*
|
|
10
|
-
* the compaction workflow.
|
|
8
|
+
* The summarizer is pluggable -- this module defines the interface and
|
|
9
|
+
* orchestrates the compaction workflow.
|
|
11
10
|
*
|
|
12
11
|
* Workflow:
|
|
13
12
|
* 1. Find sessions idle for longer than minIdleMs
|
|
@@ -25,8 +24,7 @@ import type { SessionStore } from "./session-store.js";
|
|
|
25
24
|
import type { SqliteMemoryAdapter } from "./sqlite-memory-adapter.js";
|
|
26
25
|
/**
|
|
27
26
|
* Pluggable summarizer function. Takes conversation messages and returns
|
|
28
|
-
* a summary string plus extracted facts.
|
|
29
|
-
* in Phase 3 (Agent).
|
|
27
|
+
* a summary string plus extracted facts.
|
|
30
28
|
*/
|
|
31
29
|
export type Summarizer = (messages: unknown[]) => Promise<{
|
|
32
30
|
summary: string;
|
|
@@ -6,9 +6,8 @@
|
|
|
6
6
|
* into semantic memories, keeping working memory bounded while preserving
|
|
7
7
|
* important information.
|
|
8
8
|
*
|
|
9
|
-
* The summarizer is pluggable --
|
|
10
|
-
*
|
|
11
|
-
* the compaction workflow.
|
|
9
|
+
* The summarizer is pluggable -- this module defines the interface and
|
|
10
|
+
* orchestrates the compaction workflow.
|
|
12
11
|
*
|
|
13
12
|
* Workflow:
|
|
14
13
|
* 1. Find sessions idle for longer than minIdleMs
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* @module
|
|
9
9
|
*/
|
|
10
10
|
import type Database from "better-sqlite3";
|
|
11
|
-
import type { DeliveryQueuePort } from "@comis/core";
|
|
11
|
+
import type { DeliveryQueuePort, TypedEventBus } from "@comis/core";
|
|
12
12
|
/**
|
|
13
13
|
* Create a SQLite-backed DeliveryQueuePort.
|
|
14
14
|
*
|
|
@@ -18,4 +18,4 @@ import type { DeliveryQueuePort } from "@comis/core";
|
|
|
18
18
|
* @param db - An open better-sqlite3 Database instance
|
|
19
19
|
* @returns DeliveryQueuePort implementation (frozen)
|
|
20
20
|
*/
|
|
21
|
-
export declare function createSqliteDeliveryQueue(db: Database.Database): DeliveryQueuePort;
|
|
21
|
+
export declare function createSqliteDeliveryQueue(db: Database.Database, eventBus: Pick<TypedEventBus, "emit">): DeliveryQueuePort;
|
|
@@ -50,7 +50,7 @@ function rowToEntry(row) {
|
|
|
50
50
|
* @param db - An open better-sqlite3 Database instance
|
|
51
51
|
* @returns DeliveryQueuePort implementation (frozen)
|
|
52
52
|
*/
|
|
53
|
-
export function createSqliteDeliveryQueue(db) {
|
|
53
|
+
export function createSqliteDeliveryQueue(db, eventBus) {
|
|
54
54
|
// --- Prepared statements ---
|
|
55
55
|
const insertStmt = db.prepare(`
|
|
56
56
|
INSERT INTO delivery_queue (
|
|
@@ -87,6 +87,19 @@ export function createSqliteDeliveryQueue(db) {
|
|
|
87
87
|
const pruneStmt = db.prepare(`
|
|
88
88
|
DELETE FROM delivery_queue
|
|
89
89
|
WHERE expire_at < ? AND status NOT IN ('delivered')
|
|
90
|
+
`);
|
|
91
|
+
const insertInFlightStmt = db.prepare(`
|
|
92
|
+
INSERT INTO delivery_queue (
|
|
93
|
+
id, text, channel_type, channel_id, tenant_id, options_json, origin,
|
|
94
|
+
format_applied, chunking_applied, status, attempt_count, max_attempts,
|
|
95
|
+
created_at, scheduled_at, expire_at, last_attempt_at, next_retry_at,
|
|
96
|
+
last_error, markdown_fallback_applied, delivered_message_id, trace_id
|
|
97
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, 'in_flight', 0, ?, ?, ?, ?, NULL, NULL, NULL, 0, NULL, ?)
|
|
98
|
+
`);
|
|
99
|
+
const recoverInFlightStmt = db.prepare(`
|
|
100
|
+
UPDATE delivery_queue
|
|
101
|
+
SET status = 'pending', last_error = NULL
|
|
102
|
+
WHERE status = 'in_flight'
|
|
90
103
|
`);
|
|
91
104
|
const depthStmt = db.prepare(`
|
|
92
105
|
SELECT COUNT(*) as count FROM delivery_queue
|
|
@@ -103,6 +116,32 @@ export function createSqliteDeliveryQueue(db) {
|
|
|
103
116
|
try {
|
|
104
117
|
const id = randomUUID();
|
|
105
118
|
insertStmt.run(id, entry.text, entry.channelType, entry.channelId, entry.tenantId, entry.optionsJson, entry.origin, entry.formatApplied ? 1 : 0, entry.chunkingApplied ? 1 : 0, entry.maxAttempts, entry.createdAt, entry.scheduledAt, entry.expireAt, entry.traceId ?? null);
|
|
119
|
+
// Emit AFTER SQL success -- preserves invariant: one delivery:enqueued <=> one persisted row.
|
|
120
|
+
eventBus.emit("delivery:enqueued", {
|
|
121
|
+
entryId: id,
|
|
122
|
+
channelId: entry.channelId,
|
|
123
|
+
channelType: entry.channelType,
|
|
124
|
+
origin: entry.origin,
|
|
125
|
+
timestamp: Date.now(),
|
|
126
|
+
});
|
|
127
|
+
return Promise.resolve(ok(id));
|
|
128
|
+
}
|
|
129
|
+
catch (e) {
|
|
130
|
+
return Promise.resolve(err(e instanceof Error ? e : new Error(String(e))));
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
enqueueInFlight(entry) {
|
|
134
|
+
try {
|
|
135
|
+
const id = randomUUID();
|
|
136
|
+
insertInFlightStmt.run(id, entry.text, entry.channelType, entry.channelId, entry.tenantId, entry.optionsJson, entry.origin, entry.formatApplied ? 1 : 0, entry.chunkingApplied ? 1 : 0, entry.maxAttempts, entry.createdAt, entry.scheduledAt, entry.expireAt, entry.traceId ?? null);
|
|
137
|
+
// Same delivery:enqueued event as enqueue() -- universal observability (SPEC-R5).
|
|
138
|
+
eventBus.emit("delivery:enqueued", {
|
|
139
|
+
entryId: id,
|
|
140
|
+
channelId: entry.channelId,
|
|
141
|
+
channelType: entry.channelType,
|
|
142
|
+
origin: entry.origin,
|
|
143
|
+
timestamp: Date.now(),
|
|
144
|
+
});
|
|
106
145
|
return Promise.resolve(ok(id));
|
|
107
146
|
}
|
|
108
147
|
catch (e) {
|
|
@@ -192,6 +231,15 @@ export function createSqliteDeliveryQueue(db) {
|
|
|
192
231
|
return Promise.resolve(err(e instanceof Error ? e : new Error(String(e))));
|
|
193
232
|
}
|
|
194
233
|
},
|
|
234
|
+
recoverInFlight() {
|
|
235
|
+
try {
|
|
236
|
+
const result = recoverInFlightStmt.run();
|
|
237
|
+
return Promise.resolve(ok(result.changes));
|
|
238
|
+
}
|
|
239
|
+
catch (e) {
|
|
240
|
+
return Promise.resolve(err(e instanceof Error ? e : new Error(String(e))));
|
|
241
|
+
}
|
|
242
|
+
},
|
|
195
243
|
};
|
|
196
244
|
return Object.freeze(queue);
|
|
197
245
|
}
|
|
@@ -22,6 +22,8 @@ export type { BatchIndexer, BatchIndexerOptions, BatchIndexerResult } from "./em
|
|
|
22
22
|
export { openSqliteDatabase, chmodDbFiles } from "./sqlite-adapter-base.js";
|
|
23
23
|
export type { SqliteAdapterOptions } from "./sqlite-adapter-base.js";
|
|
24
24
|
export { createSqliteSecretStore } from "./sqlite-secret-store.js";
|
|
25
|
+
export { initOAuthProfileSchema } from "./oauth-profile-schema.js";
|
|
26
|
+
export { createOAuthProfileStoreEncrypted } from "./oauth-profile-store-encrypted.js";
|
|
25
27
|
export { setupSecrets } from "./setup-secrets.js";
|
|
26
28
|
export type { SecretsBootResult } from "./setup-secrets.js";
|
|
27
29
|
export { createNamedGraphStore } from "./named-graph-store.js";
|
|
@@ -28,6 +28,9 @@ export { createBatchIndexer } from "./embedding-batch-indexer.js";
|
|
|
28
28
|
export { openSqliteDatabase, chmodDbFiles } from "./sqlite-adapter-base.js";
|
|
29
29
|
// SQLite secret store (SecretStorePort implementation)
|
|
30
30
|
export { createSqliteSecretStore } from "./sqlite-secret-store.js";
|
|
31
|
+
// OAuth profile schema + encrypted SQLite OAuthCredentialStorePort adapter
|
|
32
|
+
export { initOAuthProfileSchema } from "./oauth-profile-schema.js";
|
|
33
|
+
export { createOAuthProfileStoreEncrypted } from "./oauth-profile-store-encrypted.js";
|
|
31
34
|
// Secret store bootstrap (master key resolution)
|
|
32
35
|
export { setupSecrets } from "./setup-secrets.js";
|
|
33
36
|
// Named graph store (server-side pipeline persistence)
|
|
@@ -80,6 +80,6 @@ export interface MemoryApi {
|
|
|
80
80
|
* and memory config.
|
|
81
81
|
*
|
|
82
82
|
* The factory function pattern is consistent with createSessionStore and
|
|
83
|
-
* createSecretManager
|
|
83
|
+
* createSecretManager.
|
|
84
84
|
*/
|
|
85
85
|
export declare function createMemoryApi(db: Database.Database, adapter: SqliteMemoryAdapter, sessionStore: SessionStore, config: MemoryConfig): MemoryApi;
|
|
@@ -16,7 +16,7 @@ import { rowToEntry, buildFilterClause, countRows, groupCountRows } from "./row-
|
|
|
16
16
|
* and memory config.
|
|
17
17
|
*
|
|
18
18
|
* The factory function pattern is consistent with createSessionStore and
|
|
19
|
-
* createSecretManager
|
|
19
|
+
* createSecretManager.
|
|
20
20
|
*/
|
|
21
21
|
export function createMemoryApi(db, adapter, sessionStore, config) {
|
|
22
22
|
return {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type Database from "better-sqlite3";
|
|
2
|
+
/**
|
|
3
|
+
* Create the oauth_profiles table and supporting index.
|
|
4
|
+
*
|
|
5
|
+
* Single ciphertext+iv+auth_tag+salt per row — entire OAuthProfile JSON
|
|
6
|
+
* encrypted as one blob, no half-rotated state.
|
|
7
|
+
*
|
|
8
|
+
* Denormalized expires_at column lets the doctor query expiring profiles
|
|
9
|
+
* via SELECT profile_id FROM oauth_profiles WHERE provider = ?
|
|
10
|
+
* AND expires_at < ? without decrypting any blob.
|
|
11
|
+
*
|
|
12
|
+
* No FK to secrets table — OAuth profiles are independent from named
|
|
13
|
+
* secrets. Index on provider supports list({ provider }) filtering.
|
|
14
|
+
*
|
|
15
|
+
* Idempotent via IF NOT EXISTS — safe to call multiple times.
|
|
16
|
+
*/
|
|
17
|
+
export declare function initOAuthProfileSchema(db: Database.Database): void;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Create the oauth_profiles table and supporting index.
|
|
3
|
+
*
|
|
4
|
+
* Single ciphertext+iv+auth_tag+salt per row — entire OAuthProfile JSON
|
|
5
|
+
* encrypted as one blob, no half-rotated state.
|
|
6
|
+
*
|
|
7
|
+
* Denormalized expires_at column lets the doctor query expiring profiles
|
|
8
|
+
* via SELECT profile_id FROM oauth_profiles WHERE provider = ?
|
|
9
|
+
* AND expires_at < ? without decrypting any blob.
|
|
10
|
+
*
|
|
11
|
+
* No FK to secrets table — OAuth profiles are independent from named
|
|
12
|
+
* secrets. Index on provider supports list({ provider }) filtering.
|
|
13
|
+
*
|
|
14
|
+
* Idempotent via IF NOT EXISTS — safe to call multiple times.
|
|
15
|
+
*/
|
|
16
|
+
export function initOAuthProfileSchema(db) {
|
|
17
|
+
db.exec(`
|
|
18
|
+
CREATE TABLE IF NOT EXISTS oauth_profiles (
|
|
19
|
+
profile_id TEXT PRIMARY KEY,
|
|
20
|
+
provider TEXT NOT NULL,
|
|
21
|
+
identity TEXT NOT NULL,
|
|
22
|
+
credentials_ciphertext BLOB NOT NULL,
|
|
23
|
+
credentials_iv BLOB NOT NULL,
|
|
24
|
+
credentials_auth_tag BLOB NOT NULL,
|
|
25
|
+
credentials_salt BLOB NOT NULL,
|
|
26
|
+
expires_at INTEGER NOT NULL,
|
|
27
|
+
version INTEGER NOT NULL DEFAULT 1,
|
|
28
|
+
created_at INTEGER NOT NULL,
|
|
29
|
+
updated_at INTEGER NOT NULL
|
|
30
|
+
);
|
|
31
|
+
CREATE INDEX IF NOT EXISTS idx_oauth_profiles_provider ON oauth_profiles(provider);
|
|
32
|
+
`);
|
|
33
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Encrypted SQLite-backed OAuthCredentialStorePort adapter.
|
|
3
|
+
*
|
|
4
|
+
* Mirrors credential-mapping-store's factory pattern (takes a pre-opened
|
|
5
|
+
* Database instance, does NOT open its own). The lifecycle is owned by
|
|
6
|
+
* the caller — we share the existing secrets.db connection to keep all
|
|
7
|
+
* encrypted-at-rest data in one DB file.
|
|
8
|
+
*
|
|
9
|
+
* The entire OAuthProfile JSON payload is encrypted as one AES-256-GCM
|
|
10
|
+
* blob per row. One ciphertext+iv+authTag+salt set per profile. Atomic
|
|
11
|
+
* update — no half-rotated state where access changes but refresh doesn't.
|
|
12
|
+
*
|
|
13
|
+
* Denormalized expires_at column stays in sync on every write so the
|
|
14
|
+
* doctor can query expiring profiles without decrypting any blob.
|
|
15
|
+
*
|
|
16
|
+
* @module
|
|
17
|
+
*/
|
|
18
|
+
import type Database from "better-sqlite3";
|
|
19
|
+
import type { OAuthCredentialStorePort, SecretsCrypto } from "@comis/core";
|
|
20
|
+
/**
|
|
21
|
+
* Create an encrypted OAuthCredentialStorePort backed by a shared SQLite DB.
|
|
22
|
+
*
|
|
23
|
+
* The adapter does NOT own the db lifecycle — the caller supplies an
|
|
24
|
+
* already-open Database (typically the secrets.db chain). Initializes its
|
|
25
|
+
* own oauth_profiles table via initOAuthProfileSchema (idempotent).
|
|
26
|
+
*/
|
|
27
|
+
export declare function createOAuthProfileStoreEncrypted(db: Database.Database, crypto: SecretsCrypto): OAuthCredentialStorePort;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
/**
|
|
3
|
+
* Encrypted SQLite-backed OAuthCredentialStorePort adapter.
|
|
4
|
+
*
|
|
5
|
+
* Mirrors credential-mapping-store's factory pattern (takes a pre-opened
|
|
6
|
+
* Database instance, does NOT open its own). The lifecycle is owned by
|
|
7
|
+
* the caller — we share the existing secrets.db connection to keep all
|
|
8
|
+
* encrypted-at-rest data in one DB file.
|
|
9
|
+
*
|
|
10
|
+
* The entire OAuthProfile JSON payload is encrypted as one AES-256-GCM
|
|
11
|
+
* blob per row. One ciphertext+iv+authTag+salt set per profile. Atomic
|
|
12
|
+
* update — no half-rotated state where access changes but refresh doesn't.
|
|
13
|
+
*
|
|
14
|
+
* Denormalized expires_at column stays in sync on every write so the
|
|
15
|
+
* doctor can query expiring profiles without decrypting any blob.
|
|
16
|
+
*
|
|
17
|
+
* @module
|
|
18
|
+
*/
|
|
19
|
+
import { ok, err, fromPromise } from "@comis/shared";
|
|
20
|
+
import { validateProfileId } from "@comis/core";
|
|
21
|
+
import { initOAuthProfileSchema } from "./oauth-profile-schema.js";
|
|
22
|
+
const SCHEMA_VERSION = 1;
|
|
23
|
+
/**
|
|
24
|
+
* Create an encrypted OAuthCredentialStorePort backed by a shared SQLite DB.
|
|
25
|
+
*
|
|
26
|
+
* The adapter does NOT own the db lifecycle — the caller supplies an
|
|
27
|
+
* already-open Database (typically the secrets.db chain). Initializes its
|
|
28
|
+
* own oauth_profiles table via initOAuthProfileSchema (idempotent).
|
|
29
|
+
*/
|
|
30
|
+
export function createOAuthProfileStoreEncrypted(db, crypto) {
|
|
31
|
+
initOAuthProfileSchema(db);
|
|
32
|
+
const upsertStmt = db.prepare(`
|
|
33
|
+
INSERT INTO oauth_profiles (
|
|
34
|
+
profile_id, provider, identity,
|
|
35
|
+
credentials_ciphertext, credentials_iv, credentials_auth_tag, credentials_salt,
|
|
36
|
+
expires_at, version, created_at, updated_at
|
|
37
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
38
|
+
ON CONFLICT(profile_id) DO UPDATE SET
|
|
39
|
+
provider = excluded.provider,
|
|
40
|
+
identity = excluded.identity,
|
|
41
|
+
credentials_ciphertext = excluded.credentials_ciphertext,
|
|
42
|
+
credentials_iv = excluded.credentials_iv,
|
|
43
|
+
credentials_auth_tag = excluded.credentials_auth_tag,
|
|
44
|
+
credentials_salt = excluded.credentials_salt,
|
|
45
|
+
expires_at = excluded.expires_at,
|
|
46
|
+
version = excluded.version,
|
|
47
|
+
updated_at = excluded.updated_at
|
|
48
|
+
`);
|
|
49
|
+
const getStmt = db.prepare("SELECT * FROM oauth_profiles WHERE profile_id = ?");
|
|
50
|
+
const deleteStmt = db.prepare("DELETE FROM oauth_profiles WHERE profile_id = ?");
|
|
51
|
+
const listAllStmt = db.prepare("SELECT * FROM oauth_profiles");
|
|
52
|
+
const listByProviderStmt = db.prepare("SELECT * FROM oauth_profiles WHERE provider = ?");
|
|
53
|
+
const existsStmt = db.prepare("SELECT 1 FROM oauth_profiles WHERE profile_id = ?");
|
|
54
|
+
function rowToProfile(row) {
|
|
55
|
+
if (row.version !== SCHEMA_VERSION) {
|
|
56
|
+
return err(new Error("OAuth profile store version mismatch: expected " +
|
|
57
|
+
SCHEMA_VERSION +
|
|
58
|
+
", got " +
|
|
59
|
+
String(row.version) +
|
|
60
|
+
". Hint: drop the oauth_profiles table and re-run `comis auth login` to recreate. Stored profiles for unknown schema versions cannot be migrated."));
|
|
61
|
+
}
|
|
62
|
+
const decryptResult = crypto.decrypt({
|
|
63
|
+
ciphertext: row.credentials_ciphertext,
|
|
64
|
+
iv: row.credentials_iv,
|
|
65
|
+
authTag: row.credentials_auth_tag,
|
|
66
|
+
salt: row.credentials_salt,
|
|
67
|
+
});
|
|
68
|
+
if (!decryptResult.ok)
|
|
69
|
+
return err(decryptResult.error);
|
|
70
|
+
let parsed;
|
|
71
|
+
try {
|
|
72
|
+
parsed = JSON.parse(decryptResult.value);
|
|
73
|
+
}
|
|
74
|
+
catch (e) {
|
|
75
|
+
return err(new Error("OAuth profile decryption produced invalid JSON: " + String(e)));
|
|
76
|
+
}
|
|
77
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
78
|
+
return err(new Error("OAuth profile decryption produced non-object payload"));
|
|
79
|
+
}
|
|
80
|
+
return ok(parsed);
|
|
81
|
+
}
|
|
82
|
+
const port = {
|
|
83
|
+
async get(profileId) {
|
|
84
|
+
const validation = validateProfileId(profileId);
|
|
85
|
+
if (!validation.ok)
|
|
86
|
+
return err(validation.error);
|
|
87
|
+
return fromPromise((async () => {
|
|
88
|
+
const row = getStmt.get(profileId);
|
|
89
|
+
if (!row)
|
|
90
|
+
return undefined;
|
|
91
|
+
const r = rowToProfile(row);
|
|
92
|
+
if (!r.ok)
|
|
93
|
+
throw r.error;
|
|
94
|
+
return r.value;
|
|
95
|
+
})());
|
|
96
|
+
},
|
|
97
|
+
async set(profileId, profile) {
|
|
98
|
+
const validation = validateProfileId(profileId);
|
|
99
|
+
if (!validation.ok)
|
|
100
|
+
return err(validation.error);
|
|
101
|
+
const fullProfile = { ...profile, profileId, version: SCHEMA_VERSION };
|
|
102
|
+
const payload = JSON.stringify(fullProfile);
|
|
103
|
+
const encryptResult = crypto.encrypt(payload);
|
|
104
|
+
if (!encryptResult.ok)
|
|
105
|
+
return err(encryptResult.error);
|
|
106
|
+
const enc = encryptResult.value;
|
|
107
|
+
const now = Date.now();
|
|
108
|
+
return fromPromise((async () => {
|
|
109
|
+
upsertStmt.run(profileId, validation.value.provider, validation.value.identity, enc.ciphertext, enc.iv, enc.authTag, enc.salt, fullProfile.expires, SCHEMA_VERSION, now, now);
|
|
110
|
+
})());
|
|
111
|
+
},
|
|
112
|
+
async delete(profileId) {
|
|
113
|
+
const validation = validateProfileId(profileId);
|
|
114
|
+
if (!validation.ok)
|
|
115
|
+
return err(validation.error);
|
|
116
|
+
return fromPromise((async () => {
|
|
117
|
+
const result = deleteStmt.run(profileId);
|
|
118
|
+
return result.changes > 0;
|
|
119
|
+
})());
|
|
120
|
+
},
|
|
121
|
+
async list(filter) {
|
|
122
|
+
return fromPromise((async () => {
|
|
123
|
+
const rows = filter?.provider
|
|
124
|
+
? listByProviderStmt.all(filter.provider)
|
|
125
|
+
: listAllStmt.all();
|
|
126
|
+
const profiles = [];
|
|
127
|
+
for (const row of rows) {
|
|
128
|
+
const r = rowToProfile(row);
|
|
129
|
+
if (!r.ok)
|
|
130
|
+
throw r.error;
|
|
131
|
+
profiles.push(r.value);
|
|
132
|
+
}
|
|
133
|
+
return profiles;
|
|
134
|
+
})());
|
|
135
|
+
},
|
|
136
|
+
async has(profileId) {
|
|
137
|
+
const validation = validateProfileId(profileId);
|
|
138
|
+
if (!validation.ok)
|
|
139
|
+
return err(validation.error);
|
|
140
|
+
return fromPromise((async () => existsStmt.get(profileId) !== undefined)());
|
|
141
|
+
},
|
|
142
|
+
};
|
|
143
|
+
return Object.freeze(port);
|
|
144
|
+
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* prepared statements. Sessions survive process restarts since they are
|
|
6
6
|
* stored in SQLite.
|
|
7
7
|
*
|
|
8
|
-
* Factory function pattern (createSessionStore) consistent with
|
|
8
|
+
* Factory function pattern (createSessionStore) consistent with
|
|
9
9
|
* createSecretManager for minimal public surface area.
|
|
10
10
|
*/
|
|
11
11
|
import type Database from "better-sqlite3";
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* prepared statements. Sessions survive process restarts since they are
|
|
7
7
|
* stored in SQLite.
|
|
8
8
|
*
|
|
9
|
-
* Factory function pattern (createSessionStore) consistent with
|
|
9
|
+
* Factory function pattern (createSessionStore) consistent with
|
|
10
10
|
* createSecretManager for minimal public surface area.
|
|
11
11
|
*/
|
|
12
12
|
import { formatSessionKey } from "@comis/core";
|
|
@@ -10,7 +10,32 @@
|
|
|
10
10
|
*
|
|
11
11
|
* Persists encrypted secrets across daemon restarts.
|
|
12
12
|
*/
|
|
13
|
+
import type Database from "better-sqlite3";
|
|
13
14
|
import type { SecretStorePort, SecretsCrypto } from "@comis/core";
|
|
15
|
+
/**
|
|
16
|
+
* Concrete return type of createSqliteSecretStore.
|
|
17
|
+
*
|
|
18
|
+
* Implements SecretStorePort and additionally exposes the underlying
|
|
19
|
+
* better-sqlite3 handle for adapters that need to share the same
|
|
20
|
+
* connection (e.g., the encrypted OAuth profile store).
|
|
21
|
+
*
|
|
22
|
+
* The `db` field is intentionally additive — `SecretStorePort` itself is
|
|
23
|
+
* unchanged and remains the canonical port boundary. Consumers that only
|
|
24
|
+
* need port-level operations should accept `SecretStorePort`, not
|
|
25
|
+
* `SqliteSecretStoreHandle`.
|
|
26
|
+
*/
|
|
27
|
+
export interface SqliteSecretStoreHandle extends SecretStorePort {
|
|
28
|
+
/**
|
|
29
|
+
* Underlying better-sqlite3 handle.
|
|
30
|
+
*
|
|
31
|
+
* Use for sharing the connection with sibling tables in the same DB
|
|
32
|
+
* file (e.g., `oauth_profiles` alongside `secrets`). Eliminates the
|
|
33
|
+
* dual-handle hazard (close-order, schema-init double-execution,
|
|
34
|
+
* prepared-statement cache fragmentation) that two separate handles
|
|
35
|
+
* to the same WAL-mode SQLite file would introduce.
|
|
36
|
+
*/
|
|
37
|
+
readonly db: Database.Database;
|
|
38
|
+
}
|
|
14
39
|
/**
|
|
15
40
|
* Create a SqliteSecretStore bound to the given database path.
|
|
16
41
|
*
|
|
@@ -22,11 +47,12 @@ import type { SecretStorePort, SecretsCrypto } from "@comis/core";
|
|
|
22
47
|
* 5. Validate canary (master key mismatch detection)
|
|
23
48
|
* 6. Second chmod pass (SQLite may create WAL/SHM during canary)
|
|
24
49
|
* 7. Prepare all SQL statements once
|
|
25
|
-
* 8. Return frozen SecretStorePort
|
|
50
|
+
* 8. Return frozen SqliteSecretStoreHandle (SecretStorePort + db field)
|
|
26
51
|
*
|
|
27
52
|
* @param dbPath - Absolute path to the secrets.db file
|
|
28
53
|
* @param crypto - SecretsCrypto engine bound to the current master key
|
|
29
|
-
* @returns SecretStorePort
|
|
54
|
+
* @returns SqliteSecretStoreHandle — a SecretStorePort that also exposes
|
|
55
|
+
* the underlying better-sqlite3 handle on `.db`
|
|
30
56
|
* @throws Error if schema init, canary validation, or DB open fails
|
|
31
57
|
*/
|
|
32
|
-
export declare function createSqliteSecretStore(dbPath: string, crypto: SecretsCrypto):
|
|
58
|
+
export declare function createSqliteSecretStore(dbPath: string, crypto: SecretsCrypto): SqliteSecretStoreHandle;
|
|
@@ -25,11 +25,12 @@ import { openSqliteDatabase, chmodDbFiles } from "./sqlite-adapter-base.js";
|
|
|
25
25
|
* 5. Validate canary (master key mismatch detection)
|
|
26
26
|
* 6. Second chmod pass (SQLite may create WAL/SHM during canary)
|
|
27
27
|
* 7. Prepare all SQL statements once
|
|
28
|
-
* 8. Return frozen SecretStorePort
|
|
28
|
+
* 8. Return frozen SqliteSecretStoreHandle (SecretStorePort + db field)
|
|
29
29
|
*
|
|
30
30
|
* @param dbPath - Absolute path to the secrets.db file
|
|
31
31
|
* @param crypto - SecretsCrypto engine bound to the current master key
|
|
32
|
-
* @returns SecretStorePort
|
|
32
|
+
* @returns SqliteSecretStoreHandle — a SecretStorePort that also exposes
|
|
33
|
+
* the underlying better-sqlite3 handle on `.db`
|
|
33
34
|
* @throws Error if schema init, canary validation, or DB open fails
|
|
34
35
|
*/
|
|
35
36
|
export function createSqliteSecretStore(dbPath, crypto) {
|
|
@@ -149,5 +150,12 @@ export function createSqliteSecretStore(dbPath, crypto) {
|
|
|
149
150
|
db.close();
|
|
150
151
|
},
|
|
151
152
|
};
|
|
152
|
-
return
|
|
153
|
+
// Expose the underlying db handle on the factory return so the encrypted
|
|
154
|
+
// OAuth profile adapter (oauth-profile-store-encrypted) can share this same
|
|
155
|
+
// connection rather than opening a second handle to the same secrets.db
|
|
156
|
+
// file. The SecretStorePort surface itself is unchanged — consumers that
|
|
157
|
+
// only need port-level operations should accept SecretStorePort, not
|
|
158
|
+
// SqliteSecretStoreHandle.
|
|
159
|
+
const handle = { ...store, db };
|
|
160
|
+
return Object.freeze(handle);
|
|
153
161
|
}
|
|
@@ -14,6 +14,19 @@ export interface ExecutionLockOptions {
|
|
|
14
14
|
updateMs: number;
|
|
15
15
|
/** Callback when lock is compromised (e.g., external release). */
|
|
16
16
|
onCompromised?: (err: Error) => void;
|
|
17
|
+
/**
|
|
18
|
+
* Optional lock-acquisition retry budget. Forwarded to proper-lockfile's
|
|
19
|
+
* own retry option (uses a built-in incremental backoff). When undefined
|
|
20
|
+
* (default), retries: 0 — fail fast on contention. Lets the OAuth manager
|
|
21
|
+
* wait for a sibling refresh to complete (concurrent-refresh acceptance)
|
|
22
|
+
* without callers having to roll their own retry loop.
|
|
23
|
+
*/
|
|
24
|
+
retries?: number | {
|
|
25
|
+
retries: number;
|
|
26
|
+
minTimeout?: number;
|
|
27
|
+
maxTimeout?: number;
|
|
28
|
+
factor?: number;
|
|
29
|
+
};
|
|
17
30
|
}
|
|
18
31
|
/**
|
|
19
32
|
* Acquire a file lock, execute the function, and release the lock.
|
|
@@ -41,7 +41,7 @@ export async function withExecutionLock(lockPath, fn, options) {
|
|
|
41
41
|
release = await lockfile.lock(lockPath, {
|
|
42
42
|
stale: opts.staleMs,
|
|
43
43
|
update: opts.updateMs,
|
|
44
|
-
retries: 0,
|
|
44
|
+
retries: opts.retries ?? 0,
|
|
45
45
|
onCompromised: opts.onCompromised ?? (() => { }),
|
|
46
46
|
});
|
|
47
47
|
}
|
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
export { createExecutionTracker } from "./execution-tracker.js";
|
|
2
2
|
export type { ExecutionTracker, ExecutionLogEntry } from "./execution-tracker.js";
|
|
3
|
+
export { withExecutionLock, isLocked } from "./execution-lock.js";
|
|
4
|
+
export type { ExecutionLockOptions } from "./execution-lock.js";
|
|
@@ -158,7 +158,7 @@ export function createAgentHeartbeatSource(deps) {
|
|
|
158
158
|
},
|
|
159
159
|
};
|
|
160
160
|
// 9. Resolve model (for logging)
|
|
161
|
-
const model = resolveHeartbeatModel(undefined, // per-agent heartbeat model
|
|
161
|
+
const model = resolveHeartbeatModel(undefined, // per-agent heartbeat model not in schema
|
|
162
162
|
undefined, // global heartbeat model not yet in schema
|
|
163
163
|
agentConfig.model);
|
|
164
164
|
logger.info({ agentId, trigger, model, channelType: msg.channelType }, "Heartbeat run starting");
|
|
@@ -7,6 +7,8 @@ export { createCronScheduler } from "./cron/index.js";
|
|
|
7
7
|
export type { CronScheduler } from "./cron/index.js";
|
|
8
8
|
export { createExecutionTracker } from "./execution/index.js";
|
|
9
9
|
export type { ExecutionTracker, ExecutionLogEntry } from "./execution/index.js";
|
|
10
|
+
export { withExecutionLock, isLocked } from "./execution/execution-lock.js";
|
|
11
|
+
export type { ExecutionLockOptions } from "./execution/execution-lock.js";
|
|
10
12
|
export { HEARTBEAT_OK_TOKEN, createHeartbeatRunner } from "./heartbeat/index.js";
|
|
11
13
|
export type { HeartbeatCheckResult, HeartbeatSourcePort, HeartbeatRunner } from "./heartbeat/index.js";
|
|
12
14
|
export { resolveEffectiveHeartbeatConfig } from "./heartbeat/index.js";
|