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
@@ -9,11 +9,24 @@
9
9
  * Resolution chain (matches pi-coding-agent runtime semantics):
10
10
  * 1. KEYLESS_PROVIDER_TYPES.has(entry.type) — ollama / lm-studio
11
11
  * 2. providers.entries.<provider>.apiKeyName → secretManager.has(...)
12
- * 3. pi-ai's getEnvApiKey(provider) — canonical env + OAuth + ADC + AWS
12
+ * 3. pi-ai's getEnvApiKey(provider) — canonical env vars (incl. ANTHROPIC_OAUTH_TOKEN
13
+ * and AWS/ADC special-cases). Does NOT cover comis-managed OAuth profiles in
14
+ * ~/.comis/auth-profiles.json (e.g. openai-codex).
15
+ * 4. Comis OAuth profiles — agent.oauthProfiles[provider] resolved against an
16
+ * injected oauthProfileLoader (the OAuthCredentialStorePort handle held by
17
+ * the daemon, adapted to a synchronous has-check at the call site).
18
+ *
19
+ * Note on synchronous loader facade (quick-260504-irq): `OAuthCredentialStorePort.has`
20
+ * is async (returns Promise<Result<boolean, Error>>). To avoid an async cascade
21
+ * through every call site, this resolver remains SYNCHRONOUS and accepts a
22
+ * sync facade (`oauthProfileLoader: { has(profileId: string): boolean }`).
23
+ * The async port `has()` call MUST be performed at the daemon edge
24
+ * (config-handlers / agent-handlers) and adapted into the closure. This keeps
25
+ * the port-side validator I/O-free (Hexagonal: validator does no I/O).
13
26
  *
14
27
  * @module
15
28
  */
16
- import { getEnvApiKey } from "@mariozechner/pi-ai";
29
+ import { getEnvApiKey, getProviders, getModels } from "@mariozechner/pi-ai";
17
30
  /**
18
31
  * Provider types that don't need an API key. Mirrors agent's
19
32
  * KEYLESS_PROVIDER_TYPES at model-registry-adapter.ts:60 — extended here to
@@ -28,23 +41,73 @@ export function resolveProviderCredential(targetProvider, deps) {
28
41
  reason: `Invalid provider value: must be a non-empty string (got ${JSON.stringify(targetProvider)})`,
29
42
  };
30
43
  }
31
- // eslint-disable-next-line security/detect-object-injection -- typed Record<string, ProviderEntry> read; targetProvider validated above
32
- const entry = deps.providerEntries?.[targetProvider];
44
+ // Resolve `provider: "default"` to the operator's configured default,
45
+ // mirroring runtime resolution in `resolveAgentModel`:
46
+ // 1. If `providers.entries.default` is explicitly configured, treat that
47
+ // as the operator's intent — the entry itself carries the credential
48
+ // resolution path (keyless / apiKeyName).
49
+ // 2. Else, if `models.defaultProvider` is set, use that.
50
+ // 3. Otherwise, fall back to the most-populated native provider in the
51
+ // pi-ai catalog (same heuristic the runtime applies).
52
+ // This keeps the credential check semantically aligned with the literal
53
+ // provider the runtime will select.
54
+ let effectiveProvider = targetProvider;
55
+ if (targetProvider.toLowerCase() === "default") {
56
+ const explicitDefault = deps.providerEntries?.default;
57
+ if (!explicitDefault) {
58
+ const dp = deps.modelsConfig?.defaultProvider;
59
+ if (dp && dp.length > 0) {
60
+ effectiveProvider = dp;
61
+ }
62
+ else {
63
+ const allProviders = getProviders();
64
+ if (allProviders.length > 0) {
65
+ effectiveProvider = allProviders
66
+ .map((p) => ({ p, n: getModels(p).length }))
67
+ .sort((a, b) => b.n - a.n)[0].p;
68
+ }
69
+ }
70
+ }
71
+ }
72
+ // eslint-disable-next-line security/detect-object-injection -- typed Record<string, ProviderEntry> read; effectiveProvider validated above
73
+ const entry = deps.providerEntries?.[effectiveProvider];
33
74
  // 1. Keyless types
34
75
  if (entry && KEYLESS_PROVIDER_TYPES.has(entry.type)) {
35
- return { ok: true, source: "keyless" };
76
+ return { ok: true, source: "keyless", resolvedProvider: effectiveProvider };
36
77
  }
37
78
  // 2. Source A: providers.entries with secret-manager-resolvable apiKeyName
38
79
  if (entry?.apiKeyName && deps.secretManager?.has(entry.apiKeyName)) {
39
- return { ok: true, source: "providers_entry" };
80
+ return { ok: true, source: "providers_entry", resolvedProvider: effectiveProvider };
81
+ }
82
+ // 3. Source C: comis OAuth profile (per-agent agents.<id>.oauthProfiles).
83
+ // Covers OAuth-only providers like openai-codex whose tokens live in
84
+ // ~/.comis/auth-profiles.json — pi-ai's getEnvApiKey does NOT see them.
85
+ // Inserted before Source B so OAuth profiles win over env-canonical when
86
+ // both would resolve (the operator explicitly configured the profile).
87
+ // eslint-disable-next-line security/detect-object-injection -- typed Record<string, string> read; effectiveProvider validated above
88
+ const configuredProfileId = deps.oauthProfiles?.[effectiveProvider];
89
+ if (configuredProfileId && deps.oauthProfileLoader?.has(configuredProfileId)) {
90
+ return { ok: true, source: "oauth_profile", resolvedProvider: effectiveProvider };
40
91
  }
41
- // 3. Source B: pi-ai canonical env / OAuth / ADC chain
42
- if (getEnvApiKey(targetProvider)) {
43
- return { ok: true, source: "env_canonical" };
92
+ // 4. Source B: pi-ai canonical env / OAuth / ADC chain
93
+ if (getEnvApiKey(effectiveProvider)) {
94
+ return { ok: true, source: "env_canonical", resolvedProvider: effectiveProvider };
44
95
  }
45
- return { ok: false, reason: buildRejectionMessage(targetProvider, entry) };
96
+ return { ok: false, reason: buildRejectionMessage(effectiveProvider, entry, configuredProfileId) };
46
97
  }
47
- function buildRejectionMessage(targetProvider, entry) {
98
+ function buildRejectionMessage(targetProvider, entry, configuredProfileId) {
99
+ // OAuth-aware rejection: when the agent has an oauthProfiles entry for this
100
+ // provider but the loader could not confirm the profile, the failure mode is
101
+ // a missing OAuth profile (not a missing API key). Point the operator at
102
+ // `comis auth login` rather than env_set / apiKeyName recovery.
103
+ if (configuredProfileId) {
104
+ const lines = [];
105
+ lines.push(`Cannot set agent provider to "${targetProvider}": OAuth profile "${configuredProfileId}" is configured but not found in the OAuth credential store (~/.comis/auth-profiles.json).`);
106
+ lines.push(`Recovery:`);
107
+ lines.push(` Run \`comis auth login --provider ${targetProvider}\` to (re)authenticate and create the profile, then retry this patch.`);
108
+ lines.push(` Run \`comis auth list\` to see currently stored profiles.`);
109
+ return lines.join("\n");
110
+ }
48
111
  const lines = [];
49
112
  lines.push(`Cannot set agent provider to "${targetProvider}": no API key found.`);
50
113
  if (entry?.apiKeyName) {
@@ -6,6 +6,7 @@
6
6
  */
7
7
  import type { McpClientManager } from "@comis/skills";
8
8
  import type { ComisLogger } from "@comis/infra";
9
+ import type { SecretManager } from "@comis/core";
9
10
  import type { RpcHandler } from "./types.js";
10
11
  /** Dependencies required by MCP management RPC handlers. */
11
12
  export interface McpHandlerDeps {
@@ -17,6 +18,13 @@ export interface McpHandlerDeps {
17
18
  mcpClientManager: McpClientManager;
18
19
  /** Logger for MCP test connection (used by temporary manager). */
19
20
  logger: ComisLogger;
21
+ /**
22
+ * Optional SecretManager for env-ref validation on mcp.connect. When
23
+ * undefined (legacy/test wiring), the env-ref check is skipped — the
24
+ * existing connect behavior is preserved. In production it is always
25
+ * wired via `deps.container.secretManager` from rpc-dispatch.
26
+ */
27
+ secretManager?: SecretManager;
20
28
  }
21
29
  /**
22
30
  * Create a record of MCP management RPC handlers bound to the given deps.
@@ -6,6 +6,7 @@
6
6
  * @module
7
7
  */
8
8
  import { createMcpClientManager } from "@comis/skills";
9
+ import { findUnresolvedEnvRefs, formatMissingEnvRefError } from "@comis/core";
9
10
  // ---------------------------------------------------------------------------
10
11
  // Factory
11
12
  // ---------------------------------------------------------------------------
@@ -30,9 +31,9 @@ export function createMcpHandlers(deps) {
30
31
  return { servers, total: servers.length };
31
32
  },
32
33
  "mcp.status": async (params) => {
33
- const name = params.name;
34
+ const name = params.server_name;
34
35
  if (!name)
35
- throw new Error("Missing required parameter: name");
36
+ throw new Error("Missing required parameter: server_name");
36
37
  const manager = deps.mcpClientManager;
37
38
  const conn = manager.getConnection(name);
38
39
  if (!conn) {
@@ -59,10 +60,10 @@ export function createMcpHandlers(deps) {
59
60
  };
60
61
  },
61
62
  "mcp.connect": async (params) => {
62
- const name = params.name;
63
+ const name = params.server_name;
63
64
  const transport = params.transport;
64
65
  if (!name)
65
- throw new Error("Missing required parameter: name");
66
+ throw new Error("Missing required parameter: server_name");
66
67
  if (!transport)
67
68
  throw new Error("Missing required parameter: transport");
68
69
  const manager = deps.mcpClientManager;
@@ -76,6 +77,19 @@ export function createMcpHandlers(deps) {
76
77
  headers: params.headers,
77
78
  enabled: true,
78
79
  };
80
+ // Reject connects that reference env vars not in the secrets store.
81
+ // mcp.connect is unconditionally enabled (config.enabled = true
82
+ // above), so the check always applies when both env and secretManager
83
+ // are present. Skipped only when secretManager is unwired (test
84
+ // setups) — production always wires it via rpc-dispatch.
85
+ if (config.env && deps.secretManager) {
86
+ const sm = deps.secretManager;
87
+ const unresolved = findUnresolvedEnvRefs(config.env, (key) => sm.get(key));
88
+ if (unresolved.length > 0) {
89
+ const missingNames = unresolved.map((u) => u.varName);
90
+ throw new Error(formatMissingEnvRefError(name, missingNames));
91
+ }
92
+ }
79
93
  const result = await manager.connect(config);
80
94
  if (!result.ok) {
81
95
  throw new Error(`Failed to connect MCP server "${name}": ${result.error.message}`);
@@ -88,9 +102,9 @@ export function createMcpHandlers(deps) {
88
102
  };
89
103
  },
90
104
  "mcp.disconnect": async (params) => {
91
- const name = params.name;
105
+ const name = params.server_name;
92
106
  if (!name)
93
- throw new Error("Missing required parameter: name");
107
+ throw new Error("Missing required parameter: server_name");
94
108
  const manager = deps.mcpClientManager;
95
109
  const conn = manager.getConnection(name);
96
110
  if (!conn) {
@@ -148,9 +162,9 @@ export function createMcpHandlers(deps) {
148
162
  }
149
163
  },
150
164
  "mcp.reconnect": async (params) => {
151
- const name = params.name;
165
+ const name = params.server_name;
152
166
  if (!name)
153
- throw new Error("Missing required parameter: name");
167
+ throw new Error("Missing required parameter: server_name");
154
168
  const manager = deps.mcpClientManager;
155
169
  // Use manager's reconnect (preserves generation counter, uses stored config)
156
170
  const result = await manager.reconnect(name);
@@ -196,20 +196,17 @@ export function createProviderHandlers(deps) {
196
196
  throw new Error(`Provider already exists: ${providerId}`);
197
197
  }
198
198
  const config = params.config ?? {};
199
- // 260501-gyy: reject redundant catalog-shadowing entries before
200
- // promotion / probe / persist. A built-in provider with a catalog
201
- // (or absent) baseUrl is structurally redundant -- pi-ai's dynamic
202
- // catalog already provides its model list. Production trace
203
- // 2026-05-01 08:53 showed an LLM agent creating
204
- // providers.entries.openrouter with an invented model id, leading
205
- // to a downstream 404.
199
+ // Reject redundant catalog-shadowing entries before promotion / probe
200
+ // / persist. A built-in provider with a catalog (or absent) baseUrl is
201
+ // structurally redundant -- pi-ai's dynamic catalog already provides
202
+ // its model list.
206
203
  const guardResult = checkBuiltInProviderRedundancy(providerId, config);
207
204
  if (!guardResult.ok) {
208
205
  throw new Error(guardResult.reason);
209
206
  }
210
- // Layer 1C (260430-vwt): auto-promote type to native catalog name
211
- // when the providerId matches a pi-ai catalog entry AND the user has
212
- // not opted out via a custom baseUrl.
207
+ // Auto-promote type to native catalog name when the providerId
208
+ // matches a pi-ai catalog entry AND the user has not opted out via a
209
+ // custom baseUrl.
213
210
  const normalizedConfig = normalizeProviderEntry(providerId, config, deps.persistDeps?.logger);
214
211
  const parsedConfig = ProviderEntrySchema.parse(normalizedConfig);
215
212
  // Probe provider API key before committing config
@@ -260,8 +257,8 @@ export function createProviderHandlers(deps) {
260
257
  // Capture user-provided fields BEFORE merge -- persistToConfig does deepMerge internally,
261
258
  // so we only persist the user's partial patch (not the fully merged config).
262
259
  const userPatch = params.config ? structuredClone(params.config) : {};
263
- // Layer 1C (260430-vwt): on update, only auto-promote when the user
264
- // is actively changing the `type` field. If `type` is absent from
260
+ // On update, only auto-promote when the user is actively changing
261
+ // the `type` field. If `type` is absent from
265
262
  // the patch, the user is editing other fields and we must not
266
263
  // rewrite their existing type silently.
267
264
  let normalizedPatch = config;
@@ -185,6 +185,7 @@ export interface RpcDispatchDeps {
185
185
  globalHeartbeatConfig?: Record<string, unknown>;
186
186
  notificationService?: import("../notification/notification-service.js").NotificationService;
187
187
  imageHandlerDeps?: ImageHandlerDeps;
188
+ oauthCredentialStore?: import("@comis/core").OAuthCredentialStorePort;
188
189
  }
189
190
  /**
190
191
  * Classify an RPC error message for structured logging.
@@ -71,7 +71,17 @@ export function createRpcDispatch(deps) {
71
71
  ...createSessionHandlers(deps),
72
72
  ...createMessageHandlers(deps),
73
73
  ...createMediaHandlers(deps),
74
- ...createConfigHandlers(deps),
74
+ // Thread the daemon-level OAuth credential store into config.patch's
75
+ // credential guard so model/provider patches on OAuth-only providers
76
+ // (e.g. openai-codex) can resolve via Source C
77
+ // (agents.<id>.oauthProfiles -> ~/.comis/auth-profiles.json). Explicit
78
+ // pass-through mirrors the createAgentHandlers wiring below; do not
79
+ // simplify back to `...createConfigHandlers(deps)` (the structural-typing
80
+ // inheritance is fragile to future deps-shape narrowing).
81
+ ...createConfigHandlers({
82
+ ...deps,
83
+ oauthCredentialStore: deps.oauthCredentialStore,
84
+ }),
75
85
  ...createEnvHandlers(deps),
76
86
  ...createBrowserHandlers(deps),
77
87
  ...createSubagentHandlers(deps),
@@ -90,6 +100,14 @@ export function createRpcDispatch(deps) {
90
100
  ...deps,
91
101
  secretManager: deps.container?.secretManager,
92
102
  providerEntries: deps.container.config.providers.entries,
103
+ // Thread the daemon-level OAuth credential store into agents.update
104
+ // so the oauthProfiles existence check can run via has(). When unset
105
+ // (e.g. unwired test setups) the validation block in agent-handlers
106
+ // becomes a no-op.
107
+ oauthCredentialStore: deps.oauthCredentialStore,
108
+ // Resolves `provider: "default"` to `models.defaultProvider` in the
109
+ // credential check, mirroring `resolveAgentModel` runtime resolution.
110
+ modelsConfig: deps.container.config.models,
93
111
  persistDeps: {
94
112
  container: deps.container,
95
113
  configPaths: deps.configPaths,
@@ -135,7 +153,14 @@ export function createRpcDispatch(deps) {
135
153
  logger: deps.logger,
136
154
  },
137
155
  }),
138
- ...createMcpHandlers({ mcpClientManager: deps.mcpClientManager, logger: deps.logger }),
156
+ ...createMcpHandlers({
157
+ mcpClientManager: deps.mcpClientManager,
158
+ logger: deps.logger,
159
+ // Threaded for env-ref validation on mcp.connect. Same pattern as
160
+ // agent/provider handlers above. When undefined the validator becomes
161
+ // a no-op.
162
+ secretManager: deps.container?.secretManager,
163
+ }),
139
164
  ...createDaemonHandlers({ logLevelManager: deps.logLevelManager }),
140
165
  // Workspace file management handlers
141
166
  ...createWorkspaceHandlers({
@@ -25,6 +25,5 @@ export function emitDockerRestartPolicyWarn(logger, opts = {}) {
25
25
  logger.warn({
26
26
  hint: "Wizard 'Restart' actions, gateway.restart, gateway.env_set, and gateway.patch on restart-triggering paths all require the container to have --restart unless-stopped (or compose restart: unless-stopped). Verify from your host with: docker inspect <name> --format '{{.HostConfig.RestartPolicy.Name}}'",
27
27
  errorKind: "config",
28
- module: "daemon",
29
28
  }, "Running in Docker — restart policy required for config-reload operations");
30
29
  }
@@ -17,3 +17,5 @@ export { setupGateway, type GatewayDeps, type GatewayResult, setupRpcBridge, typ
17
17
  export { setupDeliveryQueue, type DeliveryQueueResult, setupDeliveryMirror, type DeliveryMirrorResult } from "./setup-delivery.js";
18
18
  export { setupNotifications, type NotificationContext } from "./setup-notifications.js";
19
19
  export { setupBackgroundTasks, type BackgroundTasksContext } from "./setup-background-tasks.js";
20
+ export { setupBackgroundCompletionRunner } from "./setup-background-completion-runner.js";
21
+ export type { BackgroundCompletionRunnerContext, SetupBackgroundCompletionRunnerDeps, } from "./setup-background-completion-runner.js";
@@ -16,3 +16,4 @@ export { setupGateway, setupRpcBridge } from "./setup-gateway.js";
16
16
  export { setupDeliveryQueue, setupDeliveryMirror } from "./setup-delivery.js";
17
17
  export { setupNotifications } from "./setup-notifications.js";
18
18
  export { setupBackgroundTasks } from "./setup-background-tasks.js";
19
+ export { setupBackgroundCompletionRunner } from "./setup-background-completion-runner.js";
@@ -0,0 +1,21 @@
1
+ import type { ComisLogger } from "@comis/infra";
2
+ import type { PerAgentConfig } from "@comis/core";
3
+ /**
4
+ * Returns `true` iff at least one agent's `provider` is recognised by pi-ai's
5
+ * `getOAuthProvider` as an OAuth-using provider.
6
+ *
7
+ * Single-source-of-truth check — avoids drift with pi-ai's provider catalogue.
8
+ * When this returns `false`, the daemon skips the preflight entirely (zero
9
+ * outbound probes during boot for OAuth-less deployments).
10
+ */
11
+ export declare function hasAnyOAuthAgent(agents: Record<string, PerAgentConfig>): boolean;
12
+ /**
13
+ * Run the OAuth TLS preflight and emit a single structured log line if it
14
+ * fails. Never throws — `runOAuthTlsPreflight` returns a discriminated union
15
+ * and this function only reads-and-logs.
16
+ *
17
+ * Caller is expected to invoke this fire-and-forget (`void`) AFTER the
18
+ * `"Comis daemon started"` banner so the daemon already counts as healthy
19
+ * to PM2/systemd by the time the probe resolves.
20
+ */
21
+ export declare function emitOAuthTlsPreflightWarn(logger: ComisLogger): Promise<void>;
@@ -0,0 +1,134 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ /**
3
+ * Boot-time OAuth TLS preflight wiring.
4
+ *
5
+ * Two helpers exposed for the daemon entry point:
6
+ *
7
+ * 1. `hasAnyOAuthAgent(agents)` — runtime gate. Returns `true` iff at least
8
+ * one entry in the per-agent map declares a `provider` value that
9
+ * pi-ai's `getOAuthProvider` recognises as an OAuth provider. Used to
10
+ * skip the entire preflight (and any outbound network probe) when no
11
+ * OAuth-using agent is configured.
12
+ *
13
+ * 2. `emitOAuthTlsPreflightWarn(logger)` — fire-and-forget. Calls
14
+ * `runOAuthTlsPreflight({ timeoutMs: 4000 })` from `@comis/agent`
15
+ * and surfaces the result via Pino:
16
+ * - `kind: "tls-cert"` → exactly one WARN with module + errorKind +
17
+ * distro-aware install hint + OpenSSL `code` + raw `message`.
18
+ * - `kind: "network"` → a single DEBUG (no WARN — transient failures
19
+ * should not pollute the boot path).
20
+ * - `{ ok: true }` → silent (operators do not want noise on boot).
21
+ *
22
+ * The 4000 ms timeout is intentionally tighter than the CLI doctor variant's
23
+ * 5000 ms — boot must stay under PM2 / systemd watchdog windows even on the
24
+ * worst case.
25
+ *
26
+ * Distro detection (`/etc/os-release` parser + 5-distro install-hint switch)
27
+ * is duplicated inline from `packages/cli/src/doctor/checks/oauth-health.ts`.
28
+ * Per AGENTS.md §2.3 rule of three, two callers do not yet justify a shared
29
+ * helper. If a third caller appears, extract the pair to
30
+ * `packages/agent/src/model/oauth-os-release.ts`.
31
+ *
32
+ * Per AGENTS.md §2.4 the logger is injected — no `@comis/infra` import.
33
+ *
34
+ * @module
35
+ */
36
+ import { readFile } from "node:fs/promises";
37
+ import { runOAuthTlsPreflight } from "@comis/agent";
38
+ import { getOAuthProvider } from "@mariozechner/pi-ai/oauth";
39
+ /** Boot-tighter timeout — keeps the preflight inside PM2/systemd watchdog windows. */
40
+ const PREFLIGHT_TIMEOUT_MS = 4000;
41
+ /** Pino `module` field — operators grep on this to isolate preflight logs. */
42
+ const MODULE_NAME = "oauth-tls-preflight";
43
+ /**
44
+ * Returns `true` iff at least one agent's `provider` is recognised by pi-ai's
45
+ * `getOAuthProvider` as an OAuth-using provider.
46
+ *
47
+ * Single-source-of-truth check — avoids drift with pi-ai's provider catalogue.
48
+ * When this returns `false`, the daemon skips the preflight entirely (zero
49
+ * outbound probes during boot for OAuth-less deployments).
50
+ */
51
+ export function hasAnyOAuthAgent(agents) {
52
+ return Object.values(agents).some((agent) => Boolean(getOAuthProvider(agent.provider)));
53
+ }
54
+ /**
55
+ * Parses `/etc/os-release` into `{ id, idLike }`. Returns `null` on read
56
+ * error (missing file, permission denied, malformed contents).
57
+ *
58
+ * Verbatim duplication from `oauth-health.ts` — see module JSDoc for the
59
+ * AGENTS.md §2.3 deferral rationale.
60
+ */
61
+ async function readOsRelease(path = "/etc/os-release") {
62
+ try {
63
+ const text = await readFile(path, "utf-8");
64
+ const map = new Map();
65
+ for (const line of text.split("\n")) {
66
+ const m = line.match(/^([A-Z_]+)=(.*)$/);
67
+ if (m)
68
+ map.set(m[1], m[2].replace(/^"|"$/g, ""));
69
+ }
70
+ const id = map.get("ID") ?? "";
71
+ const idLike = (map.get("ID_LIKE") ?? "").split(/\s+/).filter(Boolean);
72
+ return { id, idLike };
73
+ }
74
+ catch {
75
+ return null;
76
+ }
77
+ }
78
+ /**
79
+ * Produces a distro-aware install command for the system CA bundle.
80
+ *
81
+ * Verbatim duplication from `oauth-health.ts` — see module JSDoc for the
82
+ * AGENTS.md §2.3 deferral rationale.
83
+ */
84
+ function caCertificatesInstallHint(os) {
85
+ if (!os)
86
+ return "Install ca-certificates via your distro's package manager and retry";
87
+ const idChain = [os.id, ...os.idLike];
88
+ if (idChain.includes("alpine"))
89
+ return "apk add ca-certificates && update-ca-certificates";
90
+ if (idChain.includes("debian") || idChain.includes("ubuntu")) {
91
+ return "sudo apt-get install -y ca-certificates && sudo update-ca-certificates";
92
+ }
93
+ if (idChain.includes("fedora") || idChain.includes("rhel") || idChain.includes("centos")) {
94
+ return "sudo dnf install -y ca-certificates && sudo update-ca-trust";
95
+ }
96
+ if (idChain.includes("arch"))
97
+ return "sudo pacman -S ca-certificates && sudo trust extract-compat";
98
+ if (idChain.includes("suse") || idChain.includes("opensuse")) {
99
+ return "sudo zypper install ca-certificates && sudo update-ca-certificates";
100
+ }
101
+ return "Install ca-certificates via your distro's package manager and retry";
102
+ }
103
+ /**
104
+ * Run the OAuth TLS preflight and emit a single structured log line if it
105
+ * fails. Never throws — `runOAuthTlsPreflight` returns a discriminated union
106
+ * and this function only reads-and-logs.
107
+ *
108
+ * Caller is expected to invoke this fire-and-forget (`void`) AFTER the
109
+ * `"Comis daemon started"` banner so the daemon already counts as healthy
110
+ * to PM2/systemd by the time the probe resolves.
111
+ */
112
+ export async function emitOAuthTlsPreflightWarn(logger) {
113
+ const result = await runOAuthTlsPreflight({ timeoutMs: PREFLIGHT_TIMEOUT_MS });
114
+ if (result.ok)
115
+ return;
116
+ if (result.kind === "tls-cert") {
117
+ const os = await readOsRelease();
118
+ const hint = caCertificatesInstallHint(os);
119
+ logger.warn({
120
+ submodule: MODULE_NAME,
121
+ errorKind: "oauth_tls_cert",
122
+ hint,
123
+ code: result.code,
124
+ message: result.message,
125
+ }, "OAuth TLS preflight failed: system CA bundle cannot validate auth.openai.com");
126
+ return;
127
+ }
128
+ // kind === "network" — transient outage / DNS / firewall. DEBUG only.
129
+ logger.debug({
130
+ submodule: MODULE_NAME,
131
+ errorKind: "oauth_tls_network",
132
+ message: result.message,
133
+ }, "OAuth TLS preflight network failure (skipping WARN — likely transient)");
134
+ }
@@ -5,8 +5,9 @@
5
5
  * All agents use PiExecutor (pi-coding-agent AgentSession wrapper).
6
6
  * @module
7
7
  */
8
- import { type AppContainer, type InjectionRateLimiter, type PerAgentConfig } from "@comis/core";
8
+ import { type AppContainer, type InjectionRateLimiter, type OAuthCredentialStorePort, type SecretsCrypto, type PerAgentConfig } from "@comis/core";
9
9
  import type { ComisLogger } from "@comis/infra";
10
+ import type Database from "better-sqlite3";
10
11
  import type { SqliteMemoryAdapter, createSessionStore } from "@comis/memory";
11
12
  import { createBudgetGuard, createCostTracker, createStepCounter, createSessionLifecycle, createComisSessionManager, type AgentExecutor, type ActiveRunRegistry, type ProviderHealthMonitor, type LastKnownModelTracker } from "@comis/agent";
12
13
  import { type SkillRegistry, type SkillWatcherHandle } from "@comis/skills";
@@ -59,6 +60,32 @@ export interface SingleAgentDeps {
59
60
  backgroundTaskManager?: import("@comis/agent").BackgroundTaskManager;
60
61
  /** Callback to send completion notifications for background tasks. */
61
62
  backgroundNotifyFn?: import("@comis/agent").NotifyFn;
63
+ /**
64
+ * SecretsCrypto engine bound to SECRETS_MASTER_KEY. Defined when the daemon
65
+ * was started with a valid master key (encrypted-secrets mode). Required
66
+ * when `appConfig.oauth.storage === "encrypted"` — selectOAuthCredentialStore
67
+ * fails fast with an operator hint when missing.
68
+ */
69
+ secretsCrypto?: SecretsCrypto;
70
+ /**
71
+ * Shared better-sqlite3 handle to secrets.db (the SqliteSecretStoreHandle.db
72
+ * field, plumbed through from daemon.ts after createSqliteSecretStore).
73
+ * Required when `appConfig.oauth.storage === "encrypted"` so the OAuth
74
+ * profile adapter can share the existing connection rather than opening a
75
+ * second handle to the same DB file — eliminates the dual-handle lifecycle
76
+ * hazards: close-order, schema-init double-execution, prepared-statement
77
+ * cache fragmentation.
78
+ */
79
+ secretsDb?: Database.Database;
80
+ /**
81
+ * The daemon-level OAuthCredentialStore handle. Constructed ONCE in
82
+ * setupAgents() and passed down to every per-agent setupSingleAgent call
83
+ * AND surfaced on AgentsResult so daemon.ts can thread it into
84
+ * RpcDispatchDeps for `agents.update` existence checks. Single shared
85
+ * handle (file backend is stateless on a shared path; encrypted backend
86
+ * shares the secretsDb connection).
87
+ */
88
+ oauthCredentialStore: OAuthCredentialStorePort;
62
89
  }
63
90
  /** Per-agent outputs from setupSingleAgent(), matching the Maps in AgentsResult. */
64
91
  export interface SingleAgentResult {
@@ -103,6 +130,12 @@ export interface AgentsResult {
103
130
  singleAgentDeps: SingleAgentDeps;
104
131
  /** Global provider health monitor for daemon-level health metrics */
105
132
  providerHealth: ProviderHealthMonitor;
133
+ /**
134
+ * Daemon-level OAuthCredentialStore handle. Threaded into
135
+ * RpcDispatchDeps so agents.update can validate oauthProfiles patches
136
+ * via has().
137
+ */
138
+ oauthCredentialStore: OAuthCredentialStorePort;
106
139
  }
107
140
  /**
108
141
  * Set up a single agent's executor and all supporting services.
@@ -162,6 +195,18 @@ export declare function setupAgents(deps: {
162
195
  backgroundTaskManager?: import("@comis/agent").BackgroundTaskManager;
163
196
  /** Callback to send completion notifications for background tasks. */
164
197
  backgroundNotifyFn?: import("@comis/agent").NotifyFn;
198
+ /**
199
+ * SecretsCrypto engine bound to SECRETS_MASTER_KEY. Defined when daemon
200
+ * was started with a valid master key. Required for
201
+ * `appConfig.oauth.storage === "encrypted"` mode.
202
+ */
203
+ secretsCrypto?: SecretsCrypto;
204
+ /**
205
+ * Shared better-sqlite3 handle to secrets.db. Plumbed from daemon.ts where
206
+ * createSqliteSecretStore now exposes its db field. Required for
207
+ * `appConfig.oauth.storage === "encrypted"` mode.
208
+ */
209
+ secretsDb?: Database.Database;
165
210
  }): Promise<AgentsResult>;
166
211
  /**
167
212
  * Resolve "default" model/provider placeholders to concrete values from the