@getpaseo/server 0.1.62 → 0.1.63

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 (464) hide show
  1. package/README.md +4 -0
  2. package/dist/server/client/daemon-client-runtime-metrics.d.ts +6 -6
  3. package/dist/server/client/daemon-client-runtime-metrics.d.ts.map +1 -1
  4. package/dist/server/client/daemon-client-transport-types.d.ts +13 -13
  5. package/dist/server/client/daemon-client-transport-types.d.ts.map +1 -1
  6. package/dist/server/client/daemon-client-websocket-transport.d.ts +1 -1
  7. package/dist/server/client/daemon-client-websocket-transport.d.ts.map +1 -1
  8. package/dist/server/client/daemon-client-websocket-transport.js +5 -4
  9. package/dist/server/client/daemon-client-websocket-transport.js.map +1 -1
  10. package/dist/server/client/daemon-client.d.ts +59 -37
  11. package/dist/server/client/daemon-client.d.ts.map +1 -1
  12. package/dist/server/client/daemon-client.js +62 -17
  13. package/dist/server/client/daemon-client.js.map +1 -1
  14. package/dist/server/server/agent/agent-loading.d.ts.map +1 -1
  15. package/dist/server/server/agent/agent-loading.js +5 -3
  16. package/dist/server/server/agent/agent-loading.js.map +1 -1
  17. package/dist/server/server/agent/agent-manager.d.ts +45 -19
  18. package/dist/server/server/agent/agent-manager.d.ts.map +1 -1
  19. package/dist/server/server/agent/agent-manager.js +393 -290
  20. package/dist/server/server/agent/agent-manager.js.map +1 -1
  21. package/dist/server/server/agent/agent-metadata-generator.d.ts +6 -6
  22. package/dist/server/server/agent/agent-metadata-generator.d.ts.map +1 -1
  23. package/dist/server/server/agent/agent-metadata-generator.js +46 -38
  24. package/dist/server/server/agent/agent-metadata-generator.js.map +1 -1
  25. package/dist/server/server/agent/agent-projections.d.ts +4 -6
  26. package/dist/server/server/agent/agent-projections.d.ts.map +1 -1
  27. package/dist/server/server/agent/agent-projections.js +59 -65
  28. package/dist/server/server/agent/agent-projections.js.map +1 -1
  29. package/dist/server/server/agent/agent-response-loop.d.ts +4 -4
  30. package/dist/server/server/agent/agent-response-loop.d.ts.map +1 -1
  31. package/dist/server/server/agent/agent-response-loop.js +58 -45
  32. package/dist/server/server/agent/agent-response-loop.js.map +1 -1
  33. package/dist/server/server/agent/agent-sdk-types.d.ts +43 -40
  34. package/dist/server/server/agent/agent-sdk-types.d.ts.map +1 -1
  35. package/dist/server/server/agent/agent-sdk-types.js.map +1 -1
  36. package/dist/server/server/agent/agent-storage.d.ts +2 -2
  37. package/dist/server/server/agent/agent-storage.d.ts.map +1 -1
  38. package/dist/server/server/agent/agent-storage.js +29 -36
  39. package/dist/server/server/agent/agent-storage.js.map +1 -1
  40. package/dist/server/server/agent/agent-stream-coalescer.d.ts +6 -6
  41. package/dist/server/server/agent/agent-stream-coalescer.d.ts.map +1 -1
  42. package/dist/server/server/agent/agent-timeline-store-types.d.ts +10 -10
  43. package/dist/server/server/agent/agent-timeline-store-types.d.ts.map +1 -1
  44. package/dist/server/server/agent/agent-timeline-store.d.ts +2 -2
  45. package/dist/server/server/agent/agent-timeline-store.d.ts.map +1 -1
  46. package/dist/server/server/agent/agent-timeline-store.js +85 -64
  47. package/dist/server/server/agent/agent-timeline-store.js.map +1 -1
  48. package/dist/server/server/agent/mcp-server.d.ts.map +1 -1
  49. package/dist/server/server/agent/mcp-server.js +185 -148
  50. package/dist/server/server/agent/mcp-server.js.map +1 -1
  51. package/dist/server/server/agent/mcp-shared.d.ts +9 -2
  52. package/dist/server/server/agent/mcp-shared.d.ts.map +1 -1
  53. package/dist/server/server/agent/mcp-shared.js +2 -0
  54. package/dist/server/server/agent/mcp-shared.js.map +1 -1
  55. package/dist/server/server/agent/model-resolver.d.ts +2 -2
  56. package/dist/server/server/agent/model-resolver.d.ts.map +1 -1
  57. package/dist/server/server/agent/model-resolver.js +9 -5
  58. package/dist/server/server/agent/model-resolver.js.map +1 -1
  59. package/dist/server/server/agent/provider-launch-config.d.ts +28 -17
  60. package/dist/server/server/agent/provider-launch-config.d.ts.map +1 -1
  61. package/dist/server/server/agent/provider-launch-config.js +20 -9
  62. package/dist/server/server/agent/provider-launch-config.js.map +1 -1
  63. package/dist/server/server/agent/provider-registry.d.ts +4 -2
  64. package/dist/server/server/agent/provider-registry.d.ts.map +1 -1
  65. package/dist/server/server/agent/provider-registry.js +24 -21
  66. package/dist/server/server/agent/provider-registry.js.map +1 -1
  67. package/dist/server/server/agent/provider-snapshot-manager.d.ts +6 -5
  68. package/dist/server/server/agent/provider-snapshot-manager.d.ts.map +1 -1
  69. package/dist/server/server/agent/provider-snapshot-manager.js +40 -31
  70. package/dist/server/server/agent/provider-snapshot-manager.js.map +1 -1
  71. package/dist/server/server/agent/providers/acp-agent.d.ts +11 -12
  72. package/dist/server/server/agent/providers/acp-agent.d.ts.map +1 -1
  73. package/dist/server/server/agent/providers/acp-agent.js +148 -122
  74. package/dist/server/server/agent/providers/acp-agent.js.map +1 -1
  75. package/dist/server/server/agent/providers/claude/sidechain-tracker.d.ts +2 -0
  76. package/dist/server/server/agent/providers/claude/sidechain-tracker.d.ts.map +1 -1
  77. package/dist/server/server/agent/providers/claude/sidechain-tracker.js +47 -45
  78. package/dist/server/server/agent/providers/claude/sidechain-tracker.js.map +1 -1
  79. package/dist/server/server/agent/providers/claude/task-notification-tool-call.d.ts +2 -2
  80. package/dist/server/server/agent/providers/claude/task-notification-tool-call.d.ts.map +1 -1
  81. package/dist/server/server/agent/providers/claude/task-notification-tool-call.js +10 -5
  82. package/dist/server/server/agent/providers/claude/task-notification-tool-call.js.map +1 -1
  83. package/dist/server/server/agent/providers/claude/tool-call-detail-parser.d.ts.map +1 -1
  84. package/dist/server/server/agent/providers/claude/tool-call-detail-parser.js +11 -2
  85. package/dist/server/server/agent/providers/claude/tool-call-detail-parser.js.map +1 -1
  86. package/dist/server/server/agent/providers/claude/tool-call-mapper.d.ts +2 -2
  87. package/dist/server/server/agent/providers/claude/tool-call-mapper.d.ts.map +1 -1
  88. package/dist/server/server/agent/providers/claude/tool-call-mapper.js +20 -13
  89. package/dist/server/server/agent/providers/claude/tool-call-mapper.js.map +1 -1
  90. package/dist/server/server/agent/providers/claude-agent.d.ts +20 -8
  91. package/dist/server/server/agent/providers/claude-agent.d.ts.map +1 -1
  92. package/dist/server/server/agent/providers/claude-agent.js +610 -460
  93. package/dist/server/server/agent/providers/claude-agent.js.map +1 -1
  94. package/dist/server/server/agent/providers/codex/tool-call-detail-parser.d.ts +2 -2
  95. package/dist/server/server/agent/providers/codex/tool-call-detail-parser.d.ts.map +1 -1
  96. package/dist/server/server/agent/providers/codex/tool-call-mapper.d.ts +2 -2
  97. package/dist/server/server/agent/providers/codex/tool-call-mapper.d.ts.map +1 -1
  98. package/dist/server/server/agent/providers/codex/tool-call-mapper.js +49 -44
  99. package/dist/server/server/agent/providers/codex/tool-call-mapper.js.map +1 -1
  100. package/dist/server/server/agent/providers/codex-app-server-agent.d.ts +27 -8
  101. package/dist/server/server/agent/providers/codex-app-server-agent.d.ts.map +1 -1
  102. package/dist/server/server/agent/providers/codex-app-server-agent.js +564 -492
  103. package/dist/server/server/agent/providers/codex-app-server-agent.js.map +1 -1
  104. package/dist/server/server/agent/providers/codex-rollout-timeline.d.ts +2 -2
  105. package/dist/server/server/agent/providers/codex-rollout-timeline.d.ts.map +1 -1
  106. package/dist/server/server/agent/providers/codex-rollout-timeline.js +58 -47
  107. package/dist/server/server/agent/providers/codex-rollout-timeline.js.map +1 -1
  108. package/dist/server/server/agent/providers/copilot-acp-agent.d.ts +2 -2
  109. package/dist/server/server/agent/providers/copilot-acp-agent.d.ts.map +1 -1
  110. package/dist/server/server/agent/providers/diagnostic-utils.d.ts +3 -3
  111. package/dist/server/server/agent/providers/diagnostic-utils.d.ts.map +1 -1
  112. package/dist/server/server/agent/providers/diagnostic-utils.js +82 -9
  113. package/dist/server/server/agent/providers/diagnostic-utils.js.map +1 -1
  114. package/dist/server/server/agent/providers/generic-acp-agent.d.ts +2 -2
  115. package/dist/server/server/agent/providers/generic-acp-agent.d.ts.map +1 -1
  116. package/dist/server/server/agent/providers/mock-load-test-agent.d.ts.map +1 -1
  117. package/dist/server/server/agent/providers/mock-load-test-agent.js.map +1 -1
  118. package/dist/server/server/agent/providers/opencode/tool-call-mapper.d.ts +2 -2
  119. package/dist/server/server/agent/providers/opencode/tool-call-mapper.d.ts.map +1 -1
  120. package/dist/server/server/agent/providers/opencode-agent.d.ts +2 -2
  121. package/dist/server/server/agent/providers/opencode-agent.d.ts.map +1 -1
  122. package/dist/server/server/agent/providers/opencode-agent.js +385 -360
  123. package/dist/server/server/agent/providers/opencode-agent.js.map +1 -1
  124. package/dist/server/server/agent/providers/pi-direct-agent.d.ts +1 -0
  125. package/dist/server/server/agent/providers/pi-direct-agent.d.ts.map +1 -1
  126. package/dist/server/server/agent/providers/pi-direct-agent.js +109 -140
  127. package/dist/server/server/agent/providers/pi-direct-agent.js.map +1 -1
  128. package/dist/server/server/agent/providers/test-utils/session-stream-adapter.d.ts.map +1 -1
  129. package/dist/server/server/agent/providers/test-utils/session-stream-adapter.js +3 -1
  130. package/dist/server/server/agent/providers/test-utils/session-stream-adapter.js.map +1 -1
  131. package/dist/server/server/agent/providers/tool-call-detail-primitives.d.ts +3 -3
  132. package/dist/server/server/agent/providers/tool-call-detail-primitives.d.ts.map +1 -1
  133. package/dist/server/server/agent/providers/tool-call-detail-primitives.js +102 -73
  134. package/dist/server/server/agent/providers/tool-call-detail-primitives.js.map +1 -1
  135. package/dist/server/server/agent/providers/tool-call-mapper-utils.d.ts +2 -2
  136. package/dist/server/server/agent/providers/tool-call-mapper-utils.d.ts.map +1 -1
  137. package/dist/server/server/agent/stt-manager.d.ts.map +1 -1
  138. package/dist/server/server/agent/stt-manager.js +63 -53
  139. package/dist/server/server/agent/stt-manager.js.map +1 -1
  140. package/dist/server/server/agent/timeline-projection.d.ts +6 -6
  141. package/dist/server/server/agent/timeline-projection.d.ts.map +1 -1
  142. package/dist/server/server/agent/timeline-projection.js +11 -6
  143. package/dist/server/server/agent/timeline-projection.js.map +1 -1
  144. package/dist/server/server/agent/tts-manager.d.ts.map +1 -1
  145. package/dist/server/server/agent/tts-manager.js +1 -0
  146. package/dist/server/server/agent/tts-manager.js.map +1 -1
  147. package/dist/server/server/agent-attention-policy.d.ts +2 -2
  148. package/dist/server/server/agent-attention-policy.d.ts.map +1 -1
  149. package/dist/server/server/bootstrap.d.ts +4 -4
  150. package/dist/server/server/bootstrap.d.ts.map +1 -1
  151. package/dist/server/server/bootstrap.js +493 -485
  152. package/dist/server/server/bootstrap.js.map +1 -1
  153. package/dist/server/server/chat/chat-service.d.ts +1 -1
  154. package/dist/server/server/chat/chat-service.d.ts.map +1 -1
  155. package/dist/server/server/chat/chat-service.js +3 -3
  156. package/dist/server/server/chat/chat-service.js.map +1 -1
  157. package/dist/server/server/checkout-diff-manager.d.ts +2 -2
  158. package/dist/server/server/checkout-diff-manager.d.ts.map +1 -1
  159. package/dist/server/server/checkout-git-utils.d.ts +5 -3
  160. package/dist/server/server/checkout-git-utils.d.ts.map +1 -1
  161. package/dist/server/server/checkout-git-utils.js +1 -2
  162. package/dist/server/server/checkout-git-utils.js.map +1 -1
  163. package/dist/server/server/config.d.ts.map +1 -1
  164. package/dist/server/server/config.js +68 -39
  165. package/dist/server/server/config.js.map +1 -1
  166. package/dist/server/server/connection-offer.d.ts +2 -2
  167. package/dist/server/server/connection-offer.d.ts.map +1 -1
  168. package/dist/server/server/daemon-config-store.d.ts +5 -3
  169. package/dist/server/server/daemon-config-store.d.ts.map +1 -1
  170. package/dist/server/server/daemon-config-store.js +26 -0
  171. package/dist/server/server/daemon-config-store.js.map +1 -1
  172. package/dist/server/server/daemon-keypair.d.ts +2 -2
  173. package/dist/server/server/daemon-keypair.d.ts.map +1 -1
  174. package/dist/server/server/editor-targets.d.ts +4 -4
  175. package/dist/server/server/editor-targets.d.ts.map +1 -1
  176. package/dist/server/server/editor-targets.js +11 -15
  177. package/dist/server/server/editor-targets.js.map +1 -1
  178. package/dist/server/server/exports.d.ts +3 -3
  179. package/dist/server/server/exports.d.ts.map +1 -1
  180. package/dist/server/server/exports.js +1 -3
  181. package/dist/server/server/exports.js.map +1 -1
  182. package/dist/server/server/file-download/token-store.d.ts +4 -4
  183. package/dist/server/server/file-download/token-store.d.ts.map +1 -1
  184. package/dist/server/server/index.js +16 -12
  185. package/dist/server/server/index.js.map +1 -1
  186. package/dist/server/server/logger.d.ts +4 -4
  187. package/dist/server/server/logger.d.ts.map +1 -1
  188. package/dist/server/server/logger.js +26 -20
  189. package/dist/server/server/logger.js.map +1 -1
  190. package/dist/server/server/loop/rpc-schemas.d.ts +52 -52
  191. package/dist/server/server/loop-service.d.ts +13 -12
  192. package/dist/server/server/loop-service.d.ts.map +1 -1
  193. package/dist/server/server/loop-service.js +22 -18
  194. package/dist/server/server/loop-service.js.map +1 -1
  195. package/dist/server/server/package-version.d.ts +2 -2
  196. package/dist/server/server/package-version.d.ts.map +1 -1
  197. package/dist/server/server/package-version.js +19 -17
  198. package/dist/server/server/package-version.js.map +1 -1
  199. package/dist/server/server/pairing-offer.d.ts +2 -2
  200. package/dist/server/server/pairing-offer.d.ts.map +1 -1
  201. package/dist/server/server/paseo-env.d.ts +9 -0
  202. package/dist/server/server/paseo-env.d.ts.map +1 -0
  203. package/dist/server/server/paseo-env.js +70 -0
  204. package/dist/server/server/paseo-env.js.map +1 -0
  205. package/dist/server/server/paseo-worktree-archive-service.d.ts +4 -4
  206. package/dist/server/server/paseo-worktree-archive-service.d.ts.map +1 -1
  207. package/dist/server/server/paseo-worktree-archive-service.js +11 -11
  208. package/dist/server/server/paseo-worktree-archive-service.js.map +1 -1
  209. package/dist/server/server/persisted-config.d.ts +62 -62
  210. package/dist/server/server/persisted-config.d.ts.map +1 -1
  211. package/dist/server/server/persisted-config.js +4 -4
  212. package/dist/server/server/persisted-config.js.map +1 -1
  213. package/dist/server/server/persistence-hooks.d.ts +8 -9
  214. package/dist/server/server/persistence-hooks.d.ts.map +1 -1
  215. package/dist/server/server/persistence-hooks.js +4 -12
  216. package/dist/server/server/persistence-hooks.js.map +1 -1
  217. package/dist/server/server/pid-lock.js.map +1 -1
  218. package/dist/server/server/push/push-service.d.ts.map +1 -1
  219. package/dist/server/server/push/push-service.js +1 -3
  220. package/dist/server/server/push/push-service.js.map +1 -1
  221. package/dist/server/server/relay-transport.d.ts +8 -8
  222. package/dist/server/server/relay-transport.d.ts.map +1 -1
  223. package/dist/server/server/relay-transport.js +27 -16
  224. package/dist/server/server/relay-transport.js.map +1 -1
  225. package/dist/server/server/schedule/service.d.ts.map +1 -1
  226. package/dist/server/server/schedule/service.js +2 -2
  227. package/dist/server/server/schedule/service.js.map +1 -1
  228. package/dist/server/server/script-health-monitor.d.ts.map +1 -1
  229. package/dist/server/server/script-health-monitor.js +7 -6
  230. package/dist/server/server/script-health-monitor.js.map +1 -1
  231. package/dist/server/server/script-proxy.js +1 -1
  232. package/dist/server/server/script-proxy.js.map +1 -1
  233. package/dist/server/server/script-status-projection.d.ts +4 -4
  234. package/dist/server/server/script-status-projection.d.ts.map +1 -1
  235. package/dist/server/server/script-status-projection.js +54 -44
  236. package/dist/server/server/script-status-projection.js.map +1 -1
  237. package/dist/server/server/server-id.d.ts +4 -4
  238. package/dist/server/server/server-id.d.ts.map +1 -1
  239. package/dist/server/server/session.d.ts +45 -14
  240. package/dist/server/server/session.d.ts.map +1 -1
  241. package/dist/server/server/session.js +1098 -761
  242. package/dist/server/server/session.js.map +1 -1
  243. package/dist/server/server/speech/audio.js +1 -1
  244. package/dist/server/server/speech/audio.js.map +1 -1
  245. package/dist/server/server/speech/providers/local/config.d.ts +6 -6
  246. package/dist/server/server/speech/providers/local/config.d.ts.map +1 -1
  247. package/dist/server/server/speech/providers/local/config.js +41 -16
  248. package/dist/server/server/speech/providers/local/config.js.map +1 -1
  249. package/dist/server/server/speech/providers/local/pocket/pocket-tts-onnx.d.ts +2 -2
  250. package/dist/server/server/speech/providers/local/pocket/pocket-tts-onnx.d.ts.map +1 -1
  251. package/dist/server/server/speech/providers/local/pocket/pocket-tts-onnx.js +42 -19
  252. package/dist/server/server/speech/providers/local/pocket/pocket-tts-onnx.js.map +1 -1
  253. package/dist/server/server/speech/providers/local/runtime.d.ts +4 -4
  254. package/dist/server/server/speech/providers/local/runtime.d.ts.map +1 -1
  255. package/dist/server/server/speech/providers/local/runtime.js +108 -77
  256. package/dist/server/server/speech/providers/local/runtime.js.map +1 -1
  257. package/dist/server/server/speech/providers/local/sherpa/model-catalog.d.ts +2 -2
  258. package/dist/server/server/speech/providers/local/sherpa/model-catalog.d.ts.map +1 -1
  259. package/dist/server/server/speech/providers/local/sherpa/model-catalog.js +1 -4
  260. package/dist/server/server/speech/providers/local/sherpa/model-catalog.js.map +1 -1
  261. package/dist/server/server/speech/providers/local/sherpa/model-downloader.d.ts +2 -2
  262. package/dist/server/server/speech/providers/local/sherpa/model-downloader.d.ts.map +1 -1
  263. package/dist/server/server/speech/providers/local/sherpa/model-downloader.js +19 -19
  264. package/dist/server/server/speech/providers/local/sherpa/model-downloader.js.map +1 -1
  265. package/dist/server/server/speech/providers/local/sherpa/sherpa-offline-recognizer.d.ts +28 -7
  266. package/dist/server/server/speech/providers/local/sherpa/sherpa-offline-recognizer.d.ts.map +1 -1
  267. package/dist/server/server/speech/providers/local/sherpa/sherpa-offline-recognizer.js.map +1 -1
  268. package/dist/server/server/speech/providers/local/sherpa/sherpa-online-recognizer.d.ts +23 -4
  269. package/dist/server/server/speech/providers/local/sherpa/sherpa-online-recognizer.d.ts.map +1 -1
  270. package/dist/server/server/speech/providers/local/sherpa/sherpa-online-recognizer.js +35 -28
  271. package/dist/server/server/speech/providers/local/sherpa/sherpa-online-recognizer.js.map +1 -1
  272. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-loader.d.ts +5 -5
  273. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-loader.d.ts.map +1 -1
  274. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.d.ts +7 -7
  275. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.d.ts.map +1 -1
  276. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.js +5 -0
  277. package/dist/server/server/speech/providers/local/sherpa/sherpa-onnx-node-loader.js.map +1 -1
  278. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.d.ts.map +1 -1
  279. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.js +3 -1
  280. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-realtime-session.js.map +1 -1
  281. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-stt.d.ts +2 -2
  282. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-stt.d.ts.map +1 -1
  283. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-stt.js +3 -1
  284. package/dist/server/server/speech/providers/local/sherpa/sherpa-parakeet-stt.js.map +1 -1
  285. package/dist/server/server/speech/providers/local/sherpa/sherpa-realtime-session.d.ts.map +1 -1
  286. package/dist/server/server/speech/providers/local/sherpa/sherpa-realtime-session.js +10 -4
  287. package/dist/server/server/speech/providers/local/sherpa/sherpa-realtime-session.js.map +1 -1
  288. package/dist/server/server/speech/providers/local/sherpa/sherpa-runtime-env.d.ts +2 -2
  289. package/dist/server/server/speech/providers/local/sherpa/sherpa-runtime-env.d.ts.map +1 -1
  290. package/dist/server/server/speech/providers/local/sherpa/sherpa-stt.d.ts +2 -2
  291. package/dist/server/server/speech/providers/local/sherpa/sherpa-stt.d.ts.map +1 -1
  292. package/dist/server/server/speech/providers/local/sherpa/sherpa-stt.js +4 -1
  293. package/dist/server/server/speech/providers/local/sherpa/sherpa-stt.js.map +1 -1
  294. package/dist/server/server/speech/providers/local/sherpa/sherpa-tts.d.ts +2 -2
  295. package/dist/server/server/speech/providers/local/sherpa/sherpa-tts.d.ts.map +1 -1
  296. package/dist/server/server/speech/providers/local/sherpa/sherpa-tts.js +18 -11
  297. package/dist/server/server/speech/providers/local/sherpa/sherpa-tts.js.map +1 -1
  298. package/dist/server/server/speech/providers/openai/config.d.ts +2 -2
  299. package/dist/server/server/speech/providers/openai/config.d.ts.map +1 -1
  300. package/dist/server/server/speech/providers/openai/config.js +58 -31
  301. package/dist/server/server/speech/providers/openai/config.js.map +1 -1
  302. package/dist/server/server/speech/providers/openai/realtime-transcription-session.d.ts.map +1 -1
  303. package/dist/server/server/speech/providers/openai/realtime-transcription-session.js +2 -2
  304. package/dist/server/server/speech/providers/openai/realtime-transcription-session.js.map +1 -1
  305. package/dist/server/server/speech/providers/openai/runtime.d.ts +4 -4
  306. package/dist/server/server/speech/providers/openai/runtime.d.ts.map +1 -1
  307. package/dist/server/server/speech/providers/openai/runtime.js +37 -32
  308. package/dist/server/server/speech/providers/openai/runtime.js.map +1 -1
  309. package/dist/server/server/speech/providers/openai/stt.d.ts.map +1 -1
  310. package/dist/server/server/speech/providers/openai/stt.js +4 -3
  311. package/dist/server/server/speech/providers/openai/stt.js.map +1 -1
  312. package/dist/server/server/speech/providers/openai/tts.d.ts.map +1 -1
  313. package/dist/server/server/speech/providers/openai/tts.js +3 -2
  314. package/dist/server/server/speech/providers/openai/tts.js.map +1 -1
  315. package/dist/server/server/speech/speech-config-resolver.d.ts.map +1 -1
  316. package/dist/server/server/speech/speech-config-resolver.js +46 -17
  317. package/dist/server/server/speech/speech-config-resolver.js.map +1 -1
  318. package/dist/server/server/speech/speech-provider.d.ts +2 -2
  319. package/dist/server/server/speech/speech-provider.d.ts.map +1 -1
  320. package/dist/server/server/speech/speech-runtime.d.ts +6 -6
  321. package/dist/server/server/speech/speech-runtime.d.ts.map +1 -1
  322. package/dist/server/server/speech/speech-runtime.js +17 -17
  323. package/dist/server/server/speech/speech-runtime.js.map +1 -1
  324. package/dist/server/server/speech/speech-types.d.ts +2 -2
  325. package/dist/server/server/speech/speech-types.d.ts.map +1 -1
  326. package/dist/server/server/speech/turn-detection-provider.d.ts +2 -2
  327. package/dist/server/server/speech/turn-detection-provider.d.ts.map +1 -1
  328. package/dist/server/server/utils/diff-highlighter.d.ts +0 -3
  329. package/dist/server/server/utils/diff-highlighter.d.ts.map +1 -1
  330. package/dist/server/server/utils/diff-highlighter.js +67 -66
  331. package/dist/server/server/utils/diff-highlighter.js.map +1 -1
  332. package/dist/server/server/voice/voice-turn-controller.d.ts.map +1 -1
  333. package/dist/server/server/voice/voice-turn-controller.js +1 -0
  334. package/dist/server/server/voice/voice-turn-controller.js.map +1 -1
  335. package/dist/server/server/voice-types.d.ts +2 -2
  336. package/dist/server/server/voice-types.d.ts.map +1 -1
  337. package/dist/server/server/websocket-server.d.ts +31 -21
  338. package/dist/server/server/websocket-server.d.ts.map +1 -1
  339. package/dist/server/server/websocket-server.js +299 -197
  340. package/dist/server/server/websocket-server.js.map +1 -1
  341. package/dist/server/server/workspace-git-metadata.d.ts +2 -2
  342. package/dist/server/server/workspace-git-metadata.d.ts.map +1 -1
  343. package/dist/server/server/workspace-git-metadata.js +2 -32
  344. package/dist/server/server/workspace-git-metadata.js.map +1 -1
  345. package/dist/server/server/workspace-git-service.d.ts +8 -4
  346. package/dist/server/server/workspace-git-service.d.ts.map +1 -1
  347. package/dist/server/server/workspace-git-service.js +163 -115
  348. package/dist/server/server/workspace-git-service.js.map +1 -1
  349. package/dist/server/server/workspace-reconciliation-service.d.ts +5 -4
  350. package/dist/server/server/workspace-reconciliation-service.d.ts.map +1 -1
  351. package/dist/server/server/workspace-reconciliation-service.js +82 -82
  352. package/dist/server/server/workspace-reconciliation-service.js.map +1 -1
  353. package/dist/server/server/workspace-registry-bootstrap.d.ts.map +1 -1
  354. package/dist/server/server/workspace-registry-bootstrap.js +40 -33
  355. package/dist/server/server/workspace-registry-bootstrap.js.map +1 -1
  356. package/dist/server/server/workspace-registry-model.d.ts +19 -6
  357. package/dist/server/server/workspace-registry-model.d.ts.map +1 -1
  358. package/dist/server/server/workspace-registry-model.js +35 -21
  359. package/dist/server/server/workspace-registry-model.js.map +1 -1
  360. package/dist/server/server/workspace-registry.d.ts +2 -2
  361. package/dist/server/server/workspace-script-runtime-store.d.ts +2 -2
  362. package/dist/server/server/workspace-script-runtime-store.d.ts.map +1 -1
  363. package/dist/server/server/workspace-service-env.js +3 -3
  364. package/dist/server/server/workspace-service-env.js.map +1 -1
  365. package/dist/server/server/worktree-bootstrap.d.ts +4 -4
  366. package/dist/server/server/worktree-bootstrap.d.ts.map +1 -1
  367. package/dist/server/server/worktree-bootstrap.js +95 -67
  368. package/dist/server/server/worktree-bootstrap.js.map +1 -1
  369. package/dist/server/server/worktree-session.d.ts +8 -8
  370. package/dist/server/server/worktree-session.d.ts.map +1 -1
  371. package/dist/server/server/worktree-session.js +27 -19
  372. package/dist/server/server/worktree-session.js.map +1 -1
  373. package/dist/server/services/github-service.d.ts +1 -7
  374. package/dist/server/services/github-service.d.ts.map +1 -1
  375. package/dist/server/services/github-service.js +123 -143
  376. package/dist/server/services/github-service.js.map +1 -1
  377. package/dist/server/shared/agent-attention-notification.d.ts +9 -8
  378. package/dist/server/shared/agent-attention-notification.d.ts.map +1 -1
  379. package/dist/server/shared/agent-attention-notification.js +27 -17
  380. package/dist/server/shared/agent-attention-notification.js.map +1 -1
  381. package/dist/server/shared/daemon-endpoints.d.ts +2 -2
  382. package/dist/server/shared/daemon-endpoints.d.ts.map +1 -1
  383. package/dist/server/shared/daemon-endpoints.js +17 -2
  384. package/dist/server/shared/daemon-endpoints.js.map +1 -1
  385. package/dist/server/shared/messages.d.ts +21962 -3049
  386. package/dist/server/shared/messages.d.ts.map +1 -1
  387. package/dist/server/shared/messages.js +79 -2
  388. package/dist/server/shared/messages.js.map +1 -1
  389. package/dist/server/shared/terminal-stream-protocol.d.ts +2 -2
  390. package/dist/server/shared/terminal-stream-protocol.d.ts.map +1 -1
  391. package/dist/server/shared/tool-call-display.d.ts +2 -2
  392. package/dist/server/shared/tool-call-display.d.ts.map +1 -1
  393. package/dist/server/terminal/terminal-manager.d.ts.map +1 -1
  394. package/dist/server/terminal/terminal-manager.js +1 -3
  395. package/dist/server/terminal/terminal-manager.js.map +1 -1
  396. package/dist/server/terminal/terminal-output-coalescer.d.ts +6 -6
  397. package/dist/server/terminal/terminal-output-coalescer.d.ts.map +1 -1
  398. package/dist/server/terminal/terminal.d.ts +3 -2
  399. package/dist/server/terminal/terminal.d.ts.map +1 -1
  400. package/dist/server/terminal/terminal.js +57 -19
  401. package/dist/server/terminal/terminal.js.map +1 -1
  402. package/dist/server/utils/checkout-git.d.ts +13 -12
  403. package/dist/server/utils/checkout-git.d.ts.map +1 -1
  404. package/dist/server/utils/checkout-git.js +351 -281
  405. package/dist/server/utils/checkout-git.js.map +1 -1
  406. package/dist/server/utils/directory-suggestions.js +12 -33
  407. package/dist/server/utils/directory-suggestions.js.map +1 -1
  408. package/dist/server/utils/executable.d.ts +1 -14
  409. package/dist/server/utils/executable.d.ts.map +1 -1
  410. package/dist/server/utils/executable.js +13 -49
  411. package/dist/server/utils/executable.js.map +1 -1
  412. package/dist/server/utils/github-remote.d.ts +13 -0
  413. package/dist/server/utils/github-remote.d.ts.map +1 -0
  414. package/dist/server/utils/github-remote.js +128 -0
  415. package/dist/server/utils/github-remote.js.map +1 -0
  416. package/dist/server/utils/paseo-config-file.d.ts +30 -0
  417. package/dist/server/utils/paseo-config-file.d.ts.map +1 -0
  418. package/dist/server/utils/paseo-config-file.js +90 -0
  419. package/dist/server/utils/paseo-config-file.js.map +1 -0
  420. package/dist/server/utils/paseo-config-schema.d.ts +290 -0
  421. package/dist/server/utils/paseo-config-schema.d.ts.map +1 -0
  422. package/dist/server/utils/paseo-config-schema.js +60 -0
  423. package/dist/server/utils/paseo-config-schema.js.map +1 -0
  424. package/dist/server/utils/project-icon.d.ts.map +1 -1
  425. package/dist/server/utils/project-icon.js +84 -109
  426. package/dist/server/utils/project-icon.js.map +1 -1
  427. package/dist/server/utils/promise-timeout.d.ts +2 -2
  428. package/dist/server/utils/promise-timeout.d.ts.map +1 -1
  429. package/dist/server/utils/run-git-command.d.ts +3 -1
  430. package/dist/server/utils/run-git-command.d.ts.map +1 -1
  431. package/dist/server/utils/run-git-command.js +10 -1
  432. package/dist/server/utils/run-git-command.js.map +1 -1
  433. package/dist/server/utils/script-hostname.d.ts +2 -2
  434. package/dist/server/utils/script-hostname.d.ts.map +1 -1
  435. package/dist/server/utils/spawn.d.ts +10 -3
  436. package/dist/server/utils/spawn.d.ts.map +1 -1
  437. package/dist/server/utils/spawn.js +30 -5
  438. package/dist/server/utils/spawn.js.map +1 -1
  439. package/dist/server/utils/windows-command.d.ts +15 -0
  440. package/dist/server/utils/windows-command.d.ts.map +1 -0
  441. package/dist/server/utils/windows-command.js +37 -0
  442. package/dist/server/utils/windows-command.js.map +1 -0
  443. package/dist/server/utils/worktree.d.ts +10 -7
  444. package/dist/server/utils/worktree.d.ts.map +1 -1
  445. package/dist/server/utils/worktree.js +64 -55
  446. package/dist/server/utils/worktree.js.map +1 -1
  447. package/dist/src/server/pid-lock.js.map +1 -1
  448. package/package.json +15 -20
  449. package/dist/server/server/agent/llm-openai.d.ts +0 -7
  450. package/dist/server/server/agent/llm-openai.d.ts.map +0 -1
  451. package/dist/server/server/agent/llm-openai.js +0 -8
  452. package/dist/server/server/agent/llm-openai.js.map +0 -1
  453. package/dist/server/server/agent/orchestrator.d.ts +0 -12
  454. package/dist/server/server/agent/orchestrator.d.ts.map +0 -1
  455. package/dist/server/server/agent/orchestrator.js +0 -12
  456. package/dist/server/server/agent/orchestrator.js.map +0 -1
  457. package/dist/server/server/types.d.ts +0 -5
  458. package/dist/server/server/types.d.ts.map +0 -1
  459. package/dist/server/server/types.js +0 -3
  460. package/dist/server/server/types.js.map +0 -1
  461. package/dist/server/server/workspace-registry.test-helpers.d.ts +0 -37
  462. package/dist/server/server/workspace-registry.test-helpers.d.ts.map +0 -1
  463. package/dist/server/server/workspace-registry.test-helpers.js +0 -121
  464. package/dist/server/server/workspace-registry.test-helpers.js.map +0 -1
@@ -8,7 +8,7 @@ import { z } from "zod";
8
8
  import { loadCodexPersistedTimeline } from "./codex-rollout-timeline.js";
9
9
  import { renderPromptAttachmentAsText } from "../prompt-attachments.js";
10
10
  import { mapCodexRolloutToolCall, mapCodexToolCallFromThreadItem, } from "./codex/tool-call-mapper.js";
11
- import { applyProviderEnv, resolveProviderCommandPrefix, } from "../provider-launch-config.js";
11
+ import { createProviderEnv, createProviderEnvSpec, resolveProviderCommandPrefix, } from "../provider-launch-config.js";
12
12
  import { findExecutable, isCommandAvailable } from "../../../utils/executable.js";
13
13
  import { spawnProcess } from "../../../utils/spawn.js";
14
14
  import { extractCodexTerminalSessionId, nonEmptyString } from "./tool-call-mapper-utils.js";
@@ -96,16 +96,16 @@ function isObjectSchemaNode(schema) {
96
96
  type === "object" ||
97
97
  (Array.isArray(type) && type.includes("object")));
98
98
  }
99
- function normalizeCodexOutputSchemaNode(schema, path) {
99
+ function normalizeCodexOutputSchemaNode(schema, schemaPath) {
100
100
  if (Array.isArray(schema)) {
101
- return schema.map((entry, index) => normalizeCodexOutputSchemaNode(entry, `${path}[${index}]`));
101
+ return schema.map((entry, index) => normalizeCodexOutputSchemaNode(entry, `${schemaPath}[${index}]`));
102
102
  }
103
103
  if (!isSchemaRecord(schema)) {
104
104
  return schema;
105
105
  }
106
106
  const normalized = {};
107
107
  for (const [key, value] of Object.entries(schema)) {
108
- normalized[key] = normalizeCodexOutputSchemaNode(value, `${path}.${key}`);
108
+ normalized[key] = normalizeCodexOutputSchemaNode(value, `${schemaPath}.${key}`);
109
109
  }
110
110
  if (!isObjectSchemaNode(normalized)) {
111
111
  return normalized;
@@ -114,7 +114,7 @@ function normalizeCodexOutputSchemaNode(schema, path) {
114
114
  normalized.additionalProperties = false;
115
115
  }
116
116
  else if (normalized.additionalProperties !== false) {
117
- throw new Error(`Codex structured outputs require ${path} to set additionalProperties to false for object schemas.`);
117
+ throw new Error(`Codex structured outputs require ${schemaPath} to set additionalProperties to false for object schemas.`);
118
118
  }
119
119
  const properties = isSchemaRecord(normalized.properties) ? normalized.properties : null;
120
120
  if (!properties) {
@@ -156,6 +156,29 @@ async function resolveCodexLaunchPrefix(runtimeSettings) {
156
156
  function resolveCodexHomeDir() {
157
157
  return process.env.CODEX_HOME ?? path.join(os.homedir(), ".codex");
158
158
  }
159
+ function decodeEscapedChar(next) {
160
+ if (next === "n")
161
+ return "\n";
162
+ if (next === "t")
163
+ return "\t";
164
+ return next;
165
+ }
166
+ function resolvePermissionDecision(response) {
167
+ if (response.behavior === "allow")
168
+ return "accept";
169
+ if (response.interrupt)
170
+ return "cancel";
171
+ return "decline";
172
+ }
173
+ function firstPositiveFiniteNumber(primary, secondary) {
174
+ if (typeof primary === "number" && Number.isFinite(primary) && primary > 0) {
175
+ return primary;
176
+ }
177
+ if (typeof secondary === "number" && Number.isFinite(secondary) && secondary > 0) {
178
+ return secondary;
179
+ }
180
+ return undefined;
181
+ }
159
182
  function tokenizeCommandArgs(args) {
160
183
  const tokens = [];
161
184
  let current = "";
@@ -171,7 +194,7 @@ function tokenizeCommandArgs(args) {
171
194
  const next = args[i + 1];
172
195
  if (next === quote || next === "\\" || next === "n" || next === "t") {
173
196
  i += 1;
174
- current += next === "n" ? "\n" : next === "t" ? "\t" : next;
197
+ current += decodeEscapedChar(next);
175
198
  continue;
176
199
  }
177
200
  }
@@ -242,35 +265,27 @@ async function listCodexCustomPrompts() {
242
265
  catch {
243
266
  return [];
244
267
  }
245
- const commands = [];
246
- for (const entry of entries) {
247
- if (!entry.isFile()) {
248
- continue;
249
- }
250
- if (!entry.name.endsWith(".md")) {
251
- continue;
252
- }
268
+ const mdEntries = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".md") && entry.name.slice(0, -".md".length));
269
+ const parsedCommands = await Promise.all(mdEntries.map(async (entry) => {
253
270
  const name = entry.name.slice(0, -".md".length);
254
- if (!name) {
255
- continue;
256
- }
257
271
  const fullPath = path.join(promptsDir, entry.name);
258
272
  let content;
259
273
  try {
260
274
  content = await fs.readFile(fullPath, "utf8");
261
275
  }
262
276
  catch {
263
- continue;
277
+ return null;
264
278
  }
265
279
  const parsed = parseFrontMatter(content);
266
280
  const description = parsed.frontMatter["description"] ?? "Custom prompt";
267
281
  const argumentHint = parsed.frontMatter["argument-hint"] ?? parsed.frontMatter["argument_hint"] ?? "";
268
- commands.push({
282
+ return {
269
283
  name: `prompts:${name}`,
270
284
  description,
271
285
  argumentHint,
272
- });
273
- }
286
+ };
287
+ }));
288
+ const commands = parsedCommands.filter((cmd) => cmd !== null);
274
289
  return commands.sort((a, b) => a.name.localeCompare(b.name));
275
290
  }
276
291
  async function listCodexSkills(cwd, workspaceGitService) {
@@ -284,28 +299,30 @@ async function listCodexSkills(cwd, workspaceGitService) {
284
299
  candidates.push(path.join(repoRoot, ".codex", "skills"));
285
300
  }
286
301
  candidates.push(path.join(resolveCodexHomeDir(), "skills"));
287
- const commandsByName = new Map();
288
- for (const dir of candidates) {
302
+ const candidateReads = await Promise.all(candidates.map(async (dir) => {
289
303
  let entries;
290
304
  try {
291
305
  entries = await fs.readdir(dir, { withFileTypes: true });
292
306
  }
293
307
  catch {
294
- continue;
308
+ return [];
295
309
  }
296
- for (const entry of entries) {
297
- if (!entry.isDirectory() && !entry.isSymbolicLink()) {
298
- continue;
299
- }
310
+ const dirEntries = entries.filter((entry) => entry.isDirectory() || entry.isSymbolicLink());
311
+ const skillContents = await Promise.all(dirEntries.map(async (entry) => {
300
312
  const skillDir = path.join(dir, entry.name);
301
313
  const skillPath = path.join(skillDir, "SKILL.md");
302
- let content;
303
314
  try {
304
- content = await fs.readFile(skillPath, "utf8");
315
+ return await fs.readFile(skillPath, "utf8");
305
316
  }
306
317
  catch {
307
- continue;
318
+ return null;
308
319
  }
320
+ }));
321
+ return skillContents.filter((content) => content !== null);
322
+ }));
323
+ const commandsByName = new Map();
324
+ for (const skillContents of candidateReads) {
325
+ for (const content of skillContents) {
309
326
  const { frontMatter } = parseFrontMatter(content);
310
327
  const name = frontMatter["name"];
311
328
  const description = frontMatter["description"];
@@ -579,24 +596,8 @@ function toAgentUsage(tokenUsage) {
579
596
  if (!tokenUsage || typeof tokenUsage !== "object")
580
597
  return undefined;
581
598
  const usage = tokenUsage;
582
- const contextWindowMaxTokens = typeof usage.model_context_window === "number" &&
583
- Number.isFinite(usage.model_context_window) &&
584
- usage.model_context_window > 0
585
- ? usage.model_context_window
586
- : typeof usage.modelContextWindow === "number" &&
587
- Number.isFinite(usage.modelContextWindow) &&
588
- usage.modelContextWindow > 0
589
- ? usage.modelContextWindow
590
- : undefined;
591
- const contextWindowUsedTokens = typeof usage.last?.total_tokens === "number" &&
592
- Number.isFinite(usage.last.total_tokens) &&
593
- usage.last.total_tokens > 0
594
- ? usage.last.total_tokens
595
- : typeof usage.last?.totalTokens === "number" &&
596
- Number.isFinite(usage.last.totalTokens) &&
597
- usage.last.totalTokens > 0
598
- ? usage.last.totalTokens
599
- : undefined;
599
+ const contextWindowMaxTokens = firstPositiveFiniteNumber(usage.model_context_window, usage.modelContextWindow);
600
+ const contextWindowUsedTokens = firstPositiveFiniteNumber(usage.last?.total_tokens, usage.last?.totalTokens);
600
601
  return {
601
602
  inputTokens: usage.last?.inputTokens,
602
603
  cachedInputTokens: usage.last?.cachedInputTokens,
@@ -970,8 +971,8 @@ function parseCodexPatchChanges(changes) {
970
971
  ];
971
972
  }
972
973
  return Object.entries(recordChanges)
973
- .map(([path, value]) => {
974
- const normalizedPath = path.trim();
974
+ .map(([entryPath, value]) => {
975
+ const normalizedPath = entryPath.trim();
975
976
  if (!normalizedPath) {
976
977
  return null;
977
978
  }
@@ -1096,11 +1097,7 @@ function mapCodexPatchNotificationToToolCall(params) {
1096
1097
  : {
1097
1098
  ...(files.length > 0
1098
1099
  ? {
1099
- files: files.map((file) => ({
1100
- path: file.path,
1101
- ...(file.kind ? { kind: file.kind } : {}),
1102
- ...codexPatchTextFields(file.content ?? patchText),
1103
- })),
1100
+ files: files.map((file) => Object.assign({ path: file.path }, file.kind ? { kind: file.kind } : {}, codexPatchTextFields(file.content ?? patchText))),
1104
1101
  }
1105
1102
  : {}),
1106
1103
  ...(params.stdout ? { stdout: params.stdout } : {}),
@@ -1139,43 +1136,49 @@ function mapCodexTerminalInteractionToToolCall(params) {
1139
1136
  ...(processId ? { metadata: { processId } } : {}),
1140
1137
  };
1141
1138
  }
1139
+ function mapCodexThreadPlanItem(normalizedItem) {
1140
+ const callId = nonEmptyString(normalizedItem.id ?? normalizedItem.itemId ?? undefined) ??
1141
+ `plan:${normalizePlanMarkdown(typeof normalizedItem.text === "string" ? normalizedItem.text : "")}`;
1142
+ return mapCodexPlanToToolCall({
1143
+ callId,
1144
+ text: typeof normalizedItem.text === "string" ? normalizedItem.text : "",
1145
+ });
1146
+ }
1147
+ function mapCodexThreadReasoningItem(normalizedItem) {
1148
+ const summary = Array.isArray(normalizedItem.summary) ? normalizedItem.summary.join("\n") : "";
1149
+ const content = Array.isArray(normalizedItem.content) ? normalizedItem.content.join("\n") : "";
1150
+ const text = summary || content;
1151
+ return text ? { type: "reasoning", text } : null;
1152
+ }
1153
+ function mapCodexThreadUserMessageItem(normalizedItem, includeUserMessage) {
1154
+ if (!includeUserMessage) {
1155
+ return null;
1156
+ }
1157
+ const text = extractUserText(normalizedItem.content) ?? "";
1158
+ return { type: "user_message", text };
1159
+ }
1142
1160
  function threadItemToTimeline(item, options) {
1143
1161
  if (!item || typeof item !== "object")
1144
1162
  return null;
1163
+ const itemRecord = item;
1145
1164
  const includeUserMessage = options?.includeUserMessage ?? true;
1146
1165
  const cwd = options?.cwd ?? null;
1147
- const normalizedType = normalizeCodexThreadItemType(typeof item.type === "string" ? item.type : undefined);
1148
- const normalizedItem = normalizedType && normalizedType !== item.type
1149
- ? { ...item, type: normalizedType }
1150
- : item;
1166
+ const normalizedType = normalizeCodexThreadItemType(typeof itemRecord.type === "string" ? itemRecord.type : undefined);
1167
+ const normalizedItem = normalizedType && normalizedType !== itemRecord.type
1168
+ ? { ...itemRecord, type: normalizedType }
1169
+ : itemRecord;
1151
1170
  switch (normalizedType) {
1152
- case "userMessage": {
1153
- if (!includeUserMessage) {
1154
- return null;
1155
- }
1156
- const text = extractUserText(normalizedItem.content) ?? "";
1157
- return { type: "user_message", text };
1158
- }
1159
- case "agentMessage": {
1160
- return { type: "assistant_message", text: normalizedItem.text ?? "" };
1161
- }
1162
- case "plan": {
1163
- return mapCodexPlanToToolCall({
1164
- callId: nonEmptyString(normalizedItem.id ?? normalizedItem.itemId ?? undefined) ??
1165
- `plan:${normalizePlanMarkdown(normalizedItem.text ?? "")}`,
1166
- text: normalizedItem.text ?? "",
1167
- });
1168
- }
1169
- case "reasoning": {
1170
- const summary = Array.isArray(normalizedItem.summary)
1171
- ? normalizedItem.summary.join("\n")
1172
- : "";
1173
- const content = Array.isArray(normalizedItem.content)
1174
- ? normalizedItem.content.join("\n")
1175
- : "";
1176
- const text = summary || content;
1177
- return text ? { type: "reasoning", text } : null;
1178
- }
1171
+ case "userMessage":
1172
+ return mapCodexThreadUserMessageItem(normalizedItem, includeUserMessage);
1173
+ case "agentMessage":
1174
+ return {
1175
+ type: "assistant_message",
1176
+ text: typeof normalizedItem.text === "string" ? normalizedItem.text : "",
1177
+ };
1178
+ case "plan":
1179
+ return mapCodexThreadPlanItem(normalizedItem);
1180
+ case "reasoning":
1181
+ return mapCodexThreadReasoningItem(normalizedItem);
1179
1182
  case "commandExecution":
1180
1183
  case "fileChange":
1181
1184
  case "mcpToolCall":
@@ -1824,11 +1827,9 @@ export async function codexAppServerTurnInputFromPrompt(prompt, logger) {
1824
1827
  return [{ type: "text", text: prompt }];
1825
1828
  }
1826
1829
  const blocks = prompt;
1827
- const output = [];
1828
- for (const block of blocks) {
1830
+ const output = await Promise.all(blocks.map(async (block) => {
1829
1831
  if (!block || typeof block !== "object") {
1830
- output.push(block);
1831
- continue;
1832
+ return block;
1832
1833
  }
1833
1834
  const record = block;
1834
1835
  if (record.type === "image" &&
@@ -1836,38 +1837,32 @@ export async function codexAppServerTurnInputFromPrompt(prompt, logger) {
1836
1837
  typeof record.data === "string") {
1837
1838
  try {
1838
1839
  const filePath = await writeImageAttachment(record.mimeType, record.data);
1839
- output.push({ type: "localImage", path: filePath });
1840
+ return { type: "localImage", path: filePath };
1840
1841
  }
1841
1842
  catch (error) {
1842
1843
  const message = error instanceof Error ? error.message : String(error);
1843
1844
  logger.warn({ message }, "Failed to write Codex image attachment");
1844
- output.push({
1845
+ return {
1845
1846
  type: "text",
1846
1847
  text: `User attached image (failed to write temp file): ${message}`,
1847
- });
1848
+ };
1848
1849
  }
1849
- continue;
1850
1850
  }
1851
1851
  if (record.type === "github_pr" || record.type === "github_issue") {
1852
- output.push({
1852
+ return {
1853
1853
  type: "text",
1854
1854
  text: renderPromptAttachmentAsText(record),
1855
- });
1856
- continue;
1855
+ };
1857
1856
  }
1858
- output.push(block);
1859
- }
1857
+ return block;
1858
+ }));
1860
1859
  return output;
1861
1860
  }
1862
1861
  function buildCodexAppServerEnv(runtimeSettings, launchEnv) {
1863
- const env = applyProviderEnv(process.env, runtimeSettings);
1864
- if (!launchEnv) {
1865
- return env;
1866
- }
1867
- return {
1868
- ...env,
1869
- ...launchEnv,
1870
- };
1862
+ return createProviderEnv({
1863
+ runtimeSettings,
1864
+ overlays: [launchEnv],
1865
+ });
1871
1866
  }
1872
1867
  function buildCodexAppServerInitializeParams() {
1873
1868
  return {
@@ -1975,11 +1970,11 @@ class CodexAppServerAgentSession {
1975
1970
  const response = (await this.client.request("collaborationMode/list", {}));
1976
1971
  const data = Array.isArray(response?.data) ? response.data : [];
1977
1972
  this.collaborationModes = data.map((entry) => ({
1978
- name: String(entry.name ?? ""),
1979
- mode: entry.mode ?? null,
1980
- model: entry.model ?? null,
1981
- reasoning_effort: entry.reasoning_effort ?? null,
1982
- developer_instructions: entry.developer_instructions ?? null,
1973
+ name: typeof entry.name === "string" ? entry.name : "",
1974
+ mode: typeof entry.mode === "string" ? entry.mode : null,
1975
+ model: typeof entry.model === "string" ? entry.model : null,
1976
+ reasoning_effort: typeof entry.reasoning_effort === "string" ? entry.reasoning_effort : null,
1977
+ developer_instructions: typeof entry.developer_instructions === "string" ? entry.developer_instructions : null,
1983
1978
  }));
1984
1979
  }
1985
1980
  catch (error) {
@@ -1998,13 +1993,15 @@ class CodexAppServerAgentSession {
1998
1993
  const entries = Array.isArray(response?.data) ? response.data : [];
1999
1994
  const skills = [];
2000
1995
  for (const entry of entries) {
2001
- const list = Array.isArray(entry.skills) ? entry.skills : [];
1996
+ const list = Array.isArray(entry.skills)
1997
+ ? entry.skills
1998
+ : [];
2002
1999
  for (const skill of list) {
2003
- if (!skill?.name || !skill?.path)
2000
+ if (typeof skill?.name !== "string" || typeof skill?.path !== "string")
2004
2001
  continue;
2005
2002
  skills.push({
2006
2003
  name: skill.name,
2007
- description: skill.description ?? skill.shortDescription ?? "Skill",
2004
+ description: resolveSkillDescription(skill),
2008
2005
  path: skill.path,
2009
2006
  });
2010
2007
  }
@@ -2063,7 +2060,7 @@ class CodexAppServerAgentSession {
2063
2060
  }
2064
2061
  applyFeatureValue(featureId, value) {
2065
2062
  this.config.featureValues = {
2066
- ...(this.config.featureValues ?? {}),
2063
+ ...this.config.featureValues,
2067
2064
  [featureId]: value,
2068
2065
  };
2069
2066
  if (featureId === "fast_mode") {
@@ -2148,17 +2145,7 @@ class CodexAppServerAgentSession {
2148
2145
  if (thread && Array.isArray(thread.turns)) {
2149
2146
  for (const turn of thread.turns) {
2150
2147
  const items = Array.isArray(turn.items) ? turn.items : [];
2151
- for (const item of items) {
2152
- const timelineItem = threadItemToTimeline(item, {
2153
- cwd: this.config.cwd ?? null,
2154
- });
2155
- if (timelineItem) {
2156
- if (timelineItem.type === "tool_call") {
2157
- this.warnOnIncompleteEditToolCall(timelineItem, "thread_read", item);
2158
- }
2159
- threadTimeline.push(timelineItem);
2160
- }
2161
- }
2148
+ this.collectThreadTurnTimelineItems(items, threadTimeline);
2162
2149
  }
2163
2150
  }
2164
2151
  const timeline = rolloutTimeline.length > 0 ? rolloutTimeline : threadTimeline;
@@ -2486,55 +2473,13 @@ class CodexAppServerAgentSession {
2486
2473
  }
2487
2474
  const pendingRequest = this.pendingPermissions.get(requestId) ?? null;
2488
2475
  if (pending.kind === "plan") {
2489
- let followUpPrompt;
2490
- if (response.behavior === "allow") {
2491
- followUpPrompt = this.preparePlanImplementation({
2492
- planText: pending.planText ?? pendingRequest?.metadata?.planText,
2493
- });
2494
- }
2495
- this.pendingPermissionHandlers.delete(requestId);
2496
- this.pendingPermissions.delete(requestId);
2497
- this.resolvedPermissionRequests.add(requestId);
2498
- this.emitEvent({
2499
- type: "permission_resolved",
2500
- provider: CODEX_PROVIDER,
2501
- requestId,
2502
- resolution: response,
2503
- });
2504
- if (followUpPrompt) {
2505
- return { followUpPrompt };
2506
- }
2507
- return;
2476
+ return this.handlePlanPermissionResponse({ requestId, response, pending, pendingRequest });
2508
2477
  }
2509
2478
  this.pendingPermissionHandlers.delete(requestId);
2510
2479
  this.pendingPermissions.delete(requestId);
2511
2480
  this.resolvedPermissionRequests.add(requestId);
2512
2481
  if (response.behavior === "deny" && pendingRequest?.kind === "tool") {
2513
- const fallbackName = pendingRequest.name === "CodexBash"
2514
- ? "shell"
2515
- : pendingRequest.name === "CodexFileChange"
2516
- ? "apply_patch"
2517
- : pendingRequest.name;
2518
- this.emitEvent({
2519
- type: "timeline",
2520
- provider: CODEX_PROVIDER,
2521
- item: {
2522
- type: "tool_call",
2523
- callId: requestId,
2524
- name: fallbackName,
2525
- status: "failed",
2526
- error: { message: response.message ?? "Permission denied" },
2527
- detail: pendingRequest.detail ?? {
2528
- type: "unknown",
2529
- input: pendingRequest.input ?? null,
2530
- output: null,
2531
- },
2532
- metadata: {
2533
- permissionRequestId: requestId,
2534
- denied: true,
2535
- },
2536
- },
2537
- });
2482
+ this.emitDeniedToolCallTimelineEvent({ requestId, response, pendingRequest });
2538
2483
  }
2539
2484
  this.emitEvent({
2540
2485
  type: "permission_resolved",
@@ -2543,13 +2488,11 @@ class CodexAppServerAgentSession {
2543
2488
  resolution: response,
2544
2489
  });
2545
2490
  if (pending.kind === "command") {
2546
- const decision = response.behavior === "allow" ? "accept" : response.interrupt ? "cancel" : "decline";
2547
- pending.resolve({ decision });
2491
+ pending.resolve({ decision: resolvePermissionDecision(response) });
2548
2492
  return;
2549
2493
  }
2550
2494
  if (pending.kind === "file") {
2551
- const decision = response.behavior === "allow" ? "accept" : response.interrupt ? "cancel" : "decline";
2552
- pending.resolve({ decision });
2495
+ pending.resolve({ decision: resolvePermissionDecision(response) });
2553
2496
  return;
2554
2497
  }
2555
2498
  const questions = pending.questions ?? [];
@@ -2593,6 +2536,60 @@ class CodexAppServerAgentSession {
2593
2536
  });
2594
2537
  pending.resolve({ answers: {} });
2595
2538
  }
2539
+ handlePlanPermissionResponse(params) {
2540
+ const { requestId, response, pending, pendingRequest } = params;
2541
+ let followUpPrompt;
2542
+ if (response.behavior === "allow") {
2543
+ followUpPrompt = this.preparePlanImplementation({
2544
+ planText: pending.planText ?? pendingRequest?.metadata?.planText,
2545
+ });
2546
+ }
2547
+ this.pendingPermissionHandlers.delete(requestId);
2548
+ this.pendingPermissions.delete(requestId);
2549
+ this.resolvedPermissionRequests.add(requestId);
2550
+ this.emitEvent({
2551
+ type: "permission_resolved",
2552
+ provider: CODEX_PROVIDER,
2553
+ requestId,
2554
+ resolution: response,
2555
+ });
2556
+ if (followUpPrompt) {
2557
+ return { followUpPrompt };
2558
+ }
2559
+ }
2560
+ emitDeniedToolCallTimelineEvent(params) {
2561
+ const { requestId, response, pendingRequest } = params;
2562
+ let fallbackName;
2563
+ if (pendingRequest.name === "CodexBash") {
2564
+ fallbackName = "shell";
2565
+ }
2566
+ else if (pendingRequest.name === "CodexFileChange") {
2567
+ fallbackName = "apply_patch";
2568
+ }
2569
+ else {
2570
+ fallbackName = pendingRequest.name;
2571
+ }
2572
+ this.emitEvent({
2573
+ type: "timeline",
2574
+ provider: CODEX_PROVIDER,
2575
+ item: {
2576
+ type: "tool_call",
2577
+ callId: requestId,
2578
+ name: fallbackName,
2579
+ status: "failed",
2580
+ error: { message: response.message ?? "Permission denied" },
2581
+ detail: pendingRequest.detail ?? {
2582
+ type: "unknown",
2583
+ input: pendingRequest.input ?? null,
2584
+ output: null,
2585
+ },
2586
+ metadata: {
2587
+ permissionRequestId: requestId,
2588
+ denied: true,
2589
+ },
2590
+ },
2591
+ });
2592
+ }
2596
2593
  describePersistence() {
2597
2594
  if (!this.currentThreadId)
2598
2595
  return null;
@@ -2663,12 +2660,10 @@ class CodexAppServerAgentSession {
2663
2660
  : [];
2664
2661
  return [...appServerSkills, ...fallbackSkills, ...prompts].sort((a, b) => a.name.localeCompare(b.name));
2665
2662
  }
2666
- async ensureThread() {
2667
- if (!this.client)
2668
- return;
2669
- if (this.currentThreadId)
2670
- return;
2671
- // Resolve model + thinking defaults when omitted.
2663
+ async resolveModelAndThinking() {
2664
+ if (!this.client) {
2665
+ throw new Error("Codex client is not initialized");
2666
+ }
2672
2667
  let configuredDefaults = {};
2673
2668
  let model = this.config.model;
2674
2669
  let thinkingOptionId = normalizeCodexThinkingOptionId(this.config.thinkingOptionId);
@@ -2696,6 +2691,17 @@ class CodexAppServerAgentSession {
2696
2691
  thinkingOptionId = normalizeCodexThinkingOptionId(selectedModel.defaultReasoningEffort);
2697
2692
  }
2698
2693
  }
2694
+ if (!model) {
2695
+ throw new Error("Unable to resolve Codex model");
2696
+ }
2697
+ return { model, thinkingOptionId };
2698
+ }
2699
+ async ensureThread() {
2700
+ if (!this.client)
2701
+ return;
2702
+ if (this.currentThreadId)
2703
+ return;
2704
+ const { model, thinkingOptionId } = await this.resolveModelAndThinking();
2699
2705
  this.config.model = model;
2700
2706
  this.config.thinkingOptionId = thinkingOptionId;
2701
2707
  const preset = MODE_PRESETS[this.currentMode] ?? MODE_PRESETS[DEFAULT_CODEX_MODE_ID];
@@ -2764,96 +2770,62 @@ class CodexAppServerAgentSession {
2764
2770
  }
2765
2771
  handleNotification(method, params) {
2766
2772
  const parsed = CodexNotificationSchema.parse({ method, params });
2767
- if (parsed.kind === "thread_started") {
2768
- this.currentThreadId = parsed.threadId;
2769
- this.emitEvent({
2770
- type: "thread_started",
2771
- provider: CODEX_PROVIDER,
2772
- sessionId: parsed.threadId,
2773
- });
2774
- return;
2775
- }
2776
- if (parsed.kind === "turn_started") {
2777
- this.currentTurnId = parsed.turnId;
2778
- this.latestPlanResult = null;
2779
- this.emittedItemStartedIds.clear();
2780
- this.emittedItemCompletedIds.clear();
2781
- this.emittedExecCommandStartedCallIds.clear();
2782
- this.emittedExecCommandCompletedCallIds.clear();
2783
- this.pendingCommandOutputDeltas.clear();
2784
- this.pendingFileChangeOutputDeltas.clear();
2785
- this.warnedIncompleteEditToolCallIds.clear();
2786
- this.emitEvent({ type: "turn_started", provider: CODEX_PROVIDER });
2787
- return;
2788
- }
2789
- if (parsed.kind === "turn_completed") {
2790
- if (parsed.status === "failed") {
2791
- this.emitEvent({
2792
- type: "turn_failed",
2793
- provider: CODEX_PROVIDER,
2794
- error: parsed.errorMessage ?? "Codex turn failed",
2795
- });
2796
- }
2797
- else if (parsed.status === "interrupted") {
2798
- this.emitEvent({ type: "turn_canceled", provider: CODEX_PROVIDER, reason: "interrupted" });
2799
- }
2800
- else {
2801
- if (this.planModeEnabled && this.latestPlanResult?.text) {
2802
- this.emitSyntheticPlanApprovalRequest(this.latestPlanResult.text);
2803
- }
2804
- this.emitEvent({
2805
- type: "turn_completed",
2806
- provider: CODEX_PROVIDER,
2807
- usage: this.latestUsage,
2808
- });
2809
- }
2810
- this.activeForegroundTurnId = null;
2811
- this.latestPlanResult = null;
2812
- this.emittedItemStartedIds.clear();
2813
- this.emittedItemCompletedIds.clear();
2814
- this.emittedExecCommandStartedCallIds.clear();
2815
- this.emittedExecCommandCompletedCallIds.clear();
2816
- this.pendingCommandOutputDeltas.clear();
2817
- this.pendingFileChangeOutputDeltas.clear();
2818
- this.warnedIncompleteEditToolCallIds.clear();
2819
- return;
2820
- }
2821
- if (parsed.kind === "plan_updated") {
2822
- const timelineItem = mapCodexPlanToToolCall({
2823
- callId: `plan:${this.currentTurnId ?? this.currentThreadId ?? "current"}`,
2824
- text: planStepsToMarkdown(parsed.plan.map((entry) => ({
2825
- step: entry.step ?? "",
2826
- status: entry.status ?? "pending",
2827
- }))),
2828
- });
2829
- if (timelineItem) {
2830
- this.rememberPlanResult(timelineItem);
2831
- this.emitEvent({
2832
- type: "timeline",
2833
- provider: CODEX_PROVIDER,
2834
- item: timelineItem,
2835
- });
2836
- }
2837
- return;
2838
- }
2839
- if (parsed.kind === "diff_updated") {
2840
- // NOTE: Codex app-server emits frequent `turn/diff/updated` notifications
2841
- // containing a full accumulated unified diff for the *entire turn*.
2842
- // This is not a concrete file-change tool call; it is progress telemetry.
2843
- // We intentionally do NOT store every diff update in the timeline.
2844
- return;
2845
- }
2846
- if (parsed.kind === "token_usage_updated") {
2847
- this.latestUsage = toAgentUsage(parsed.tokenUsage);
2848
- if (this.latestUsage) {
2849
- this.notifySubscribers({
2850
- type: "usage_updated",
2851
- provider: CODEX_PROVIDER,
2852
- usage: this.latestUsage,
2853
- });
2854
- }
2855
- return;
2773
+ switch (parsed.kind) {
2774
+ case "thread_started":
2775
+ this.handleThreadStartedNotification(parsed);
2776
+ return;
2777
+ case "turn_started":
2778
+ this.handleTurnStartedNotification(parsed);
2779
+ return;
2780
+ case "turn_completed":
2781
+ this.handleTurnCompletedNotification(parsed);
2782
+ return;
2783
+ case "plan_updated":
2784
+ this.handlePlanUpdatedNotification(parsed);
2785
+ return;
2786
+ case "diff_updated":
2787
+ // NOTE: Codex app-server emits frequent `turn/diff/updated` notifications
2788
+ // containing a full accumulated unified diff for the *entire turn*.
2789
+ // This is not a concrete file-change tool call; it is progress telemetry.
2790
+ return;
2791
+ case "token_usage_updated":
2792
+ this.handleTokenUsageUpdatedNotification(parsed);
2793
+ return;
2794
+ case "agent_message_delta":
2795
+ case "reasoning_delta":
2796
+ case "exec_command_output_delta":
2797
+ case "file_change_output_delta":
2798
+ this.handleCodexDeltaNotification(parsed);
2799
+ return;
2800
+ case "exec_command_started":
2801
+ this.handleExecCommandStartedNotification(parsed);
2802
+ return;
2803
+ case "exec_command_completed":
2804
+ this.handleExecCommandCompletedNotification(parsed);
2805
+ return;
2806
+ case "terminal_interaction":
2807
+ this.handleTerminalInteractionNotification(parsed);
2808
+ return;
2809
+ case "patch_apply_started":
2810
+ this.handlePatchApplyStartedNotification(parsed);
2811
+ return;
2812
+ case "patch_apply_completed":
2813
+ this.handlePatchApplyCompletedNotification(parsed);
2814
+ return;
2815
+ case "item_completed":
2816
+ this.handleItemCompletedNotification(parsed);
2817
+ return;
2818
+ case "item_started":
2819
+ this.handleItemStartedNotification(parsed);
2820
+ return;
2821
+ case "invalid_payload":
2822
+ this.warnInvalidNotificationPayload(parsed.method, parsed.params);
2823
+ return;
2824
+ default:
2825
+ this.warnUnknownNotificationMethod(parsed.method, parsed.params);
2856
2826
  }
2827
+ }
2828
+ handleCodexDeltaNotification(parsed) {
2857
2829
  if (parsed.kind === "agent_message_delta") {
2858
2830
  const prev = this.pendingAgentMessages.get(parsed.itemId) ?? "";
2859
2831
  this.pendingAgentMessages.set(parsed.itemId, prev + parsed.delta);
@@ -2871,192 +2843,255 @@ class CodexAppServerAgentSession {
2871
2843
  });
2872
2844
  return;
2873
2845
  }
2874
- if (parsed.kind === "file_change_output_delta") {
2875
- this.appendOutputDeltaChunk(this.pendingFileChangeOutputDeltas, parsed.itemId, parsed.delta);
2876
- return;
2846
+ this.appendOutputDeltaChunk(this.pendingFileChangeOutputDeltas, parsed.itemId, parsed.delta);
2847
+ }
2848
+ handleThreadStartedNotification(parsed) {
2849
+ this.currentThreadId = parsed.threadId;
2850
+ this.emitEvent({
2851
+ type: "thread_started",
2852
+ provider: CODEX_PROVIDER,
2853
+ sessionId: parsed.threadId,
2854
+ });
2855
+ }
2856
+ handleTurnStartedNotification(parsed) {
2857
+ this.currentTurnId = parsed.turnId;
2858
+ this.resetTurnTrackingState();
2859
+ this.emitEvent({ type: "turn_started", provider: CODEX_PROVIDER });
2860
+ }
2861
+ handleTurnCompletedNotification(parsed) {
2862
+ if (parsed.status === "failed") {
2863
+ this.emitEvent({
2864
+ type: "turn_failed",
2865
+ provider: CODEX_PROVIDER,
2866
+ error: parsed.errorMessage ?? "Codex turn failed",
2867
+ });
2868
+ }
2869
+ else if (parsed.status === "interrupted") {
2870
+ this.emitEvent({ type: "turn_canceled", provider: CODEX_PROVIDER, reason: "interrupted" });
2877
2871
  }
2878
- if (parsed.kind === "exec_command_started") {
2879
- if (parsed.callId) {
2880
- this.emittedExecCommandStartedCallIds.add(parsed.callId);
2881
- this.pendingCommandOutputDeltas.delete(parsed.callId);
2872
+ else {
2873
+ if (this.planModeEnabled && this.latestPlanResult?.text) {
2874
+ this.emitSyntheticPlanApprovalRequest(this.latestPlanResult.text);
2882
2875
  }
2883
- const timelineItem = mapCodexExecNotificationToToolCall({
2884
- callId: parsed.callId,
2885
- command: parsed.command,
2886
- cwd: parsed.cwd ?? this.config.cwd ?? null,
2887
- running: true,
2876
+ this.emitEvent({
2877
+ type: "turn_completed",
2878
+ provider: CODEX_PROVIDER,
2879
+ usage: this.latestUsage,
2888
2880
  });
2889
- if (timelineItem) {
2890
- this.emitEvent({ type: "timeline", provider: CODEX_PROVIDER, item: timelineItem });
2891
- }
2892
- return;
2893
2881
  }
2894
- if (parsed.kind === "exec_command_completed") {
2895
- const bufferedOutput = this.consumeOutputDelta(this.pendingCommandOutputDeltas, parsed.callId);
2896
- const resolvedOutput = parsed.output ?? bufferedOutput;
2897
- this.rememberTerminalProcessForCommand(parsed.command, resolvedOutput);
2898
- const timelineItem = mapCodexExecNotificationToToolCall({
2899
- callId: parsed.callId,
2900
- command: parsed.command,
2901
- cwd: parsed.cwd ?? this.config.cwd ?? null,
2902
- output: resolvedOutput,
2903
- exitCode: parsed.exitCode,
2904
- success: parsed.success,
2905
- stderr: parsed.stderr,
2906
- running: false,
2907
- });
2908
- if (timelineItem) {
2909
- this.emittedExecCommandCompletedCallIds.add(timelineItem.callId);
2910
- this.emitEvent({ type: "timeline", provider: CODEX_PROVIDER, item: timelineItem });
2911
- }
2912
- return;
2882
+ this.activeForegroundTurnId = null;
2883
+ this.resetTurnTrackingState();
2884
+ }
2885
+ resetTurnTrackingState() {
2886
+ this.latestPlanResult = null;
2887
+ this.emittedItemStartedIds.clear();
2888
+ this.emittedItemCompletedIds.clear();
2889
+ this.emittedExecCommandStartedCallIds.clear();
2890
+ this.emittedExecCommandCompletedCallIds.clear();
2891
+ this.pendingCommandOutputDeltas.clear();
2892
+ this.pendingFileChangeOutputDeltas.clear();
2893
+ this.warnedIncompleteEditToolCallIds.clear();
2894
+ }
2895
+ handlePlanUpdatedNotification(parsed) {
2896
+ const timelineItem = mapCodexPlanToToolCall({
2897
+ callId: `plan:${this.currentTurnId ?? this.currentThreadId ?? "current"}`,
2898
+ text: planStepsToMarkdown(parsed.plan.map((entry) => ({
2899
+ step: entry.step ?? "",
2900
+ status: entry.status ?? "pending",
2901
+ }))),
2902
+ });
2903
+ if (timelineItem) {
2904
+ this.rememberPlanResult(timelineItem);
2905
+ this.emitEvent({ type: "timeline", provider: CODEX_PROVIDER, item: timelineItem });
2913
2906
  }
2914
- if (parsed.kind === "terminal_interaction") {
2915
- const interactionKey = [parsed.processId ?? "", parsed.stdin ?? ""].join("\u0000");
2916
- if (!this.shouldEmitTerminalInteractionKey(interactionKey)) {
2917
- return;
2918
- }
2919
- const command = (parsed.processId ? this.terminalCommandByProcessId.get(parsed.processId) : undefined) ??
2920
- null;
2921
- if (!command && parsed.processId) {
2922
- this.pendingUnlabeledTerminalInteractions.add(parsed.processId);
2923
- }
2924
- const timelineItem = mapCodexTerminalInteractionToToolCall({
2925
- processId: parsed.processId,
2926
- fallbackCallId: parsed.callId,
2927
- command,
2907
+ }
2908
+ handleTokenUsageUpdatedNotification(parsed) {
2909
+ this.latestUsage = toAgentUsage(parsed.tokenUsage);
2910
+ if (this.latestUsage) {
2911
+ this.notifySubscribers({
2912
+ type: "usage_updated",
2913
+ provider: CODEX_PROVIDER,
2914
+ usage: this.latestUsage,
2928
2915
  });
2916
+ }
2917
+ }
2918
+ handleExecCommandStartedNotification(parsed) {
2919
+ if (parsed.callId) {
2920
+ this.emittedExecCommandStartedCallIds.add(parsed.callId);
2921
+ this.pendingCommandOutputDeltas.delete(parsed.callId);
2922
+ }
2923
+ const timelineItem = mapCodexExecNotificationToToolCall({
2924
+ callId: parsed.callId,
2925
+ command: parsed.command,
2926
+ cwd: parsed.cwd ?? this.config.cwd ?? null,
2927
+ running: true,
2928
+ });
2929
+ if (timelineItem) {
2930
+ this.emitEvent({ type: "timeline", provider: CODEX_PROVIDER, item: timelineItem });
2931
+ }
2932
+ }
2933
+ handleExecCommandCompletedNotification(parsed) {
2934
+ const bufferedOutput = this.consumeOutputDelta(this.pendingCommandOutputDeltas, parsed.callId);
2935
+ const resolvedOutput = parsed.output ?? bufferedOutput;
2936
+ this.rememberTerminalProcessForCommand(parsed.command, resolvedOutput);
2937
+ const timelineItem = mapCodexExecNotificationToToolCall({
2938
+ callId: parsed.callId,
2939
+ command: parsed.command,
2940
+ cwd: parsed.cwd ?? this.config.cwd ?? null,
2941
+ output: resolvedOutput,
2942
+ exitCode: parsed.exitCode,
2943
+ success: parsed.success,
2944
+ stderr: parsed.stderr,
2945
+ running: false,
2946
+ });
2947
+ if (timelineItem) {
2948
+ this.emittedExecCommandCompletedCallIds.add(timelineItem.callId);
2929
2949
  this.emitEvent({ type: "timeline", provider: CODEX_PROVIDER, item: timelineItem });
2950
+ }
2951
+ }
2952
+ handleTerminalInteractionNotification(parsed) {
2953
+ const interactionKey = [parsed.processId ?? "", parsed.stdin ?? ""].join("\u0000");
2954
+ if (!this.shouldEmitTerminalInteractionKey(interactionKey)) {
2930
2955
  return;
2931
2956
  }
2932
- if (parsed.kind === "patch_apply_started") {
2933
- if (parsed.callId) {
2934
- this.pendingFileChangeOutputDeltas.delete(parsed.callId);
2935
- }
2936
- const timelineItem = mapCodexPatchNotificationToToolCall({
2957
+ const command = (parsed.processId ? this.terminalCommandByProcessId.get(parsed.processId) : undefined) ??
2958
+ null;
2959
+ if (!command && parsed.processId) {
2960
+ this.pendingUnlabeledTerminalInteractions.add(parsed.processId);
2961
+ }
2962
+ const timelineItem = mapCodexTerminalInteractionToToolCall({
2963
+ processId: parsed.processId,
2964
+ fallbackCallId: parsed.callId,
2965
+ command,
2966
+ });
2967
+ this.emitEvent({ type: "timeline", provider: CODEX_PROVIDER, item: timelineItem });
2968
+ }
2969
+ handlePatchApplyStartedNotification(parsed) {
2970
+ if (parsed.callId) {
2971
+ this.pendingFileChangeOutputDeltas.delete(parsed.callId);
2972
+ }
2973
+ const timelineItem = mapCodexPatchNotificationToToolCall({
2974
+ callId: parsed.callId,
2975
+ changes: parsed.changes,
2976
+ cwd: this.config.cwd ?? null,
2977
+ running: true,
2978
+ });
2979
+ if (timelineItem) {
2980
+ this.warnOnIncompleteEditToolCall(timelineItem, "patch_apply_started", {
2937
2981
  callId: parsed.callId,
2938
2982
  changes: parsed.changes,
2939
- cwd: this.config.cwd ?? null,
2940
- running: true,
2941
2983
  });
2942
- if (timelineItem) {
2943
- this.warnOnIncompleteEditToolCall(timelineItem, "patch_apply_started", {
2944
- callId: parsed.callId,
2945
- changes: parsed.changes,
2946
- });
2947
- this.emitEvent({ type: "timeline", provider: CODEX_PROVIDER, item: timelineItem });
2948
- }
2949
- return;
2984
+ this.emitEvent({ type: "timeline", provider: CODEX_PROVIDER, item: timelineItem });
2950
2985
  }
2951
- if (parsed.kind === "patch_apply_completed") {
2952
- const bufferedOutput = this.consumeOutputDelta(this.pendingFileChangeOutputDeltas, parsed.callId);
2953
- const timelineItem = mapCodexPatchNotificationToToolCall({
2986
+ }
2987
+ handlePatchApplyCompletedNotification(parsed) {
2988
+ const bufferedOutput = this.consumeOutputDelta(this.pendingFileChangeOutputDeltas, parsed.callId);
2989
+ const timelineItem = mapCodexPatchNotificationToToolCall({
2990
+ callId: parsed.callId,
2991
+ changes: parsed.changes,
2992
+ cwd: this.config.cwd ?? null,
2993
+ stdout: parsed.stdout ?? bufferedOutput,
2994
+ stderr: parsed.stderr,
2995
+ success: parsed.success,
2996
+ running: false,
2997
+ });
2998
+ if (timelineItem) {
2999
+ this.warnOnIncompleteEditToolCall(timelineItem, "patch_apply_completed", {
2954
3000
  callId: parsed.callId,
2955
3001
  changes: parsed.changes,
2956
- cwd: this.config.cwd ?? null,
2957
- stdout: parsed.stdout ?? bufferedOutput,
2958
- stderr: parsed.stderr,
2959
- success: parsed.success,
2960
- running: false,
3002
+ stdout: parsed.stdout,
2961
3003
  });
2962
- if (timelineItem) {
2963
- this.warnOnIncompleteEditToolCall(timelineItem, "patch_apply_completed", {
2964
- callId: parsed.callId,
2965
- changes: parsed.changes,
2966
- stdout: parsed.stdout,
2967
- });
2968
- this.emitEvent({ type: "timeline", provider: CODEX_PROVIDER, item: timelineItem });
2969
- }
3004
+ this.emitEvent({ type: "timeline", provider: CODEX_PROVIDER, item: timelineItem });
3005
+ }
3006
+ }
3007
+ handleItemCompletedNotification(parsed) {
3008
+ // Codex emits mirrored lifecycle notifications via both `codex/event/item_*`
3009
+ // and canonical `item/*`. We render only the canonical channel to avoid
3010
+ // duplicated assistant/reasoning rows.
3011
+ if (parsed.source === "codex_event") {
2970
3012
  return;
2971
3013
  }
2972
- if (parsed.kind === "item_completed") {
2973
- // Codex emits mirrored lifecycle notifications via both `codex/event/item_*`
2974
- // and canonical `item/*`. We render only the canonical channel to avoid
2975
- // duplicated assistant/reasoning rows.
2976
- if (parsed.source === "codex_event") {
3014
+ const timelineItem = threadItemToTimeline(parsed.item, {
3015
+ includeUserMessage: false,
3016
+ cwd: this.config.cwd ?? null,
3017
+ });
3018
+ if (!timelineItem) {
3019
+ return;
3020
+ }
3021
+ const normalizedItemType = normalizeCodexThreadItemType(typeof parsed.item.type === "string" ? parsed.item.type : undefined);
3022
+ const itemId = parsed.item.id;
3023
+ // For commandExecution items, codex/event/exec_command_* is authoritative.
3024
+ if (timelineItem.type === "tool_call" && normalizedItemType === "commandExecution") {
3025
+ const callId = timelineItem.callId || itemId;
3026
+ if (callId && this.emittedExecCommandCompletedCallIds.has(callId)) {
2977
3027
  return;
2978
3028
  }
2979
- const timelineItem = threadItemToTimeline(parsed.item, {
2980
- includeUserMessage: false,
2981
- cwd: this.config.cwd ?? null,
2982
- });
2983
- if (timelineItem) {
2984
- const normalizedItemType = normalizeCodexThreadItemType(typeof parsed.item.type === "string" ? parsed.item.type : undefined);
2985
- const itemId = parsed.item.id;
2986
- // For commandExecution items, codex/event/exec_command_* is authoritative.
2987
- // Keep item/completed as fallback only when no exec_command completion was seen.
2988
- if (timelineItem.type === "tool_call" && normalizedItemType === "commandExecution") {
2989
- const callId = timelineItem.callId || itemId;
2990
- if (callId && this.emittedExecCommandCompletedCallIds.has(callId)) {
2991
- return;
2992
- }
2993
- }
2994
- if (itemId && this.emittedItemCompletedIds.has(itemId)) {
2995
- return;
2996
- }
2997
- if (timelineItem.type === "assistant_message" && itemId) {
2998
- const buffered = this.pendingAgentMessages.get(itemId);
2999
- if (buffered && buffered.length > 0) {
3000
- timelineItem.text = buffered;
3001
- }
3002
- }
3003
- if (timelineItem.type === "reasoning" && itemId) {
3004
- const buffered = this.pendingReasoning.get(itemId);
3005
- if (buffered && buffered.length > 0) {
3006
- timelineItem.text = buffered.join("");
3007
- }
3008
- }
3009
- if (timelineItem.type === "tool_call") {
3010
- if (timelineItem.detail.type === "plan") {
3011
- this.rememberPlanResult(timelineItem);
3012
- }
3013
- this.warnOnIncompleteEditToolCall(timelineItem, "item_completed", parsed.item);
3014
- }
3015
- this.emitEvent({ type: "timeline", provider: CODEX_PROVIDER, item: timelineItem });
3016
- if (itemId) {
3017
- this.emittedItemCompletedIds.add(itemId);
3018
- this.emittedItemStartedIds.delete(itemId);
3019
- this.pendingCommandOutputDeltas.delete(itemId);
3020
- this.pendingFileChangeOutputDeltas.delete(itemId);
3021
- }
3029
+ }
3030
+ if (itemId && this.emittedItemCompletedIds.has(itemId)) {
3031
+ return;
3032
+ }
3033
+ this.applyBufferedDeltaTextToTimelineItem(timelineItem, itemId);
3034
+ if (timelineItem.type === "tool_call") {
3035
+ if (timelineItem.detail.type === "plan") {
3036
+ this.rememberPlanResult(timelineItem);
3022
3037
  }
3038
+ this.warnOnIncompleteEditToolCall(timelineItem, "item_completed", parsed.item);
3039
+ }
3040
+ this.emitEvent({ type: "timeline", provider: CODEX_PROVIDER, item: timelineItem });
3041
+ if (itemId) {
3042
+ this.emittedItemCompletedIds.add(itemId);
3043
+ this.emittedItemStartedIds.delete(itemId);
3044
+ this.pendingCommandOutputDeltas.delete(itemId);
3045
+ this.pendingFileChangeOutputDeltas.delete(itemId);
3046
+ }
3047
+ }
3048
+ applyBufferedDeltaTextToTimelineItem(timelineItem, itemId) {
3049
+ if (!itemId) {
3023
3050
  return;
3024
3051
  }
3025
- if (parsed.kind === "item_started") {
3026
- if (parsed.source === "codex_event") {
3027
- return;
3052
+ if (timelineItem.type === "assistant_message") {
3053
+ const buffered = this.pendingAgentMessages.get(itemId);
3054
+ if (buffered && buffered.length > 0) {
3055
+ timelineItem.text = buffered;
3028
3056
  }
3029
- const timelineItem = threadItemToTimeline(parsed.item, {
3030
- includeUserMessage: false,
3031
- cwd: this.config.cwd ?? null,
3032
- });
3033
- if (timelineItem && timelineItem.type === "tool_call") {
3034
- const normalizedItemType = normalizeCodexThreadItemType(typeof parsed.item.type === "string" ? parsed.item.type : undefined);
3035
- const itemId = parsed.item.id;
3036
- if (normalizedItemType === "commandExecution") {
3037
- const callId = timelineItem.callId || itemId;
3038
- if (callId && this.emittedExecCommandStartedCallIds.has(callId)) {
3039
- return;
3040
- }
3041
- }
3042
- if (itemId && this.emittedItemStartedIds.has(itemId)) {
3043
- return;
3044
- }
3045
- this.warnOnIncompleteEditToolCall(timelineItem, "item_started", parsed.item);
3046
- this.emitEvent({ type: "timeline", provider: CODEX_PROVIDER, item: timelineItem });
3047
- if (itemId) {
3048
- this.emittedItemStartedIds.add(itemId);
3049
- this.pendingCommandOutputDeltas.delete(itemId);
3050
- this.pendingFileChangeOutputDeltas.delete(itemId);
3051
- }
3057
+ return;
3058
+ }
3059
+ if (timelineItem.type === "reasoning") {
3060
+ const buffered = this.pendingReasoning.get(itemId);
3061
+ if (buffered && buffered.length > 0) {
3062
+ timelineItem.text = buffered.join("");
3052
3063
  }
3064
+ }
3065
+ }
3066
+ handleItemStartedNotification(parsed) {
3067
+ if (parsed.source === "codex_event") {
3053
3068
  return;
3054
3069
  }
3055
- if (parsed.kind === "invalid_payload") {
3056
- this.warnInvalidNotificationPayload(parsed.method, parsed.params);
3070
+ const timelineItem = threadItemToTimeline(parsed.item, {
3071
+ includeUserMessage: false,
3072
+ cwd: this.config.cwd ?? null,
3073
+ });
3074
+ if (!timelineItem || timelineItem.type !== "tool_call") {
3057
3075
  return;
3058
3076
  }
3059
- this.warnUnknownNotificationMethod(parsed.method, parsed.params);
3077
+ const normalizedItemType = normalizeCodexThreadItemType(typeof parsed.item.type === "string" ? parsed.item.type : undefined);
3078
+ const itemId = parsed.item.id;
3079
+ if (normalizedItemType === "commandExecution") {
3080
+ const callId = timelineItem.callId || itemId;
3081
+ if (callId && this.emittedExecCommandStartedCallIds.has(callId)) {
3082
+ return;
3083
+ }
3084
+ }
3085
+ if (itemId && this.emittedItemStartedIds.has(itemId)) {
3086
+ return;
3087
+ }
3088
+ this.warnOnIncompleteEditToolCall(timelineItem, "item_started", parsed.item);
3089
+ this.emitEvent({ type: "timeline", provider: CODEX_PROVIDER, item: timelineItem });
3090
+ if (itemId) {
3091
+ this.emittedItemStartedIds.add(itemId);
3092
+ this.pendingCommandOutputDeltas.delete(itemId);
3093
+ this.pendingFileChangeOutputDeltas.delete(itemId);
3094
+ }
3060
3095
  }
3061
3096
  warnUnknownNotificationMethod(method, params) {
3062
3097
  if (this.warnedUnknownNotificationMethods.has(method)) {
@@ -3132,6 +3167,20 @@ class CodexAppServerAgentSession {
3132
3167
  this.emittedTerminalInteractionKeys.add(key);
3133
3168
  return true;
3134
3169
  }
3170
+ collectThreadTurnTimelineItems(items, target) {
3171
+ for (const item of items) {
3172
+ const timelineItem = threadItemToTimeline(item, {
3173
+ cwd: this.config.cwd ?? null,
3174
+ });
3175
+ if (!timelineItem) {
3176
+ continue;
3177
+ }
3178
+ if (timelineItem.type === "tool_call") {
3179
+ this.warnOnIncompleteEditToolCall(timelineItem, "thread_read", item);
3180
+ }
3181
+ target.push(timelineItem);
3182
+ }
3183
+ }
3135
3184
  warnOnIncompleteEditToolCall(item, source, payload) {
3136
3185
  if (!isEditToolCallWithoutContent(item)) {
3137
3186
  return;
@@ -3280,7 +3329,10 @@ export class CodexAppServerAgentClient {
3280
3329
  return spawnProcess(launchPrefix.command, [...launchPrefix.args, "app-server"], {
3281
3330
  detached: process.platform !== "win32",
3282
3331
  stdio: ["pipe", "pipe", "pipe"],
3283
- env: buildCodexAppServerEnv(this.runtimeSettings, launchEnv),
3332
+ ...createProviderEnvSpec({
3333
+ runtimeSettings: this.runtimeSettings,
3334
+ overlays: [launchEnv],
3335
+ }),
3284
3336
  });
3285
3337
  }
3286
3338
  async createSession(config, launchContext) {
@@ -3310,18 +3362,19 @@ export class CodexAppServerAgentClient {
3310
3362
  const limit = options?.limit ?? 20;
3311
3363
  const response = (await client.request("thread/list", { limit }));
3312
3364
  const threads = Array.isArray(response?.data) ? response.data : [];
3313
- const descriptors = [];
3314
- for (const thread of threads.slice(0, limit)) {
3315
- const threadId = thread.id;
3316
- const cwd = thread.cwd ?? process.cwd();
3317
- const title = thread.preview ?? null;
3365
+ const descriptors = await Promise.all(threads.slice(0, limit).map(async (thread) => {
3366
+ const threadId = typeof thread.id === "string" ? thread.id : "";
3367
+ const cwd = typeof thread.cwd === "string" ? thread.cwd : process.cwd();
3368
+ const title = typeof thread.preview === "string" ? thread.preview : null;
3318
3369
  let timeline = [];
3319
3370
  try {
3320
- const rolloutTimeline = await loadCodexPersistedTimeline(threadId, undefined, this.logger);
3321
- const read = (await client.request("thread/read", {
3322
- threadId,
3323
- includeTurns: true,
3324
- }));
3371
+ const [rolloutTimeline, read] = await Promise.all([
3372
+ loadCodexPersistedTimeline(threadId, undefined, this.logger),
3373
+ client.request("thread/read", {
3374
+ threadId,
3375
+ includeTurns: true,
3376
+ }),
3377
+ ]);
3325
3378
  const turns = read.thread?.turns ?? [];
3326
3379
  const itemsFromThreadRead = [];
3327
3380
  for (const turn of turns) {
@@ -3336,12 +3389,14 @@ export class CodexAppServerAgentClient {
3336
3389
  catch {
3337
3390
  timeline = [];
3338
3391
  }
3339
- descriptors.push({
3392
+ return {
3340
3393
  provider: CODEX_PROVIDER,
3341
3394
  sessionId: threadId,
3342
3395
  cwd,
3343
3396
  title,
3344
- lastActivityAt: new Date((thread.updatedAt ?? thread.createdAt ?? 0) * 1000),
3397
+ lastActivityAt: new Date(((typeof thread.updatedAt === "number" ? thread.updatedAt : undefined) ??
3398
+ (typeof thread.createdAt === "number" ? thread.createdAt : undefined) ??
3399
+ 0) * 1000),
3345
3400
  persistence: {
3346
3401
  provider: CODEX_PROVIDER,
3347
3402
  sessionId: threadId,
@@ -3354,8 +3409,8 @@ export class CodexAppServerAgentClient {
3354
3409
  },
3355
3410
  },
3356
3411
  timeline,
3357
- });
3358
- }
3412
+ };
3413
+ }));
3359
3414
  return descriptors;
3360
3415
  }
3361
3416
  finally {
@@ -3377,55 +3432,11 @@ export class CodexAppServerAgentClient {
3377
3432
  const hasConfiguredDefaultModel = typeof configuredDefaultModelId === "string"
3378
3433
  ? models.some((model) => model?.id === configuredDefaultModelId)
3379
3434
  : false;
3380
- return models.map((model) => {
3381
- const defaultReasoningEffort = normalizeCodexThinkingOptionId(typeof model.defaultReasoningEffort === "string" ? model.defaultReasoningEffort : null);
3382
- const resolvedDefaultReasoningEffort = configuredDefaultThinkingOptionId ?? defaultReasoningEffort;
3383
- const thinkingById = new Map();
3384
- if (Array.isArray(model.supportedReasoningEfforts)) {
3385
- for (const entry of model.supportedReasoningEfforts) {
3386
- const id = normalizeCodexThinkingOptionId(typeof entry?.reasoningEffort === "string" ? entry.reasoningEffort : null);
3387
- if (!id)
3388
- continue;
3389
- const description = typeof entry?.description === "string" && entry.description.trim().length > 0
3390
- ? entry.description
3391
- : undefined;
3392
- thinkingById.set(id, { id, label: id, description });
3393
- }
3394
- }
3395
- if (resolvedDefaultReasoningEffort && !thinkingById.has(resolvedDefaultReasoningEffort)) {
3396
- thinkingById.set(resolvedDefaultReasoningEffort, {
3397
- id: resolvedDefaultReasoningEffort,
3398
- label: resolvedDefaultReasoningEffort,
3399
- description: configuredDefaultThinkingOptionId === resolvedDefaultReasoningEffort
3400
- ? "Configured default reasoning effort"
3401
- : "Model default reasoning effort",
3402
- });
3403
- }
3404
- const thinkingOptions = Array.from(thinkingById.values()).map((option) => ({
3405
- ...option,
3406
- isDefault: option.id === resolvedDefaultReasoningEffort,
3407
- }));
3408
- const defaultThinkingOptionId = resolvedDefaultReasoningEffort ??
3409
- thinkingOptions.find((option) => option.isDefault)?.id ??
3410
- thinkingOptions[0]?.id;
3411
- const isDefaultModel = hasConfiguredDefaultModel
3412
- ? model.id === configuredDefaultModelId
3413
- : model.isDefault;
3414
- return {
3415
- provider: CODEX_PROVIDER,
3416
- id: model.id,
3417
- label: normalizeCodexModelLabel(model.displayName),
3418
- description: model.description,
3419
- isDefault: isDefaultModel,
3420
- thinkingOptions: thinkingOptions.length > 0 ? thinkingOptions : undefined,
3421
- defaultThinkingOptionId,
3422
- metadata: {
3423
- model: model.model,
3424
- defaultReasoningEffort: model.defaultReasoningEffort,
3425
- supportedReasoningEfforts: model.supportedReasoningEfforts,
3426
- },
3427
- };
3428
- });
3435
+ return models.map((model) => buildCodexModelDefinition(model, {
3436
+ configuredDefaultModelId,
3437
+ configuredDefaultThinkingOptionId,
3438
+ hasConfiguredDefaultModel,
3439
+ }));
3429
3440
  }
3430
3441
  finally {
3431
3442
  await client.dispose();
@@ -3484,6 +3495,67 @@ export class CodexAppServerAgentClient {
3484
3495
  }
3485
3496
  }
3486
3497
  }
3498
+ function buildCodexModelDefinition(model, ctx) {
3499
+ const defaultReasoningEffort = normalizeCodexThinkingOptionId(typeof model.defaultReasoningEffort === "string" ? model.defaultReasoningEffort : null);
3500
+ const resolvedDefaultReasoningEffort = ctx.configuredDefaultThinkingOptionId ?? defaultReasoningEffort;
3501
+ const thinkingById = buildCodexThinkingOptionMap(model.supportedReasoningEfforts, resolvedDefaultReasoningEffort, ctx.configuredDefaultThinkingOptionId);
3502
+ const thinkingOptions = Array.from(thinkingById.values()).map((option) => Object.assign({}, option, {
3503
+ isDefault: option.id === resolvedDefaultReasoningEffort,
3504
+ }));
3505
+ const defaultThinkingOptionId = resolvedDefaultReasoningEffort ??
3506
+ thinkingOptions.find((option) => option.isDefault)?.id ??
3507
+ thinkingOptions[0]?.id;
3508
+ const isDefaultModel = ctx.hasConfiguredDefaultModel
3509
+ ? model.id === ctx.configuredDefaultModelId
3510
+ : model.isDefault;
3511
+ return {
3512
+ provider: CODEX_PROVIDER,
3513
+ id: model.id,
3514
+ label: normalizeCodexModelLabel(model.displayName ?? ""),
3515
+ description: model.description,
3516
+ isDefault: isDefaultModel,
3517
+ thinkingOptions: thinkingOptions.length > 0 ? thinkingOptions : undefined,
3518
+ defaultThinkingOptionId,
3519
+ metadata: {
3520
+ model: model.model,
3521
+ defaultReasoningEffort: model.defaultReasoningEffort,
3522
+ supportedReasoningEfforts: model.supportedReasoningEfforts,
3523
+ },
3524
+ };
3525
+ }
3526
+ function buildCodexThinkingOptionMap(supportedReasoningEfforts, resolvedDefaultReasoningEffort, configuredDefaultThinkingOptionId) {
3527
+ const thinkingById = new Map();
3528
+ if (Array.isArray(supportedReasoningEfforts)) {
3529
+ for (const entry of supportedReasoningEfforts) {
3530
+ const id = normalizeCodexThinkingOptionId(typeof entry?.reasoningEffort === "string" ? entry.reasoningEffort : null);
3531
+ if (!id)
3532
+ continue;
3533
+ const description = typeof entry?.description === "string" && entry.description.trim().length > 0
3534
+ ? entry.description
3535
+ : undefined;
3536
+ thinkingById.set(id, { id, label: id, description });
3537
+ }
3538
+ }
3539
+ if (resolvedDefaultReasoningEffort && !thinkingById.has(resolvedDefaultReasoningEffort)) {
3540
+ thinkingById.set(resolvedDefaultReasoningEffort, {
3541
+ id: resolvedDefaultReasoningEffort,
3542
+ label: resolvedDefaultReasoningEffort,
3543
+ description: configuredDefaultThinkingOptionId === resolvedDefaultReasoningEffort
3544
+ ? "Configured default reasoning effort"
3545
+ : "Model default reasoning effort",
3546
+ });
3547
+ }
3548
+ return thinkingById;
3549
+ }
3550
+ function resolveSkillDescription(skill) {
3551
+ if (typeof skill.description === "string") {
3552
+ return skill.description;
3553
+ }
3554
+ if (typeof skill.shortDescription === "string") {
3555
+ return skill.shortDescription;
3556
+ }
3557
+ return "Skill";
3558
+ }
3487
3559
  export const __codexAppServerInternals = {
3488
3560
  buildCodexAppServerEnv,
3489
3561
  CodexAppServerClient,