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,279 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
/**
|
|
3
|
+
* Plaintext file-backed OAuthCredentialStorePort adapter.
|
|
4
|
+
*
|
|
5
|
+
* Default storage backend for OAuth credentials (derives from existing
|
|
6
|
+
* dataDir, no separate config key). Stores all profiles in a single JSON
|
|
7
|
+
* file at ${dataDir}/auth-profiles.json with mode 0o600.
|
|
8
|
+
*
|
|
9
|
+
* Atomic write sequence (full POSIX crash safety on ext4):
|
|
10
|
+
* write tmp 0o600 → fsync(tmpFd) → close(tmpFd) → rename(tmp, canonical)
|
|
11
|
+
* → fsync(parentDirFd) → close(parentDirFd)
|
|
12
|
+
*
|
|
13
|
+
* cron-store.ts does NOT fsync the parent directory; this adapter MUST
|
|
14
|
+
* because OAuth credentials are security-critical (a lost rename due to
|
|
15
|
+
* power-loss-after-data-write would silently log the user out).
|
|
16
|
+
*
|
|
17
|
+
* Per-profile-ID locking via withExecutionLock: different providers and
|
|
18
|
+
* different identities for the same provider can refresh in parallel.
|
|
19
|
+
*
|
|
20
|
+
* Schema versioning: single integer version at top level. Hard-fail on
|
|
21
|
+
* mismatch — pre-1.0 software, no migration plumbing.
|
|
22
|
+
*
|
|
23
|
+
* @module
|
|
24
|
+
*/
|
|
25
|
+
import * as fs from "node:fs/promises";
|
|
26
|
+
import { ok, err, fromPromise, suppressError } from "@comis/shared";
|
|
27
|
+
import { safePath } from "@comis/core";
|
|
28
|
+
import { validateProfileId, } from "@comis/core";
|
|
29
|
+
import { withExecutionLock } from "@comis/scheduler";
|
|
30
|
+
const SCHEMA_VERSION = 1;
|
|
31
|
+
const FILE_NAME = "auth-profiles.json";
|
|
32
|
+
const LOCKS_SUBDIR = ".locks";
|
|
33
|
+
const LOCK_OPTIONS = { staleMs: 30_000, updateMs: 5_000 };
|
|
34
|
+
/**
|
|
35
|
+
* Per-profile in-process serialization queue.
|
|
36
|
+
*
|
|
37
|
+
* `withExecutionLock` uses `retries: 0` so two concurrent same-profile writes
|
|
38
|
+
* within the SAME Node process would race the cross-process file lock and the
|
|
39
|
+
* second caller would get `err("locked")`. The in-process mutex serializes
|
|
40
|
+
* same-profile writes BEFORE they reach the file lock — different profiles
|
|
41
|
+
* still proceed in parallel (each gets its own queue), preserving per-profile
|
|
42
|
+
* lock granularity. Mirrors cron-store.ts:181.
|
|
43
|
+
*/
|
|
44
|
+
function createPerProfileMutex() {
|
|
45
|
+
const chains = new Map();
|
|
46
|
+
return {
|
|
47
|
+
serialize(profileId, fn) {
|
|
48
|
+
const prior = chains.get(profileId) ?? Promise.resolve();
|
|
49
|
+
const next = prior.then(fn, fn);
|
|
50
|
+
// Swallow rejections in the chain so subsequent serialize() calls keep running.
|
|
51
|
+
chains.set(profileId, next.then(() => undefined, () => undefined));
|
|
52
|
+
return next;
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Sanitize a profile-ID for safe inclusion in a lock-file path.
|
|
58
|
+
* One-way transformation, lock-file name only — the canonical profile-ID
|
|
59
|
+
* stored in the JSON file keeps its original form.
|
|
60
|
+
*
|
|
61
|
+
* Mappings: ":" → "__", "@" → "_at_".
|
|
62
|
+
*/
|
|
63
|
+
function sanitizeProfileIdForLockPath(profileId) {
|
|
64
|
+
return profileId.replace(/:/g, "__").replace(/@/g, "_at_");
|
|
65
|
+
}
|
|
66
|
+
function lockSentinelPath(dataDir, profileId) {
|
|
67
|
+
return safePath(dataDir, LOCKS_SUBDIR, "auth-profile__" + sanitizeProfileIdForLockPath(profileId) + ".lock");
|
|
68
|
+
}
|
|
69
|
+
function authProfilesFilePath(dataDir) {
|
|
70
|
+
return safePath(dataDir, FILE_NAME);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Atomic write with parent-dir fsync.
|
|
74
|
+
* Sequence: write tmp 0o600 → fsync(tmp) → close(tmp) → rename(tmp, canonical)
|
|
75
|
+
* → fsync(parentDir) → close(parentDir).
|
|
76
|
+
*
|
|
77
|
+
* Tmp filename includes pid + random suffix so concurrent writes (different
|
|
78
|
+
* profile-IDs holding different per-profile locks) don't race on the same
|
|
79
|
+
* tmp path. Mirrors cron-store.ts:103.
|
|
80
|
+
*/
|
|
81
|
+
async function atomicWriteJson(canonicalPath, parentDir, data) {
|
|
82
|
+
const tmpPath = canonicalPath + "." + String(process.pid) + "." + Math.random().toString(16).slice(2) + ".tmp";
|
|
83
|
+
await fs.writeFile(tmpPath, JSON.stringify(data, null, 2), {
|
|
84
|
+
encoding: "utf-8",
|
|
85
|
+
mode: 0o600,
|
|
86
|
+
});
|
|
87
|
+
const tmpFd = await fs.open(tmpPath, "r");
|
|
88
|
+
try {
|
|
89
|
+
await tmpFd.sync();
|
|
90
|
+
}
|
|
91
|
+
finally {
|
|
92
|
+
await tmpFd.close();
|
|
93
|
+
}
|
|
94
|
+
await fs.rename(tmpPath, canonicalPath);
|
|
95
|
+
const dirFd = await fs.open(parentDir, "r");
|
|
96
|
+
try {
|
|
97
|
+
await dirFd.sync();
|
|
98
|
+
}
|
|
99
|
+
finally {
|
|
100
|
+
await dirFd.close();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Load the auth-profiles file. Hard-fails on schema-version mismatch.
|
|
105
|
+
* ENOENT → returns ok({ version: 1, profiles: {} }) (empty store).
|
|
106
|
+
*/
|
|
107
|
+
async function loadAuthProfiles(filePath) {
|
|
108
|
+
return fromPromise((async () => {
|
|
109
|
+
let raw;
|
|
110
|
+
try {
|
|
111
|
+
raw = await fs.readFile(filePath, "utf-8");
|
|
112
|
+
}
|
|
113
|
+
catch (e) {
|
|
114
|
+
if (e !== null &&
|
|
115
|
+
typeof e === "object" &&
|
|
116
|
+
"code" in e &&
|
|
117
|
+
e.code === "ENOENT") {
|
|
118
|
+
return { version: SCHEMA_VERSION, profiles: {} };
|
|
119
|
+
}
|
|
120
|
+
throw e;
|
|
121
|
+
}
|
|
122
|
+
const parsed = JSON.parse(raw);
|
|
123
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
124
|
+
throw new Error("auth-profiles.json: malformed (expected object). Hint: Delete " +
|
|
125
|
+
filePath +
|
|
126
|
+
" and re-login to recreate.");
|
|
127
|
+
}
|
|
128
|
+
const obj = parsed;
|
|
129
|
+
const version = obj.version;
|
|
130
|
+
if (version !== SCHEMA_VERSION) {
|
|
131
|
+
throw new Error("OAuth profile store version mismatch: expected " +
|
|
132
|
+
SCHEMA_VERSION +
|
|
133
|
+
", got " +
|
|
134
|
+
String(version) +
|
|
135
|
+
". Hint: Delete " +
|
|
136
|
+
filePath +
|
|
137
|
+
" and re-run `comis auth login` to recreate the profile. Stored profiles for unknown schema versions cannot be migrated.");
|
|
138
|
+
}
|
|
139
|
+
const profilesRaw = obj.profiles;
|
|
140
|
+
if (profilesRaw === null ||
|
|
141
|
+
typeof profilesRaw !== "object" ||
|
|
142
|
+
Array.isArray(profilesRaw)) {
|
|
143
|
+
throw new Error("auth-profiles.json: profiles field malformed. Hint: Delete " +
|
|
144
|
+
filePath +
|
|
145
|
+
" and re-login.");
|
|
146
|
+
}
|
|
147
|
+
return {
|
|
148
|
+
version,
|
|
149
|
+
profiles: profilesRaw,
|
|
150
|
+
};
|
|
151
|
+
})());
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Cleanup orphaned *.tmp files from previous crashed writes (hygiene).
|
|
155
|
+
* Best-effort — failures are silent; this is housekeeping, not correctness.
|
|
156
|
+
*/
|
|
157
|
+
async function cleanupStaleTmpFiles(parentDir) {
|
|
158
|
+
try {
|
|
159
|
+
const entries = await fs.readdir(parentDir);
|
|
160
|
+
const tmpFiles = entries.filter((n) => n.startsWith(FILE_NAME) && n.endsWith(".tmp"));
|
|
161
|
+
for (const name of tmpFiles) {
|
|
162
|
+
try {
|
|
163
|
+
await fs.unlink(safePath(parentDir, name));
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
// best-effort cleanup
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
// dir may not exist yet
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Create a plaintext file-backed OAuthCredentialStorePort adapter.
|
|
176
|
+
*
|
|
177
|
+
* Atomic, lock-protected, version-validated. Lifecycle:
|
|
178
|
+
* - On factory call: ensures dataDir exists (mkdir 0o700 recursive); cleans up stale .tmp files.
|
|
179
|
+
* - On every set/delete: per-profile-ID file lock → load → mutate → atomic-write.
|
|
180
|
+
* - On every get/has/list: load (no lock — readers see snapshot per POSIX rename atomicity).
|
|
181
|
+
*/
|
|
182
|
+
export function createOAuthCredentialStoreFile(config) {
|
|
183
|
+
const { dataDir } = config;
|
|
184
|
+
const filePath = authProfilesFilePath(dataDir);
|
|
185
|
+
const parentDir = dataDir;
|
|
186
|
+
const mutex = createPerProfileMutex();
|
|
187
|
+
// Best-effort startup hygiene — do not block factory return.
|
|
188
|
+
suppressError(cleanupStaleTmpFiles(parentDir), "oauth-credential-store-file: stale .tmp cleanup");
|
|
189
|
+
async function ensureParentDir() {
|
|
190
|
+
await fs.mkdir(parentDir, { recursive: true, mode: 0o700 });
|
|
191
|
+
}
|
|
192
|
+
const port = {
|
|
193
|
+
async get(profileId) {
|
|
194
|
+
const validation = validateProfileId(profileId);
|
|
195
|
+
if (!validation.ok)
|
|
196
|
+
return err(validation.error);
|
|
197
|
+
const loadRes = await loadAuthProfiles(filePath);
|
|
198
|
+
if (!loadRes.ok)
|
|
199
|
+
return err(loadRes.error);
|
|
200
|
+
return ok(loadRes.value.profiles[profileId]);
|
|
201
|
+
},
|
|
202
|
+
async set(profileId, profile) {
|
|
203
|
+
const validation = validateProfileId(profileId);
|
|
204
|
+
if (!validation.ok)
|
|
205
|
+
return err(validation.error);
|
|
206
|
+
await ensureParentDir();
|
|
207
|
+
const lockPath = lockSentinelPath(dataDir, profileId);
|
|
208
|
+
return mutex.serialize(profileId, async () => {
|
|
209
|
+
const lockResult = await withExecutionLock(lockPath, async () => {
|
|
210
|
+
const loadRes = await loadAuthProfiles(filePath);
|
|
211
|
+
if (!loadRes.ok)
|
|
212
|
+
throw loadRes.error;
|
|
213
|
+
const data = loadRes.value;
|
|
214
|
+
data.profiles[profileId] = {
|
|
215
|
+
...profile,
|
|
216
|
+
profileId,
|
|
217
|
+
version: SCHEMA_VERSION,
|
|
218
|
+
};
|
|
219
|
+
await atomicWriteJson(filePath, parentDir, data);
|
|
220
|
+
}, LOCK_OPTIONS);
|
|
221
|
+
if (!lockResult.ok) {
|
|
222
|
+
return err(new Error("OAuth file adapter set(" +
|
|
223
|
+
profileId +
|
|
224
|
+
") failed: lock " +
|
|
225
|
+
lockResult.error));
|
|
226
|
+
}
|
|
227
|
+
return ok(undefined);
|
|
228
|
+
});
|
|
229
|
+
},
|
|
230
|
+
async delete(profileId) {
|
|
231
|
+
const validation = validateProfileId(profileId);
|
|
232
|
+
if (!validation.ok)
|
|
233
|
+
return err(validation.error);
|
|
234
|
+
await ensureParentDir();
|
|
235
|
+
const lockPath = lockSentinelPath(dataDir, profileId);
|
|
236
|
+
return mutex.serialize(profileId, async () => {
|
|
237
|
+
let deleted = false;
|
|
238
|
+
const lockResult = await withExecutionLock(lockPath, async () => {
|
|
239
|
+
const loadRes = await loadAuthProfiles(filePath);
|
|
240
|
+
if (!loadRes.ok)
|
|
241
|
+
throw loadRes.error;
|
|
242
|
+
const data = loadRes.value;
|
|
243
|
+
if (profileId in data.profiles) {
|
|
244
|
+
delete data.profiles[profileId];
|
|
245
|
+
deleted = true;
|
|
246
|
+
await atomicWriteJson(filePath, parentDir, data);
|
|
247
|
+
}
|
|
248
|
+
}, LOCK_OPTIONS);
|
|
249
|
+
if (!lockResult.ok) {
|
|
250
|
+
return err(new Error("OAuth file adapter delete(" +
|
|
251
|
+
profileId +
|
|
252
|
+
") failed: lock " +
|
|
253
|
+
lockResult.error));
|
|
254
|
+
}
|
|
255
|
+
return ok(deleted);
|
|
256
|
+
});
|
|
257
|
+
},
|
|
258
|
+
async list(filter) {
|
|
259
|
+
const loadRes = await loadAuthProfiles(filePath);
|
|
260
|
+
if (!loadRes.ok)
|
|
261
|
+
return err(loadRes.error);
|
|
262
|
+
const all = Object.values(loadRes.value.profiles);
|
|
263
|
+
if (filter?.provider) {
|
|
264
|
+
return ok(all.filter((p) => p.provider === filter.provider));
|
|
265
|
+
}
|
|
266
|
+
return ok(all);
|
|
267
|
+
},
|
|
268
|
+
async has(profileId) {
|
|
269
|
+
const validation = validateProfileId(profileId);
|
|
270
|
+
if (!validation.ok)
|
|
271
|
+
return err(validation.error);
|
|
272
|
+
const loadRes = await loadAuthProfiles(filePath);
|
|
273
|
+
if (!loadRes.ok)
|
|
274
|
+
return err(loadRes.error);
|
|
275
|
+
return ok(profileId in loadRes.value.profiles);
|
|
276
|
+
},
|
|
277
|
+
};
|
|
278
|
+
return Object.freeze(port);
|
|
279
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth credential store selector.
|
|
3
|
+
*
|
|
4
|
+
* The CLI process needs to instantiate the same adapter the daemon uses, but
|
|
5
|
+
* @comis/cli cannot import from @comis/daemon (dep direction). Daemon and CLI
|
|
6
|
+
* both consume from @comis/agent.
|
|
7
|
+
*
|
|
8
|
+
* Throws (NOT a Result — daemon bootstrap is a synchronous trust boundary
|
|
9
|
+
* where fail-fast is the right policy) when:
|
|
10
|
+
* - storage === "encrypted" AND either secretsCrypto or secretsDb is missing
|
|
11
|
+
* (operator forgot to set SECRETS_MASTER_KEY but selected encrypted mode)
|
|
12
|
+
*
|
|
13
|
+
* For the encrypted branch the adapter SHARES the supplied secretsDb handle —
|
|
14
|
+
* a single connection serves both `secrets` and `oauth_profiles` tables in the
|
|
15
|
+
* same file.
|
|
16
|
+
*
|
|
17
|
+
* @module
|
|
18
|
+
*/
|
|
19
|
+
import type Database from "better-sqlite3";
|
|
20
|
+
import type { SecretsCrypto, OAuthCredentialStorePort } from "@comis/core";
|
|
21
|
+
import { createOAuthProfileStoreEncrypted } from "@comis/memory";
|
|
22
|
+
import { createOAuthCredentialStoreFile } from "./oauth-credential-store-file.js";
|
|
23
|
+
/** Storage backend selector from `appConfig.oauth.storage`. */
|
|
24
|
+
export type OAuthStorageMode = "file" | "encrypted";
|
|
25
|
+
/**
|
|
26
|
+
* Inputs for selectOAuthCredentialStore. Extracted to a typed shape so the
|
|
27
|
+
* helper can be unit-tested without spinning up a full setupSingleAgent path.
|
|
28
|
+
*/
|
|
29
|
+
export interface SelectOAuthCredentialStoreInput {
|
|
30
|
+
/** Storage backend selector from `appConfig.oauth.storage`. */
|
|
31
|
+
storage: OAuthStorageMode;
|
|
32
|
+
/** Absolute data directory (e.g. ~/.comis). Constructed via `safePath` upstream. */
|
|
33
|
+
dataDir: string;
|
|
34
|
+
/** Optional SecretsCrypto engine — REQUIRED when storage === "encrypted". */
|
|
35
|
+
secretsCrypto?: SecretsCrypto;
|
|
36
|
+
/** Optional shared better-sqlite3 handle — REQUIRED when storage === "encrypted". */
|
|
37
|
+
secretsDb?: Database.Database;
|
|
38
|
+
/** Optional injection points for unit tests (defaults to the real factories). */
|
|
39
|
+
factories?: {
|
|
40
|
+
file?: typeof createOAuthCredentialStoreFile;
|
|
41
|
+
encrypted?: typeof createOAuthProfileStoreEncrypted;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Select and instantiate the right OAuthCredentialStorePort adapter from
|
|
46
|
+
* `appConfig.oauth.storage`. Used by both the daemon (setup-agents.ts) and
|
|
47
|
+
* the CLI commands (`comis auth login/list/logout/status`).
|
|
48
|
+
*/
|
|
49
|
+
export declare function selectOAuthCredentialStore(input: SelectOAuthCredentialStoreInput): OAuthCredentialStorePort;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
/**
|
|
3
|
+
* OAuth credential store selector.
|
|
4
|
+
*
|
|
5
|
+
* The CLI process needs to instantiate the same adapter the daemon uses, but
|
|
6
|
+
* @comis/cli cannot import from @comis/daemon (dep direction). Daemon and CLI
|
|
7
|
+
* both consume from @comis/agent.
|
|
8
|
+
*
|
|
9
|
+
* Throws (NOT a Result — daemon bootstrap is a synchronous trust boundary
|
|
10
|
+
* where fail-fast is the right policy) when:
|
|
11
|
+
* - storage === "encrypted" AND either secretsCrypto or secretsDb is missing
|
|
12
|
+
* (operator forgot to set SECRETS_MASTER_KEY but selected encrypted mode)
|
|
13
|
+
*
|
|
14
|
+
* For the encrypted branch the adapter SHARES the supplied secretsDb handle —
|
|
15
|
+
* a single connection serves both `secrets` and `oauth_profiles` tables in the
|
|
16
|
+
* same file.
|
|
17
|
+
*
|
|
18
|
+
* @module
|
|
19
|
+
*/
|
|
20
|
+
import { createOAuthProfileStoreEncrypted } from "@comis/memory";
|
|
21
|
+
import { createOAuthCredentialStoreFile } from "./oauth-credential-store-file.js";
|
|
22
|
+
/**
|
|
23
|
+
* Select and instantiate the right OAuthCredentialStorePort adapter from
|
|
24
|
+
* `appConfig.oauth.storage`. Used by both the daemon (setup-agents.ts) and
|
|
25
|
+
* the CLI commands (`comis auth login/list/logout/status`).
|
|
26
|
+
*/
|
|
27
|
+
export function selectOAuthCredentialStore(input) {
|
|
28
|
+
const { storage, dataDir, secretsCrypto, secretsDb, factories } = input;
|
|
29
|
+
const fileFactory = factories?.file ?? createOAuthCredentialStoreFile;
|
|
30
|
+
const encryptedFactory = factories?.encrypted ?? createOAuthProfileStoreEncrypted;
|
|
31
|
+
if (storage === "encrypted") {
|
|
32
|
+
// Bootstrap precondition: encrypted-mode requires BOTH a SecretsCrypto
|
|
33
|
+
// engine and the shared secrets.db handle. No silent fallback to file
|
|
34
|
+
// mode — fail fast with operator hint.
|
|
35
|
+
if (!secretsCrypto || !secretsDb) {
|
|
36
|
+
throw new Error("OAuth storage mode is 'encrypted' but the secrets DB / crypto engine " +
|
|
37
|
+
"is not initialized. Hint: set SECRETS_MASTER_KEY env var (and restart " +
|
|
38
|
+
"the daemon) so the encrypted secrets store boots, or change " +
|
|
39
|
+
"appConfig.oauth.storage to 'file' to use the plaintext file backend.");
|
|
40
|
+
}
|
|
41
|
+
// SHARE the existing better-sqlite3 connection from createSqliteSecretStore
|
|
42
|
+
// (NOT a second handle to the same file). initOAuthProfileSchema (called
|
|
43
|
+
// inside createOAuthProfileStoreEncrypted) is idempotent (CREATE TABLE IF
|
|
44
|
+
// NOT EXISTS), so it's safe to call from this adapter on a db that already
|
|
45
|
+
// has the secrets table.
|
|
46
|
+
return encryptedFactory(secretsDb, secretsCrypto);
|
|
47
|
+
}
|
|
48
|
+
// Default: plaintext file-backed adapter at ${dataDir}/auth-profiles.json.
|
|
49
|
+
return fileFactory({ dataDir });
|
|
50
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth device-code login for OpenAI Codex.
|
|
3
|
+
*
|
|
4
|
+
* Port of the upstream device-code reference module with Comis-specific
|
|
5
|
+
* adaptations:
|
|
6
|
+
* 1. ORIGINATOR header is the literal "comis".
|
|
7
|
+
* 2. The cosmetic version-header lookup is DROPPED — header is
|
|
8
|
+
* informational; CLAUDE.md forbids reading runtime env in library code.
|
|
9
|
+
* 3. trimNonEmptyString is INLINE (3-line helper) per AGENTS.md §2.3.
|
|
10
|
+
* 4. resolveCodexAccessTokenExpiry is imported from Comis's
|
|
11
|
+
* oauth-identity.ts module (same signature as the upstream variant).
|
|
12
|
+
* 5. Public boundary returns Result<T,E> per AGENTS.md §2.1 — internal
|
|
13
|
+
* helpers still throw, but the top-level loginOpenAICodexDeviceCode
|
|
14
|
+
* wraps everything in try/catch + rewriteOAuthError + narrowing.
|
|
15
|
+
*
|
|
16
|
+
* Protocol: OpenAI's proprietary 3-step device-code flow (NOT RFC 8628):
|
|
17
|
+
* 1. POST /api/accounts/deviceauth/usercode -> device_auth_id + user_code
|
|
18
|
+
* 2. Poll POST /api/accounts/deviceauth/token (403/404 = pending, 200 =
|
|
19
|
+
* authorization_code + code_verifier; verifier comes FROM the server)
|
|
20
|
+
* 3. POST /oauth/token grant_type=authorization_code -> tokens
|
|
21
|
+
*
|
|
22
|
+
* This module never logs — the caller (oauth-login-runner.ts) is responsible
|
|
23
|
+
* for surfacing progress via prompter.log.info / Pino. Per AGENTS.md §2.4 no
|
|
24
|
+
* logger import.
|
|
25
|
+
*
|
|
26
|
+
* @module
|
|
27
|
+
*/
|
|
28
|
+
import type { Result } from "@comis/shared";
|
|
29
|
+
import type { LoginError } from "./oauth-login-runner.js";
|
|
30
|
+
/** The verification prompt surfaced to the caller — userCode + URL the user types/visits on phone. */
|
|
31
|
+
export interface DeviceCodeVerificationPrompt {
|
|
32
|
+
verificationUrl: string;
|
|
33
|
+
userCode: string;
|
|
34
|
+
expiresInMs: number;
|
|
35
|
+
}
|
|
36
|
+
/** Options / DI seams for loginOpenAICodexDeviceCode. */
|
|
37
|
+
export interface LoginOpenAICodexDeviceCodeOptions {
|
|
38
|
+
/** Dependency-injected fetch — defaults to globalThis.fetch. Used by tests. */
|
|
39
|
+
fetchFn?: typeof fetch;
|
|
40
|
+
/** Called once when userCode + verificationUrl are known. */
|
|
41
|
+
onVerification: (prompt: DeviceCodeVerificationPrompt) => Promise<void> | void;
|
|
42
|
+
/** Optional progress callback fired with stage strings during the flow. */
|
|
43
|
+
onProgress?: (message: string) => void;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Run the OpenAI Codex device-code flow end-to-end.
|
|
47
|
+
*
|
|
48
|
+
* Returns ok({ access, refresh, expires }) on success, err({ code, message,
|
|
49
|
+
* hint }) on failure. NEVER throws — internal helpers throw, the boundary
|
|
50
|
+
* wraps everything in try/catch and pipes through rewriteOAuthError +
|
|
51
|
+
* narrowToLoginError.
|
|
52
|
+
*/
|
|
53
|
+
export declare function loginOpenAICodexDeviceCode(params: LoginOpenAICodexDeviceCodeOptions): Promise<Result<{
|
|
54
|
+
access: string;
|
|
55
|
+
refresh: string;
|
|
56
|
+
expires: number;
|
|
57
|
+
}, LoginError>>;
|