@getpaseo/server 0.1.69 → 0.1.71

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 (360) hide show
  1. package/dist/server/client/daemon-client-runtime-metrics.js.map +1 -1
  2. package/dist/server/client/daemon-client-websocket-transport.js.map +1 -1
  3. package/dist/server/client/daemon-client.d.ts +57 -4
  4. package/dist/server/client/daemon-client.d.ts.map +1 -1
  5. package/dist/server/client/daemon-client.js +78 -3
  6. package/dist/server/client/daemon-client.js.map +1 -1
  7. package/dist/server/server/agent/agent-manager.d.ts +25 -4
  8. package/dist/server/server/agent/agent-manager.d.ts.map +1 -1
  9. package/dist/server/server/agent/agent-manager.js +231 -26
  10. package/dist/server/server/agent/agent-manager.js.map +1 -1
  11. package/dist/server/server/agent/agent-metadata-generator.d.ts +2 -0
  12. package/dist/server/server/agent/agent-metadata-generator.d.ts.map +1 -1
  13. package/dist/server/server/agent/agent-metadata-generator.js +16 -7
  14. package/dist/server/server/agent/agent-metadata-generator.js.map +1 -1
  15. package/dist/server/server/agent/agent-projections.d.ts +6 -2
  16. package/dist/server/server/agent/agent-projections.d.ts.map +1 -1
  17. package/dist/server/server/agent/agent-projections.js +32 -0
  18. package/dist/server/server/agent/agent-projections.js.map +1 -1
  19. package/dist/server/server/agent/agent-prompt.d.ts +72 -0
  20. package/dist/server/server/agent/agent-prompt.d.ts.map +1 -0
  21. package/dist/server/server/agent/agent-prompt.js +169 -0
  22. package/dist/server/server/agent/agent-prompt.js.map +1 -0
  23. package/dist/server/server/agent/agent-response-loop.js.map +1 -1
  24. package/dist/server/server/agent/agent-sdk-types.d.ts +27 -2
  25. package/dist/server/server/agent/agent-sdk-types.d.ts.map +1 -1
  26. package/dist/server/server/agent/agent-stream-coalescer.d.ts +1 -1
  27. package/dist/server/server/agent/agent-stream-coalescer.d.ts.map +1 -1
  28. package/dist/server/server/agent/agent-timeline-store.js +1 -1
  29. package/dist/server/server/agent/agent-timeline-store.js.map +1 -1
  30. package/dist/server/server/agent/create-agent-mode.d.ts +16 -0
  31. package/dist/server/server/agent/create-agent-mode.d.ts.map +1 -0
  32. package/dist/server/server/agent/create-agent-mode.js +26 -0
  33. package/dist/server/server/agent/create-agent-mode.js.map +1 -0
  34. package/dist/server/server/agent/import-sessions.d.ts +33 -0
  35. package/dist/server/server/agent/import-sessions.d.ts.map +1 -0
  36. package/dist/server/server/agent/import-sessions.js +107 -0
  37. package/dist/server/server/agent/import-sessions.js.map +1 -0
  38. package/dist/server/server/agent/mcp-server.d.ts +1 -1
  39. package/dist/server/server/agent/mcp-server.d.ts.map +1 -1
  40. package/dist/server/server/agent/mcp-server.js +61 -14
  41. package/dist/server/server/agent/mcp-server.js.map +1 -1
  42. package/dist/server/server/agent/mcp-shared.d.ts +1 -43
  43. package/dist/server/server/agent/mcp-shared.d.ts.map +1 -1
  44. package/dist/server/server/agent/mcp-shared.js +0 -138
  45. package/dist/server/server/agent/mcp-shared.js.map +1 -1
  46. package/dist/server/server/agent/pcm16-resampler.js.map +1 -1
  47. package/dist/server/server/agent/prompt-attachments.d.ts.map +1 -1
  48. package/dist/server/server/agent/prompt-attachments.js +2 -0
  49. package/dist/server/server/agent/prompt-attachments.js.map +1 -1
  50. package/dist/server/server/agent/provider-launch-config.js.map +1 -1
  51. package/dist/server/server/agent/provider-manifest.d.ts +4 -1
  52. package/dist/server/server/agent/provider-manifest.d.ts.map +1 -1
  53. package/dist/server/server/agent/provider-manifest.js +11 -0
  54. package/dist/server/server/agent/provider-manifest.js.map +1 -1
  55. package/dist/server/server/agent/provider-registry.d.ts +7 -0
  56. package/dist/server/server/agent/provider-registry.d.ts.map +1 -1
  57. package/dist/server/server/agent/provider-registry.js +13 -3
  58. package/dist/server/server/agent/provider-registry.js.map +1 -1
  59. package/dist/server/server/agent/provider-snapshot-manager.js.map +1 -1
  60. package/dist/server/server/agent/providers/acp-agent.d.ts +2 -1
  61. package/dist/server/server/agent/providers/acp-agent.d.ts.map +1 -1
  62. package/dist/server/server/agent/providers/acp-agent.js +35 -17
  63. package/dist/server/server/agent/providers/acp-agent.js.map +1 -1
  64. package/dist/server/server/agent/providers/{claude-agent.d.ts → claude/agent.d.ts} +9 -6
  65. package/dist/server/server/agent/providers/claude/agent.d.ts.map +1 -0
  66. package/dist/server/server/agent/providers/{claude-agent.js → claude/agent.js} +185 -152
  67. package/dist/server/server/agent/providers/claude/agent.js.map +1 -0
  68. package/dist/server/server/agent/providers/claude/{claude-models.d.ts → models.d.ts} +1 -1
  69. package/dist/server/server/agent/providers/claude/models.d.ts.map +1 -0
  70. package/dist/server/server/agent/providers/claude/{claude-models.js → models.js} +8 -1
  71. package/dist/server/server/agent/providers/claude/models.js.map +1 -0
  72. package/dist/server/server/agent/providers/claude/query.d.ts +14 -0
  73. package/dist/server/server/agent/providers/claude/query.d.ts.map +1 -0
  74. package/dist/server/server/agent/providers/claude/query.js +84 -0
  75. package/dist/server/server/agent/providers/claude/query.js.map +1 -0
  76. package/dist/server/server/agent/providers/claude/tool-call-mapper.js.map +1 -1
  77. package/dist/server/server/agent/providers/codex-app-server-agent.d.ts +19 -3
  78. package/dist/server/server/agent/providers/codex-app-server-agent.d.ts.map +1 -1
  79. package/dist/server/server/agent/providers/codex-app-server-agent.js +447 -93
  80. package/dist/server/server/agent/providers/codex-app-server-agent.js.map +1 -1
  81. package/dist/server/server/agent/providers/diagnostic-utils.d.ts.map +1 -1
  82. package/dist/server/server/agent/providers/diagnostic-utils.js +4 -0
  83. package/dist/server/server/agent/providers/diagnostic-utils.js.map +1 -1
  84. package/dist/server/server/agent/providers/generic-acp-agent.d.ts +1 -1
  85. package/dist/server/server/agent/providers/generic-acp-agent.d.ts.map +1 -1
  86. package/dist/server/server/agent/providers/generic-acp-agent.js +0 -3
  87. package/dist/server/server/agent/providers/generic-acp-agent.js.map +1 -1
  88. package/dist/server/server/agent/providers/mock-load-test-agent.d.ts.map +1 -1
  89. package/dist/server/server/agent/providers/mock-load-test-agent.js +6 -2
  90. package/dist/server/server/agent/providers/mock-load-test-agent.js.map +1 -1
  91. package/dist/server/server/agent/providers/opencode-agent.d.ts +3 -2
  92. package/dist/server/server/agent/providers/opencode-agent.d.ts.map +1 -1
  93. package/dist/server/server/agent/providers/opencode-agent.js +204 -31
  94. package/dist/server/server/agent/providers/opencode-agent.js.map +1 -1
  95. package/dist/server/server/agent/providers/provider-image-output.d.ts +20 -0
  96. package/dist/server/server/agent/providers/provider-image-output.d.ts.map +1 -0
  97. package/dist/server/server/agent/providers/provider-image-output.js +51 -0
  98. package/dist/server/server/agent/providers/provider-image-output.js.map +1 -0
  99. package/dist/server/server/agent/providers/provider-runner.d.ts +3 -3
  100. package/dist/server/server/agent/providers/provider-runner.d.ts.map +1 -1
  101. package/dist/server/server/agent/providers/test-utils/session-stream-adapter.js.map +1 -1
  102. package/dist/server/server/agent/providers/tool-call-detail-primitives.d.ts +7 -7
  103. package/dist/server/server/agent/providers/tool-call-detail-primitives.d.ts.map +1 -1
  104. package/dist/server/server/agent/providers/tool-call-detail-primitives.js +12 -18
  105. package/dist/server/server/agent/providers/tool-call-detail-primitives.js.map +1 -1
  106. package/dist/server/server/agent/stt-manager.d.ts +1 -0
  107. package/dist/server/server/agent/stt-manager.d.ts.map +1 -1
  108. package/dist/server/server/agent/stt-manager.js +3 -0
  109. package/dist/server/server/agent/stt-manager.js.map +1 -1
  110. package/dist/server/server/agent/tool-name-normalization.js.map +1 -1
  111. package/dist/server/server/agent/tts-manager.js.map +1 -1
  112. package/dist/server/server/bootstrap.d.ts +1 -0
  113. package/dist/server/server/bootstrap.d.ts.map +1 -1
  114. package/dist/server/server/bootstrap.js +3 -1
  115. package/dist/server/server/bootstrap.js.map +1 -1
  116. package/dist/server/server/chat/chat-mentions.d.ts +24 -8
  117. package/dist/server/server/chat/chat-mentions.d.ts.map +1 -1
  118. package/dist/server/server/chat/chat-mentions.js +77 -35
  119. package/dist/server/server/chat/chat-mentions.js.map +1 -1
  120. package/dist/server/server/chat/chat-service.d.ts +4 -0
  121. package/dist/server/server/chat/chat-service.d.ts.map +1 -1
  122. package/dist/server/server/chat/chat-service.js +9 -0
  123. package/dist/server/server/chat/chat-service.js.map +1 -1
  124. package/dist/server/server/config.d.ts +1 -0
  125. package/dist/server/server/config.d.ts.map +1 -1
  126. package/dist/server/server/config.js +7 -1
  127. package/dist/server/server/config.js.map +1 -1
  128. package/dist/server/server/connection-offer.d.ts +1 -0
  129. package/dist/server/server/connection-offer.d.ts.map +1 -1
  130. package/dist/server/server/daemon-config-store.d.ts.map +1 -1
  131. package/dist/server/server/daemon-config-store.js +2 -6
  132. package/dist/server/server/daemon-config-store.js.map +1 -1
  133. package/dist/server/server/daemon-keypair.d.ts.map +1 -1
  134. package/dist/server/server/daemon-keypair.js +4 -2
  135. package/dist/server/server/daemon-keypair.js.map +1 -1
  136. package/dist/server/server/daemon-worker.js +3 -0
  137. package/dist/server/server/daemon-worker.js.map +1 -1
  138. package/dist/server/server/editor-targets.js.map +1 -1
  139. package/dist/server/server/exports.d.ts +1 -0
  140. package/dist/server/server/exports.d.ts.map +1 -1
  141. package/dist/server/server/exports.js +1 -0
  142. package/dist/server/server/exports.js.map +1 -1
  143. package/dist/server/server/json-utils.js.map +1 -1
  144. package/dist/server/server/logger.js.map +1 -1
  145. package/dist/server/server/loop/rpc-schemas.d.ts +68 -0
  146. package/dist/server/server/loop/rpc-schemas.d.ts.map +1 -1
  147. package/dist/server/server/loop/rpc-schemas.js +4 -0
  148. package/dist/server/server/loop/rpc-schemas.js.map +1 -1
  149. package/dist/server/server/loop-service.d.ts +8 -0
  150. package/dist/server/server/loop-service.d.ts.map +1 -1
  151. package/dist/server/server/loop-service.js +11 -2
  152. package/dist/server/server/loop-service.js.map +1 -1
  153. package/dist/server/server/package-version.d.ts +12 -0
  154. package/dist/server/server/package-version.d.ts.map +1 -1
  155. package/dist/server/server/package-version.js +13 -1
  156. package/dist/server/server/package-version.js.map +1 -1
  157. package/dist/server/server/pairing-offer.d.ts +1 -0
  158. package/dist/server/server/pairing-offer.d.ts.map +1 -1
  159. package/dist/server/server/pairing-offer.js +2 -1
  160. package/dist/server/server/pairing-offer.js.map +1 -1
  161. package/dist/server/server/pairing-qr.js +1 -1
  162. package/dist/server/server/pairing-qr.js.map +1 -1
  163. package/dist/server/server/paseo-env.d.ts +7 -3
  164. package/dist/server/server/paseo-env.d.ts.map +1 -1
  165. package/dist/server/server/paseo-env.js +16 -33
  166. package/dist/server/server/paseo-env.js.map +1 -1
  167. package/dist/server/server/paseo-home.js +2 -2
  168. package/dist/server/server/paseo-home.js.map +1 -1
  169. package/dist/server/server/persisted-config.d.ts +9 -0
  170. package/dist/server/server/persisted-config.d.ts.map +1 -1
  171. package/dist/server/server/persisted-config.js +6 -4
  172. package/dist/server/server/persisted-config.js.map +1 -1
  173. package/dist/server/server/persistence-hooks.js.map +1 -1
  174. package/dist/server/server/pid-lock.d.ts +21 -4
  175. package/dist/server/server/pid-lock.d.ts.map +1 -1
  176. package/dist/server/server/pid-lock.js +30 -8
  177. package/dist/server/server/pid-lock.js.map +1 -1
  178. package/dist/server/server/private-files.d.ts +7 -0
  179. package/dist/server/server/private-files.d.ts.map +1 -0
  180. package/dist/server/server/private-files.js +42 -0
  181. package/dist/server/server/private-files.js.map +1 -0
  182. package/dist/server/server/push/token-store.d.ts.map +1 -1
  183. package/dist/server/server/push/token-store.js +4 -6
  184. package/dist/server/server/push/token-store.js.map +1 -1
  185. package/dist/server/server/relay-transport.d.ts +2 -1
  186. package/dist/server/server/relay-transport.d.ts.map +1 -1
  187. package/dist/server/server/relay-transport.js +8 -5
  188. package/dist/server/server/relay-transport.js.map +1 -1
  189. package/dist/server/server/schedule/rpc-schemas.d.ts +1136 -0
  190. package/dist/server/server/schedule/rpc-schemas.d.ts.map +1 -1
  191. package/dist/server/server/schedule/rpc-schemas.js +39 -0
  192. package/dist/server/server/schedule/rpc-schemas.js.map +1 -1
  193. package/dist/server/server/schedule/service.d.ts +4 -2
  194. package/dist/server/server/schedule/service.d.ts.map +1 -1
  195. package/dist/server/server/schedule/service.js +106 -16
  196. package/dist/server/server/schedule/service.js.map +1 -1
  197. package/dist/server/server/schedule/types.d.ts +16 -0
  198. package/dist/server/server/schedule/types.d.ts.map +1 -1
  199. package/dist/server/server/script-health-monitor.js.map +1 -1
  200. package/dist/server/server/server-id.d.ts.map +1 -1
  201. package/dist/server/server/server-id.js +8 -3
  202. package/dist/server/server/server-id.js.map +1 -1
  203. package/dist/server/server/session.d.ts +5 -4
  204. package/dist/server/server/session.d.ts.map +1 -1
  205. package/dist/server/server/session.js +318 -149
  206. package/dist/server/server/session.js.map +1 -1
  207. package/dist/server/server/speech/audio.js.map +1 -1
  208. package/dist/server/server/speech/providers/local/pocket/pocket-tts-onnx.d.ts.map +1 -1
  209. package/dist/server/server/speech/providers/local/pocket/pocket-tts-onnx.js +52 -52
  210. package/dist/server/server/speech/providers/local/pocket/pocket-tts-onnx.js.map +1 -1
  211. package/dist/server/server/speech/providers/local/sherpa/model-catalog.d.ts.map +1 -1
  212. package/dist/server/server/speech/providers/local/sherpa/model-catalog.js +9 -3
  213. package/dist/server/server/speech/providers/local/sherpa/model-catalog.js.map +1 -1
  214. package/dist/server/server/speech/providers/local/sherpa/model-downloader.d.ts.map +1 -1
  215. package/dist/server/server/speech/providers/local/sherpa/model-downloader.js +12 -10
  216. package/dist/server/server/speech/providers/local/sherpa/model-downloader.js.map +1 -1
  217. package/dist/server/server/speech/providers/local/sherpa/sherpa-realtime-session.js +2 -2
  218. package/dist/server/server/speech/providers/local/sherpa/sherpa-realtime-session.js.map +1 -1
  219. package/dist/server/server/speech/providers/local/sherpa/sherpa-stt.js +1 -1
  220. package/dist/server/server/speech/providers/local/sherpa/sherpa-stt.js.map +1 -1
  221. package/dist/server/server/speech/providers/local/sherpa/sherpa-tts.js.map +1 -1
  222. package/dist/server/server/voice/voice-turn-controller.d.ts +16 -13
  223. package/dist/server/server/voice/voice-turn-controller.d.ts.map +1 -1
  224. package/dist/server/server/voice/voice-turn-controller.js +303 -71
  225. package/dist/server/server/voice/voice-turn-controller.js.map +1 -1
  226. package/dist/server/server/voice-config.js +1 -1
  227. package/dist/server/server/voice-config.js.map +1 -1
  228. package/dist/server/server/websocket-server.js.map +1 -1
  229. package/dist/server/server/workspace-directory.d.ts.map +1 -1
  230. package/dist/server/server/workspace-directory.js +4 -2
  231. package/dist/server/server/workspace-directory.js.map +1 -1
  232. package/dist/server/server/workspace-git-metadata.d.ts.map +1 -1
  233. package/dist/server/server/workspace-git-metadata.js +12 -5
  234. package/dist/server/server/workspace-git-metadata.js.map +1 -1
  235. package/dist/server/server/workspace-git-service.d.ts +4 -1
  236. package/dist/server/server/workspace-git-service.d.ts.map +1 -1
  237. package/dist/server/server/workspace-git-service.js +50 -2
  238. package/dist/server/server/workspace-git-service.js.map +1 -1
  239. package/dist/server/server/workspace-registry-model.d.ts.map +1 -1
  240. package/dist/server/server/workspace-registry-model.js +10 -3
  241. package/dist/server/server/workspace-registry-model.js.map +1 -1
  242. package/dist/server/server/worktree-branch-name-generator.d.ts +2 -0
  243. package/dist/server/server/worktree-branch-name-generator.d.ts.map +1 -1
  244. package/dist/server/server/worktree-branch-name-generator.js +18 -11
  245. package/dist/server/server/worktree-branch-name-generator.js.map +1 -1
  246. package/dist/server/server/worktree-session.js +1 -1
  247. package/dist/server/server/worktree-session.js.map +1 -1
  248. package/dist/server/services/github-service.d.ts +13 -0
  249. package/dist/server/services/github-service.d.ts.map +1 -1
  250. package/dist/server/services/github-service.js +21 -4
  251. package/dist/server/services/github-service.js.map +1 -1
  252. package/dist/server/shared/agent-labels.d.ts +2 -0
  253. package/dist/server/shared/agent-labels.d.ts.map +1 -0
  254. package/dist/server/shared/agent-labels.js +2 -0
  255. package/dist/server/shared/agent-labels.js.map +1 -0
  256. package/dist/server/shared/connection-offer.d.ts +10 -0
  257. package/dist/server/shared/connection-offer.d.ts.map +1 -1
  258. package/dist/server/shared/connection-offer.js +1 -0
  259. package/dist/server/shared/connection-offer.js.map +1 -1
  260. package/dist/server/shared/daemon-endpoints.d.ts +4 -0
  261. package/dist/server/shared/daemon-endpoints.d.ts.map +1 -1
  262. package/dist/server/shared/daemon-endpoints.js +6 -1
  263. package/dist/server/shared/daemon-endpoints.js.map +1 -1
  264. package/dist/server/shared/error-utils.d.ts +11 -0
  265. package/dist/server/shared/error-utils.d.ts.map +1 -0
  266. package/dist/server/shared/error-utils.js +27 -0
  267. package/dist/server/shared/error-utils.js.map +1 -0
  268. package/dist/server/shared/importable-providers.d.ts +7 -0
  269. package/dist/server/shared/importable-providers.d.ts.map +1 -0
  270. package/dist/server/shared/importable-providers.js +7 -0
  271. package/dist/server/shared/importable-providers.js.map +1 -0
  272. package/dist/server/shared/messages.d.ts +12753 -2085
  273. package/dist/server/shared/messages.d.ts.map +1 -1
  274. package/dist/server/shared/messages.js +61 -5
  275. package/dist/server/shared/messages.js.map +1 -1
  276. package/dist/server/shared/tool-call-display.d.ts.map +1 -1
  277. package/dist/server/shared/tool-call-display.js +2 -0
  278. package/dist/server/shared/tool-call-display.js.map +1 -1
  279. package/dist/server/terminal/terminal-manager.d.ts +2 -1
  280. package/dist/server/terminal/terminal-manager.d.ts.map +1 -1
  281. package/dist/server/terminal/terminal-manager.js +2 -1
  282. package/dist/server/terminal/terminal-manager.js.map +1 -1
  283. package/dist/server/terminal/terminal-output-coalescer.js.map +1 -1
  284. package/dist/server/terminal/terminal-session-controller.d.ts.map +1 -1
  285. package/dist/server/terminal/terminal-session-controller.js +2 -0
  286. package/dist/server/terminal/terminal-session-controller.js.map +1 -1
  287. package/dist/server/terminal/terminal.d.ts +1 -1
  288. package/dist/server/terminal/terminal.d.ts.map +1 -1
  289. package/dist/server/terminal/terminal.js +53 -8
  290. package/dist/server/terminal/terminal.js.map +1 -1
  291. package/dist/server/terminal/worker-terminal-manager.js.map +1 -1
  292. package/dist/server/utils/build-metadata-prompt.d.ts +14 -0
  293. package/dist/server/utils/build-metadata-prompt.d.ts.map +1 -0
  294. package/dist/server/utils/build-metadata-prompt.js +28 -0
  295. package/dist/server/utils/build-metadata-prompt.js.map +1 -0
  296. package/dist/server/utils/checkout-git.d.ts +2 -1
  297. package/dist/server/utils/checkout-git.d.ts.map +1 -1
  298. package/dist/server/utils/checkout-git.js +67 -11
  299. package/dist/server/utils/checkout-git.js.map +1 -1
  300. package/dist/server/utils/directory-suggestions.js.map +1 -1
  301. package/dist/server/utils/executable.d.ts +2 -1
  302. package/dist/server/utils/executable.d.ts.map +1 -1
  303. package/dist/server/utils/executable.js +50 -51
  304. package/dist/server/utils/executable.js.map +1 -1
  305. package/dist/server/utils/paseo-config-file.d.ts +1 -1
  306. package/dist/server/utils/paseo-config-file.d.ts.map +1 -1
  307. package/dist/server/utils/paseo-config-schema.d.ts +625 -0
  308. package/dist/server/utils/paseo-config-schema.d.ts.map +1 -1
  309. package/dist/server/utils/paseo-config-schema.js +17 -0
  310. package/dist/server/utils/paseo-config-schema.js.map +1 -1
  311. package/dist/server/utils/spawn.d.ts +2 -0
  312. package/dist/server/utils/spawn.d.ts.map +1 -1
  313. package/dist/server/utils/spawn.js +2 -1
  314. package/dist/server/utils/spawn.js.map +1 -1
  315. package/dist/server/utils/tree-kill.d.ts +18 -0
  316. package/dist/server/utils/tree-kill.d.ts.map +1 -0
  317. package/dist/server/utils/{process-tree.js → tree-kill.js} +14 -33
  318. package/dist/server/utils/tree-kill.js.map +1 -0
  319. package/dist/server/utils/worktree.js.map +1 -1
  320. package/dist/server/utils/wrap-user-instructions.d.ts +2 -0
  321. package/dist/server/utils/wrap-user-instructions.d.ts.map +1 -0
  322. package/dist/server/utils/wrap-user-instructions.js +13 -0
  323. package/dist/server/utils/wrap-user-instructions.js.map +1 -0
  324. package/dist/src/server/agent/provider-launch-config.js.map +1 -1
  325. package/dist/src/server/agent/provider-manifest.js +11 -0
  326. package/dist/src/server/agent/provider-manifest.js.map +1 -1
  327. package/dist/src/server/loop/rpc-schemas.js +4 -0
  328. package/dist/src/server/loop/rpc-schemas.js.map +1 -1
  329. package/dist/src/server/paseo-env.js +16 -33
  330. package/dist/src/server/paseo-env.js.map +1 -1
  331. package/dist/src/server/paseo-home.js +2 -2
  332. package/dist/src/server/paseo-home.js.map +1 -1
  333. package/dist/src/server/persisted-config.js +6 -4
  334. package/dist/src/server/persisted-config.js.map +1 -1
  335. package/dist/src/server/pid-lock.js +30 -8
  336. package/dist/src/server/pid-lock.js.map +1 -1
  337. package/dist/src/server/private-files.js +42 -0
  338. package/dist/src/server/private-files.js.map +1 -0
  339. package/dist/src/server/schedule/rpc-schemas.js +39 -0
  340. package/dist/src/server/schedule/rpc-schemas.js.map +1 -1
  341. package/dist/src/shared/messages.js +61 -5
  342. package/dist/src/shared/messages.js.map +1 -1
  343. package/dist/src/utils/executable.js +50 -51
  344. package/dist/src/utils/executable.js.map +1 -1
  345. package/dist/src/utils/paseo-config-schema.js +17 -0
  346. package/dist/src/utils/paseo-config-schema.js.map +1 -1
  347. package/dist/src/utils/spawn.js +2 -1
  348. package/dist/src/utils/spawn.js.map +1 -1
  349. package/package.json +5 -4
  350. package/dist/server/server/agent/providers/claude/claude-models.d.ts.map +0 -1
  351. package/dist/server/server/agent/providers/claude/claude-models.js.map +0 -1
  352. package/dist/server/server/agent/providers/claude-agent.d.ts.map +0 -1
  353. package/dist/server/server/agent/providers/claude-agent.js.map +0 -1
  354. package/dist/server/server/voice/fixed-duration-pcm-ring-buffer.d.ts +0 -16
  355. package/dist/server/server/voice/fixed-duration-pcm-ring-buffer.d.ts.map +0 -1
  356. package/dist/server/server/voice/fixed-duration-pcm-ring-buffer.js +0 -35
  357. package/dist/server/server/voice/fixed-duration-pcm-ring-buffer.js.map +0 -1
  358. package/dist/server/utils/process-tree.d.ts +0 -25
  359. package/dist/server/utils/process-tree.d.ts.map +0 -1
  360. package/dist/server/utils/process-tree.js.map +0 -1
@@ -1,5 +1,6 @@
1
1
  import { homedir } from "node:os";
2
2
  import { randomUUID } from "node:crypto";
3
+ import * as fsSync from "node:fs";
3
4
  import fs from "node:fs/promises";
4
5
  import os from "node:os";
5
6
  import path from "node:path";
@@ -10,12 +11,21 @@ import { curateAgentActivity } from "../activity-curator.js";
10
11
  import { mapCodexRolloutToolCall, mapCodexToolCallFromThreadItem, } from "./codex/tool-call-mapper.js";
11
12
  import { createProviderEnv, createProviderEnvSpec, resolveProviderCommandPrefix, } from "../provider-launch-config.js";
12
13
  import { findExecutable, isCommandAvailable } from "../../../utils/executable.js";
13
- import { terminateProcessTree } from "../../../utils/process-tree.js";
14
+ import { terminateWithTreeKill } from "../../../utils/tree-kill.js";
14
15
  import { spawnProcess } from "../../../utils/spawn.js";
15
16
  import { extractCodexTerminalSessionId, nonEmptyString } from "./tool-call-mapper-utils.js";
16
17
  import { buildCodexFeatures, codexModelSupportsFastMode } from "./codex-feature-definitions.js";
18
+ import { renderProviderImageOutputAsAssistantMarkdown, } from "./provider-image-output.js";
17
19
  import { formatDiagnosticStatus, formatProviderDiagnostic, formatProviderDiagnosticError, resolveBinaryVersion, toDiagnosticErrorMessage, } from "./diagnostic-utils.js";
18
20
  import { runProviderTurn } from "./provider-runner.js";
21
+ function assertChildWithPipes(child) {
22
+ if (!child.stdin || !child.stdout || !child.stderr) {
23
+ throw new Error("Child process did not expose stdio pipes");
24
+ }
25
+ }
26
+ function isRecord(value) {
27
+ return value != null && typeof value === "object" && !Array.isArray(value);
28
+ }
19
29
  const DEFAULT_TIMEOUT_MS = 14 * 24 * 60 * 60 * 1000;
20
30
  const TURN_START_TIMEOUT_MS = 90 * 1000;
21
31
  const INTERRUPT_TIMEOUT_MS = 2000;
@@ -24,7 +34,52 @@ const APP_SERVER_FORCE_SHUTDOWN_TIMEOUT_MS = 1000;
24
34
  const CODEX_PROVIDER = "codex";
25
35
  const CODEX_IMAGE_ATTACHMENT_DIR = "paseo-attachments";
26
36
  const ASSISTANT_MESSAGE_BOUNDARY_MARKDOWN = "\n\n---\n\n";
37
+ const CODEX_TOOL_THREAD_ITEM_TYPES = new Set([
38
+ "commandExecution",
39
+ "fileChange",
40
+ "mcpToolCall",
41
+ "webSearch",
42
+ "collabAgentToolCall",
43
+ ]);
27
44
  const CODEX_PLAN_IMPLEMENTATION_PROMPT_PREFIX = "The user approved the plan. Implement it now. Do not restate or revise the plan unless blocked.";
45
+ // Codex's experimental `goals` feature ships in 0.128.0+. Older binaries reject
46
+ // `--enable goals` at launch, so we gate by version and silently skip the flag
47
+ // (and the /goal slash command) when the binary is too old.
48
+ const CODEX_GOALS_MIN_VERSION = [0, 128, 0];
49
+ function parseCodexVersion(versionOutput) {
50
+ const match = versionOutput.match(/(\d+)\.(\d+)\.(\d+)/);
51
+ if (!match)
52
+ return null;
53
+ return [Number(match[1]), Number(match[2]), Number(match[3])];
54
+ }
55
+ function codexVersionAtLeast(versionOutput, min) {
56
+ const parsed = parseCodexVersion(versionOutput);
57
+ if (!parsed)
58
+ return false;
59
+ for (let i = 0; i < 3; i += 1) {
60
+ if (parsed[i] > min[i])
61
+ return true;
62
+ if (parsed[i] < min[i])
63
+ return false;
64
+ }
65
+ return true;
66
+ }
67
+ function parseGoalSubcommand(args) {
68
+ const trimmed = (args ?? "").trim();
69
+ if (!trimmed)
70
+ return { kind: "usage" };
71
+ const lower = trimmed.toLowerCase();
72
+ if (lower === "pause")
73
+ return { kind: "pause" };
74
+ if (lower === "resume")
75
+ return { kind: "resume" };
76
+ if (lower === "clear")
77
+ return { kind: "clear" };
78
+ return { kind: "set", objective: trimmed };
79
+ }
80
+ function formatOutOfBandStatusMessage(text) {
81
+ return `${text.replace(/\n+$/u, "")}\n\n`;
82
+ }
28
83
  const CODEX_APP_SERVER_CAPABILITIES = {
29
84
  supportsStreaming: true,
30
85
  supportsSessionPersistence: true,
@@ -397,8 +452,60 @@ function toCodexMcpConfig(config) {
397
452
  url: config.url,
398
453
  http_headers: config.headers,
399
454
  };
455
+ default: {
456
+ const _exhaustive = config;
457
+ throw new Error(`Unsupported MCP config type: ${String(_exhaustive.type)}`);
458
+ }
400
459
  }
401
460
  }
461
+ function isJsonRpcResponse(msg) {
462
+ if (!isRecord(msg))
463
+ return false;
464
+ if (typeof msg.id !== "number")
465
+ return false;
466
+ return msg.result !== undefined || !!msg.error;
467
+ }
468
+ function isJsonRpcRequest(msg) {
469
+ if (!isRecord(msg))
470
+ return false;
471
+ return typeof msg.id === "number" && typeof msg.method === "string";
472
+ }
473
+ function isJsonRpcNotification(msg) {
474
+ if (!isRecord(msg))
475
+ return false;
476
+ return typeof msg.method === "string" && typeof msg.id !== "number";
477
+ }
478
+ function toObjectRecord(value) {
479
+ return isRecord(value) ? value : undefined;
480
+ }
481
+ const CodexModelListResponseSchema = z.object({
482
+ data: z
483
+ .array(z.object({
484
+ id: z.string(),
485
+ displayName: z.string().optional(),
486
+ description: z.string().optional(),
487
+ isDefault: z.boolean().optional(),
488
+ model: z.string().optional(),
489
+ defaultReasoningEffort: z.string().optional(),
490
+ supportedReasoningEfforts: z
491
+ .array(z.object({
492
+ reasoningEffort: z.string().optional(),
493
+ description: z.string().optional(),
494
+ }))
495
+ .optional(),
496
+ }))
497
+ .optional(),
498
+ });
499
+ function filterCodexThreadsByCwd(threads, cwd) {
500
+ if (!cwd) {
501
+ return threads;
502
+ }
503
+ // thread/list rows carry an optional cwd. The descriptor builder later
504
+ // falls back to process.cwd() if the field is missing, so we only match
505
+ // here when the row genuinely carries a cwd string — otherwise threads
506
+ // with no cwd would falsely match the daemon's own cwd.
507
+ return threads.filter((thread) => typeof thread.cwd === "string" && thread.cwd === cwd);
508
+ }
402
509
  class CodexAppServerClient {
403
510
  constructor(child, logger) {
404
511
  this.child = child;
@@ -490,7 +597,7 @@ class CodexAppServerClient {
490
597
  catch {
491
598
  // ignore
492
599
  }
493
- const result = await terminateProcessTree(this.child, {
600
+ const result = await terminateWithTreeKill(this.child, {
494
601
  gracefulTimeoutMs: APP_SERVER_GRACEFUL_SHUTDOWN_TIMEOUT_MS,
495
602
  forceTimeoutMs: APP_SERVER_FORCE_SHUTDOWN_TIMEOUT_MS,
496
603
  onForceSignal: () => {
@@ -504,33 +611,30 @@ class CodexAppServerClient {
504
611
  async handleLine(line) {
505
612
  if (!line.trim())
506
613
  return;
507
- let msg;
508
- try {
509
- msg = JSON.parse(line);
510
- }
511
- catch (error) {
512
- this.logger.warn({ error, line }, "Failed to parse Codex app-server JSON");
614
+ const raw = JSON.parse(line);
615
+ if (!isRecord(raw)) {
616
+ this.logger.warn({ line }, "Parsed JSON is not an object");
513
617
  return;
514
618
  }
515
- if (typeof msg.id === "number") {
516
- const id = msg.id;
517
- if (msg.result !== undefined || msg.error) {
619
+ if (isJsonRpcResponse(raw)) {
620
+ const id = raw.id;
621
+ if (raw.result !== undefined || raw.error) {
518
622
  const pending = this.pending.get(id);
519
623
  if (!pending)
520
624
  return;
521
625
  clearTimeout(pending.timer);
522
626
  this.pending.delete(id);
523
- if (msg.error) {
524
- pending.reject(new Error(msg.error?.message ?? "Unknown error"));
627
+ if (raw.error) {
628
+ pending.reject(new Error(raw.error.message ?? "Unknown error"));
525
629
  }
526
630
  else {
527
- pending.resolve(msg.result);
631
+ pending.resolve(raw.result);
528
632
  }
529
633
  return;
530
634
  }
531
635
  // Server-initiated request
532
- if (typeof msg.method === "string") {
533
- const request = msg;
636
+ if (isJsonRpcRequest(raw)) {
637
+ const request = raw;
534
638
  const handler = this.requestHandlers.get(request.method);
535
639
  try {
536
640
  const result = handler ? await handler(request.params) : {};
@@ -545,22 +649,22 @@ class CodexAppServerClient {
545
649
  return;
546
650
  }
547
651
  }
548
- if (typeof msg.method === "string") {
549
- const notification = msg;
550
- this.notificationHandler?.(notification.method, notification.params);
652
+ if (isJsonRpcNotification(raw)) {
653
+ this.notificationHandler?.(raw.method, raw.params);
551
654
  }
552
655
  }
553
656
  }
554
657
  function toAgentUsage(tokenUsage) {
555
- if (!tokenUsage || typeof tokenUsage !== "object")
658
+ const usage = toObjectRecord(tokenUsage);
659
+ if (!usage)
556
660
  return undefined;
557
- const usage = tokenUsage;
661
+ const last = toObjectRecord(usage.last);
558
662
  const contextWindowMaxTokens = firstPositiveFiniteNumber(usage.model_context_window, usage.modelContextWindow);
559
- const contextWindowUsedTokens = firstPositiveFiniteNumber(usage.last?.total_tokens, usage.last?.totalTokens);
663
+ const contextWindowUsedTokens = firstPositiveFiniteNumber(last?.total_tokens, last?.totalTokens);
560
664
  return {
561
- inputTokens: usage.last?.inputTokens,
562
- cachedInputTokens: usage.last?.cachedInputTokens,
563
- outputTokens: usage.last?.outputTokens,
665
+ inputTokens: typeof last?.inputTokens === "number" ? last.inputTokens : undefined,
666
+ cachedInputTokens: typeof last?.cachedInputTokens === "number" ? last.cachedInputTokens : undefined,
667
+ outputTokens: typeof last?.outputTokens === "number" ? last.outputTokens : undefined,
564
668
  ...(contextWindowMaxTokens !== undefined ? { contextWindowMaxTokens } : {}),
565
669
  ...(contextWindowUsedTokens !== undefined ? { contextWindowUsedTokens } : {}),
566
670
  };
@@ -570,11 +674,12 @@ function extractUserText(content) {
570
674
  return null;
571
675
  const parts = [];
572
676
  for (const item of content) {
573
- if (item && typeof item === "object") {
574
- const obj = item;
575
- if (obj.type === "text" && typeof obj.text === "string") {
576
- parts.push(obj.text);
577
- }
677
+ const record = toObjectRecord(item);
678
+ if (!record) {
679
+ continue;
680
+ }
681
+ if (record.type === "text" && typeof record.text === "string") {
682
+ parts.push(record.text);
578
683
  }
579
684
  }
580
685
  return parts.length > 0 ? parts.join("\n") : null;
@@ -661,10 +766,10 @@ function normalizeCodexQuestionPrompts(raw) {
661
766
  }
662
767
  const questions = [];
663
768
  for (const item of raw) {
664
- if (!item || typeof item !== "object") {
769
+ const record = toObjectRecord(item);
770
+ if (!record) {
665
771
  continue;
666
772
  }
667
- const record = item;
668
773
  const id = nonEmptyString(record.id);
669
774
  const header = nonEmptyString(record.header);
670
775
  const question = nonEmptyString(record.question);
@@ -673,10 +778,10 @@ function normalizeCodexQuestionPrompts(raw) {
673
778
  }
674
779
  const options = Array.isArray(record.options)
675
780
  ? record.options.flatMap((option) => {
676
- if (!option || typeof option !== "object") {
781
+ const optionRecord = toObjectRecord(option);
782
+ if (!optionRecord) {
677
783
  return [];
678
784
  }
679
- const optionRecord = option;
680
785
  const label = nonEmptyString(optionRecord.label);
681
786
  if (!label) {
682
787
  return [];
@@ -771,10 +876,9 @@ function mapCodexQuestionResponseByHeader(params) {
771
876
  if (params.response.behavior !== "allow") {
772
877
  return null;
773
878
  }
774
- const answersRecord = params.response.updatedInput && typeof params.response.updatedInput === "object"
775
- ? params.response.updatedInput.answers
776
- : undefined;
777
- if (!answersRecord || typeof answersRecord !== "object") {
879
+ const updatedInputRecord = toObjectRecord(params.response.updatedInput);
880
+ const answersRecord = toObjectRecord(updatedInputRecord?.answers);
881
+ if (!answersRecord) {
778
882
  return null;
779
883
  }
780
884
  const answers = {};
@@ -800,10 +904,10 @@ function mapCodexQuestionResponseByHeader(params) {
800
904
  return Object.keys(answers).length > 0 ? answers : null;
801
905
  }
802
906
  function extractPatchLikeText(value) {
803
- if (!value || typeof value !== "object") {
907
+ const record = toObjectRecord(value);
908
+ if (!record) {
804
909
  return undefined;
805
910
  }
806
- const record = value;
807
911
  const candidates = [
808
912
  record.diff,
809
913
  record.patch,
@@ -842,6 +946,10 @@ function normalizeCodexThreadItemType(rawType) {
842
946
  return "webSearch";
843
947
  case "CollabAgentToolCall":
844
948
  return "collabAgentToolCall";
949
+ case "ImageView":
950
+ return "imageView";
951
+ case "ImageGeneration":
952
+ return "imageGeneration";
845
953
  default:
846
954
  return rawType;
847
955
  }
@@ -900,10 +1008,10 @@ function parseCodexPatchChanges(changes) {
900
1008
  if (Array.isArray(changes)) {
901
1009
  return changes
902
1010
  .map((entry) => {
903
- if (!entry || typeof entry !== "object") {
1011
+ const record = toObjectRecord(entry);
1012
+ if (!record) {
904
1013
  return null;
905
1014
  }
906
- const record = entry;
907
1015
  const pathValue = resolvePathFromRecord(record);
908
1016
  if (!pathValue) {
909
1017
  return null;
@@ -918,7 +1026,10 @@ function parseCodexPatchChanges(changes) {
918
1026
  })
919
1027
  .filter((entry) => entry !== null);
920
1028
  }
921
- const recordChanges = changes;
1029
+ const recordChanges = toObjectRecord(changes);
1030
+ if (!recordChanges) {
1031
+ return [];
1032
+ }
922
1033
  const directPathValue = resolvePathFromRecord(recordChanges);
923
1034
  if (directPathValue) {
924
1035
  return [
@@ -1118,16 +1229,81 @@ function mapCodexThreadUserMessageItem(normalizedItem, includeUserMessage) {
1118
1229
  const text = extractUserText(normalizedItem.content) ?? "";
1119
1230
  return { type: "user_message", text };
1120
1231
  }
1232
+ function firstStringField(record, fields) {
1233
+ for (const field of fields) {
1234
+ const value = record[field];
1235
+ if (typeof value === "string") {
1236
+ return value;
1237
+ }
1238
+ }
1239
+ return null;
1240
+ }
1241
+ function codexImageOutputFromResult(result) {
1242
+ if (typeof result === "string") {
1243
+ const trimmed = result.trim();
1244
+ if (trimmed.toLowerCase().startsWith("data:image/") ||
1245
+ (/^[A-Za-z0-9+/]+={0,2}$/.test(trimmed) && trimmed.length > 64)) {
1246
+ return { data: trimmed };
1247
+ }
1248
+ return { url: trimmed };
1249
+ }
1250
+ const resultRecord = toObjectRecord(result);
1251
+ if (!resultRecord) {
1252
+ return null;
1253
+ }
1254
+ return {
1255
+ path: firstStringField(resultRecord, ["path", "savedPath", "saved_path"]),
1256
+ url: firstStringField(resultRecord, ["url"]),
1257
+ data: firstStringField(resultRecord, ["data"]),
1258
+ mimeType: firstStringField(resultRecord, ["mimeType", "mime_type"]),
1259
+ };
1260
+ }
1261
+ function writeImageAttachmentSync(mimeType, data) {
1262
+ const attachmentsDir = path.join(os.tmpdir(), CODEX_IMAGE_ATTACHMENT_DIR);
1263
+ fsSync.mkdirSync(attachmentsDir, { recursive: true });
1264
+ const normalized = normalizeImageData(mimeType, data);
1265
+ const extension = getImageExtension(normalized.mimeType);
1266
+ const filename = `${randomUUID()}.${extension}`;
1267
+ const filePath = path.join(attachmentsDir, filename);
1268
+ fsSync.writeFileSync(filePath, Buffer.from(normalized.data, "base64"));
1269
+ return filePath;
1270
+ }
1271
+ function materializeCodexImageOutput(image) {
1272
+ return {
1273
+ path: writeImageAttachmentSync(image.mimeType ?? "image/png", image.data),
1274
+ };
1275
+ }
1276
+ function mapCodexThreadImageItem(normalizedType, normalizedItem) {
1277
+ if (normalizedType === "imageView") {
1278
+ return renderProviderImageOutputAsAssistantMarkdown({
1279
+ path: firstStringField(normalizedItem, ["path"]),
1280
+ });
1281
+ }
1282
+ const savedPath = firstStringField(normalizedItem, ["savedPath", "saved_path"]);
1283
+ const result = codexImageOutputFromResult(normalizedItem.result);
1284
+ return renderProviderImageOutputAsAssistantMarkdown({
1285
+ path: savedPath ?? result?.path ?? null,
1286
+ url: result?.url ?? null,
1287
+ data: result?.data ?? null,
1288
+ mimeType: result?.mimeType ?? null,
1289
+ }, { materialize: materializeCodexImageOutput });
1290
+ }
1121
1291
  function threadItemToTimeline(item, options) {
1122
- if (!item || typeof item !== "object")
1292
+ const itemRecord = toObjectRecord(item);
1293
+ if (!itemRecord)
1123
1294
  return null;
1124
- const itemRecord = item;
1125
1295
  const includeUserMessage = options?.includeUserMessage ?? true;
1126
1296
  const cwd = options?.cwd ?? null;
1127
1297
  const normalizedType = normalizeCodexThreadItemType(typeof itemRecord.type === "string" ? itemRecord.type : undefined);
1128
1298
  const normalizedItem = normalizedType && normalizedType !== itemRecord.type
1129
1299
  ? { ...itemRecord, type: normalizedType }
1130
1300
  : itemRecord;
1301
+ if (normalizedType === "imageView" || normalizedType === "imageGeneration") {
1302
+ return mapCodexThreadImageItem(normalizedType, normalizedItem);
1303
+ }
1304
+ if (normalizedType && CODEX_TOOL_THREAD_ITEM_TYPES.has(normalizedType)) {
1305
+ return mapCodexToolCallFromThreadItem(normalizedItem, { cwd });
1306
+ }
1131
1307
  switch (normalizedType) {
1132
1308
  case "userMessage":
1133
1309
  return mapCodexThreadUserMessageItem(normalizedItem, includeUserMessage);
@@ -1140,12 +1316,6 @@ function threadItemToTimeline(item, options) {
1140
1316
  return mapCodexThreadPlanItem(normalizedItem);
1141
1317
  case "reasoning":
1142
1318
  return mapCodexThreadReasoningItem(normalizedItem);
1143
- case "commandExecution":
1144
- case "fileChange":
1145
- case "mcpToolCall":
1146
- case "webSearch":
1147
- case "collabAgentToolCall":
1148
- return mapCodexToolCallFromThreadItem(normalizedItem, { cwd });
1149
1319
  default:
1150
1320
  return null;
1151
1321
  }
@@ -1816,10 +1986,13 @@ async function writeImageAttachment(mimeType, data) {
1816
1986
  async function readCodexConfiguredDefaults(client, logger) {
1817
1987
  let savedConfigDefaults = {};
1818
1988
  try {
1819
- const response = (await client.request("getUserSavedConfig", {}));
1989
+ const response = toObjectRecord(await client.request("getUserSavedConfig", {}));
1990
+ const config = toObjectRecord(response?.config);
1991
+ const modelValue = typeof config?.model === "string" ? config.model : undefined;
1992
+ const thinkingOptionValue = typeof config?.modelReasoningEffort === "string" ? config.modelReasoningEffort : null;
1820
1993
  savedConfigDefaults = {
1821
- model: normalizeCodexModelId(response?.config?.model),
1822
- thinkingOptionId: normalizeCodexThinkingOptionId(response?.config?.modelReasoningEffort ?? null),
1994
+ model: normalizeCodexModelId(modelValue),
1995
+ thinkingOptionId: normalizeCodexThinkingOptionId(thinkingOptionValue),
1823
1996
  };
1824
1997
  }
1825
1998
  catch (error) {
@@ -1830,10 +2003,13 @@ async function readCodexConfiguredDefaults(client, logger) {
1830
2003
  }
1831
2004
  let configReadDefaults = {};
1832
2005
  try {
1833
- const response = (await client.request("config/read", {}));
2006
+ const response = toObjectRecord(await client.request("config/read", {}));
2007
+ const config = toObjectRecord(response?.config);
2008
+ const modelValue = typeof config?.model === "string" ? config.model : undefined;
2009
+ const thinkingOptionValue = typeof config?.model_reasoning_effort === "string" ? config.model_reasoning_effort : null;
1834
2010
  configReadDefaults = {
1835
- model: normalizeCodexModelId(response?.config?.model),
1836
- thinkingOptionId: normalizeCodexThinkingOptionId(response?.config?.model_reasoning_effort ?? null),
2011
+ model: normalizeCodexModelId(modelValue),
2012
+ thinkingOptionId: normalizeCodexThinkingOptionId(thinkingOptionValue),
1837
2013
  };
1838
2014
  }
1839
2015
  catch (error) {
@@ -1905,11 +2081,12 @@ function buildCodexAppServerInitializeParams() {
1905
2081
  };
1906
2082
  }
1907
2083
  class CodexAppServerAgentSession {
1908
- constructor(config, resumeHandle, logger, spawnAppServer, deps = {}, ephemeral = false) {
2084
+ constructor(config, resumeHandle, logger, spawnAppServer, deps = {}, ephemeral = false, goalsEnabled = false) {
1909
2085
  this.resumeHandle = resumeHandle;
1910
2086
  this.spawnAppServer = spawnAppServer;
1911
2087
  this.deps = deps;
1912
2088
  this.ephemeral = ephemeral;
2089
+ this.goalsEnabled = goalsEnabled;
1913
2090
  this.provider = CODEX_PROVIDER;
1914
2091
  this.capabilities = CODEX_APP_SERVER_CAPABILITIES;
1915
2092
  this.currentThreadId = null;
@@ -1999,15 +2176,20 @@ class CodexAppServerAgentSession {
1999
2176
  if (!this.client)
2000
2177
  return;
2001
2178
  try {
2002
- const response = (await this.client.request("collaborationMode/list", {}));
2179
+ const response = toObjectRecord(await this.client.request("collaborationMode/list", {}));
2003
2180
  const data = Array.isArray(response?.data) ? response.data : [];
2004
- this.collaborationModes = data.map((entry) => ({
2005
- name: typeof entry.name === "string" ? entry.name : "",
2006
- mode: typeof entry.mode === "string" ? entry.mode : null,
2007
- model: typeof entry.model === "string" ? entry.model : null,
2008
- reasoning_effort: typeof entry.reasoning_effort === "string" ? entry.reasoning_effort : null,
2009
- developer_instructions: typeof entry.developer_instructions === "string" ? entry.developer_instructions : null,
2010
- }));
2181
+ this.collaborationModes = data.map((entry) => {
2182
+ const record = toObjectRecord(entry);
2183
+ return {
2184
+ name: typeof record?.name === "string" ? record.name : "",
2185
+ mode: typeof record?.mode === "string" ? record.mode : null,
2186
+ model: typeof record?.model === "string" ? record.model : null,
2187
+ reasoning_effort: typeof record?.reasoning_effort === "string" ? record.reasoning_effort : null,
2188
+ developer_instructions: typeof record?.developer_instructions === "string"
2189
+ ? record.developer_instructions
2190
+ : null,
2191
+ };
2192
+ });
2011
2193
  }
2012
2194
  catch (error) {
2013
2195
  this.logger.trace({ error }, "Failed to load collaboration modes");
@@ -2019,22 +2201,22 @@ class CodexAppServerAgentSession {
2019
2201
  if (!this.client)
2020
2202
  return;
2021
2203
  try {
2022
- const response = (await this.client.request("skills/list", {
2204
+ const response = toObjectRecord(await this.client.request("skills/list", {
2023
2205
  cwd: [this.config.cwd],
2024
2206
  }));
2025
2207
  const entries = Array.isArray(response?.data) ? response.data : [];
2026
2208
  const skills = [];
2027
2209
  for (const entry of entries) {
2028
- const list = Array.isArray(entry.skills)
2029
- ? entry.skills
2030
- : [];
2210
+ const entryRecord = toObjectRecord(entry);
2211
+ const list = Array.isArray(entryRecord?.skills) ? entryRecord.skills : [];
2031
2212
  for (const skill of list) {
2032
- if (typeof skill?.name !== "string" || typeof skill?.path !== "string")
2213
+ const skillRecord = toObjectRecord(skill);
2214
+ if (typeof skillRecord?.name !== "string" || typeof skillRecord?.path !== "string")
2033
2215
  continue;
2034
2216
  skills.push({
2035
- name: skill.name,
2036
- description: resolveSkillDescription(skill),
2037
- path: skill.path,
2217
+ name: skillRecord.name,
2218
+ description: resolveSkillDescription(skillRecord),
2219
+ path: skillRecord.path,
2038
2220
  });
2039
2221
  }
2040
2222
  }
@@ -2183,7 +2365,7 @@ class CodexAppServerAgentSession {
2183
2365
  if (!this.client || !this.currentThreadId)
2184
2366
  return;
2185
2367
  try {
2186
- const loaded = (await this.client.request("thread/loaded/list", {}));
2368
+ const loaded = toObjectRecord(await this.client.request("thread/loaded/list", {}));
2187
2369
  const ids = Array.isArray(loaded?.data) ? loaded.data : [];
2188
2370
  if (ids.includes(this.currentThreadId)) {
2189
2371
  return;
@@ -2622,7 +2804,86 @@ class CodexAppServerAgentSession {
2622
2804
  const fallbackSkills = appServerSkills.length === 0
2623
2805
  ? await listCodexSkills(this.config.cwd, this.deps.workspaceGitService)
2624
2806
  : [];
2625
- return [...appServerSkills, ...fallbackSkills, ...prompts].sort((a, b) => a.name.localeCompare(b.name));
2807
+ const builtin = [];
2808
+ if (this.goalsEnabled) {
2809
+ builtin.push({
2810
+ name: "goal",
2811
+ description: "Set, pause, resume, or clear the agent's goal",
2812
+ argumentHint: "[<objective>|pause|resume|clear]",
2813
+ });
2814
+ }
2815
+ return [...builtin, ...appServerSkills, ...fallbackSkills, ...prompts].sort((a, b) => a.name.localeCompare(b.name));
2816
+ }
2817
+ tryHandleOutOfBand(prompt) {
2818
+ if (!this.goalsEnabled)
2819
+ return null;
2820
+ if (typeof prompt !== "string")
2821
+ return null;
2822
+ const parsed = this.parseSlashCommandInput(prompt);
2823
+ if (!parsed || parsed.commandName !== "goal")
2824
+ return null;
2825
+ const subcommand = parseGoalSubcommand(parsed.args);
2826
+ return {
2827
+ run: async ({ emit }) => {
2828
+ const text = formatOutOfBandStatusMessage(await this.executeGoalSubcommand(subcommand));
2829
+ emit({
2830
+ type: "timeline",
2831
+ provider: CODEX_PROVIDER,
2832
+ item: { type: "assistant_message", text },
2833
+ });
2834
+ },
2835
+ };
2836
+ }
2837
+ async executeGoalSubcommand(subcommand) {
2838
+ if (subcommand.kind === "usage") {
2839
+ return "Usage: /goal <objective>|pause|resume|clear";
2840
+ }
2841
+ try {
2842
+ await this.connect();
2843
+ if (this.currentThreadId) {
2844
+ await this.ensureThreadLoaded();
2845
+ }
2846
+ else {
2847
+ await this.ensureThread();
2848
+ }
2849
+ if (!this.client || !this.currentThreadId) {
2850
+ throw new Error("Codex thread is not available");
2851
+ }
2852
+ switch (subcommand.kind) {
2853
+ case "set": {
2854
+ await this.client.request("thread/goal/set", {
2855
+ threadId: this.currentThreadId,
2856
+ objective: subcommand.objective,
2857
+ status: "active",
2858
+ });
2859
+ return `Goal set: ${subcommand.objective}`;
2860
+ }
2861
+ case "pause": {
2862
+ await this.client.request("thread/goal/set", {
2863
+ threadId: this.currentThreadId,
2864
+ status: "paused",
2865
+ });
2866
+ return "Goal paused.";
2867
+ }
2868
+ case "resume": {
2869
+ await this.client.request("thread/goal/set", {
2870
+ threadId: this.currentThreadId,
2871
+ status: "active",
2872
+ });
2873
+ return "Goal resumed.";
2874
+ }
2875
+ case "clear": {
2876
+ await this.client.request("thread/goal/clear", {
2877
+ threadId: this.currentThreadId,
2878
+ });
2879
+ return "Goal cleared.";
2880
+ }
2881
+ }
2882
+ }
2883
+ catch (error) {
2884
+ const message = error instanceof Error ? error.message : "unknown error";
2885
+ return `Failed to update goal: ${message}`;
2886
+ }
2626
2887
  }
2627
2888
  async resolveModelAndThinking() {
2628
2889
  if (!this.client) {
@@ -2641,8 +2902,20 @@ class CodexAppServerAgentSession {
2641
2902
  thinkingOptionId = configuredDefaults.thinkingOptionId;
2642
2903
  }
2643
2904
  if (!model || !thinkingOptionId) {
2644
- const modelResponse = (await this.client.request("model/list", {}));
2645
- const models = modelResponse?.data ?? [];
2905
+ const modelResponse = toObjectRecord(await this.client.request("model/list", {}));
2906
+ const modelData = Array.isArray(modelResponse?.data) ? modelResponse.data : [];
2907
+ const models = modelData
2908
+ .map((m) => {
2909
+ const record = toObjectRecord(m);
2910
+ return {
2911
+ id: typeof record?.id === "string" ? record.id : "",
2912
+ isDefault: !!record?.isDefault,
2913
+ defaultReasoningEffort: typeof record?.defaultReasoningEffort === "string"
2914
+ ? record.defaultReasoningEffort
2915
+ : undefined,
2916
+ };
2917
+ })
2918
+ .filter((m) => m.id);
2646
2919
  const defaultModel = models.find((m) => m.isDefault) ?? models[0];
2647
2920
  if (!defaultModel) {
2648
2921
  throw new Error("No models available from Codex app-server");
@@ -2672,7 +2945,7 @@ class CodexAppServerAgentSession {
2672
2945
  const approvalPolicy = this.config.approvalPolicy ?? preset.approvalPolicy;
2673
2946
  const sandbox = this.config.sandboxMode ?? preset.sandbox;
2674
2947
  const innerConfig = this.buildCodexInnerConfig();
2675
- const response = (await this.client.request("thread/start", {
2948
+ const rawResponse = await this.client.request("thread/start", {
2676
2949
  model,
2677
2950
  cwd: this.config.cwd ?? null,
2678
2951
  approvalPolicy,
@@ -2682,8 +2955,10 @@ class CodexAppServerAgentSession {
2682
2955
  : {}),
2683
2956
  ...(innerConfig ? { config: innerConfig } : {}),
2684
2957
  ...(this.ephemeral ? { ephemeral: true } : {}),
2685
- }));
2686
- const threadId = response?.thread?.id;
2958
+ });
2959
+ const response = toObjectRecord(rawResponse);
2960
+ const threadRecord = toObjectRecord(response?.thread);
2961
+ const threadId = typeof threadRecord?.id === "string" ? threadRecord.id : undefined;
2687
2962
  if (!threadId) {
2688
2963
  throw new Error("Codex app-server did not return thread id");
2689
2964
  }
@@ -3367,7 +3642,16 @@ class CodexAppServerAgentSession {
3367
3642
  }, "Codex edit tool call is missing diff/content fields");
3368
3643
  }
3369
3644
  handleCommandApprovalRequest(params) {
3370
- const parsed = params;
3645
+ const parsed = z
3646
+ .object({
3647
+ itemId: z.string(),
3648
+ threadId: z.string(),
3649
+ turnId: z.string(),
3650
+ command: z.string().nullable().optional(),
3651
+ cwd: z.string().nullable().optional(),
3652
+ reason: z.string().nullable().optional(),
3653
+ })
3654
+ .parse(params);
3371
3655
  const commandPreview = mapCodexExecNotificationToToolCall({
3372
3656
  callId: parsed.itemId,
3373
3657
  command: parsed.command,
@@ -3408,7 +3692,14 @@ class CodexAppServerAgentSession {
3408
3692
  });
3409
3693
  }
3410
3694
  handleFileChangeApprovalRequest(params) {
3411
- const parsed = params;
3695
+ const parsed = z
3696
+ .object({
3697
+ itemId: z.string(),
3698
+ threadId: z.string(),
3699
+ turnId: z.string(),
3700
+ reason: z.string().nullable().optional(),
3701
+ })
3702
+ .parse(params);
3412
3703
  const requestId = `permission-${parsed.itemId}`;
3413
3704
  const request = {
3414
3705
  id: requestId,
@@ -3437,7 +3728,14 @@ class CodexAppServerAgentSession {
3437
3728
  });
3438
3729
  }
3439
3730
  handleToolApprovalRequest(params) {
3440
- const parsed = params;
3731
+ const parsed = z
3732
+ .object({
3733
+ itemId: z.string(),
3734
+ threadId: z.string(),
3735
+ turnId: z.string(),
3736
+ questions: z.array(z.unknown()),
3737
+ })
3738
+ .parse(params);
3441
3739
  const requestId = `permission-${parsed.itemId}`;
3442
3740
  const questions = normalizeCodexQuestionPrompts(parsed.questions);
3443
3741
  const request = {
@@ -3487,13 +3785,37 @@ export class CodexAppServerAgentClient {
3487
3785
  this.deps = deps;
3488
3786
  this.provider = CODEX_PROVIDER;
3489
3787
  this.capabilities = CODEX_APP_SERVER_CAPABILITIES;
3788
+ this.goalsEnabledPromise = null;
3789
+ }
3790
+ resolveGoalsEnabled() {
3791
+ if (!this.goalsEnabledPromise) {
3792
+ this.goalsEnabledPromise = (async () => {
3793
+ try {
3794
+ const launchPrefix = await resolveCodexLaunchPrefix(this.runtimeSettings);
3795
+ const versionOutput = await resolveBinaryVersion(launchPrefix.command);
3796
+ const enabled = codexVersionAtLeast(versionOutput, CODEX_GOALS_MIN_VERSION);
3797
+ this.logger.trace({ versionOutput, enabled }, "Resolved codex goals feature gate");
3798
+ return enabled;
3799
+ }
3800
+ catch (error) {
3801
+ this.logger.warn({ err: error }, "Failed to probe codex version for goals gate");
3802
+ return false;
3803
+ }
3804
+ })();
3805
+ }
3806
+ return this.goalsEnabledPromise;
3490
3807
  }
3491
- async spawnAppServer(launchEnv) {
3808
+ async spawnAppServer(launchEnv, options) {
3492
3809
  const launchPrefix = await resolveCodexLaunchPrefix(this.runtimeSettings);
3810
+ const args = [...launchPrefix.args, "app-server"];
3811
+ if (options?.goalsEnabled) {
3812
+ args.push("--enable", "goals");
3813
+ }
3493
3814
  this.logger.trace({
3494
3815
  launchPrefix,
3816
+ goalsEnabled: options?.goalsEnabled === true,
3495
3817
  }, "Spawning Codex app server");
3496
- return spawnProcess(launchPrefix.command, [...launchPrefix.args, "app-server"], {
3818
+ const child = spawnProcess(launchPrefix.command, args, {
3497
3819
  detached: process.platform !== "win32",
3498
3820
  stdio: ["pipe", "pipe", "pipe"],
3499
3821
  ...createProviderEnvSpec({
@@ -3501,10 +3823,18 @@ export class CodexAppServerAgentClient {
3501
3823
  overlays: [launchEnv],
3502
3824
  }),
3503
3825
  });
3826
+ assertChildWithPipes(child);
3827
+ return child;
3504
3828
  }
3505
3829
  async createSession(config, launchContext, options) {
3830
+ if (options?.persistSession === false) {
3831
+ this.logger.debug("Codex app-server does not expose an ephemeral-session option; persistSession=false is currently a no-op");
3832
+ // TODO: Honor persistSession=false if app-server adds support, or route
3833
+ // utility generations through `codex exec --ephemeral` in a larger change.
3834
+ }
3506
3835
  const sessionConfig = { ...config, provider: CODEX_PROVIDER };
3507
- const session = new CodexAppServerAgentSession(sessionConfig, null, this.logger, () => this.spawnAppServer(launchContext?.env), this.deps, options?.persistSession === false);
3836
+ const goalsEnabled = await this.resolveGoalsEnabled();
3837
+ const session = new CodexAppServerAgentSession(sessionConfig, null, this.logger, () => this.spawnAppServer(launchContext?.env, { goalsEnabled }), this.deps, options?.persistSession === false, goalsEnabled);
3508
3838
  await session.connect();
3509
3839
  return session;
3510
3840
  }
@@ -3516,19 +3846,27 @@ export class CodexAppServerAgentClient {
3516
3846
  provider: CODEX_PROVIDER,
3517
3847
  cwd: overrides?.cwd ?? storedConfig.cwd ?? process.cwd(),
3518
3848
  };
3519
- const session = new CodexAppServerAgentSession(merged, handle, this.logger, () => this.spawnAppServer(launchContext?.env), this.deps);
3849
+ const goalsEnabled = await this.resolveGoalsEnabled();
3850
+ const session = new CodexAppServerAgentSession(merged, handle, this.logger, () => this.spawnAppServer(launchContext?.env, { goalsEnabled }), this.deps, false, goalsEnabled);
3520
3851
  await session.connect();
3521
3852
  return session;
3522
3853
  }
3523
3854
  async listPersistedAgents(options) {
3524
3855
  const child = await this.spawnAppServer();
3525
- const client = new CodexAppServerClient(child, this.logger);
3856
+ const client = this.deps._createCodexClient?.(child, this.logger) ??
3857
+ new CodexAppServerClient(child, this.logger);
3526
3858
  try {
3527
3859
  await client.request("initialize", buildCodexAppServerInitializeParams());
3528
3860
  client.notify("initialized", {});
3529
3861
  const limit = options?.limit ?? 20;
3530
- const response = (await client.request("thread/list", { limit }));
3531
- const threads = Array.isArray(response?.data) ? response.data : [];
3862
+ // thread/list returns the cheap `cwd` field. When the caller supplied
3863
+ // a cwd hint we filter here so the per-thread `thread/read includeTurns`
3864
+ // hydration below only runs for matching threads. Fetch a wider window
3865
+ // when filtering since most threads will be from other cwds.
3866
+ const listLimit = options?.cwd ? Math.max(limit, 50) : limit;
3867
+ const response = toObjectRecord(await client.request("thread/list", { limit: listLimit }));
3868
+ const allThreads = Array.isArray(response?.data) ? response.data.filter(isRecord) : [];
3869
+ const threads = filterCodexThreadsByCwd(allThreads, options?.cwd);
3532
3870
  const descriptors = await Promise.all(threads.slice(0, limit).map(async (thread) => {
3533
3871
  const threadId = typeof thread.id === "string" ? thread.id : "";
3534
3872
  const cwd = typeof thread.cwd === "string" ? thread.cwd : process.cwd();
@@ -3581,8 +3919,9 @@ export class CodexAppServerAgentClient {
3581
3919
  try {
3582
3920
  await client.request("initialize", buildCodexAppServerInitializeParams());
3583
3921
  client.notify("initialized", {});
3584
- const response = (await client.request("model/list", {}));
3585
- const models = Array.isArray(response?.data) ? response.data : [];
3922
+ const rawResponse = await client.request("model/list", {});
3923
+ const parsedResponse = CodexModelListResponseSchema.safeParse(rawResponse);
3924
+ const models = parsedResponse.success ? (parsedResponse.data.data ?? []) : [];
3586
3925
  const configuredDefaults = await readCodexConfiguredDefaults(client, this.logger);
3587
3926
  const configuredDefaultModelId = configuredDefaults.model;
3588
3927
  const configuredDefaultThinkingOptionId = configuredDefaults.thinkingOptionId;
@@ -3599,6 +3938,21 @@ export class CodexAppServerAgentClient {
3599
3938
  await client.dispose();
3600
3939
  }
3601
3940
  }
3941
+ async archiveNativeSession(handle) {
3942
+ const threadId = handle.nativeHandle ?? handle.sessionId;
3943
+ if (!threadId)
3944
+ return;
3945
+ const child = await this.spawnAppServer();
3946
+ const client = new CodexAppServerClient(child, this.logger);
3947
+ try {
3948
+ await client.request("initialize", buildCodexAppServerInitializeParams());
3949
+ client.notify("initialized", {});
3950
+ await client.request("thread/archive", { threadId });
3951
+ }
3952
+ finally {
3953
+ await client.dispose();
3954
+ }
3955
+ }
3602
3956
  async isAvailable() {
3603
3957
  const command = this.runtimeSettings?.command;
3604
3958
  if (command?.mode === "replace") {