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,302 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ /**
3
+ * OAuth device-code login for OpenAI Codex.
4
+ *
5
+ * Port of the upstream device-code reference module with Comis-specific
6
+ * adaptations:
7
+ * 1. ORIGINATOR header is the literal "comis".
8
+ * 2. The cosmetic version-header lookup is DROPPED — header is
9
+ * informational; CLAUDE.md forbids reading runtime env in library code.
10
+ * 3. trimNonEmptyString is INLINE (3-line helper) per AGENTS.md §2.3.
11
+ * 4. resolveCodexAccessTokenExpiry is imported from Comis's
12
+ * oauth-identity.ts module (same signature as the upstream variant).
13
+ * 5. Public boundary returns Result<T,E> per AGENTS.md §2.1 — internal
14
+ * helpers still throw, but the top-level loginOpenAICodexDeviceCode
15
+ * wraps everything in try/catch + rewriteOAuthError + narrowing.
16
+ *
17
+ * Protocol: OpenAI's proprietary 3-step device-code flow (NOT RFC 8628):
18
+ * 1. POST /api/accounts/deviceauth/usercode -> device_auth_id + user_code
19
+ * 2. Poll POST /api/accounts/deviceauth/token (403/404 = pending, 200 =
20
+ * authorization_code + code_verifier; verifier comes FROM the server)
21
+ * 3. POST /oauth/token grant_type=authorization_code -> tokens
22
+ *
23
+ * This module never logs — the caller (oauth-login-runner.ts) is responsible
24
+ * for surfacing progress via prompter.log.info / Pino. Per AGENTS.md §2.4 no
25
+ * logger import.
26
+ *
27
+ * @module
28
+ */
29
+ import { ok, err } from "@comis/shared";
30
+ import { rewriteOAuthError } from "./oauth-errors.js";
31
+ import { resolveCodexAccessTokenExpiry } from "./oauth-identity.js";
32
+ // -------- Constants --------
33
+ const OPENAI_AUTH_BASE_URL = "https://auth.openai.com";
34
+ const OPENAI_CODEX_CLIENT_ID = "app_EMoamEEZ73f0CkXaXp7hrann";
35
+ const OPENAI_CODEX_DEVICE_CODE_TIMEOUT_MS = 15 * 60_000;
36
+ const OPENAI_CODEX_DEVICE_CODE_DEFAULT_INTERVAL_MS = 5_000;
37
+ const OPENAI_CODEX_DEVICE_CODE_MIN_INTERVAL_MS = 1_000;
38
+ const OPENAI_CODEX_DEVICE_CALLBACK_URL = `${OPENAI_AUTH_BASE_URL}/deviceauth/callback`;
39
+ const ORIGINATOR = "comis";
40
+ const VERIFICATION_URL = `${OPENAI_AUTH_BASE_URL}/codex/device`;
41
+ // -------- Helpers (port verbatim from upstream, with Comis adaptations) --------
42
+ /**
43
+ * INLINE 3-line helper per AGENTS.md §2.3 (rule of three not met — same
44
+ * shape as the helper in oauth-identity.ts but kept local to avoid coupling).
45
+ */
46
+ function trimNonEmptyString(value) {
47
+ if (typeof value !== "string")
48
+ return undefined;
49
+ const trimmed = value.trim();
50
+ return trimmed.length === 0 ? undefined : trimmed;
51
+ }
52
+ /**
53
+ * Build the 3-key header set for the device-code flow.
54
+ * Adaptation vs upstream: drop the cosmetic version-header lookup
55
+ * (CLAUDE.md §2.2). Header values are fixed strings — no env reads.
56
+ */
57
+ function resolveOpenAICodexDeviceCodeHeaders(contentType) {
58
+ return {
59
+ "Content-Type": contentType,
60
+ originator: ORIGINATOR,
61
+ "User-Agent": ORIGINATOR,
62
+ };
63
+ }
64
+ function normalizePositiveMilliseconds(value) {
65
+ if (typeof value === "number" && Number.isFinite(value) && value > 0) {
66
+ return Math.trunc(value * 1000);
67
+ }
68
+ if (typeof value === "string" && /^\d+$/.test(value.trim())) {
69
+ const seconds = Number.parseInt(value.trim(), 10);
70
+ return seconds > 0 ? seconds * 1000 : undefined;
71
+ }
72
+ return undefined;
73
+ }
74
+ function normalizeTokenLifetimeMs(value) {
75
+ if (typeof value === "number" && Number.isFinite(value) && value > 0) {
76
+ return Math.trunc(value * 1000);
77
+ }
78
+ if (typeof value === "string" && /^\d+$/.test(value.trim())) {
79
+ return Number.parseInt(value.trim(), 10) * 1000;
80
+ }
81
+ return undefined;
82
+ }
83
+ function parseJsonObject(text) {
84
+ try {
85
+ const parsed = JSON.parse(text);
86
+ return parsed && typeof parsed === "object" ? parsed : null;
87
+ }
88
+ catch {
89
+ return null;
90
+ }
91
+ }
92
+ /**
93
+ * Strip ANSI/control characters from upstream error bodies before bubbling
94
+ * the message to a user-facing surface. Defends against terminal hijack via
95
+ * malicious error responses.
96
+ */
97
+ function sanitizeDeviceCodeErrorText(value) {
98
+ const esc = String.fromCharCode(0x1b);
99
+ // eslint-disable-next-line security/detect-non-literal-regexp -- regex built from module constants only (String.fromCharCode literal); no user input reaches the constructor
100
+ const ansiCsiRegex = new RegExp(`${esc}\\[[\\u0020-\\u003f]*[\\u0040-\\u007e]`, "g");
101
+ // eslint-disable-next-line security/detect-non-literal-regexp -- regex built from module constants only
102
+ const osc8Regex = new RegExp(`${esc}\\]8;;.*?${esc}\\\\|${esc}\\]8;;${esc}\\\\`, "g");
103
+ const c0Start = String.fromCharCode(0x00);
104
+ const c0End = String.fromCharCode(0x1f);
105
+ const del = String.fromCharCode(0x7f);
106
+ const c1Start = String.fromCharCode(0x80);
107
+ const c1End = String.fromCharCode(0x9f);
108
+ // eslint-disable-next-line security/detect-non-literal-regexp -- regex built from module constants only
109
+ const controlCharsRegex = new RegExp(`[${c0Start}-${c0End}${del}${c1Start}-${c1End}]`, "g");
110
+ return value
111
+ .replace(osc8Regex, "")
112
+ .replace(ansiCsiRegex, "")
113
+ .replace(controlCharsRegex, " ")
114
+ .replace(/\s+/g, " ")
115
+ .trim();
116
+ }
117
+ function resolveNextDeviceCodePollDelayMs(intervalMs, deadlineMs) {
118
+ const remainingMs = Math.max(0, deadlineMs - Date.now());
119
+ return Math.min(Math.max(intervalMs, OPENAI_CODEX_DEVICE_CODE_MIN_INTERVAL_MS), remainingMs);
120
+ }
121
+ function formatDeviceCodeError(params) {
122
+ const body = parseJsonObject(params.bodyText);
123
+ const error = trimNonEmptyString(body?.error);
124
+ const description = trimNonEmptyString(body?.error_description);
125
+ const safeError = error ? sanitizeDeviceCodeErrorText(error) : undefined;
126
+ const safeDescription = description ? sanitizeDeviceCodeErrorText(description) : undefined;
127
+ if (safeError && safeDescription) {
128
+ return `${params.prefix}: ${safeError} (${safeDescription})`;
129
+ }
130
+ if (safeError) {
131
+ return `${params.prefix}: ${safeError}`;
132
+ }
133
+ const bodyText = sanitizeDeviceCodeErrorText(params.bodyText);
134
+ return bodyText
135
+ ? `${params.prefix}: HTTP ${params.status} ${bodyText}`
136
+ : `${params.prefix}: HTTP ${params.status}`;
137
+ }
138
+ async function requestOpenAICodexDeviceCode(fetchFn) {
139
+ const response = await fetchFn(`${OPENAI_AUTH_BASE_URL}/api/accounts/deviceauth/usercode`, {
140
+ method: "POST",
141
+ headers: resolveOpenAICodexDeviceCodeHeaders("application/json"),
142
+ body: JSON.stringify({
143
+ client_id: OPENAI_CODEX_CLIENT_ID,
144
+ }),
145
+ });
146
+ const bodyText = await response.text();
147
+ if (!response.ok) {
148
+ if (response.status === 404) {
149
+ throw new Error("OpenAI Codex device code login is not enabled for this server. Use ChatGPT OAuth instead.");
150
+ }
151
+ throw new Error(formatDeviceCodeError({
152
+ prefix: "OpenAI device code request failed",
153
+ status: response.status,
154
+ bodyText,
155
+ }));
156
+ }
157
+ const body = parseJsonObject(bodyText);
158
+ const deviceAuthId = trimNonEmptyString(body?.device_auth_id);
159
+ const userCode = trimNonEmptyString(body?.user_code) ?? trimNonEmptyString(body?.usercode);
160
+ if (!deviceAuthId || !userCode) {
161
+ throw new Error("OpenAI device code response was missing the device code or user code.");
162
+ }
163
+ return {
164
+ deviceAuthId,
165
+ userCode,
166
+ verificationUrl: VERIFICATION_URL,
167
+ intervalMs: normalizePositiveMilliseconds(body?.interval) ?? OPENAI_CODEX_DEVICE_CODE_DEFAULT_INTERVAL_MS,
168
+ };
169
+ }
170
+ async function pollOpenAICodexDeviceCode(params) {
171
+ const deadline = Date.now() + OPENAI_CODEX_DEVICE_CODE_TIMEOUT_MS;
172
+ while (Date.now() < deadline) {
173
+ const response = await params.fetchFn(`${OPENAI_AUTH_BASE_URL}/api/accounts/deviceauth/token`, {
174
+ method: "POST",
175
+ headers: resolveOpenAICodexDeviceCodeHeaders("application/json"),
176
+ body: JSON.stringify({
177
+ device_auth_id: params.deviceAuthId,
178
+ user_code: params.userCode,
179
+ }),
180
+ });
181
+ const bodyText = await response.text();
182
+ if (response.ok) {
183
+ const body = parseJsonObject(bodyText);
184
+ const authorizationCode = trimNonEmptyString(body?.authorization_code);
185
+ const codeVerifier = trimNonEmptyString(body?.code_verifier);
186
+ if (!authorizationCode || !codeVerifier) {
187
+ throw new Error("OpenAI device authorization response was missing the exchange code.");
188
+ }
189
+ return {
190
+ authorizationCode,
191
+ codeVerifier,
192
+ };
193
+ }
194
+ if (response.status === 403 || response.status === 404) {
195
+ await new Promise((resolve) => setTimeout(resolve, resolveNextDeviceCodePollDelayMs(params.intervalMs, deadline)));
196
+ continue;
197
+ }
198
+ throw new Error(formatDeviceCodeError({
199
+ prefix: "OpenAI device authorization failed",
200
+ status: response.status,
201
+ bodyText,
202
+ }));
203
+ }
204
+ throw new Error("OpenAI device authorization timed out after 15 minutes.");
205
+ }
206
+ async function exchangeOpenAICodexDeviceCode(params) {
207
+ const response = await params.fetchFn(`${OPENAI_AUTH_BASE_URL}/oauth/token`, {
208
+ method: "POST",
209
+ headers: resolveOpenAICodexDeviceCodeHeaders("application/x-www-form-urlencoded"),
210
+ body: new URLSearchParams({
211
+ grant_type: "authorization_code",
212
+ code: params.authorizationCode,
213
+ redirect_uri: OPENAI_CODEX_DEVICE_CALLBACK_URL,
214
+ client_id: OPENAI_CODEX_CLIENT_ID,
215
+ code_verifier: params.codeVerifier,
216
+ }),
217
+ });
218
+ const bodyText = await response.text();
219
+ if (!response.ok) {
220
+ throw new Error(formatDeviceCodeError({
221
+ prefix: "OpenAI device token exchange failed",
222
+ status: response.status,
223
+ bodyText,
224
+ }));
225
+ }
226
+ const body = parseJsonObject(bodyText);
227
+ const access = trimNonEmptyString(body?.access_token);
228
+ const refresh = trimNonEmptyString(body?.refresh_token);
229
+ if (!access || !refresh) {
230
+ throw new Error("OpenAI token exchange succeeded but did not return OAuth tokens.");
231
+ }
232
+ const expiresInMs = normalizeTokenLifetimeMs(body?.expires_in);
233
+ const expires = expiresInMs !== undefined
234
+ ? Date.now() + expiresInMs
235
+ : (resolveCodexAccessTokenExpiry(access) ?? Date.now());
236
+ return {
237
+ access,
238
+ refresh,
239
+ expires,
240
+ };
241
+ }
242
+ /**
243
+ * Narrow the (broader) OAuthErrorCode catalogue back to the 4-case
244
+ * LoginError["code"] union the public boundary promises. Mirror of
245
+ * oauth-login-runner.ts:269-281 — duplicated verbatim because each call
246
+ * site has a distinct LoginError-shaped union (rule of three not met).
247
+ */
248
+ function narrowToLoginError(code) {
249
+ switch (code) {
250
+ case "unsupported_region":
251
+ case "callback_validation_failed":
252
+ case "callback_timeout":
253
+ case "identity_decode_failed":
254
+ return code;
255
+ case "invalid_grant":
256
+ case "refresh_token_reused":
257
+ return "callback_timeout";
258
+ }
259
+ }
260
+ // -------- Public boundary --------
261
+ /**
262
+ * Run the OpenAI Codex device-code flow end-to-end.
263
+ *
264
+ * Returns ok({ access, refresh, expires }) on success, err({ code, message,
265
+ * hint }) on failure. NEVER throws — internal helpers throw, the boundary
266
+ * wraps everything in try/catch and pipes through rewriteOAuthError +
267
+ * narrowToLoginError.
268
+ */
269
+ export async function loginOpenAICodexDeviceCode(params) {
270
+ const fetchFn = params.fetchFn ?? fetch;
271
+ try {
272
+ params.onProgress?.("Requesting device code…");
273
+ const deviceCode = await requestOpenAICodexDeviceCode(fetchFn);
274
+ await params.onVerification({
275
+ verificationUrl: deviceCode.verificationUrl,
276
+ userCode: deviceCode.userCode,
277
+ expiresInMs: OPENAI_CODEX_DEVICE_CODE_TIMEOUT_MS,
278
+ });
279
+ params.onProgress?.("Waiting for device authorization…");
280
+ const authorization = await pollOpenAICodexDeviceCode({
281
+ fetchFn,
282
+ deviceAuthId: deviceCode.deviceAuthId,
283
+ userCode: deviceCode.userCode,
284
+ intervalMs: deviceCode.intervalMs,
285
+ });
286
+ params.onProgress?.("Exchanging device code…");
287
+ const creds = await exchangeOpenAICodexDeviceCode({
288
+ fetchFn,
289
+ authorizationCode: authorization.authorizationCode,
290
+ codeVerifier: authorization.codeVerifier,
291
+ });
292
+ return ok(creds);
293
+ }
294
+ catch (caught) {
295
+ const rewritten = rewriteOAuthError(caught);
296
+ return err({
297
+ code: narrowToLoginError(rewritten.code),
298
+ message: rewritten.userMessage,
299
+ hint: rewritten.hint,
300
+ });
301
+ }
302
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * VPS / headless environment detection.
3
+ *
4
+ * Pure function: given the env block + optional override, returns true when
5
+ * the current process is on a remote/headless host (no DISPLAY, SSH session,
6
+ * etc.) and should fall back to manual-paste OAuth instead of opening a
7
+ * browser via the `open` package.
8
+ *
9
+ * Plumbing: --remote / --local CLI flags map to `force: "remote" | "local"`
10
+ * so operators can override the heuristic when it guesses wrong (e.g. tmux
11
+ * over SSH where DISPLAY is set by tunneling but they still want manual paste).
12
+ *
13
+ * @module
14
+ */
15
+ /** Input shape for isRemoteEnvironment. Pure: no process.env reads internally. */
16
+ export interface IsRemoteEnvironmentInput {
17
+ /** The env block to inspect — typically process.env at the call site. */
18
+ env: NodeJS.ProcessEnv;
19
+ /** CLI flag override: "remote" forces true; "local" forces false; absent = heuristic. */
20
+ force?: "remote" | "local";
21
+ }
22
+ /**
23
+ * Decide whether to skip browser-open and go straight to manual-paste.
24
+ *
25
+ * Heuristic (simplified from OpenClaw's remote-env.ts — no WAYLAND_DISPLAY,
26
+ * no isWSLEnv check; Comis is Linux-only per CLAUDE.md):
27
+ * - force === "remote" → true
28
+ * - force === "local" → false
29
+ * - SSH_CLIENT or SSH_TTY present → true
30
+ * - !DISPLAY → true
31
+ * - else → false
32
+ */
33
+ export declare function isRemoteEnvironment(input: IsRemoteEnvironmentInput): boolean;
@@ -0,0 +1,38 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ /**
3
+ * VPS / headless environment detection.
4
+ *
5
+ * Pure function: given the env block + optional override, returns true when
6
+ * the current process is on a remote/headless host (no DISPLAY, SSH session,
7
+ * etc.) and should fall back to manual-paste OAuth instead of opening a
8
+ * browser via the `open` package.
9
+ *
10
+ * Plumbing: --remote / --local CLI flags map to `force: "remote" | "local"`
11
+ * so operators can override the heuristic when it guesses wrong (e.g. tmux
12
+ * over SSH where DISPLAY is set by tunneling but they still want manual paste).
13
+ *
14
+ * @module
15
+ */
16
+ /**
17
+ * Decide whether to skip browser-open and go straight to manual-paste.
18
+ *
19
+ * Heuristic (simplified from OpenClaw's remote-env.ts — no WAYLAND_DISPLAY,
20
+ * no isWSLEnv check; Comis is Linux-only per CLAUDE.md):
21
+ * - force === "remote" → true
22
+ * - force === "local" → false
23
+ * - SSH_CLIENT or SSH_TTY present → true
24
+ * - !DISPLAY → true
25
+ * - else → false
26
+ */
27
+ export function isRemoteEnvironment(input) {
28
+ if (input.force === "remote")
29
+ return true;
30
+ if (input.force === "local")
31
+ return false;
32
+ const env = input.env;
33
+ if (env.SSH_CLIENT || env.SSH_TTY)
34
+ return true;
35
+ if (!env.DISPLAY)
36
+ return true;
37
+ return false;
38
+ }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Error catalogue for OpenAI Codex OAuth flows.
3
+ *
4
+ * Pure classification: maps an unknown error (typically thrown by pi-ai's
5
+ * loginOpenAICodex / refreshOpenAICodexToken or our own wrappers) into a
6
+ * discriminated record used by both the login runner and the doctor's
7
+ * refresh-test.
8
+ *
9
+ * The substring matchers for `refresh_token_reused` are lifted from
10
+ * OpenClaw's auth-profiles/oauth.ts:117-123 (battle-tested in production
11
+ * for ~6 months).
12
+ *
13
+ * CRITICAL ORDERING: refresh_token_reused MUST be tested BEFORE
14
+ * invalid_grant — refresh_token_reused is a SPECIFIC kind of
15
+ * invalid_grant; the more-specific matcher must win.
16
+ *
17
+ * Field convention (CLAUDE.md): `errorKind` mirrors `code` 1:1 so Pino
18
+ * log calls can use `{ errorKind: result.errorKind, hint: result.hint }`
19
+ * directly without remapping.
20
+ *
21
+ * @module
22
+ */
23
+ /** Discriminator union for the 6 classifiable OAuth error cases. */
24
+ export type OAuthErrorCode = "unsupported_region" | "callback_validation_failed" | "invalid_grant" | "refresh_token_reused" | "identity_decode_failed" | "callback_timeout";
25
+ /** Output record carrying both UX-facing text and Pino-log-field values. */
26
+ export interface RewrittenOAuthError {
27
+ /** Discriminator. Also the `errorKind` value used in Pino logs + event payloads. */
28
+ code: OAuthErrorCode;
29
+ /** Mirror of `code` so logs can use `errorKind:` consistently per CLAUDE.md. */
30
+ errorKind: string;
31
+ /** Concrete, paste-ready message for CLI stderr. */
32
+ userMessage: string;
33
+ /** Shorter operator-action recommendation. Goes into Pino `hint` field. */
34
+ hint: string;
35
+ }
36
+ /**
37
+ * Classify an unknown error into a `RewrittenOAuthError`. Pure; never throws.
38
+ * Non-Error inputs are coerced via `String(err)` (defensive — covers
39
+ * primitives, null, undefined, and objects without a `.message` field).
40
+ */
41
+ export declare function rewriteOAuthError(err: unknown): RewrittenOAuthError;
@@ -0,0 +1,88 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ /**
3
+ * Error catalogue for OpenAI Codex OAuth flows.
4
+ *
5
+ * Pure classification: maps an unknown error (typically thrown by pi-ai's
6
+ * loginOpenAICodex / refreshOpenAICodexToken or our own wrappers) into a
7
+ * discriminated record used by both the login runner and the doctor's
8
+ * refresh-test.
9
+ *
10
+ * The substring matchers for `refresh_token_reused` are lifted from
11
+ * OpenClaw's auth-profiles/oauth.ts:117-123 (battle-tested in production
12
+ * for ~6 months).
13
+ *
14
+ * CRITICAL ORDERING: refresh_token_reused MUST be tested BEFORE
15
+ * invalid_grant — refresh_token_reused is a SPECIFIC kind of
16
+ * invalid_grant; the more-specific matcher must win.
17
+ *
18
+ * Field convention (CLAUDE.md): `errorKind` mirrors `code` 1:1 so Pino
19
+ * log calls can use `{ errorKind: result.errorKind, hint: result.hint }`
20
+ * directly without remapping.
21
+ *
22
+ * @module
23
+ */
24
+ /**
25
+ * Classify an unknown error into a `RewrittenOAuthError`. Pure; never throws.
26
+ * Non-Error inputs are coerced via `String(err)` (defensive — covers
27
+ * primitives, null, undefined, and objects without a `.message` field).
28
+ */
29
+ export function rewriteOAuthError(err) {
30
+ const message = err instanceof Error ? err.message : String(err);
31
+ // CRITICAL ORDERING: refresh_token_reused FIRST — it is a SPECIFIC kind
32
+ // of invalid_grant. Match the more specific pattern before the generic.
33
+ // Substring set verbatim from OpenClaw auth-profiles/oauth.ts:117-123.
34
+ if (/refresh_token_reused/i.test(message) ||
35
+ /refresh token has already been used/i.test(message) ||
36
+ /already been used to generate a new access token/i.test(message)) {
37
+ return {
38
+ code: "refresh_token_reused",
39
+ errorKind: "refresh_token_reused",
40
+ userMessage: "Refresh token was reused. The OpenAI account has been auto-locked for security. " +
41
+ "Re-authenticate with: comis auth login --provider openai-codex",
42
+ hint: "refresh_token_reused — re-login required",
43
+ };
44
+ }
45
+ if (/invalid_grant/i.test(message)) {
46
+ return {
47
+ code: "invalid_grant",
48
+ errorKind: "invalid_grant",
49
+ userMessage: "Refresh token was rejected by OpenAI (invalid_grant). " +
50
+ "Re-authenticate with: comis auth login --provider openai-codex",
51
+ hint: "invalid_grant — re-login required",
52
+ };
53
+ }
54
+ if (/unsupported_country_region_territory/i.test(message)) {
55
+ return {
56
+ code: "unsupported_region",
57
+ errorKind: "unsupported_region",
58
+ userMessage: "OpenAI rejected the request for this country, region, or network route. " +
59
+ "If you normally use a proxy, verify HTTPS_PROXY, HTTP_PROXY, or ALL_PROXY is set " +
60
+ "for the Comis process. NOTE: Node's built-in fetch does NOT honor HTTPS_PROXY " +
61
+ "by default (see docs/operations/proxy.mdx).",
62
+ hint: "Set HTTPS_PROXY to a US-region proxy and retry",
63
+ };
64
+ }
65
+ if (/state mismatch|missing authorization code/i.test(message)) {
66
+ return {
67
+ code: "callback_validation_failed",
68
+ errorKind: "callback_validation_failed",
69
+ userMessage: "Browser callback validation failed (likely a stale browser tab). Retry the login flow.",
70
+ hint: "Browser callback validation failed — retry",
71
+ };
72
+ }
73
+ if (/Failed to extract accountId/i.test(message)) {
74
+ return {
75
+ code: "identity_decode_failed",
76
+ errorKind: "identity_decode_failed",
77
+ userMessage: "The OAuth response did not contain a parseable identity claim. " +
78
+ "Re-run login or open an issue if the problem persists.",
79
+ hint: "JWT had no identity claim",
80
+ };
81
+ }
82
+ return {
83
+ code: "callback_timeout",
84
+ errorKind: "callback_timeout",
85
+ userMessage: message,
86
+ hint: "Restart the login flow",
87
+ };
88
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * OAuth identity extraction for Codex JWTs.
3
+ *
4
+ * Decodes the access-token JWT payload (no signature verification — pi-ai's
5
+ * token exchange validated the source) and resolves the canonical identity
6
+ * for use in profile IDs.
7
+ *
8
+ * Verbatim port of OpenClaw's openai-codex-auth-identity.ts
9
+ * plus the email-redaction helper.
10
+ *
11
+ * @module
12
+ */
13
+ /**
14
+ * Decode the payload segment of a JWT.
15
+ * Returns null on any malformed input (wrong segment count, bad base64url,
16
+ * invalid JSON, non-object payload). Returning null is a sentinel, not
17
+ * silent error swallowing.
18
+ */
19
+ export declare function decodeCodexJwtPayload(accessToken: string): Record<string, unknown> | null;
20
+ /**
21
+ * Resolve the canonical stable subject for fallback profile naming.
22
+ * Priority: chatgpt_account_user_id > chatgpt_user_id > user_id > iss|sub > sub.
23
+ */
24
+ export declare function resolveCodexStableSubject(payload: Record<string, unknown>): string | undefined;
25
+ /**
26
+ * Resolve the canonical email + profileName for a Codex identity.
27
+ * Priority for email: explicit `opts.email` > JWT `https://api.openai.com/profile.email`.
28
+ * profileName = email when available, else `id-<base64url(stableSubject)>`.
29
+ */
30
+ export declare function resolveCodexAuthIdentity(opts: {
31
+ accessToken: string;
32
+ email?: string;
33
+ }): {
34
+ email?: string;
35
+ profileName?: string;
36
+ };
37
+ /**
38
+ * Extract the access-token expiry as milliseconds since epoch.
39
+ * The JWT exp claim is in seconds (RFC 7519); we multiply by 1000 to match
40
+ * pi-ai's OAuthCredentials.expires unit (ms).
41
+ * Accepts numeric `exp` and digit-only string `exp`.
42
+ */
43
+ export declare function resolveCodexAccessTokenExpiry(accessToken: string): number | undefined;
44
+ /**
45
+ * Semi-redact an email for safe inclusion in logs.
46
+ * Format: first 2 chars + ellipsis + last char of local-part, then "@" + full domain.
47
+ * Edge cases:
48
+ * - undefined input → undefined
49
+ * - input without "@" → returned unchanged
50
+ * - 1-char local-part → "…@<domain>"
51
+ * - 2-char local-part → "<first>…<last>@<domain>" (single char on each side)
52
+ */
53
+ export declare function redactEmailForLog(email: string | undefined): string | undefined;