comisai 1.0.33 → 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/health/watchdog.js +18 -3
- 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
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
/**
|
|
3
|
+
* OAuth callback route for the Comis gateway.
|
|
4
|
+
*
|
|
5
|
+
* Mounted at `GET /callback/:provider` via `app.route("/oauth", subApp)`. The
|
|
6
|
+
* handler validates code+state, looks up the state in the in-memory pending-
|
|
7
|
+
* flow map, verifies path-vs-flow provider match, deletes the entry BEFORE
|
|
8
|
+
* the token exchange (one-time-use invariant), exchanges the code at
|
|
9
|
+
* auth.openai.com/oauth/token, resolves identity via
|
|
10
|
+
* resolveCodexAuthIdentity, persists via OAuthCredentialStorePort.set, emits
|
|
11
|
+
* auth:profile_bootstrapped, and returns a static "Login Successful" HTML
|
|
12
|
+
* page (200) on success or a "Login Failed" HTML page (400/500) on failure.
|
|
13
|
+
*
|
|
14
|
+
* HTTP method is GET, NOT POST (OAuth servers always redirect with GET).
|
|
15
|
+
* Logging discipline (CLAUDE.md): submodule: "oauth-callback"
|
|
16
|
+
* on every line; NEVER log code/state/verifier/access/refresh values.
|
|
17
|
+
*
|
|
18
|
+
* @module
|
|
19
|
+
*/
|
|
20
|
+
import { Hono } from "hono";
|
|
21
|
+
import { resolveCodexAuthIdentity, rewriteOAuthError, redactEmailForLog, } from "@comis/agent";
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
// Constants
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
/** 5-minute pending-flow expiry. Exported for test parity. */
|
|
26
|
+
export const PENDING_FLOW_TIMEOUT_MS = 5 * 60_000;
|
|
27
|
+
/** OpenAI Codex token endpoint — same as oauth-token-manager.ts:301. */
|
|
28
|
+
const OPENAI_TOKEN_URL = "https://auth.openai.com/oauth/token";
|
|
29
|
+
/** Public OpenAI Codex client_id (NOT a comis secret — per pi-ai source). */
|
|
30
|
+
const OPENAI_CODEX_CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
|
|
31
|
+
/** Redirect URI matches pi-ai device-callback convention. */
|
|
32
|
+
const OPENAI_CODEX_DEVICE_CALLBACK_URL = "https://auth.openai.com/deviceauth/callback";
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
// Internal helpers
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
function escapeHtml(s) {
|
|
37
|
+
return s
|
|
38
|
+
.replace(/&/g, "&")
|
|
39
|
+
.replace(/</g, "<")
|
|
40
|
+
.replace(/>/g, ">")
|
|
41
|
+
.replace(/"/g, """)
|
|
42
|
+
.replace(/'/g, "'");
|
|
43
|
+
}
|
|
44
|
+
function oauthSuccessHtml(message) {
|
|
45
|
+
return [
|
|
46
|
+
"<!DOCTYPE html>",
|
|
47
|
+
'<html><head><meta charset="utf-8"><title>Login Successful</title>',
|
|
48
|
+
"<style>body{font-family:system-ui,sans-serif;max-width:480px;margin:8em auto;padding:2em;text-align:center;color:#222}h1{color:#0a7d2c}</style>",
|
|
49
|
+
"</head><body><h1>Login Successful</h1>",
|
|
50
|
+
`<p>${escapeHtml(message)}</p>`,
|
|
51
|
+
"<p>You can close this window.</p>",
|
|
52
|
+
"</body></html>",
|
|
53
|
+
].join("");
|
|
54
|
+
}
|
|
55
|
+
function oauthErrorHtml(message) {
|
|
56
|
+
return [
|
|
57
|
+
"<!DOCTYPE html>",
|
|
58
|
+
'<html><head><meta charset="utf-8"><title>Login Failed</title>',
|
|
59
|
+
"<style>body{font-family:system-ui,sans-serif;max-width:480px;margin:8em auto;padding:2em;text-align:center;color:#222}h1{color:#b00020}</style>",
|
|
60
|
+
"</head><body><h1>Login Failed</h1>",
|
|
61
|
+
`<p>${escapeHtml(message)}</p>`,
|
|
62
|
+
"</body></html>",
|
|
63
|
+
].join("");
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Exchange an authorization_code at OpenAI's /oauth/token endpoint.
|
|
67
|
+
*
|
|
68
|
+
* Mirrors refreshOpenAICodexTokenLocal (oauth-token-manager.ts:298-385) but
|
|
69
|
+
* uses grant_type=authorization_code with code + code_verifier. Throws on
|
|
70
|
+
* non-OK status; the public boundary catches and routes through
|
|
71
|
+
* rewriteOAuthError.
|
|
72
|
+
*/
|
|
73
|
+
async function exchangeAuthorizationCode(params) {
|
|
74
|
+
const body = new URLSearchParams({
|
|
75
|
+
grant_type: "authorization_code",
|
|
76
|
+
code: params.code,
|
|
77
|
+
redirect_uri: OPENAI_CODEX_DEVICE_CALLBACK_URL,
|
|
78
|
+
client_id: OPENAI_CODEX_CLIENT_ID,
|
|
79
|
+
code_verifier: params.verifier,
|
|
80
|
+
});
|
|
81
|
+
const response = await fetch(OPENAI_TOKEN_URL, {
|
|
82
|
+
method: "POST",
|
|
83
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
84
|
+
body,
|
|
85
|
+
});
|
|
86
|
+
if (!response.ok) {
|
|
87
|
+
let bodyText = "";
|
|
88
|
+
try {
|
|
89
|
+
bodyText = await response.text();
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
/* defensive — body read may fail */
|
|
93
|
+
}
|
|
94
|
+
// Surface the wire error verbatim so rewriteOAuthError can detect
|
|
95
|
+
// invalid_grant / unsupported_country_region_territory substrings.
|
|
96
|
+
throw new Error(`OAuth token exchange failed: HTTP ${response.status} ${bodyText}`);
|
|
97
|
+
}
|
|
98
|
+
const json = (await response.json());
|
|
99
|
+
return {
|
|
100
|
+
access: json.access_token,
|
|
101
|
+
refresh: json.refresh_token,
|
|
102
|
+
expires: Date.now() + json.expires_in * 1000,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
// ---------------------------------------------------------------------------
|
|
106
|
+
// Public boundary
|
|
107
|
+
// ---------------------------------------------------------------------------
|
|
108
|
+
/**
|
|
109
|
+
* Seed the pending-flow map with a new state -> PendingFlow entry, scheduling
|
|
110
|
+
* a 5-minute auto-delete cleanup timer.
|
|
111
|
+
*
|
|
112
|
+
* The caller is responsible for generating `state` via crypto.randomBytes(16)
|
|
113
|
+
* — never hand-roll a PRNG.
|
|
114
|
+
*/
|
|
115
|
+
export function insertPendingFlow(map, state, flow, logger) {
|
|
116
|
+
const timer = setTimeout(() => {
|
|
117
|
+
map.delete(state);
|
|
118
|
+
logger.debug({ provider: flow.provider, submodule: "oauth-callback" }, "Pending OAuth flow expired");
|
|
119
|
+
}, PENDING_FLOW_TIMEOUT_MS);
|
|
120
|
+
map.set(state, { ...flow, timer });
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Create the OAuth callback Hono sub-app.
|
|
124
|
+
*
|
|
125
|
+
* Mount via:
|
|
126
|
+
* const app = new Hono();
|
|
127
|
+
* app.route("/oauth", createOAuthCallbackRoute(deps));
|
|
128
|
+
* Resulting URL: GET /oauth/callback/:provider
|
|
129
|
+
*/
|
|
130
|
+
export function createOAuthCallbackRoute(deps) {
|
|
131
|
+
const app = new Hono();
|
|
132
|
+
app.get("/callback/:provider", async (c) => {
|
|
133
|
+
const provider = c.req.param("provider");
|
|
134
|
+
const code = c.req.query("code");
|
|
135
|
+
const state = c.req.query("state");
|
|
136
|
+
if (!state || !code) {
|
|
137
|
+
return c.html(oauthErrorHtml("Missing code or state parameter"), 400);
|
|
138
|
+
}
|
|
139
|
+
const flow = deps.pendingFlows.get(state);
|
|
140
|
+
if (!flow) {
|
|
141
|
+
// No log — stale browser tab is a benign user error (debug-level
|
|
142
|
+
// logging acceptable but not required by tests; keep silent here).
|
|
143
|
+
return c.html(oauthErrorHtml("Invalid or expired state"), 400);
|
|
144
|
+
}
|
|
145
|
+
if (flow.provider !== provider) {
|
|
146
|
+
// Preserve the entry — the legitimate provider's callback may still
|
|
147
|
+
// arrive.
|
|
148
|
+
return c.html(oauthErrorHtml("Provider mismatch"), 400);
|
|
149
|
+
}
|
|
150
|
+
// One-time-use: cancel the timer + remove the entry BEFORE the
|
|
151
|
+
// exchange so even a failed exchange does not leave a reusable state.
|
|
152
|
+
clearTimeout(flow.timer);
|
|
153
|
+
deps.pendingFlows.delete(state);
|
|
154
|
+
try {
|
|
155
|
+
const tokens = await exchangeAuthorizationCode({
|
|
156
|
+
code,
|
|
157
|
+
verifier: flow.verifier,
|
|
158
|
+
});
|
|
159
|
+
const identity = resolveCodexAuthIdentity({
|
|
160
|
+
accessToken: tokens.access,
|
|
161
|
+
});
|
|
162
|
+
const identityKey = identity.email ?? identity.profileName;
|
|
163
|
+
if (!identityKey) {
|
|
164
|
+
// Treat as identity_decode_failed; rewriteOAuthError will route
|
|
165
|
+
// the substring "Failed to extract accountId" to the right code.
|
|
166
|
+
throw new Error("Failed to extract accountId — identity decode failed");
|
|
167
|
+
}
|
|
168
|
+
const profileId = `${provider}:${identityKey}`;
|
|
169
|
+
const profile = {
|
|
170
|
+
provider,
|
|
171
|
+
profileId,
|
|
172
|
+
access: tokens.access,
|
|
173
|
+
refresh: tokens.refresh,
|
|
174
|
+
expires: tokens.expires,
|
|
175
|
+
email: identity.email,
|
|
176
|
+
displayName: identity.profileName,
|
|
177
|
+
version: 1,
|
|
178
|
+
};
|
|
179
|
+
const writeResult = await deps.credentialStore.set(profileId, profile);
|
|
180
|
+
if (!writeResult.ok) {
|
|
181
|
+
throw new Error(`Failed to persist OAuth profile: ${writeResult.error.message}`);
|
|
182
|
+
}
|
|
183
|
+
const identityForEvent = redactEmailForLog(identity.email) ??
|
|
184
|
+
identity.profileName ??
|
|
185
|
+
identityKey;
|
|
186
|
+
deps.eventBus.emit("auth:profile_bootstrapped", {
|
|
187
|
+
provider,
|
|
188
|
+
profileId,
|
|
189
|
+
identity: identityForEvent,
|
|
190
|
+
timestamp: Date.now(),
|
|
191
|
+
});
|
|
192
|
+
deps.logger.info({
|
|
193
|
+
provider,
|
|
194
|
+
profileId,
|
|
195
|
+
identity: identityForEvent,
|
|
196
|
+
submodule: "oauth-callback",
|
|
197
|
+
}, "Gateway OAuth callback success");
|
|
198
|
+
return c.html(oauthSuccessHtml("Login successful — you can close this window and return to Comis."));
|
|
199
|
+
}
|
|
200
|
+
catch (caught) {
|
|
201
|
+
const rewritten = rewriteOAuthError(caught);
|
|
202
|
+
deps.logger.warn({
|
|
203
|
+
provider,
|
|
204
|
+
errorKind: rewritten.errorKind,
|
|
205
|
+
hint: rewritten.hint,
|
|
206
|
+
submodule: "oauth-callback",
|
|
207
|
+
}, "OAuth callback exchange failed");
|
|
208
|
+
return c.html(oauthErrorHtml(rewritten.userMessage), 500);
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
return app;
|
|
212
|
+
}
|
|
@@ -7,6 +7,8 @@ import type { HmacAlgorithm } from "../webhook/hmac-verifier.js";
|
|
|
7
7
|
import { type TokenStore } from "../auth/token-auth.js";
|
|
8
8
|
import { WsConnectionManager } from "../rpc/ws-handler.js";
|
|
9
9
|
import { type WebhookHandler } from "../webhook/webhook-endpoint.js";
|
|
10
|
+
import { type PendingFlow } from "../oauth/oauth-callback-route.js";
|
|
11
|
+
import type { OAuthCredentialStorePort } from "@comis/core";
|
|
10
12
|
/**
|
|
11
13
|
* Logger interface for gateway server (minimal pino-compatible).
|
|
12
14
|
*/
|
|
@@ -41,6 +43,18 @@ export interface GatewayServerDeps {
|
|
|
41
43
|
algorithm?: HmacAlgorithm;
|
|
42
44
|
headerName?: string;
|
|
43
45
|
};
|
|
46
|
+
/**
|
|
47
|
+
* Optional OAuth callback deps. When provided, the gateway mounts
|
|
48
|
+
* GET /oauth/callback/:provider for browser-redirect OAuth flows
|
|
49
|
+
* (web-UI-initiated logins). Pending-flow map is owned by the caller
|
|
50
|
+
* (e.g., setup-gateway.ts) so daemon restart cleanly drops all in-flight
|
|
51
|
+
* states.
|
|
52
|
+
*/
|
|
53
|
+
readonly oauthCallbackDeps?: {
|
|
54
|
+
credentialStore: OAuthCredentialStorePort;
|
|
55
|
+
eventBus: TypedEventBus;
|
|
56
|
+
pendingFlows: Map<string, PendingFlow>;
|
|
57
|
+
};
|
|
44
58
|
/** Optional hook runner for lifecycle hooks (no-op when absent) */
|
|
45
59
|
readonly hookRunner?: HookRunner;
|
|
46
60
|
/** Optional web dashboard deps (mount REST/SSE/static when provided) */
|
|
@@ -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;
|