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.
Files changed (285) hide show
  1. package/node_modules/@comis/agent/dist/background/auto-background-middleware.d.ts +11 -1
  2. package/node_modules/@comis/agent/dist/background/auto-background-middleware.js +21 -4
  3. package/node_modules/@comis/agent/dist/background/background-task-manager.d.ts +2 -2
  4. package/node_modules/@comis/agent/dist/background/background-task-manager.js +61 -20
  5. package/node_modules/@comis/agent/dist/background/background-task-persistence.js +10 -3
  6. package/node_modules/@comis/agent/dist/background/background-task-types.d.ts +10 -3
  7. package/node_modules/@comis/agent/dist/background/background-task-types.js +1 -1
  8. package/node_modules/@comis/agent/dist/background/completion-formatter.d.ts +39 -0
  9. package/node_modules/@comis/agent/dist/background/completion-formatter.js +77 -0
  10. package/node_modules/@comis/agent/dist/background/completion-runner.d.ts +53 -0
  11. package/node_modules/@comis/agent/dist/background/completion-runner.js +151 -0
  12. package/node_modules/@comis/agent/dist/background/index.d.ts +4 -0
  13. package/node_modules/@comis/agent/dist/background/index.js +2 -0
  14. package/node_modules/@comis/agent/dist/bridge/bridge-metrics.d.ts +17 -2
  15. package/node_modules/@comis/agent/dist/bridge/bridge-metrics.js +14 -2
  16. package/node_modules/@comis/agent/dist/bridge/pi-event-bridge.d.ts +23 -23
  17. package/node_modules/@comis/agent/dist/bridge/pi-event-bridge.js +72 -60
  18. package/node_modules/@comis/agent/dist/bridge/thinking-block-hash-invariant.d.ts +6 -7
  19. package/node_modules/@comis/agent/dist/bridge/thinking-block-hash-invariant.js +24 -25
  20. package/node_modules/@comis/agent/dist/budget/cost-tracker.d.ts +1 -1
  21. package/node_modules/@comis/agent/dist/context-engine/constants.d.ts +5 -5
  22. package/node_modules/@comis/agent/dist/context-engine/constants.js +12 -12
  23. package/node_modules/@comis/agent/dist/context-engine/context-engine.js +13 -4
  24. package/node_modules/@comis/agent/dist/context-engine/dag-annotator.d.ts +1 -2
  25. package/node_modules/@comis/agent/dist/context-engine/dag-annotator.js +1 -2
  26. package/node_modules/@comis/agent/dist/context-engine/llm-compaction.js +20 -16
  27. package/node_modules/@comis/agent/dist/context-engine/rehydration.js +6 -6
  28. package/node_modules/@comis/agent/dist/context-engine/signature-replay-scrubber.d.ts +12 -12
  29. package/node_modules/@comis/agent/dist/context-engine/signature-replay-scrubber.js +36 -22
  30. package/node_modules/@comis/agent/dist/context-engine/types-core.d.ts +15 -0
  31. package/node_modules/@comis/agent/dist/executor/cache-break-detection.d.ts +6 -6
  32. package/node_modules/@comis/agent/dist/executor/cache-break-detection.js +8 -8
  33. package/node_modules/@comis/agent/dist/executor/executor-context-engine-setup.d.ts +16 -0
  34. package/node_modules/@comis/agent/dist/executor/executor-context-engine-setup.js +46 -5
  35. package/node_modules/@comis/agent/dist/executor/executor-post-execution.d.ts +30 -0
  36. package/node_modules/@comis/agent/dist/executor/executor-post-execution.js +17 -1
  37. package/node_modules/@comis/agent/dist/executor/executor-prompt-runner.js +1 -1
  38. package/node_modules/@comis/agent/dist/executor/executor-response-filter.d.ts +7 -6
  39. package/node_modules/@comis/agent/dist/executor/executor-response-filter.js +9 -42
  40. package/node_modules/@comis/agent/dist/executor/executor-tool-assembly.js +2 -3
  41. package/node_modules/@comis/agent/dist/executor/gemini-cache-injector.d.ts +2 -2
  42. package/node_modules/@comis/agent/dist/executor/gemini-cache-injector.js +4 -4
  43. package/node_modules/@comis/agent/dist/executor/phase-filter.d.ts +2 -2
  44. package/node_modules/@comis/agent/dist/executor/phase-filter.js +5 -7
  45. package/node_modules/@comis/agent/dist/executor/pi-executor.d.ts +13 -0
  46. package/node_modules/@comis/agent/dist/executor/pi-executor.js +71 -6
  47. package/node_modules/@comis/agent/dist/executor/post-batch-continuation.js +7 -7
  48. package/node_modules/@comis/agent/dist/executor/stream-wrappers/request-body-injector.d.ts +1 -1
  49. package/node_modules/@comis/agent/dist/executor/stream-wrappers/request-body-injector.js +1 -1
  50. package/node_modules/@comis/agent/dist/executor/tool-deferral.d.ts +2 -2
  51. package/node_modules/@comis/agent/dist/executor/tool-deferral.js +7 -7
  52. package/node_modules/@comis/agent/dist/index.d.ts +17 -0
  53. package/node_modules/@comis/agent/dist/index.js +32 -11
  54. package/node_modules/@comis/agent/dist/model/auth-provider.d.ts +25 -2
  55. package/node_modules/@comis/agent/dist/model/auth-provider.js +6 -0
  56. package/node_modules/@comis/agent/dist/model/compaction-model-resolver.d.ts +3 -3
  57. package/node_modules/@comis/agent/dist/model/compaction-model-resolver.js +3 -3
  58. package/node_modules/@comis/agent/dist/model/oauth-credential-store-file.d.ts +37 -0
  59. package/node_modules/@comis/agent/dist/model/oauth-credential-store-file.js +279 -0
  60. package/node_modules/@comis/agent/dist/model/oauth-credential-store-selector.d.ts +49 -0
  61. package/node_modules/@comis/agent/dist/model/oauth-credential-store-selector.js +50 -0
  62. package/node_modules/@comis/agent/dist/model/oauth-device-code.d.ts +57 -0
  63. package/node_modules/@comis/agent/dist/model/oauth-device-code.js +302 -0
  64. package/node_modules/@comis/agent/dist/model/oauth-env.d.ts +33 -0
  65. package/node_modules/@comis/agent/dist/model/oauth-env.js +38 -0
  66. package/node_modules/@comis/agent/dist/model/oauth-errors.d.ts +41 -0
  67. package/node_modules/@comis/agent/dist/model/oauth-errors.js +88 -0
  68. package/node_modules/@comis/agent/dist/model/oauth-identity.d.ts +53 -0
  69. package/node_modules/@comis/agent/dist/model/oauth-identity.js +141 -0
  70. package/node_modules/@comis/agent/dist/model/oauth-login-runner.d.ts +99 -0
  71. package/node_modules/@comis/agent/dist/model/oauth-login-runner.js +374 -0
  72. package/node_modules/@comis/agent/dist/model/oauth-tls-preflight.d.ts +58 -0
  73. package/node_modules/@comis/agent/dist/model/oauth-tls-preflight.js +82 -0
  74. package/node_modules/@comis/agent/dist/model/oauth-token-manager.d.ts +86 -16
  75. package/node_modules/@comis/agent/dist/model/oauth-token-manager.js +961 -66
  76. package/node_modules/@comis/agent/dist/model/operation-model-defaults.d.ts +9 -4
  77. package/node_modules/@comis/agent/dist/model/operation-model-defaults.js +36 -9
  78. package/node_modules/@comis/agent/dist/model/resolve-provider-api-key.d.ts +48 -0
  79. package/node_modules/@comis/agent/dist/model/resolve-provider-api-key.js +66 -0
  80. package/node_modules/@comis/agent/dist/provider/capabilities.d.ts +5 -5
  81. package/node_modules/@comis/agent/dist/provider/capabilities.js +10 -23
  82. package/node_modules/@comis/agent/dist/safety/tool-output-safety.js +3 -3
  83. package/node_modules/@comis/agent/dist/session/comis-session-manager.d.ts +1 -1
  84. package/node_modules/@comis/agent/dist/session/comis-session-manager.js +1 -1
  85. package/node_modules/@comis/agent/dist/spawn/narrative-caster.d.ts +10 -0
  86. package/node_modules/@comis/agent/dist/spawn/narrative-caster.js +5 -1
  87. package/node_modules/@comis/agent/package.json +1 -1
  88. package/node_modules/@comis/channels/dist/email/email-adapter.js +6 -6
  89. package/node_modules/@comis/channels/dist/email/imap-lifecycle.js +7 -7
  90. package/node_modules/@comis/channels/dist/shared/deliver-to-channel.js +12 -10
  91. package/node_modules/@comis/channels/dist/telegram/telegram-adapter.js +1 -1
  92. package/node_modules/@comis/channels/package.json +1 -1
  93. package/node_modules/@comis/cli/dist/cli.js +2 -0
  94. package/node_modules/@comis/cli/dist/commands/agent.d.ts +3 -3
  95. package/node_modules/@comis/cli/dist/commands/agent.js +46 -3
  96. package/node_modules/@comis/cli/dist/commands/auth.d.ts +37 -0
  97. package/node_modules/@comis/cli/dist/commands/auth.js +433 -0
  98. package/node_modules/@comis/cli/dist/commands/doctor.d.ts +4 -1
  99. package/node_modules/@comis/cli/dist/commands/doctor.js +20 -5
  100. package/node_modules/@comis/cli/dist/doctor/checks/oauth-health.d.ts +39 -0
  101. package/node_modules/@comis/cli/dist/doctor/checks/oauth-health.js +399 -0
  102. package/node_modules/@comis/cli/dist/doctor/types.d.ts +19 -0
  103. package/node_modules/@comis/cli/dist/index.d.ts +1 -0
  104. package/node_modules/@comis/cli/dist/index.js +10 -4
  105. package/node_modules/@comis/cli/dist/output/relative-time.d.ts +23 -0
  106. package/node_modules/@comis/cli/dist/output/relative-time.js +36 -0
  107. package/node_modules/@comis/cli/dist/wizard/non-interactive.js +17 -8
  108. package/node_modules/@comis/cli/dist/wizard/steps/03-provider.js +2 -1
  109. package/node_modules/@comis/cli/dist/wizard/steps/04-credentials.js +223 -34
  110. package/node_modules/@comis/cli/dist/wizard/steps/10-write-config.js +14 -0
  111. package/node_modules/@comis/cli/dist/wizard/steps/11-daemon-start.js +3 -3
  112. package/node_modules/@comis/cli/dist/wizard/types.d.ts +7 -0
  113. package/node_modules/@comis/cli/package.json +1 -1
  114. package/node_modules/@comis/core/dist/bootstrap.d.ts +1 -1
  115. package/node_modules/@comis/core/dist/config/env-substitution.d.ts +66 -0
  116. package/node_modules/@comis/core/dist/config/env-substitution.js +115 -0
  117. package/node_modules/@comis/core/dist/config/index.d.ts +3 -1
  118. package/node_modules/@comis/core/dist/config/index.js +2 -1
  119. package/node_modules/@comis/core/dist/config/loader.js +61 -0
  120. package/node_modules/@comis/core/dist/config/managed-sections.d.ts +3 -3
  121. package/node_modules/@comis/core/dist/config/managed-sections.js +10 -5
  122. package/node_modules/@comis/core/dist/config/schema-agent.d.ts +4 -0
  123. package/node_modules/@comis/core/dist/config/schema-agent.js +16 -1
  124. package/node_modules/@comis/core/dist/config/schema-background-tasks.d.ts +7 -0
  125. package/node_modules/@comis/core/dist/config/schema-background-tasks.js +7 -0
  126. package/node_modules/@comis/core/dist/config/schema-delivery.d.ts +2 -0
  127. package/node_modules/@comis/core/dist/config/schema-delivery.js +2 -0
  128. package/node_modules/@comis/core/dist/config/schema-gemini-cache.d.ts +0 -2
  129. package/node_modules/@comis/core/dist/config/schema-gemini-cache.js +0 -2
  130. package/node_modules/@comis/core/dist/config/schema-oauth.d.ts +23 -0
  131. package/node_modules/@comis/core/dist/config/schema-oauth.js +19 -0
  132. package/node_modules/@comis/core/dist/config/schema-skills.d.ts +6 -8
  133. package/node_modules/@comis/core/dist/config/schema-skills.js +3 -4
  134. package/node_modules/@comis/core/dist/config/schema.d.ts +10 -0
  135. package/node_modules/@comis/core/dist/config/schema.js +3 -0
  136. package/node_modules/@comis/core/dist/domain/background-task-origin.d.ts +39 -0
  137. package/node_modules/@comis/core/dist/domain/background-task-origin.js +39 -0
  138. package/node_modules/@comis/core/dist/event-bus/events-infra.d.ts +71 -2
  139. package/node_modules/@comis/core/dist/exports/config.d.ts +2 -2
  140. package/node_modules/@comis/core/dist/exports/config.js +1 -1
  141. package/node_modules/@comis/core/dist/exports/domain.d.ts +2 -0
  142. package/node_modules/@comis/core/dist/exports/domain.js +1 -0
  143. package/node_modules/@comis/core/dist/exports/ports.d.ts +2 -2
  144. package/node_modules/@comis/core/dist/exports/ports.js +1 -1
  145. package/node_modules/@comis/core/dist/ports/delivery-queue.d.ts +23 -0
  146. package/node_modules/@comis/core/dist/ports/delivery-queue.js +2 -0
  147. package/node_modules/@comis/core/dist/ports/index.d.ts +2 -0
  148. package/node_modules/@comis/core/dist/ports/index.js +1 -0
  149. package/node_modules/@comis/core/dist/ports/oauth-credential-store.d.ts +64 -0
  150. package/node_modules/@comis/core/dist/ports/oauth-credential-store.js +37 -0
  151. package/node_modules/@comis/core/dist/tool-metadata.d.ts +20 -0
  152. package/node_modules/@comis/core/package.json +1 -1
  153. package/node_modules/@comis/daemon/dist/daemon-types.d.ts +23 -3
  154. package/node_modules/@comis/daemon/dist/daemon.js +82 -19
  155. package/node_modules/@comis/daemon/dist/health/watchdog.js +18 -3
  156. package/node_modules/@comis/daemon/dist/index.d.ts +2 -0
  157. package/node_modules/@comis/daemon/dist/index.js +5 -0
  158. package/node_modules/@comis/daemon/dist/observability/channel-health-logger.js +3 -3
  159. package/node_modules/@comis/daemon/dist/observability/delivery-queue-logger.js +1 -1
  160. package/node_modules/@comis/daemon/dist/rpc/agent-handlers.d.ts +22 -1
  161. package/node_modules/@comis/daemon/dist/rpc/agent-handlers.js +84 -21
  162. package/node_modules/@comis/daemon/dist/rpc/agent-inline-workspace.js +2 -2
  163. package/node_modules/@comis/daemon/dist/rpc/config-handlers.d.ts +9 -1
  164. package/node_modules/@comis/daemon/dist/rpc/config-handlers.js +104 -23
  165. package/node_modules/@comis/daemon/dist/rpc/credential-resolver.d.ts +30 -1
  166. package/node_modules/@comis/daemon/dist/rpc/credential-resolver.js +74 -11
  167. package/node_modules/@comis/daemon/dist/rpc/mcp-handlers.d.ts +8 -0
  168. package/node_modules/@comis/daemon/dist/rpc/mcp-handlers.js +22 -8
  169. package/node_modules/@comis/daemon/dist/rpc/provider-handlers.js +9 -12
  170. package/node_modules/@comis/daemon/dist/rpc/rpc-dispatch.d.ts +1 -0
  171. package/node_modules/@comis/daemon/dist/rpc/rpc-dispatch.js +27 -2
  172. package/node_modules/@comis/daemon/dist/setup-docker-restart-warn.js +0 -1
  173. package/node_modules/@comis/daemon/dist/wiring/index.d.ts +2 -0
  174. package/node_modules/@comis/daemon/dist/wiring/index.js +1 -0
  175. package/node_modules/@comis/daemon/dist/wiring/oauth-preflight.d.ts +21 -0
  176. package/node_modules/@comis/daemon/dist/wiring/oauth-preflight.js +134 -0
  177. package/node_modules/@comis/daemon/dist/wiring/setup-agents.d.ts +46 -1
  178. package/node_modules/@comis/daemon/dist/wiring/setup-agents.js +127 -3
  179. package/node_modules/@comis/daemon/dist/wiring/setup-background-completion-runner.d.ts +39 -0
  180. package/node_modules/@comis/daemon/dist/wiring/setup-background-completion-runner.js +32 -0
  181. package/node_modules/@comis/daemon/dist/wiring/setup-background-tasks.d.ts +10 -3
  182. package/node_modules/@comis/daemon/dist/wiring/setup-background-tasks.js +11 -5
  183. package/node_modules/@comis/daemon/dist/wiring/setup-channels.js +20 -1
  184. package/node_modules/@comis/daemon/dist/wiring/setup-cross-session.js +1 -1
  185. package/node_modules/@comis/daemon/dist/wiring/setup-delivery.d.ts +14 -5
  186. package/node_modules/@comis/daemon/dist/wiring/setup-delivery.js +52 -19
  187. package/node_modules/@comis/daemon/dist/wiring/setup-schedulers.js +4 -0
  188. package/node_modules/@comis/daemon/package.json +1 -1
  189. package/node_modules/@comis/gateway/dist/index.d.ts +2 -0
  190. package/node_modules/@comis/gateway/dist/index.js +2 -0
  191. package/node_modules/@comis/gateway/dist/oauth/oauth-callback-route.d.ts +66 -0
  192. package/node_modules/@comis/gateway/dist/oauth/oauth-callback-route.js +212 -0
  193. package/node_modules/@comis/gateway/dist/server/hono-server.d.ts +14 -0
  194. package/node_modules/@comis/gateway/dist/server/hono-server.js +10 -0
  195. package/node_modules/@comis/gateway/package.json +1 -1
  196. package/node_modules/@comis/infra/dist/logging/log-fields.d.ts +23 -0
  197. package/node_modules/@comis/infra/package.json +1 -1
  198. package/node_modules/@comis/memory/dist/compaction.d.ts +3 -5
  199. package/node_modules/@comis/memory/dist/compaction.js +2 -3
  200. package/node_modules/@comis/memory/dist/delivery-queue-adapter.d.ts +2 -2
  201. package/node_modules/@comis/memory/dist/delivery-queue-adapter.js +49 -1
  202. package/node_modules/@comis/memory/dist/index.d.ts +2 -0
  203. package/node_modules/@comis/memory/dist/index.js +3 -0
  204. package/node_modules/@comis/memory/dist/memory-api.d.ts +1 -1
  205. package/node_modules/@comis/memory/dist/memory-api.js +1 -1
  206. package/node_modules/@comis/memory/dist/oauth-profile-schema.d.ts +17 -0
  207. package/node_modules/@comis/memory/dist/oauth-profile-schema.js +33 -0
  208. package/node_modules/@comis/memory/dist/oauth-profile-store-encrypted.d.ts +27 -0
  209. package/node_modules/@comis/memory/dist/oauth-profile-store-encrypted.js +144 -0
  210. package/node_modules/@comis/memory/dist/session-store.d.ts +1 -1
  211. package/node_modules/@comis/memory/dist/session-store.js +1 -1
  212. package/node_modules/@comis/memory/dist/sqlite-secret-store.d.ts +29 -3
  213. package/node_modules/@comis/memory/dist/sqlite-secret-store.js +11 -3
  214. package/node_modules/@comis/memory/package.json +1 -1
  215. package/node_modules/@comis/scheduler/dist/execution/execution-lock.d.ts +13 -0
  216. package/node_modules/@comis/scheduler/dist/execution/execution-lock.js +1 -1
  217. package/node_modules/@comis/scheduler/dist/execution/index.d.ts +2 -0
  218. package/node_modules/@comis/scheduler/dist/execution/index.js +2 -0
  219. package/node_modules/@comis/scheduler/dist/heartbeat/agent-heartbeat-source.js +1 -1
  220. package/node_modules/@comis/scheduler/dist/index.d.ts +2 -0
  221. package/node_modules/@comis/scheduler/dist/index.js +2 -0
  222. package/node_modules/@comis/scheduler/package.json +1 -1
  223. package/node_modules/@comis/shared/package.json +1 -1
  224. package/node_modules/@comis/skills/dist/bridge/schema-validator.d.ts +38 -0
  225. package/node_modules/@comis/skills/dist/bridge/schema-validator.js +169 -0
  226. package/node_modules/@comis/skills/dist/bridge/tool-metadata-enforcement.js +12 -0
  227. package/node_modules/@comis/skills/dist/bridge/tool-metadata-registry.js +130 -0
  228. package/node_modules/@comis/skills/dist/builtin/exec-diagnostics.d.ts +32 -0
  229. package/node_modules/@comis/skills/dist/builtin/exec-diagnostics.js +127 -0
  230. package/node_modules/@comis/skills/dist/builtin/exec-security.js +38 -0
  231. package/node_modules/@comis/skills/dist/builtin/exec-tool.js +9 -0
  232. package/node_modules/@comis/skills/dist/builtin/file-tools/grep-tool.js +6 -6
  233. package/node_modules/@comis/skills/dist/builtin/platform/agents-manage-tool.d.ts +5 -4
  234. package/node_modules/@comis/skills/dist/builtin/platform/agents-manage-tool.js +38 -27
  235. package/node_modules/@comis/skills/dist/builtin/platform/background-tasks-tool.d.ts +4 -1
  236. package/node_modules/@comis/skills/dist/builtin/platform/background-tasks-tool.js +3 -3
  237. package/node_modules/@comis/skills/dist/builtin/platform/cron-tool.js +1 -1
  238. package/node_modules/@comis/skills/dist/builtin/platform/gateway-tool.js +6 -6
  239. package/node_modules/@comis/skills/dist/builtin/platform/mcp-manage-tool.d.ts +1 -1
  240. package/node_modules/@comis/skills/dist/builtin/platform/mcp-manage-tool.js +9 -9
  241. package/node_modules/@comis/skills/dist/builtin/sandbox/bwrap-provider.d.ts +11 -0
  242. package/node_modules/@comis/skills/dist/builtin/sandbox/bwrap-provider.js +114 -1
  243. package/node_modules/@comis/skills/dist/builtin/sandbox/detect-provider.js +40 -15
  244. package/node_modules/@comis/skills/dist/media/ssrf-fetcher.d.ts +7 -0
  245. package/node_modules/@comis/skills/dist/media/ssrf-fetcher.js +9 -2
  246. package/node_modules/@comis/skills/package.json +1 -1
  247. package/node_modules/@comis/web/dist/assets/{agent-detail-71BSbSfD.js → agent-detail-q8t1NB7w.js} +1 -1
  248. package/node_modules/@comis/web/dist/assets/{agent-editor-CTSDZhwT.js → agent-editor-B46io5gv.js} +1 -1
  249. package/node_modules/@comis/web/dist/assets/{agent-list-BEhni2ea.js → agent-list-DQ6g2Rcx.js} +1 -1
  250. package/node_modules/@comis/web/dist/assets/{billing-view-DVP1IvVs.js → billing-view-IWPR8LgF.js} +1 -1
  251. package/node_modules/@comis/web/dist/assets/{channel-detail-N_YK74xC.js → channel-detail-DlNNZuuC.js} +1 -1
  252. package/node_modules/@comis/web/dist/assets/{channel-list-DRk6ZJaF.js → channel-list-DhGwxiMc.js} +1 -1
  253. package/node_modules/@comis/web/dist/assets/{chat-console-Dm-GtSf9.js → chat-console-Nv6fM3Rc.js} +1 -1
  254. package/node_modules/@comis/web/dist/assets/{config-editor-CIferYX6.js → config-editor-BYKuJF76.js} +1 -1
  255. package/node_modules/@comis/web/dist/assets/{context-dag-browser-CL84rXXM.js → context-dag-browser-ClNEtzYE.js} +1 -1
  256. package/node_modules/@comis/web/dist/assets/{context-engine-B1HOTEZv.js → context-engine-BZJ6HChd.js} +1 -1
  257. package/node_modules/@comis/web/dist/assets/{delivery-view-Y6JKYVFw.js → delivery-view-Cb7I3vGu.js} +1 -1
  258. package/node_modules/@comis/web/dist/assets/{diagnostics-view-DWV1UQjz.js → diagnostics-view-9u9Lyu5a.js} +1 -1
  259. package/node_modules/@comis/web/dist/assets/{ic-chat-message-DfSERzzg.js → ic-chat-message-BFt3cVpx.js} +1 -1
  260. package/node_modules/@comis/web/dist/assets/{ic-connection-dot-CXyhlJup.js → ic-connection-dot-y77LZ3Gu.js} +1 -1
  261. package/node_modules/@comis/web/dist/assets/{ic-tool-call-DNmwTjek.js → ic-tool-call-qt6w1NQl.js} +1 -1
  262. package/node_modules/@comis/web/dist/assets/{index-CBr0Tm9_.js → index-8Tg9oc-C.js} +2 -2
  263. package/node_modules/@comis/web/dist/assets/{mcp-management-BaH2-vox.js → mcp-management-69dtH_kY.js} +2 -2
  264. package/node_modules/@comis/web/dist/assets/{media-config-CZLshJoN.js → media-config-BdjLj5c1.js} +1 -1
  265. package/node_modules/@comis/web/dist/assets/{media-test-C9NUWgo_.js → media-test-DuPqrixi.js} +1 -1
  266. package/node_modules/@comis/web/dist/assets/{memory-inspector-D_fmTcRN.js → memory-inspector-B-Pepbq-.js} +1 -1
  267. package/node_modules/@comis/web/dist/assets/{message-center-BBFlNCZn.js → message-center-B7l0yNYY.js} +1 -1
  268. package/node_modules/@comis/web/dist/assets/{models-BytGLm99.js → models-JHFHuv5S.js} +1 -1
  269. package/node_modules/@comis/web/dist/assets/{observe-view-VXtHqaqq.js → observe-view-r8mqhy4O.js} +1 -1
  270. package/node_modules/@comis/web/dist/assets/{pipeline-builder-CfXczlfJ.js → pipeline-builder-XjkiZRcR.js} +1 -1
  271. package/node_modules/@comis/web/dist/assets/{pipeline-history-CPmXFnbe.js → pipeline-history-CZqJv_Hj.js} +1 -1
  272. package/node_modules/@comis/web/dist/assets/{pipeline-history-detail-DcueTMs9.js → pipeline-history-detail-BEFGMoDy.js} +1 -1
  273. package/node_modules/@comis/web/dist/assets/{pipeline-list-B-xG5WZh.js → pipeline-list-B6q5LvO1.js} +1 -1
  274. package/node_modules/@comis/web/dist/assets/{pipeline-monitor-pnIOYaSY.js → pipeline-monitor-BNomXjVL.js} +1 -1
  275. package/node_modules/@comis/web/dist/assets/{scheduler-BtUIFHhA.js → scheduler-BJEjcGKA.js} +1 -1
  276. package/node_modules/@comis/web/dist/assets/{security-C8mWRq2y.js → security-2G1jhBfV.js} +1 -1
  277. package/node_modules/@comis/web/dist/assets/{session-detail-DgdkO5ka.js → session-detail-DmVPzFBR.js} +1 -1
  278. package/node_modules/@comis/web/dist/assets/{session-list-DcylcfTn.js → session-list-CsqMQoHs.js} +1 -1
  279. package/node_modules/@comis/web/dist/assets/{setup-wizard-BP5yjsuL.js → setup-wizard-CAdM-gSP.js} +1 -1
  280. package/node_modules/@comis/web/dist/assets/{skills-DXt1bX8Z.js → skills-2ODqKaWr.js} +1 -1
  281. package/node_modules/@comis/web/dist/assets/{subagents-C7YbUHXY.js → subagents-BFlwfTbD.js} +1 -1
  282. package/node_modules/@comis/web/dist/assets/{workspace-manager-DP6pW4wa.js → workspace-manager--CbOx_dI.js} +1 -1
  283. package/node_modules/@comis/web/dist/index.html +1 -1
  284. package/node_modules/@comis/web/package.json +1 -1
  285. 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, "&lt;")
40
+ .replace(/>/g, "&gt;")
41
+ .replace(/"/g, "&quot;")
42
+ .replace(/'/g, "&#39;");
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) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/gateway",
3
3
  "private": true,
4
- "version": "1.0.33",
4
+ "version": "1.0.36",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "HTTP, JSON-RPC, and WebSocket gateway for Comis",
@@ -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"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/infra",
3
3
  "private": true,
4
- "version": "1.0.33",
4
+ "version": "1.0.36",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "Structured logging infrastructure for Comis",
@@ -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 -- the actual LLM call will be wired in
9
- * Phase 3 (Agent). This module defines the interface and orchestrates
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. The actual LLM call is wired
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 -- the actual LLM call will be wired in
10
- * Phase 3 (Agent). This module defines the interface and orchestrates
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 from Phase 1.
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 from Phase 1.
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;