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
@@ -0,0 +1,141 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ /**
3
+ * OAuth identity extraction for Codex JWTs.
4
+ *
5
+ * Decodes the access-token JWT payload (no signature verification — pi-ai's
6
+ * token exchange validated the source) and resolves the canonical identity
7
+ * for use in profile IDs.
8
+ *
9
+ * Verbatim port of OpenClaw's openai-codex-auth-identity.ts
10
+ * plus the email-redaction helper.
11
+ *
12
+ * @module
13
+ */
14
+ const PROFILE_CLAIM_NS = "https://api.openai.com/profile";
15
+ function trimNonEmptyString(value) {
16
+ if (typeof value !== "string")
17
+ return undefined;
18
+ const trimmed = value.trim();
19
+ return trimmed.length === 0 ? undefined : trimmed;
20
+ }
21
+ /**
22
+ * Decode the payload segment of a JWT.
23
+ * Returns null on any malformed input (wrong segment count, bad base64url,
24
+ * invalid JSON, non-object payload). Returning null is a sentinel, not
25
+ * silent error swallowing.
26
+ */
27
+ export function decodeCodexJwtPayload(accessToken) {
28
+ if (typeof accessToken !== "string")
29
+ return null;
30
+ const parts = accessToken.split(".");
31
+ if (parts.length !== 3)
32
+ return null;
33
+ try {
34
+ const decoded = Buffer.from(parts[1] ?? "", "base64url").toString("utf8");
35
+ const parsed = JSON.parse(decoded);
36
+ if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
37
+ return parsed;
38
+ }
39
+ return null;
40
+ }
41
+ catch {
42
+ return null;
43
+ }
44
+ }
45
+ /**
46
+ * Resolve the canonical stable subject for fallback profile naming.
47
+ * Priority: chatgpt_account_user_id > chatgpt_user_id > user_id > iss|sub > sub.
48
+ */
49
+ export function resolveCodexStableSubject(payload) {
50
+ const candidates = [
51
+ trimNonEmptyString(payload.chatgpt_account_user_id),
52
+ trimNonEmptyString(payload.chatgpt_user_id),
53
+ trimNonEmptyString(payload.user_id),
54
+ (() => {
55
+ const iss = trimNonEmptyString(payload.iss);
56
+ const sub = trimNonEmptyString(payload.sub);
57
+ if (iss && sub)
58
+ return iss + "|" + sub;
59
+ return undefined;
60
+ })(),
61
+ trimNonEmptyString(payload.sub),
62
+ ];
63
+ for (const c of candidates)
64
+ if (c)
65
+ return c;
66
+ return undefined;
67
+ }
68
+ /**
69
+ * Resolve the canonical email + profileName for a Codex identity.
70
+ * Priority for email: explicit `opts.email` > JWT `https://api.openai.com/profile.email`.
71
+ * profileName = email when available, else `id-<base64url(stableSubject)>`.
72
+ */
73
+ export function resolveCodexAuthIdentity(opts) {
74
+ const explicit = trimNonEmptyString(opts.email);
75
+ const payload = decodeCodexJwtPayload(opts.accessToken);
76
+ let email = explicit;
77
+ if (!email && payload) {
78
+ // eslint-disable-next-line security/detect-object-injection -- PROFILE_CLAIM_NS is a literal module constant, not user input
79
+ const profile = payload[PROFILE_CLAIM_NS];
80
+ if (profile !== null && typeof profile === "object" && !Array.isArray(profile)) {
81
+ email = trimNonEmptyString(profile.email);
82
+ }
83
+ }
84
+ if (email)
85
+ return { email, profileName: email };
86
+ if (payload) {
87
+ const subject = resolveCodexStableSubject(payload);
88
+ if (subject) {
89
+ const subjectB64 = Buffer.from(subject, "utf8").toString("base64url");
90
+ return { email: undefined, profileName: "id-" + subjectB64 };
91
+ }
92
+ }
93
+ return { email: undefined, profileName: undefined };
94
+ }
95
+ /**
96
+ * Extract the access-token expiry as milliseconds since epoch.
97
+ * The JWT exp claim is in seconds (RFC 7519); we multiply by 1000 to match
98
+ * pi-ai's OAuthCredentials.expires unit (ms).
99
+ * Accepts numeric `exp` and digit-only string `exp`.
100
+ */
101
+ export function resolveCodexAccessTokenExpiry(accessToken) {
102
+ const payload = decodeCodexJwtPayload(accessToken);
103
+ if (!payload)
104
+ return undefined;
105
+ const expRaw = payload.exp;
106
+ let expSec;
107
+ if (typeof expRaw === "number" && Number.isFinite(expRaw)) {
108
+ expSec = expRaw;
109
+ }
110
+ else if (typeof expRaw === "string" && /^\d+$/.test(expRaw)) {
111
+ expSec = Number(expRaw);
112
+ }
113
+ if (expSec === undefined)
114
+ return undefined;
115
+ return expSec * 1000;
116
+ }
117
+ /**
118
+ * Semi-redact an email for safe inclusion in logs.
119
+ * Format: first 2 chars + ellipsis + last char of local-part, then "@" + full domain.
120
+ * Edge cases:
121
+ * - undefined input → undefined
122
+ * - input without "@" → returned unchanged
123
+ * - 1-char local-part → "…@<domain>"
124
+ * - 2-char local-part → "<first>…<last>@<domain>" (single char on each side)
125
+ */
126
+ export function redactEmailForLog(email) {
127
+ if (email === undefined)
128
+ return undefined;
129
+ const atIdx = email.indexOf("@");
130
+ if (atIdx < 0)
131
+ return email;
132
+ const local = email.slice(0, atIdx);
133
+ const domain = email.slice(atIdx + 1);
134
+ if (local.length === 0)
135
+ return email;
136
+ if (local.length === 1)
137
+ return "…@" + domain;
138
+ if (local.length === 2)
139
+ return local.charAt(0) + "…" + local.charAt(1) + "@" + domain;
140
+ return local.slice(0, 2) + "…" + local.charAt(local.length - 1) + "@" + domain;
141
+ }
@@ -0,0 +1,99 @@
1
+ /**
2
+ * OAuth login orchestrator for OpenAI Codex.
3
+ *
4
+ * Wraps pi-ai's loginOpenAICodex with VPS-aware handlers, manual-paste
5
+ * fallback (15s + 1s grace mirroring OpenClaw), and error rewriting for
6
+ * 2 user-friendly mappings (unsupported_region, callback_validation_failed)
7
+ * + 1 identity-decode error path. Returns Result<LoginRunnerSuccess, LoginError>
8
+ * per AGENTS.md §2.1 — never throws at the public boundary.
9
+ *
10
+ * Both the CLI (`comis auth login`) and wizard step 04 OpenAI OAuth branch
11
+ * import and call loginOpenAICodexOAuth — this is the single shared runner.
12
+ *
13
+ * Pi-ai (0.71.0) owns the protocol: PKCE generation, the local callback
14
+ * server (hardcoded 127.0.0.1:1455), the token exchange POST to
15
+ * https://auth.openai.com/oauth/token. This module owns the UX: browser-open
16
+ * vs manual-paste, fallback timing, error mapping, identity derivation via
17
+ * resolveCodexAuthIdentity.
18
+ *
19
+ * Logging discipline (CLAUDE.md): submodule: "oauth-login" on every call.
20
+ * NEVER log access tokens, refresh tokens, PKCE state, or callback `code`.
21
+ * Identity in success logs uses redactEmailForLog (semi-redacted).
22
+ *
23
+ * @module
24
+ */
25
+ import type { Result } from "@comis/shared";
26
+ import type { ComisLogger } from "@comis/infra";
27
+ /**
28
+ * Minimal prompter shape used by the runner. Defined locally — the runner
29
+ * cannot import WizardPrompter from @comis/cli (cli depends on agent, not
30
+ * the reverse — AGENTS.md §1 hexagonal architecture).
31
+ *
32
+ * Production: @comis/cli's WizardPrompter STRUCTURALLY satisfies this
33
+ * (TypeScript structural typing); the CLI passes its WizardPrompter
34
+ * instance directly. Test: build a small mock object with the required
35
+ * methods.
36
+ */
37
+ export interface RunnerPrompter {
38
+ text(opts: {
39
+ message: string;
40
+ placeholder?: string;
41
+ validate?: (value: string) => string | undefined;
42
+ }): Promise<string>;
43
+ spinner(): {
44
+ start(msg: string): void;
45
+ update(msg: string): void;
46
+ stop(msg: string): void;
47
+ };
48
+ log: {
49
+ info(msg: string): void;
50
+ warn(msg: string): void;
51
+ };
52
+ }
53
+ /** Inputs to the public loginOpenAICodexOAuth function. */
54
+ export interface LoginRunnerParams {
55
+ prompter: RunnerPrompter;
56
+ isRemote: boolean;
57
+ /**
58
+ * Browser opener — typically `import open from "open"` from the consumer.
59
+ * Stubbed in tests with a vi.fn that captures the URL. Returns
60
+ * Promise<unknown> because the `open` package returns Promise<ChildProcess>
61
+ * which the runner does not consume.
62
+ */
63
+ openUrl: (url: string) => Promise<unknown>;
64
+ /** Optional logger — callers without one get a no-op fallback. */
65
+ logger?: ComisLogger;
66
+ /**
67
+ * Login method. "browser" (default) uses pi-ai's loginOpenAICodex with
68
+ * local-callback-server + manual-paste fallback; "device-code" uses the
69
+ * OpenAI proprietary 3-step device-code flow (no clipboard, suitable for
70
+ * SSH sessions). Only "openai-codex" supports "device-code"; the CLI
71
+ * rejects other providers at parse time.
72
+ */
73
+ method?: "browser" | "device-code";
74
+ }
75
+ /** Error codes returned by the runner. */
76
+ export interface LoginError {
77
+ code: "unsupported_region" | "callback_validation_failed" | "callback_timeout" | "identity_decode_failed";
78
+ message: string;
79
+ hint: string;
80
+ }
81
+ /** Successful-login payload — caller persists this via OAuthCredentialStorePort. */
82
+ export interface LoginRunnerSuccess {
83
+ access: string;
84
+ refresh: string;
85
+ expires: number;
86
+ accountId?: string;
87
+ email?: string;
88
+ displayName?: string;
89
+ /** Canonical "openai-codex:<email>" or "openai-codex:id-<base64url>" form. */
90
+ profileId: string;
91
+ }
92
+ /**
93
+ * Run the interactive OAuth login for OpenAI Codex.
94
+ *
95
+ * Returns ok({access, refresh, expires, accountId?, email?, displayName?,
96
+ * profileId}) on success, err({code, message, hint}) on failure. NEVER
97
+ * throws — the caller pattern-matches on result.ok.
98
+ */
99
+ export declare function loginOpenAICodexOAuth(params: LoginRunnerParams): Promise<Result<LoginRunnerSuccess, LoginError>>;
@@ -0,0 +1,374 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ /**
3
+ * OAuth login orchestrator for OpenAI Codex.
4
+ *
5
+ * Wraps pi-ai's loginOpenAICodex with VPS-aware handlers, manual-paste
6
+ * fallback (15s + 1s grace mirroring OpenClaw), and error rewriting for
7
+ * 2 user-friendly mappings (unsupported_region, callback_validation_failed)
8
+ * + 1 identity-decode error path. Returns Result<LoginRunnerSuccess, LoginError>
9
+ * per AGENTS.md §2.1 — never throws at the public boundary.
10
+ *
11
+ * Both the CLI (`comis auth login`) and wizard step 04 OpenAI OAuth branch
12
+ * import and call loginOpenAICodexOAuth — this is the single shared runner.
13
+ *
14
+ * Pi-ai (0.71.0) owns the protocol: PKCE generation, the local callback
15
+ * server (hardcoded 127.0.0.1:1455), the token exchange POST to
16
+ * https://auth.openai.com/oauth/token. This module owns the UX: browser-open
17
+ * vs manual-paste, fallback timing, error mapping, identity derivation via
18
+ * resolveCodexAuthIdentity.
19
+ *
20
+ * Logging discipline (CLAUDE.md): submodule: "oauth-login" on every call.
21
+ * NEVER log access tokens, refresh tokens, PKCE state, or callback `code`.
22
+ * Identity in success logs uses redactEmailForLog (semi-redacted).
23
+ *
24
+ * @module
25
+ */
26
+ import { ok, err } from "@comis/shared";
27
+ import { loginOpenAICodex } from "@mariozechner/pi-ai/oauth";
28
+ import { resolveCodexAuthIdentity, redactEmailForLog, } from "./oauth-identity.js";
29
+ import { rewriteOAuthError } from "./oauth-errors.js";
30
+ import { loginOpenAICodexDeviceCode, } from "./oauth-device-code.js";
31
+ // ---------------------------------------------------------------------------
32
+ // Internal types + constants
33
+ // ---------------------------------------------------------------------------
34
+ const PROVIDER = "openai-codex";
35
+ const ORIGINATOR = "comis"; // NOT "openclaw"
36
+ /**
37
+ * Manual-paste fallback timing — exact mirror of OpenClaw's
38
+ * provider-openai-codex-oauth.ts:15-16 constants.
39
+ */
40
+ const localManualFallbackDelayMs = 15_000;
41
+ const localManualFallbackGraceMs = 1_000;
42
+ const validateRequiredInput = (value) => value.trim().length > 0 ? undefined : "Required";
43
+ // ---------------------------------------------------------------------------
44
+ // Internal: VPS-aware OAuth handlers (port from OpenClaw provider-oauth-flow.ts;
45
+ // replace runtime.log with prompter.log.info)
46
+ // ---------------------------------------------------------------------------
47
+ function createVpsAwareOAuthHandlers(params) {
48
+ const manualPromptMessage = params.manualPromptMessage ?? "Paste the redirect URL";
49
+ let manualCodePromise;
50
+ return {
51
+ onAuth: async ({ url }) => {
52
+ if (params.isRemote) {
53
+ params.spin.stop("OAuth URL ready");
54
+ // Use prompter.log.info, NOT prompter.note, mid-spinner (clack note
55
+ // tears apart spinner display).
56
+ params.prompter.log.info(`\nOpen this URL in your LOCAL browser:\n\n${url}\n`);
57
+ manualCodePromise = params.prompter.text({
58
+ message: manualPromptMessage,
59
+ validate: validateRequiredInput,
60
+ });
61
+ return;
62
+ }
63
+ params.spin.update(params.localBrowserMessage);
64
+ await params.openUrl(url);
65
+ params.prompter.log.info(`Open: ${url}`);
66
+ },
67
+ onPrompt: async (prompt) => {
68
+ if (manualCodePromise)
69
+ return manualCodePromise;
70
+ return params.prompter.text({
71
+ message: prompt.message,
72
+ placeholder: prompt.placeholder,
73
+ validate: validateRequiredInput,
74
+ });
75
+ },
76
+ };
77
+ }
78
+ // ---------------------------------------------------------------------------
79
+ // Internal: Manual-paste fallback race (port from OpenClaw
80
+ // provider-openai-codex-oauth.ts:15-131)
81
+ // ---------------------------------------------------------------------------
82
+ function waitForDelayOrLoginSettle(params) {
83
+ return new Promise((resolve) => {
84
+ let finished = false;
85
+ const finish = (outcome) => {
86
+ if (finished)
87
+ return;
88
+ finished = true;
89
+ clearTimeout(timeoutHandle);
90
+ resolve(outcome);
91
+ };
92
+ const timeoutHandle = setTimeout(() => finish("delay"), params.delayMs);
93
+ params.waitForLoginToSettle.then(() => finish("settled"), () => finish("settled"));
94
+ });
95
+ }
96
+ function createNeverSettlingPromptResult() {
97
+ return new Promise(() => undefined);
98
+ }
99
+ function createManualCodeInputHandler(params) {
100
+ if (params.isRemote) {
101
+ return async () => params.onPrompt({
102
+ message: "Paste the authorization code (or full redirect URL):",
103
+ });
104
+ }
105
+ return async () => {
106
+ if (!params.hasBrowserAuthStarted()) {
107
+ params.spin.update("Local OAuth callback was unavailable. Paste the redirect URL to continue…");
108
+ return params.onPrompt({
109
+ message: "Paste the authorization code (or full redirect URL):",
110
+ });
111
+ }
112
+ const outcome = await waitForDelayOrLoginSettle({
113
+ delayMs: localManualFallbackDelayMs,
114
+ waitForLoginToSettle: params.waitForLoginToSettle,
115
+ });
116
+ if (outcome === "settled")
117
+ return createNeverSettlingPromptResult();
118
+ const settledDuringGraceWindow = await waitForDelayOrLoginSettle({
119
+ delayMs: localManualFallbackGraceMs,
120
+ waitForLoginToSettle: params.waitForLoginToSettle,
121
+ });
122
+ if (settledDuringGraceWindow === "settled")
123
+ return createNeverSettlingPromptResult();
124
+ params.spin.update("Browser callback did not finish. Paste the redirect URL to continue…");
125
+ return params.onPrompt({
126
+ message: "Paste the authorization code (or full redirect URL):",
127
+ });
128
+ };
129
+ }
130
+ // ---------------------------------------------------------------------------
131
+ // Internal: Error rewriting — moved to ./oauth-errors.ts.
132
+ // The shared module exposes 6 cases (vs the 3 + default this runner originally
133
+ // shipped); the 2 new cases (invalid_grant, refresh_token_reused) only fire
134
+ // from the refresh path, never from interactive login. We narrow back to
135
+ // LoginError["code"] at the call sites via narrowToLoginError() below.
136
+ // ---------------------------------------------------------------------------
137
+ /**
138
+ * Narrow a (broader) `OAuthErrorCode` back to the 4-case `LoginError["code"]`
139
+ * union the runner promises at its public boundary. The login flow itself
140
+ * cannot produce `invalid_grant` or `refresh_token_reused` (those are
141
+ * refresh-only failures), but the shared classifier accepts both — coerce
142
+ * defensively to the timeout default. Exhaustive `switch` ensures any future
143
+ * `OAuthErrorCode` addition surfaces as a TypeScript compile error.
144
+ */
145
+ function narrowToLoginError(code) {
146
+ switch (code) {
147
+ case "unsupported_region":
148
+ case "callback_validation_failed":
149
+ case "callback_timeout":
150
+ case "identity_decode_failed":
151
+ return code;
152
+ case "invalid_grant":
153
+ case "refresh_token_reused":
154
+ // Login flow does not produce these (refresh-only failures); coerce.
155
+ return "callback_timeout";
156
+ }
157
+ }
158
+ // ---------------------------------------------------------------------------
159
+ // Public boundary
160
+ // ---------------------------------------------------------------------------
161
+ const NO_OP_LOGGER = {
162
+ info: () => undefined,
163
+ warn: () => undefined,
164
+ debug: () => undefined,
165
+ error: () => undefined,
166
+ trace: () => undefined,
167
+ fatal: () => undefined,
168
+ audit: () => undefined,
169
+ child: () => NO_OP_LOGGER,
170
+ };
171
+ /**
172
+ * Shared identity-derivation + LoginRunnerSuccess builder used by both
173
+ * the browser flow and the device-code flow. Extracted on the third
174
+ * caller per AGENTS.md §2.3 rule-of-three.
175
+ *
176
+ * Returns ok(success) on identity success; err(identity_decode_failed)
177
+ * when neither email nor profileName can be derived from the JWT.
178
+ *
179
+ * NEVER logs the access/refresh values — only the resulting identity
180
+ * (semi-redacted via redactEmailForLog) and durationMs.
181
+ */
182
+ function deriveLoginRunnerSuccess(creds, logger) {
183
+ const identity = resolveCodexAuthIdentity({ accessToken: creds.access });
184
+ const identityKey = identity.email ?? identity.profileName;
185
+ if (!identityKey) {
186
+ const rewritten = rewriteOAuthError(new Error("Failed to extract accountId from token"));
187
+ logger.warn({
188
+ provider: PROVIDER,
189
+ errorKind: rewritten.code,
190
+ hint: rewritten.hint,
191
+ submodule: "oauth-login",
192
+ }, "OAuth login failed — identity could not be derived");
193
+ return err({
194
+ code: narrowToLoginError(rewritten.code),
195
+ message: rewritten.userMessage,
196
+ hint: rewritten.hint,
197
+ });
198
+ }
199
+ const profileId = `${PROVIDER}:${identityKey}`;
200
+ const success = {
201
+ access: creds.access,
202
+ refresh: creds.refresh,
203
+ expires: creds.expires,
204
+ accountId: creds.accountId,
205
+ email: identity.email,
206
+ displayName: identity.profileName,
207
+ profileId,
208
+ };
209
+ return ok(success);
210
+ }
211
+ /**
212
+ * Run the interactive OAuth login for OpenAI Codex.
213
+ *
214
+ * Returns ok({access, refresh, expires, accountId?, email?, displayName?,
215
+ * profileId}) on success, err({code, message, hint}) on failure. NEVER
216
+ * throws — the caller pattern-matches on result.ok.
217
+ */
218
+ export async function loginOpenAICodexOAuth(params) {
219
+ const logger = params.logger ?? NO_OP_LOGGER;
220
+ const startedAt = Date.now();
221
+ // Device-code dispatch. Only "openai-codex" supports device-code today;
222
+ // the CLI rejects other providers at parse time.
223
+ if (params.method === "device-code") {
224
+ return loginOpenAICodexDeviceCodeRunner(params, logger);
225
+ }
226
+ logger.info({ provider: PROVIDER, isRemote: params.isRemote, submodule: "oauth-login" }, "OAuth login starting");
227
+ // Spinner lifecycle — start now; handlers update/stop it in their flow.
228
+ const spin = params.prompter.spinner();
229
+ spin.start(params.isRemote ? "Preparing OAuth URL..." : "Opening browser for OAuth...");
230
+ // Track whether the browser-callback path actually opened — feeds the
231
+ // manual-paste fallback's hasBrowserAuthStarted() check.
232
+ let hasBrowserAuthStarted = false;
233
+ let resolveLoginSettled;
234
+ const waitForLoginToSettle = new Promise((resolve) => {
235
+ resolveLoginSettled = resolve;
236
+ });
237
+ const handlers = createVpsAwareOAuthHandlers({
238
+ isRemote: params.isRemote,
239
+ prompter: params.prompter,
240
+ spin,
241
+ openUrl: params.openUrl,
242
+ localBrowserMessage: "Browser opened. Waiting for OAuth callback...",
243
+ });
244
+ // Wrap onAuth to flip hasBrowserAuthStarted in local mode.
245
+ const onAuth = async (event) => {
246
+ logger.debug({
247
+ submodule: "oauth-login",
248
+ // Log URL but redact the state param.
249
+ url: event.url.replace(/state=[^&]+/, "state=***"),
250
+ }, "OAuth authorize URL ready");
251
+ if (!params.isRemote)
252
+ hasBrowserAuthStarted = true;
253
+ return handlers.onAuth(event);
254
+ };
255
+ const onManualCodeInput = createManualCodeInputHandler({
256
+ isRemote: params.isRemote,
257
+ onPrompt: handlers.onPrompt,
258
+ spin,
259
+ waitForLoginToSettle,
260
+ hasBrowserAuthStarted: () => hasBrowserAuthStarted,
261
+ });
262
+ try {
263
+ const creds = await loginOpenAICodex({
264
+ onAuth,
265
+ onPrompt: handlers.onPrompt,
266
+ onManualCodeInput,
267
+ onProgress: (msg) => spin.update(msg),
268
+ originator: ORIGINATOR,
269
+ });
270
+ // Identity derivation via shared helper (rule-of-three: browser, device-code,
271
+ // device-code-on-failure all converge on this exact identity-derivation path).
272
+ const successResult = deriveLoginRunnerSuccess({
273
+ access: creds.access,
274
+ refresh: creds.refresh,
275
+ expires: creds.expires,
276
+ accountId: creds.accountId,
277
+ }, logger);
278
+ if (!successResult.ok) {
279
+ spin.stop("OAuth login failed");
280
+ resolveLoginSettled();
281
+ return successResult;
282
+ }
283
+ spin.stop("OAuth login complete");
284
+ logger.info({
285
+ provider: PROVIDER,
286
+ profileId: successResult.value.profileId,
287
+ durationMs: Date.now() - startedAt,
288
+ identity: redactEmailForLog(successResult.value.email) ??
289
+ successResult.value.displayName ??
290
+ `id-${creds.accountId ?? "<unknown>"}`,
291
+ submodule: "oauth-login",
292
+ }, "OAuth login complete");
293
+ resolveLoginSettled();
294
+ return successResult;
295
+ }
296
+ catch (caught) {
297
+ spin.stop("OAuth login failed");
298
+ const rewritten = rewriteOAuthError(caught);
299
+ logger.warn({
300
+ provider: PROVIDER,
301
+ errorKind: rewritten.code,
302
+ hint: rewritten.hint,
303
+ err: caught,
304
+ submodule: "oauth-login",
305
+ }, "OAuth login failed");
306
+ resolveLoginSettled();
307
+ return err({
308
+ code: narrowToLoginError(rewritten.code),
309
+ message: rewritten.userMessage,
310
+ hint: rewritten.hint,
311
+ });
312
+ }
313
+ }
314
+ /**
315
+ * Device-code login runner.
316
+ *
317
+ * Wraps loginOpenAICodexDeviceCode in the LoginRunnerSuccess shape so
318
+ * the CLI/wizard can pattern-match on the same result type regardless
319
+ * of method. Owns the spinner UX: start, transition on verification
320
+ * prompt, restart for polling, stop on completion.
321
+ *
322
+ * NEVER logs or surfaces tokens, userCode, or verifier values. Identity
323
+ * derivation reuses the shared deriveLoginRunnerSuccess helper.
324
+ */
325
+ async function loginOpenAICodexDeviceCodeRunner(params, logger) {
326
+ const startedAt = Date.now();
327
+ logger.info({
328
+ provider: PROVIDER,
329
+ isRemote: params.isRemote,
330
+ method: "device-code",
331
+ submodule: "oauth-login",
332
+ }, "Device-code OAuth login starting");
333
+ const spin = params.prompter.spinner();
334
+ spin.start("Requesting device code…");
335
+ const result = await loginOpenAICodexDeviceCode({
336
+ onVerification: (prompt) => {
337
+ spin.stop("Device code ready");
338
+ params.prompter.log.info("\nOpen this URL on any device (your phone, another desktop, etc.):\n\n" +
339
+ ` ${prompt.verificationUrl}\n\n` +
340
+ `Enter the code: ${prompt.userCode}\n\n` +
341
+ "(this code expires in 15 minutes)\n");
342
+ spin.start("Waiting for authorization (polling every 5s)…");
343
+ },
344
+ onProgress: (msg) => {
345
+ spin.update(msg);
346
+ },
347
+ });
348
+ if (!result.ok) {
349
+ spin.stop("OAuth login failed");
350
+ logger.warn({
351
+ provider: PROVIDER,
352
+ errorKind: result.error.code,
353
+ hint: result.error.hint,
354
+ submodule: "oauth-login",
355
+ }, "Device-code login failed");
356
+ return err(result.error);
357
+ }
358
+ const successResult = deriveLoginRunnerSuccess(result.value, logger);
359
+ if (!successResult.ok) {
360
+ spin.stop("OAuth login failed");
361
+ return successResult;
362
+ }
363
+ spin.stop("OAuth login complete");
364
+ logger.info({
365
+ provider: PROVIDER,
366
+ profileId: successResult.value.profileId,
367
+ durationMs: Date.now() - startedAt,
368
+ identity: redactEmailForLog(successResult.value.email) ??
369
+ successResult.value.displayName ??
370
+ "id-unknown",
371
+ submodule: "oauth-login",
372
+ }, "Device-code login complete");
373
+ return successResult;
374
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * OAuth TLS preflight for OpenAI Codex `auth.openai.com`.
3
+ *
4
+ * Issues a single 5-second `fetch` GET against the OAuth authorize endpoint
5
+ * and classifies failures as `tls-cert` (system CA bundle missing/broken;
6
+ * fixable via `apt install ca-certificates` etc.) or `network` (DNS,
7
+ * firewall, proxy — operator action required).
8
+ *
9
+ * Verbatim port of OpenClaw's provider-openai-codex-oauth-tls.ts minus the
10
+ * Homebrew prefix-resolution branch and minus the `note()` UI (caller decides
11
+ * how to surface the result; this module is pure).
12
+ *
13
+ * The probe URL uses the public OpenAI Codex client_id
14
+ * `app_EMoamEEZ73f0CkXaXp7hrann` (NOT a Comis-distinct value) to avoid
15
+ * fingerprinting in OpenAI logs.
16
+ *
17
+ * This module never logs — the caller is responsible for surfacing
18
+ * the result via Pino (daemon) or DoctorFinding (CLI). Per AGENTS.md §2.4
19
+ * no `@comis/infra` import.
20
+ *
21
+ * @module
22
+ */
23
+ /** Discriminator for non-OK preflight outcomes. */
24
+ export type TlsPreflightFailureKind = "tls-cert" | "network";
25
+ /**
26
+ * Discriminated union returned by runOAuthTlsPreflight.
27
+ *
28
+ * NOTE on Result<T,E> deviation: this shape predates AGENTS.md §2.1 in
29
+ * the OpenClaw port. Callers pattern-match on `.kind` for actionable
30
+ * routing, which is more ergonomic than `.error.kind`.
31
+ */
32
+ export type TlsPreflightResult = {
33
+ ok: true;
34
+ } | {
35
+ ok: false;
36
+ kind: TlsPreflightFailureKind;
37
+ /** OpenSSL error code when available (e.g. UNABLE_TO_GET_ISSUER_CERT_LOCALLY). */
38
+ code?: string;
39
+ /** Raw error string for log `err` field — safe to surface to operators. */
40
+ message: string;
41
+ };
42
+ /** Options for the preflight probe. */
43
+ export interface RunOAuthTlsPreflightOptions {
44
+ /** Defaults to 5000 ms (matches OpenClaw doctor variant; daemon-boot caller passes 4000). */
45
+ timeoutMs?: number;
46
+ /** Dependency-injected fetch — used by tests; defaults to globalThis.fetch. */
47
+ fetchImpl?: typeof fetch;
48
+ }
49
+ /**
50
+ * Issue a single TLS preflight GET against auth.openai.com/oauth/authorize.
51
+ *
52
+ * Resolves to {ok:true} on any HTTP response (302 included — that's the
53
+ * expected success path with redirect:"manual"). Resolves to {ok:false,
54
+ * kind, code?, message} on fetch error.
55
+ *
56
+ * Never throws.
57
+ */
58
+ export declare function runOAuthTlsPreflight(opts?: RunOAuthTlsPreflightOptions): Promise<TlsPreflightResult>;