comisai 1.0.34 → 1.0.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (284) 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/index.d.ts +2 -0
  156. package/node_modules/@comis/daemon/dist/index.js +5 -0
  157. package/node_modules/@comis/daemon/dist/observability/channel-health-logger.js +3 -3
  158. package/node_modules/@comis/daemon/dist/observability/delivery-queue-logger.js +1 -1
  159. package/node_modules/@comis/daemon/dist/rpc/agent-handlers.d.ts +22 -1
  160. package/node_modules/@comis/daemon/dist/rpc/agent-handlers.js +84 -21
  161. package/node_modules/@comis/daemon/dist/rpc/agent-inline-workspace.js +2 -2
  162. package/node_modules/@comis/daemon/dist/rpc/config-handlers.d.ts +9 -1
  163. package/node_modules/@comis/daemon/dist/rpc/config-handlers.js +104 -23
  164. package/node_modules/@comis/daemon/dist/rpc/credential-resolver.d.ts +30 -1
  165. package/node_modules/@comis/daemon/dist/rpc/credential-resolver.js +74 -11
  166. package/node_modules/@comis/daemon/dist/rpc/mcp-handlers.d.ts +8 -0
  167. package/node_modules/@comis/daemon/dist/rpc/mcp-handlers.js +22 -8
  168. package/node_modules/@comis/daemon/dist/rpc/provider-handlers.js +9 -12
  169. package/node_modules/@comis/daemon/dist/rpc/rpc-dispatch.d.ts +1 -0
  170. package/node_modules/@comis/daemon/dist/rpc/rpc-dispatch.js +27 -2
  171. package/node_modules/@comis/daemon/dist/setup-docker-restart-warn.js +0 -1
  172. package/node_modules/@comis/daemon/dist/wiring/index.d.ts +2 -0
  173. package/node_modules/@comis/daemon/dist/wiring/index.js +1 -0
  174. package/node_modules/@comis/daemon/dist/wiring/oauth-preflight.d.ts +21 -0
  175. package/node_modules/@comis/daemon/dist/wiring/oauth-preflight.js +134 -0
  176. package/node_modules/@comis/daemon/dist/wiring/setup-agents.d.ts +46 -1
  177. package/node_modules/@comis/daemon/dist/wiring/setup-agents.js +127 -3
  178. package/node_modules/@comis/daemon/dist/wiring/setup-background-completion-runner.d.ts +39 -0
  179. package/node_modules/@comis/daemon/dist/wiring/setup-background-completion-runner.js +32 -0
  180. package/node_modules/@comis/daemon/dist/wiring/setup-background-tasks.d.ts +10 -3
  181. package/node_modules/@comis/daemon/dist/wiring/setup-background-tasks.js +11 -5
  182. package/node_modules/@comis/daemon/dist/wiring/setup-channels.js +20 -1
  183. package/node_modules/@comis/daemon/dist/wiring/setup-cross-session.js +1 -1
  184. package/node_modules/@comis/daemon/dist/wiring/setup-delivery.d.ts +14 -5
  185. package/node_modules/@comis/daemon/dist/wiring/setup-delivery.js +52 -19
  186. package/node_modules/@comis/daemon/dist/wiring/setup-schedulers.js +4 -0
  187. package/node_modules/@comis/daemon/package.json +1 -1
  188. package/node_modules/@comis/gateway/dist/index.d.ts +2 -0
  189. package/node_modules/@comis/gateway/dist/index.js +2 -0
  190. package/node_modules/@comis/gateway/dist/oauth/oauth-callback-route.d.ts +66 -0
  191. package/node_modules/@comis/gateway/dist/oauth/oauth-callback-route.js +212 -0
  192. package/node_modules/@comis/gateway/dist/server/hono-server.d.ts +14 -0
  193. package/node_modules/@comis/gateway/dist/server/hono-server.js +10 -0
  194. package/node_modules/@comis/gateway/package.json +1 -1
  195. package/node_modules/@comis/infra/dist/logging/log-fields.d.ts +23 -0
  196. package/node_modules/@comis/infra/package.json +1 -1
  197. package/node_modules/@comis/memory/dist/compaction.d.ts +3 -5
  198. package/node_modules/@comis/memory/dist/compaction.js +2 -3
  199. package/node_modules/@comis/memory/dist/delivery-queue-adapter.d.ts +2 -2
  200. package/node_modules/@comis/memory/dist/delivery-queue-adapter.js +49 -1
  201. package/node_modules/@comis/memory/dist/index.d.ts +2 -0
  202. package/node_modules/@comis/memory/dist/index.js +3 -0
  203. package/node_modules/@comis/memory/dist/memory-api.d.ts +1 -1
  204. package/node_modules/@comis/memory/dist/memory-api.js +1 -1
  205. package/node_modules/@comis/memory/dist/oauth-profile-schema.d.ts +17 -0
  206. package/node_modules/@comis/memory/dist/oauth-profile-schema.js +33 -0
  207. package/node_modules/@comis/memory/dist/oauth-profile-store-encrypted.d.ts +27 -0
  208. package/node_modules/@comis/memory/dist/oauth-profile-store-encrypted.js +144 -0
  209. package/node_modules/@comis/memory/dist/session-store.d.ts +1 -1
  210. package/node_modules/@comis/memory/dist/session-store.js +1 -1
  211. package/node_modules/@comis/memory/dist/sqlite-secret-store.d.ts +29 -3
  212. package/node_modules/@comis/memory/dist/sqlite-secret-store.js +11 -3
  213. package/node_modules/@comis/memory/package.json +1 -1
  214. package/node_modules/@comis/scheduler/dist/execution/execution-lock.d.ts +13 -0
  215. package/node_modules/@comis/scheduler/dist/execution/execution-lock.js +1 -1
  216. package/node_modules/@comis/scheduler/dist/execution/index.d.ts +2 -0
  217. package/node_modules/@comis/scheduler/dist/execution/index.js +2 -0
  218. package/node_modules/@comis/scheduler/dist/heartbeat/agent-heartbeat-source.js +1 -1
  219. package/node_modules/@comis/scheduler/dist/index.d.ts +2 -0
  220. package/node_modules/@comis/scheduler/dist/index.js +2 -0
  221. package/node_modules/@comis/scheduler/package.json +1 -1
  222. package/node_modules/@comis/shared/package.json +1 -1
  223. package/node_modules/@comis/skills/dist/bridge/schema-validator.d.ts +38 -0
  224. package/node_modules/@comis/skills/dist/bridge/schema-validator.js +169 -0
  225. package/node_modules/@comis/skills/dist/bridge/tool-metadata-enforcement.js +12 -0
  226. package/node_modules/@comis/skills/dist/bridge/tool-metadata-registry.js +130 -0
  227. package/node_modules/@comis/skills/dist/builtin/exec-diagnostics.d.ts +32 -0
  228. package/node_modules/@comis/skills/dist/builtin/exec-diagnostics.js +127 -0
  229. package/node_modules/@comis/skills/dist/builtin/exec-security.js +38 -0
  230. package/node_modules/@comis/skills/dist/builtin/exec-tool.js +9 -0
  231. package/node_modules/@comis/skills/dist/builtin/file-tools/grep-tool.js +6 -6
  232. package/node_modules/@comis/skills/dist/builtin/platform/agents-manage-tool.d.ts +5 -4
  233. package/node_modules/@comis/skills/dist/builtin/platform/agents-manage-tool.js +38 -27
  234. package/node_modules/@comis/skills/dist/builtin/platform/background-tasks-tool.d.ts +4 -1
  235. package/node_modules/@comis/skills/dist/builtin/platform/background-tasks-tool.js +3 -3
  236. package/node_modules/@comis/skills/dist/builtin/platform/cron-tool.js +1 -1
  237. package/node_modules/@comis/skills/dist/builtin/platform/gateway-tool.js +6 -6
  238. package/node_modules/@comis/skills/dist/builtin/platform/mcp-manage-tool.d.ts +1 -1
  239. package/node_modules/@comis/skills/dist/builtin/platform/mcp-manage-tool.js +9 -9
  240. package/node_modules/@comis/skills/dist/builtin/sandbox/bwrap-provider.d.ts +11 -0
  241. package/node_modules/@comis/skills/dist/builtin/sandbox/bwrap-provider.js +114 -1
  242. package/node_modules/@comis/skills/dist/builtin/sandbox/detect-provider.js +40 -15
  243. package/node_modules/@comis/skills/dist/media/ssrf-fetcher.d.ts +7 -0
  244. package/node_modules/@comis/skills/dist/media/ssrf-fetcher.js +9 -2
  245. package/node_modules/@comis/skills/package.json +1 -1
  246. package/node_modules/@comis/web/dist/assets/{agent-detail-71BSbSfD.js → agent-detail-q8t1NB7w.js} +1 -1
  247. package/node_modules/@comis/web/dist/assets/{agent-editor-CTSDZhwT.js → agent-editor-B46io5gv.js} +1 -1
  248. package/node_modules/@comis/web/dist/assets/{agent-list-BEhni2ea.js → agent-list-DQ6g2Rcx.js} +1 -1
  249. package/node_modules/@comis/web/dist/assets/{billing-view-DVP1IvVs.js → billing-view-IWPR8LgF.js} +1 -1
  250. package/node_modules/@comis/web/dist/assets/{channel-detail-N_YK74xC.js → channel-detail-DlNNZuuC.js} +1 -1
  251. package/node_modules/@comis/web/dist/assets/{channel-list-DRk6ZJaF.js → channel-list-DhGwxiMc.js} +1 -1
  252. package/node_modules/@comis/web/dist/assets/{chat-console-Dm-GtSf9.js → chat-console-Nv6fM3Rc.js} +1 -1
  253. package/node_modules/@comis/web/dist/assets/{config-editor-CIferYX6.js → config-editor-BYKuJF76.js} +1 -1
  254. package/node_modules/@comis/web/dist/assets/{context-dag-browser-CL84rXXM.js → context-dag-browser-ClNEtzYE.js} +1 -1
  255. package/node_modules/@comis/web/dist/assets/{context-engine-B1HOTEZv.js → context-engine-BZJ6HChd.js} +1 -1
  256. package/node_modules/@comis/web/dist/assets/{delivery-view-Y6JKYVFw.js → delivery-view-Cb7I3vGu.js} +1 -1
  257. package/node_modules/@comis/web/dist/assets/{diagnostics-view-DWV1UQjz.js → diagnostics-view-9u9Lyu5a.js} +1 -1
  258. package/node_modules/@comis/web/dist/assets/{ic-chat-message-DfSERzzg.js → ic-chat-message-BFt3cVpx.js} +1 -1
  259. package/node_modules/@comis/web/dist/assets/{ic-connection-dot-CXyhlJup.js → ic-connection-dot-y77LZ3Gu.js} +1 -1
  260. package/node_modules/@comis/web/dist/assets/{ic-tool-call-DNmwTjek.js → ic-tool-call-qt6w1NQl.js} +1 -1
  261. package/node_modules/@comis/web/dist/assets/{index-CBr0Tm9_.js → index-8Tg9oc-C.js} +2 -2
  262. package/node_modules/@comis/web/dist/assets/{mcp-management-BaH2-vox.js → mcp-management-69dtH_kY.js} +2 -2
  263. package/node_modules/@comis/web/dist/assets/{media-config-CZLshJoN.js → media-config-BdjLj5c1.js} +1 -1
  264. package/node_modules/@comis/web/dist/assets/{media-test-C9NUWgo_.js → media-test-DuPqrixi.js} +1 -1
  265. package/node_modules/@comis/web/dist/assets/{memory-inspector-D_fmTcRN.js → memory-inspector-B-Pepbq-.js} +1 -1
  266. package/node_modules/@comis/web/dist/assets/{message-center-BBFlNCZn.js → message-center-B7l0yNYY.js} +1 -1
  267. package/node_modules/@comis/web/dist/assets/{models-BytGLm99.js → models-JHFHuv5S.js} +1 -1
  268. package/node_modules/@comis/web/dist/assets/{observe-view-VXtHqaqq.js → observe-view-r8mqhy4O.js} +1 -1
  269. package/node_modules/@comis/web/dist/assets/{pipeline-builder-CfXczlfJ.js → pipeline-builder-XjkiZRcR.js} +1 -1
  270. package/node_modules/@comis/web/dist/assets/{pipeline-history-CPmXFnbe.js → pipeline-history-CZqJv_Hj.js} +1 -1
  271. package/node_modules/@comis/web/dist/assets/{pipeline-history-detail-DcueTMs9.js → pipeline-history-detail-BEFGMoDy.js} +1 -1
  272. package/node_modules/@comis/web/dist/assets/{pipeline-list-B-xG5WZh.js → pipeline-list-B6q5LvO1.js} +1 -1
  273. package/node_modules/@comis/web/dist/assets/{pipeline-monitor-pnIOYaSY.js → pipeline-monitor-BNomXjVL.js} +1 -1
  274. package/node_modules/@comis/web/dist/assets/{scheduler-BtUIFHhA.js → scheduler-BJEjcGKA.js} +1 -1
  275. package/node_modules/@comis/web/dist/assets/{security-C8mWRq2y.js → security-2G1jhBfV.js} +1 -1
  276. package/node_modules/@comis/web/dist/assets/{session-detail-DgdkO5ka.js → session-detail-DmVPzFBR.js} +1 -1
  277. package/node_modules/@comis/web/dist/assets/{session-list-DcylcfTn.js → session-list-CsqMQoHs.js} +1 -1
  278. package/node_modules/@comis/web/dist/assets/{setup-wizard-BP5yjsuL.js → setup-wizard-CAdM-gSP.js} +1 -1
  279. package/node_modules/@comis/web/dist/assets/{skills-DXt1bX8Z.js → skills-2ODqKaWr.js} +1 -1
  280. package/node_modules/@comis/web/dist/assets/{subagents-C7YbUHXY.js → subagents-BFlwfTbD.js} +1 -1
  281. package/node_modules/@comis/web/dist/assets/{workspace-manager-DP6pW4wa.js → workspace-manager--CbOx_dI.js} +1 -1
  282. package/node_modules/@comis/web/dist/index.html +1 -1
  283. package/node_modules/@comis/web/package.json +1 -1
  284. package/package.json +17 -16
@@ -17,6 +17,17 @@
17
17
  */
18
18
  import { updateState, sectionSeparator, info, validateApiKey, getKeyPrefix, } from "../index.js";
19
19
  import { getModels } from "@mariozechner/pi-ai";
20
+ // ---- OAuth interactive-flow imports ----
21
+ // CLI cannot import from packages/daemon (dep-direction); the OAuth
22
+ // runner + selector + remote-env detector live in @comis/agent
23
+ // (selectOAuthCredentialStore lives there). The browser opener is the
24
+ // `open` package (exact-pinned in @comis/cli per CLAUDE.md
25
+ // supply-chain invariants).
26
+ import { homedir } from "node:os";
27
+ import open from "open";
28
+ import { loginOpenAICodexOAuth, isRemoteEnvironment, selectOAuthCredentialStore, redactEmailForLog, } from "@comis/agent";
29
+ import { loadConfigFile, validateConfig, safePath, } from "@comis/core";
30
+ import { createLogger } from "@comis/infra";
20
31
  // ---------- Provider Help URLs ----------
21
32
  const PROVIDER_HELP_URLS = {
22
33
  anthropic: "https://console.anthropic.com/settings/keys",
@@ -31,7 +42,13 @@ const PROVIDER_HELP_URLS = {
31
42
  openrouter: "https://openrouter.ai/settings/keys",
32
43
  };
33
44
  // ---------- Auth Method Options ----------
34
- /** Providers that offer an OAuth token alternative to API keys. */
45
+ /**
46
+ * Providers that offer an OAuth token alternative to API keys.
47
+ *
48
+ * openai is API-key-only -- OAuth lives exclusively on the separate
49
+ * `openai-codex` provider id (which has its own dedicated branch with
50
+ * a method picker). Only anthropic remains here.
51
+ */
35
52
  const AUTH_METHOD_PROVIDERS = {
36
53
  anthropic: {
37
54
  options: [
@@ -47,20 +64,6 @@ const AUTH_METHOD_PROVIDERS = {
47
64
  oauth: "Generate with: claude setup-token",
48
65
  },
49
66
  },
50
- openai: {
51
- options: [
52
- { value: "apikey", label: "API Key", hint: "sk-..." },
53
- { value: "oauth", label: "OAuth Token", hint: "From OAuth app flow" },
54
- ],
55
- helpUrls: {
56
- apikey: "https://platform.openai.com/api-keys",
57
- oauth: null,
58
- },
59
- helpNotes: {
60
- apikey: null,
61
- oauth: "Use the token from your OAuth application flow.",
62
- },
63
- },
64
67
  };
65
68
  // ---------- Provider Validation Endpoints ----------
66
69
  /**
@@ -79,14 +82,6 @@ const AUTH_METHOD_PROVIDERS = {
79
82
  * https://generativelanguage.googleapis.com/v1beta/models,
80
83
  * https://api.groq.com/openai/v1/models).
81
84
  *
82
- * Follow-up to 260501-kqq Sub-Fix C: that migration replaced the static
83
- * PROVIDER_VALIDATION map (which had host-only baseUrls + correct /v1/models
84
- * suffixes) with the catalog-driven `getValidationEndpoint` helper, but the
85
- * path-table values were copied verbatim -- producing double-prefixed URLs
86
- * (e.g., https://api.openai.com/v1/v1/models -> 404) for the 6 providers
87
- * whose catalog baseUrl includes the version segment. 260501-mvw corrects
88
- * the table; the helper itself is unchanged.
89
- *
90
85
  * Drift risk: if pi-ai upgrades a provider's baseUrl AND its path convention
91
86
  * changes, this table must be updated. Acceptable trade-off -- explicit
92
87
  * beats clever (auto-detection of duplicated path segments could mask
@@ -95,10 +90,9 @@ const AUTH_METHOD_PROVIDERS = {
95
90
  * Excluded: `together` and `ollama` are NOT in pi-ai 0.71.0's catalog
96
91
  * (`getModels(p)[0]?.baseUrl` returns undefined for both). The line-130
97
92
  * fallback (`if (!entry) return { valid: true };`) handles them by
98
- * skipping live validation entirely. For `together` this is a deliberate
99
- * behavior change vs the pre-260501-kqq state -- live validation against
100
- * api.together.xyz is now skipped. Users can still target Together via
101
- * the synthetic `custom` endpoint route.
93
+ * skipping live validation entirely. Live validation against
94
+ * api.together.xyz is skipped; users can still target Together via the
95
+ * synthetic `custom` endpoint route.
102
96
  */
103
97
  const PROVIDER_VALIDATION_PATHS = {
104
98
  // Catalog baseUrl is HOST-ONLY for these providers -> path needs the /v1 prefix.
@@ -117,8 +111,8 @@ const PROVIDER_VALIDATION_PATHS = {
117
111
  };
118
112
  /**
119
113
  * Resolve the validation endpoint for a provider by reading the catalog
120
- * baseUrl from pi-ai (260501-gyy precedent: builtin-provider-guard.ts:45)
121
- * and combining it with a known path from PROVIDER_VALIDATION_PATHS.
114
+ * baseUrl from pi-ai (precedent: builtin-provider-guard.ts:45) and
115
+ * combining it with a known path from PROVIDER_VALIDATION_PATHS.
122
116
  *
123
117
  * Returns `undefined` for providers not in the catalog (or providers
124
118
  * with no models, e.g., ollama with no remote endpoint) -- callers
@@ -257,16 +251,24 @@ async function handleCustomEndpoint(state, prompter) {
257
251
  }
258
252
  /**
259
253
  * Branch C: Standard provider -- help URL, format pre-check, live validation, retry loop.
254
+ *
255
+ * Accepts an optional `preResolvedAuthMethod` parameter so the
256
+ * dispatcher (credentialsStep.execute) can hoist the auth-method select
257
+ * BEFORE deciding which branch handler to run. When set, the internal
258
+ * select is skipped — preventing a double-prompt for AUTH_METHOD_PROVIDERS
259
+ * entries. When undefined, the internal select runs.
260
260
  */
261
- async function handleStandardProvider(state, prompter, providerId) {
261
+ async function handleStandardProvider(state, prompter, providerId, preResolvedAuthMethod) {
262
262
  // Auth method selection for providers that support OAuth
263
- let authMethod;
263
+ let authMethod = preResolvedAuthMethod;
264
264
  const authConfig = AUTH_METHOD_PROVIDERS[providerId];
265
- if (authConfig) {
265
+ if (authConfig && authMethod === undefined) {
266
266
  authMethod = await prompter.select({
267
267
  message: `${providerId} authentication method`,
268
268
  options: authConfig.options,
269
269
  });
270
+ }
271
+ if (authConfig) {
270
272
  // Show help URL or note based on auth method
271
273
  const helpUrl = authConfig.helpUrls[authMethod];
272
274
  const helpNote = authConfig.helpNotes[authMethod];
@@ -357,6 +359,172 @@ async function handleStandardProvider(state, prompter, providerId) {
357
359
  // but handle gracefully
358
360
  return state;
359
361
  }
362
+ // ---------- Branch D: openai-codex OAuth ----------
363
+ const wizardLogger = createLogger({ name: "wizard-oauth" });
364
+ /**
365
+ * Open the OAuth credential store from the current config (mirrors the
366
+ * helper installed in `auth.ts`). Defaults to file storage when config
367
+ * is absent or doesn't set `oauth.storage`. Encrypted-mode CLI wiring
368
+ * requires SECRETS_MASTER_KEY + secretsDb — if `storage='encrypted'`,
369
+ * the wizard surfaces a fail-fast error (operator can switch to file mode
370
+ * for the wizard, then back to encrypted after).
371
+ */
372
+ async function openWizardOAuthStore() {
373
+ const dataDir = safePath(homedir(), ".comis");
374
+ // eslint-disable-next-line no-restricted-syntax -- CLI bootstrap before SecretManager (matches doctor.ts:45 / health.ts:43 precedent)
375
+ const envPaths = process.env["COMIS_CONFIG_PATHS"];
376
+ const configPath = envPaths?.split(":")[0] ??
377
+ safePath(homedir(), ".comis", "config.yaml");
378
+ const loadResult = loadConfigFile(configPath);
379
+ if (!loadResult.ok) {
380
+ return selectOAuthCredentialStore({ storage: "file", dataDir });
381
+ }
382
+ const validated = validateConfig(loadResult.value);
383
+ if (!validated.ok) {
384
+ return selectOAuthCredentialStore({ storage: "file", dataDir });
385
+ }
386
+ const storage = validated.value.oauth?.storage ?? "file";
387
+ if (storage === "encrypted") {
388
+ throw new Error("OAuth storage mode is 'encrypted' but the wizard cannot bootstrap the encrypted store. " +
389
+ "Hint: set appConfig.oauth.storage to 'file' temporarily for the wizard, or run " +
390
+ "`comis auth login --provider openai-codex` from a shell where SECRETS_MASTER_KEY is exported.");
391
+ }
392
+ return selectOAuthCredentialStore({ storage: "file", dataDir });
393
+ }
394
+ /**
395
+ * Branch D: openai-codex OAuth — interactive method picker + runner dispatch.
396
+ *
397
+ * Surfaces the runner's three login methods (browser auto-open, browser
398
+ * manual paste, device-code) plus a "skip for now" escape hatch. OAuth
399
+ * lives on its own provider id so the openai (API-key) flow is
400
+ * straight-through.
401
+ *
402
+ * On runner success: writes the profile to the OAuth store AND updates
403
+ * wizard state with apiKey + oauthProfileId + validated=true. The matching
404
+ * `oauthProfiles` config emission in step 10 wires the daemon to resolve
405
+ * this identity for openai-codex calls.
406
+ *
407
+ * On "skip for now": leaves the wizard advancing with provider.id set but
408
+ * validated=false; logs the literal hint pointing to `comis auth login`.
409
+ */
410
+ async function handleCodexOAuth(state, prompter) {
411
+ const isRemoteDefault = isRemoteEnvironment({ env: process.env });
412
+ const maxRetries = 3;
413
+ // Inline helpNote -- AUTH_METHOD_PROVIDERS no longer has an openai entry,
414
+ // so we cannot pull the note from the map. Keep the wording user-facing
415
+ // and explicit about what the picker will do.
416
+ prompter.note(info("OpenAI Codex uses your ChatGPT/Codex subscription -- no API key needed. Choose how you want to sign in."), "openai-codex OAuth");
417
+ const methodChoice = await prompter.select({
418
+ message: "How do you want to sign in?",
419
+ options: [
420
+ { value: "browser-auto", label: "Browser (auto-open)", hint: "Local desktop, opens default browser" },
421
+ { value: "browser-manual", label: "Browser (manual paste)", hint: "VPS, you paste callback URL after sign-in" },
422
+ { value: "device-code", label: "Device code (phone)", hint: "SSH/headless, type a short code on a phone" },
423
+ { value: "skip", label: "Skip for now", hint: "finish wizard, run `comis auth login` later" },
424
+ ],
425
+ initialValue: isRemoteDefault ? "device-code" : "browser-auto",
426
+ });
427
+ if (methodChoice === "skip") {
428
+ prompter.log.info("Skipped OAuth -- run `comis auth login --provider openai-codex` before starting the daemon.");
429
+ return updateState(state, {
430
+ provider: { id: "openai-codex", validated: false },
431
+ });
432
+ }
433
+ // Compute runner params from the method choice. The runner ignores
434
+ // isRemote when method === "device-code" but we still pass the detected
435
+ // value for log fidelity. browser-manual forces isRemote=true so the
436
+ // manual-paste handlers run regardless of detection.
437
+ let method;
438
+ let isRemote;
439
+ switch (methodChoice) {
440
+ case "browser-auto":
441
+ method = "browser";
442
+ isRemote = false;
443
+ break;
444
+ case "browser-manual":
445
+ method = "browser";
446
+ isRemote = true;
447
+ break;
448
+ case "device-code":
449
+ method = "device-code";
450
+ isRemote = isRemoteDefault;
451
+ break;
452
+ }
453
+ let store;
454
+ try {
455
+ store = await openWizardOAuthStore();
456
+ }
457
+ catch (err) {
458
+ const msg = err instanceof Error ? err.message : String(err);
459
+ prompter.log.error(msg);
460
+ return state;
461
+ }
462
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
463
+ const result = await loginOpenAICodexOAuth({
464
+ prompter,
465
+ isRemote,
466
+ openUrl: open,
467
+ logger: wizardLogger,
468
+ method,
469
+ });
470
+ if (result.ok) {
471
+ const v = result.value;
472
+ const profile = {
473
+ provider: "openai-codex",
474
+ profileId: v.profileId,
475
+ access: v.access,
476
+ refresh: v.refresh,
477
+ expires: v.expires,
478
+ accountId: v.accountId,
479
+ email: v.email,
480
+ displayName: v.displayName,
481
+ version: 1,
482
+ };
483
+ const writeResult = await store.set(v.profileId, profile);
484
+ if (!writeResult.ok) {
485
+ prompter.log.error(`Failed to persist OAuth profile: ${writeResult.error.message}`);
486
+ if (attempt === maxRetries)
487
+ return state;
488
+ continue;
489
+ }
490
+ wizardLogger.info({
491
+ provider: "openai-codex",
492
+ profileId: v.profileId,
493
+ identity: redactEmailForLog(v.email) ?? `id-${v.accountId ?? "<unknown>"}`,
494
+ action: "wizard-login",
495
+ submodule: "wizard-oauth",
496
+ }, "OAuth profile written by wizard");
497
+ return updateState(state, {
498
+ provider: {
499
+ id: "openai-codex",
500
+ authMethod: "oauth",
501
+ apiKey: v.access,
502
+ oauthProfileId: v.profileId,
503
+ validated: true,
504
+ },
505
+ });
506
+ }
507
+ // Failure path -- surface the rewritten error + recovery options.
508
+ prompter.log.warn(result.error.message);
509
+ if (result.error.hint)
510
+ prompter.log.info(result.error.hint);
511
+ const isLastAttempt = attempt === maxRetries;
512
+ const recoveryOptions = isLastAttempt
513
+ ? [{ value: "skip", label: "Skip provider setup" }]
514
+ : [
515
+ { value: "retry", label: "Try again" },
516
+ { value: "skip", label: "Skip provider setup" },
517
+ ];
518
+ const choice = await prompter.select({
519
+ message: "What would you like to do?",
520
+ options: recoveryOptions,
521
+ });
522
+ if (choice === "skip")
523
+ return state;
524
+ // choice === "retry" -> continue loop
525
+ }
526
+ return state;
527
+ }
360
528
  // ---------- Step Implementation ----------
361
529
  export const credentialsStep = {
362
530
  id: "credentials",
@@ -376,7 +544,28 @@ export const credentialsStep = {
376
544
  if (providerId === "custom") {
377
545
  return handleCustomEndpoint(state, prompter);
378
546
  }
379
- // Branch C: Standard provider
380
- return handleStandardProvider(state, prompter, providerId);
547
+ // Branch D: openai-codex OAuth -- dedicated method picker
548
+ // dispatching to loginOpenAICodexOAuth. Kept ABOVE the auth-method
549
+ // hoist so openai-codex never sees the apikey/oauth select prompt.
550
+ if (providerId === "openai-codex") {
551
+ return handleCodexOAuth(state, prompter);
552
+ }
553
+ // Hoisted auth-method select runs UP FRONT for providers in
554
+ // AUTH_METHOD_PROVIDERS so the dispatcher can branch on the chosen
555
+ // method before handleStandardProvider runs. Only anthropic remains
556
+ // in the map -- openai is API-key-only.
557
+ let authMethod;
558
+ // eslint-disable-next-line security/detect-object-injection -- read of static const map indexed by validated provider string
559
+ const authConfig = AUTH_METHOD_PROVIDERS[providerId];
560
+ if (authConfig) {
561
+ authMethod = await prompter.select({
562
+ message: `${providerId} authentication method`,
563
+ options: authConfig.options,
564
+ });
565
+ }
566
+ // Branch C: Standard provider -- pass the hoisted authMethod so the
567
+ // handler doesn't double-prompt. Anthropic OAuth still flows through
568
+ // here for the existing claude setup-token paste path.
569
+ return handleStandardProvider(state, prompter, providerId, authMethod);
381
570
  },
382
571
  };
@@ -25,6 +25,10 @@ function getDefaultModel(provider) {
25
25
  const defaults = {
26
26
  anthropic: "claude-sonnet-4-5-20250929",
27
27
  openai: "gpt-4o",
28
+ // pi-ai catalog's first entry for openai-codex (verified via
29
+ // getModels("openai-codex")[0].id). If pi-ai shuffles its catalog,
30
+ // the daemon's runtime default kicks in (same path as unknown providers).
31
+ "openai-codex": "gpt-5.1",
28
32
  google: "gemini-2.0-flash",
29
33
  groq: "llama-3.3-70b-versatile",
30
34
  ollama: "llama3",
@@ -55,6 +59,16 @@ function buildConfigObject(state) {
55
59
  if (state.provider?.compatMode) {
56
60
  agentConfig.compatMode = state.provider.compatMode;
57
61
  }
62
+ // OAuth profile wiring -- when handleCodexOAuth (step 04) produced a
63
+ // profile, emit it onto the agent so the daemon resolves the right
64
+ // identity for this provider's LLM calls. PerAgentConfigSchema accepts
65
+ // oauthProfiles as Record<provider, profileId> with the literal
66
+ // <provider>:<identity> format already validated at runner time.
67
+ if (state.provider?.oauthProfileId && state.provider?.id) {
68
+ agentConfig.oauthProfiles = {
69
+ [state.provider.id]: state.provider.oauthProfileId,
70
+ };
71
+ }
58
72
  // Elevated reply (sender trust map)
59
73
  if (state.senderTrustEntries && state.senderTrustEntries.length > 0) {
60
74
  const senderTrustMap = {};
@@ -438,9 +438,9 @@ export const daemonStartStep = {
438
438
  dockerSpinner.start("Signalling container daemon to restart...");
439
439
  const targetPid = await findContainerDaemonPid();
440
440
  if (targetPid) {
441
- // 260428-qrn: Prime the user BEFORE the SIGTERM so they have a
442
- // breadcrumb pointing at the missing `--restart unless-stopped`
443
- // flag. This is a heads-up, not an abort -- the existing
441
+ // Prime the user BEFORE the SIGTERM so they have a breadcrumb
442
+ // pointing at the missing `--restart unless-stopped` flag.
443
+ // This is a heads-up, not an abort -- the existing
444
444
  // waitForRestart detector still handles the failure path below.
445
445
  prompter.log.warn("Restarting daemon via SIGTERM. The container must have been started with `--restart unless-stopped` (or equivalent compose `restart: unless-stopped`). If the container exits and stays exited, run `docker restart <container-name>` from your host.");
446
446
  try {
@@ -79,6 +79,13 @@ export type ProviderConfig = {
79
79
  customEndpoint?: string;
80
80
  compatMode?: "openai" | "anthropic";
81
81
  validated?: boolean;
82
+ /**
83
+ * Set when authMethod === "oauth" and the interactive
84
+ * loginOpenAICodexOAuth flow succeeded. Carries the canonical
85
+ * `<provider>:<identity>` profile-store key so downstream consumers
86
+ * (multi-account selection) can locate the persisted profile.
87
+ */
88
+ oauthProfileId?: string;
82
89
  };
83
90
  /**
84
91
  * Immutable state accumulator for the wizard.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@comis/cli",
3
3
  "private": true,
4
- "version": "1.0.34",
4
+ "version": "1.0.36",
5
5
  "author": "Moshe Anconina",
6
6
  "license": "Apache-2.0",
7
7
  "description": "Command-line interface for the Comis AI agent platform",
@@ -16,7 +16,7 @@ export interface BootstrapOptions {
16
16
  /**
17
17
  * The application dependency container.
18
18
  *
19
- * Created by bootstrap(), this wires all Phase 1 services together
19
+ * Created by bootstrap(), this wires all services together
20
20
  * and provides a single shutdown() method for graceful cleanup.
21
21
  */
22
22
  export interface AppContainer {
@@ -35,6 +35,72 @@ export declare function substituteEnvVars(obj: unknown, getSecret: (key: string)
35
35
  * @returns Set of unique VAR_NAME strings referenced anywhere in the tree
36
36
  */
37
37
  export declare function extractReferencedSecretNames(obj: unknown): Set<string>;
38
+ /**
39
+ * A single unresolved env-var reference discovered while walking an object tree.
40
+ *
41
+ * `path` is the dot-notation location of the *string value* containing the
42
+ * reference (e.g. `"servers[0].env.FINNHUB_API_KEY"`), matching the path
43
+ * format used by `warnSuspiciousEnvValues`. `varName` is the name being
44
+ * referenced (e.g. `"FINNHUB_API_KEY"`).
45
+ *
46
+ * Two missing vars in the *same* string produce two entries with the *same*
47
+ * `path` but different `varName`s — accepted, deterministic, useful for
48
+ * downstream message formatting.
49
+ */
50
+ export interface UnresolvedEnvRef {
51
+ /** Dot-notation path to the string value that contains the reference. */
52
+ readonly path: string;
53
+ /** The referenced env var name (without `${}` braces). */
54
+ readonly varName: string;
55
+ }
56
+ /**
57
+ * Walk an object tree and return every `${VAR_NAME}` (or whole-string bare
58
+ * `$VAR_NAME`) reference whose name `getSecret` cannot resolve.
59
+ *
60
+ * Complement of `extractReferencedSecretNames`: that function returns *all*
61
+ * referenced names (used by exec's `secretRefs` policy); this function returns
62
+ * only the *unresolved* subset (used by daemon-side config-write validation
63
+ * gates — `config.patch` and `mcp.connect`).
64
+ *
65
+ * Resolution semantics mirror `substituteEnvVars`:
66
+ * - `getSecret` returning `undefined` → ref is missing (included in result).
67
+ * - `getSecret` returning `""` → ref is a valid empty value (NOT included).
68
+ * - `$${VAR}` escapes are literals, never refs (NOT included).
69
+ *
70
+ * Path format mirrors `warnSuspiciousEnvValues`: `parent.child[N].leaf`,
71
+ * with the dot prefix omitted at the root.
72
+ *
73
+ * The env-substitution skip on disabled MCP servers makes the
74
+ * `enabled:false + ${VAR}` placeholder pattern harmless at bootstrap; this
75
+ * helper lets the daemon's config-write paths reject `enabled:true + missing
76
+ * ${VAR}` *at write time* so it never reaches disk.
77
+ *
78
+ * @param obj - Object tree to scan.
79
+ * @param getSecret - Callback that returns the value for a given var name,
80
+ * or `undefined` if not in the secrets store.
81
+ * @returns Array of `{ path, varName }` entries for each unresolved ref.
82
+ * Empty when every ref resolves.
83
+ */
84
+ export declare function findUnresolvedEnvRefs(obj: unknown, getSecret: (key: string) => string | undefined): UnresolvedEnvRef[];
85
+ /**
86
+ * Build the structured `[invalid_value]` error string for an enabled MCP
87
+ * server whose `env` block references env vars not in the secrets store.
88
+ *
89
+ * Used identically by `config.patch` and `mcp.connect` to keep the agent-
90
+ * facing message in lockstep across the two RPC surfaces.
91
+ *
92
+ * Behavior:
93
+ * - `missingVarNames` is sorted lexicographically for deterministic output.
94
+ * - First 3 names are listed; if more, ` (+N more)` is appended.
95
+ * - Single-var case uses singular "env var"; multi-var uses plural "env vars".
96
+ * - Recovery option (1) `secrets_manage({action:"set", ...})` always names the
97
+ * FIRST missing var (alphabetical). Agents fix one at a time, then re-try.
98
+ *
99
+ * @param serverName - The MCP server name (`"<unnamed>"` if absent).
100
+ * @param missingVarNames - Names that `findUnresolvedEnvRefs` reported missing.
101
+ * @returns The exact `[invalid_value] ...` message.
102
+ */
103
+ export declare function formatMissingEnvRefError(serverName: string, missingVarNames: readonly string[]): string;
38
104
  /** A warning about a suspicious env value found during config validation. */
39
105
  export interface EnvValueWarning {
40
106
  /** Dot-notation path to the suspicious value (e.g., "integrations.mcp.servers[1].env.TAVILY_API_KEY"). */
@@ -207,6 +207,121 @@ function collectRefsFromString(input, out) {
207
207
  return "";
208
208
  });
209
209
  }
210
+ /**
211
+ * Walk an object tree and return every `${VAR_NAME}` (or whole-string bare
212
+ * `$VAR_NAME`) reference whose name `getSecret` cannot resolve.
213
+ *
214
+ * Complement of `extractReferencedSecretNames`: that function returns *all*
215
+ * referenced names (used by exec's `secretRefs` policy); this function returns
216
+ * only the *unresolved* subset (used by daemon-side config-write validation
217
+ * gates — `config.patch` and `mcp.connect`).
218
+ *
219
+ * Resolution semantics mirror `substituteEnvVars`:
220
+ * - `getSecret` returning `undefined` → ref is missing (included in result).
221
+ * - `getSecret` returning `""` → ref is a valid empty value (NOT included).
222
+ * - `$${VAR}` escapes are literals, never refs (NOT included).
223
+ *
224
+ * Path format mirrors `warnSuspiciousEnvValues`: `parent.child[N].leaf`,
225
+ * with the dot prefix omitted at the root.
226
+ *
227
+ * The env-substitution skip on disabled MCP servers makes the
228
+ * `enabled:false + ${VAR}` placeholder pattern harmless at bootstrap; this
229
+ * helper lets the daemon's config-write paths reject `enabled:true + missing
230
+ * ${VAR}` *at write time* so it never reaches disk.
231
+ *
232
+ * @param obj - Object tree to scan.
233
+ * @param getSecret - Callback that returns the value for a given var name,
234
+ * or `undefined` if not in the secrets store.
235
+ * @returns Array of `{ path, varName }` entries for each unresolved ref.
236
+ * Empty when every ref resolves.
237
+ */
238
+ export function findUnresolvedEnvRefs(obj, getSecret) {
239
+ const out = [];
240
+ scanForUnresolved(obj, "", getSecret, out);
241
+ return out;
242
+ }
243
+ function scanForUnresolved(value, path, getSecret, out) {
244
+ if (value === null || value === undefined)
245
+ return;
246
+ if (typeof value === "string") {
247
+ collectUnresolvedFromString(value, path, getSecret, out);
248
+ return;
249
+ }
250
+ if (Array.isArray(value)) {
251
+ for (let i = 0; i < value.length; i++) {
252
+ scanForUnresolved(value[i], `${path}[${i}]`, getSecret, out);
253
+ }
254
+ return;
255
+ }
256
+ if (typeof value === "object") {
257
+ const record = value;
258
+ for (const key of Object.keys(record)) {
259
+ const childPath = path ? `${path}.${key}` : key;
260
+ scanForUnresolved(record[key], childPath, getSecret, out);
261
+ }
262
+ }
263
+ }
264
+ /**
265
+ * Extract `${VAR}` and whole-string bare `$VAR` references from a single
266
+ * string and append `{ path, varName }` for each one whose value `getSecret`
267
+ * cannot resolve. Mirrors `collectRefsFromString` exactly so this helper and
268
+ * `extractReferencedSecretNames` agree on what counts as a reference.
269
+ */
270
+ function collectUnresolvedFromString(input, path, getSecret, out) {
271
+ // Whole-string bare reference first (mirrors substituteString step 0).
272
+ const bareMatch = input.match(BARE_VAR_PATTERN);
273
+ if (bareMatch) {
274
+ const varName = bareMatch[1];
275
+ if (getSecret(varName) === undefined) {
276
+ out.push({ path, varName });
277
+ }
278
+ return;
279
+ }
280
+ // Mask escapes so they don't match ENV_VAR_PATTERN. Same SENTINEL pattern
281
+ // as substituteString / collectRefsFromString for parity.
282
+ const SENTINEL = "\x00ESC_VAR\x00";
283
+ const working = input.replace(ESCAPED_VAR_PATTERN, () => `${SENTINEL}${SENTINEL}`);
284
+ working.replace(ENV_VAR_PATTERN, (_match, varName) => {
285
+ if (getSecret(varName) === undefined) {
286
+ out.push({ path, varName });
287
+ }
288
+ return "";
289
+ });
290
+ }
291
+ /**
292
+ * Build the structured `[invalid_value]` error string for an enabled MCP
293
+ * server whose `env` block references env vars not in the secrets store.
294
+ *
295
+ * Used identically by `config.patch` and `mcp.connect` to keep the agent-
296
+ * facing message in lockstep across the two RPC surfaces.
297
+ *
298
+ * Behavior:
299
+ * - `missingVarNames` is sorted lexicographically for deterministic output.
300
+ * - First 3 names are listed; if more, ` (+N more)` is appended.
301
+ * - Single-var case uses singular "env var"; multi-var uses plural "env vars".
302
+ * - Recovery option (1) `secrets_manage({action:"set", ...})` always names the
303
+ * FIRST missing var (alphabetical). Agents fix one at a time, then re-try.
304
+ *
305
+ * @param serverName - The MCP server name (`"<unnamed>"` if absent).
306
+ * @param missingVarNames - Names that `findUnresolvedEnvRefs` reported missing.
307
+ * @returns The exact `[invalid_value] ...` message.
308
+ */
309
+ export function formatMissingEnvRefError(serverName, missingVarNames) {
310
+ // Defensive copy + sort for determinism.
311
+ const sorted = [...missingVarNames].sort();
312
+ const visible = sorted.slice(0, 3);
313
+ const overflow = sorted.length - visible.length;
314
+ const overflowSuffix = overflow > 0 ? ` (+${overflow} more)` : "";
315
+ const isPlural = sorted.length > 1;
316
+ const subject = isPlural ? "env vars" : "env var";
317
+ const list = visible.join(", ") + overflowSuffix;
318
+ // Recovery option (1) references the first (alphabetical) missing var only.
319
+ const firstName = sorted[0] ?? "VAR_NAME";
320
+ return (`[invalid_value] enabled MCP server "${serverName}" references ${subject} ${list} which is not in the secrets store. Either:\n` +
321
+ ` 1) secrets_manage({action:"set", name:"${firstName}", value:"..."})\n` +
322
+ ` 2) Drop the env block from this server (omit the env field)\n` +
323
+ ` 3) Set enabled:false to defer until the secret is available`);
324
+ }
210
325
  /**
211
326
  * Scan an object tree for env-like string values that look suspicious —
212
327
  * bare `$VAR` references, placeholder strings like "[REDACTED]", or raw API keys.
@@ -30,6 +30,8 @@ export { IntegrationsConfigSchema, BraveSearchConfigSchema, McpServerEntrySchema
30
30
  export { MonitoringConfigSchema } from "./schema-observability.js";
31
31
  export { ObservabilityConfigSchema } from "./schema-observability.js";
32
32
  export type { ObservabilityConfig, ObservabilityPersistenceConfig } from "./schema-observability.js";
33
+ export { OAuthConfigSchema } from "./schema-oauth.js";
34
+ export type { OAuthConfig } from "./schema-oauth.js";
33
35
  export { PluginsConfigSchema, PluginEntrySchema } from "./schema-plugins.js";
34
36
  export { QueueConfigSchema, QueueModeSchema, OverflowPolicySchema, PerChannelQueueConfigSchema, OverflowConfigSchema, DebounceBufferConfigSchema, FollowupConfigSchema, PriorityLaneConfigSchema, LaneAssignmentConfigSchema, } from "./schema-queue.js";
35
37
  export { StreamingConfigSchema, PerChannelStreamingConfigSchema, TypingModeSchema, ChunkModeSchema, TableModeSchema, } from "./schema-streaming.js";
@@ -61,7 +63,7 @@ export { loadConfigFile, validateConfig } from "./loader.js";
61
63
  export type { ConfigLoadOptions } from "./loader.js";
62
64
  export { resolveIncludes, MAX_INCLUDE_DEPTH } from "./include-resolver.js";
63
65
  export type { IncludeResolverDeps } from "./include-resolver.js";
64
- export { substituteEnvVars, warnSuspiciousEnvValues, extractReferencedSecretNames, type EnvValueWarning } from "./env-substitution.js";
66
+ export { substituteEnvVars, warnSuspiciousEnvValues, extractReferencedSecretNames, findUnresolvedEnvRefs, formatMissingEnvRefError, type EnvValueWarning, type UnresolvedEnvRef, } from "./env-substitution.js";
65
67
  export { migrateConfig } from "./migrate.js";
66
68
  export { deepMerge, mergeLayered, loadLayered } from "./layered.js";
67
69
  export { IMMUTABLE_CONFIG_PREFIXES, MUTABLE_CONFIG_OVERRIDES, isImmutableConfigPath, matchesOverridePattern, getMutableOverridesForSection } from "./immutable-keys.js";
@@ -32,6 +32,7 @@ export { GatewayConfigSchema, GatewayTlsConfigSchema, GatewayTokenSchema, Gatewa
32
32
  export { IntegrationsConfigSchema, BraveSearchConfigSchema, McpServerEntrySchema, McpConfigSchema, TranscriptionConfigSchema, TtsConfigSchema, TtsAutoModeSchema, ElevenLabsVoiceSettingsSchema, TtsOutputFormatSchema, ImageAnalysisConfigSchema, VisionScopeRuleSchema, VisionConfigSchema, LinkUnderstandingConfigSchema, MediaInfraConfigSchema, MediaConfigSchema, AutoReplyRuleSchema, AutoReplyConfigSchema, DOCUMENT_MIME_WHITELIST, FileExtractionConfigSchema, MediaPersistenceConfigSchema, ImageGenerationConfigSchema, } from "./schema-integrations.js";
33
33
  export { MonitoringConfigSchema } from "./schema-observability.js";
34
34
  export { ObservabilityConfigSchema } from "./schema-observability.js";
35
+ export { OAuthConfigSchema } from "./schema-oauth.js";
35
36
  export { PluginsConfigSchema, PluginEntrySchema } from "./schema-plugins.js";
36
37
  export { QueueConfigSchema, QueueModeSchema, OverflowPolicySchema, PerChannelQueueConfigSchema, OverflowConfigSchema, DebounceBufferConfigSchema, FollowupConfigSchema, PriorityLaneConfigSchema, LaneAssignmentConfigSchema, } from "./schema-queue.js";
37
38
  export { StreamingConfigSchema, PerChannelStreamingConfigSchema, TypingModeSchema, ChunkModeSchema, TableModeSchema, } from "./schema-streaming.js";
@@ -51,7 +52,7 @@ export { loadConfigFile, validateConfig } from "./loader.js";
51
52
  // Include resolver ($include directive processing)
52
53
  export { resolveIncludes, MAX_INCLUDE_DEPTH } from "./include-resolver.js";
53
54
  // Environment variable substitution (${VAR} processing)
54
- export { substituteEnvVars, warnSuspiciousEnvValues, extractReferencedSecretNames } from "./env-substitution.js";
55
+ export { substituteEnvVars, warnSuspiciousEnvValues, extractReferencedSecretNames, findUnresolvedEnvRefs, formatMissingEnvRefError, } from "./env-substitution.js";
55
56
  // Config migration (legacy key transformation)
56
57
  export { migrateConfig } from "./migrate.js";
57
58
  // Layered merge