remote-codex 0.11.9 → 0.11.11

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 (325) hide show
  1. package/apps/relay-server/dist/index.js +75 -6
  2. package/apps/supervisor-api/dist/{chunk-NWZLUCQV.js → chunk-2QAVWDYV.js} +1137 -349
  3. package/apps/supervisor-api/dist/index.js +1 -1
  4. package/apps/supervisor-api/dist/worker-index.js +1 -1
  5. package/apps/supervisor-web/dist/assets/core-oEok_Crl.js +12 -0
  6. package/apps/supervisor-web/dist/assets/{css-DPfMkruS.js → css-CLj8gQPS.js} +1 -1
  7. package/apps/supervisor-web/dist/assets/engine-javascript-DBd1bXLz.js +141 -0
  8. package/apps/supervisor-web/dist/assets/graph-vendor-C5ap-Sga.css +1 -0
  9. package/apps/supervisor-web/dist/assets/graph-vendor-DVPtkh3h.js +23 -0
  10. package/apps/supervisor-web/dist/assets/{html-GMplVEZG.js → html-pp8916En.js} +1 -1
  11. package/apps/supervisor-web/dist/assets/index-Cp9GkemI.css +1 -0
  12. package/apps/supervisor-web/dist/assets/index-Dsq8QmDr.js +6 -0
  13. package/apps/supervisor-web/dist/assets/markdown-vendor-BQJfKm05.js +291 -0
  14. package/apps/supervisor-web/dist/assets/react-vendor-CgLzZcV4.js +60 -0
  15. package/apps/supervisor-web/dist/assets/{shellscript-Yzrsuije.js → shellscript-CEILq0vU.js} +1 -1
  16. package/apps/supervisor-web/dist/assets/{sql-BLtJtn59.js → sql-CRqJ_cUM.js} +1 -1
  17. package/apps/supervisor-web/dist/assets/{terminal-vendor-BHwWZ4Dd.js → terminal-vendor-B365Go3Z.js} +1 -1
  18. package/apps/supervisor-web/dist/assets/thread-ui-DldLSgqC.js +3604 -0
  19. package/apps/supervisor-web/dist/assets/ui-vendor-CeKGesq3.js +50 -0
  20. package/apps/supervisor-web/dist/index.html +9 -8
  21. package/package.json +2 -2
  22. package/packages/agent-runtime/src/types.ts +1 -0
  23. package/packages/codex/src/appServerManager.test.ts +52 -0
  24. package/packages/codex/src/appServerManager.ts +12 -14
  25. package/packages/codex/src/historyItems.test.ts +33 -0
  26. package/packages/codex/src/historyItems.ts +49 -2
  27. package/packages/codex/src/runtimeAdapter.test.ts +76 -0
  28. package/packages/codex/src/runtimeAdapter.ts +72 -2
  29. package/packages/codex/src/types.ts +13 -0
  30. package/packages/shared/src/index.ts +3 -0
  31. package/apps/supervisor-api/dist/chunk-2ELO2EVR.js +0 -27897
  32. package/apps/supervisor-api/dist/chunk-XKQPZVOC.js +0 -27890
  33. package/apps/supervisor-web/dist/assets/abap-BdImnpbu.js +0 -1
  34. package/apps/supervisor-web/dist/assets/actionscript-3-CoDkCxhg.js +0 -1
  35. package/apps/supervisor-web/dist/assets/ada-bCR0ucgS.js +0 -1
  36. package/apps/supervisor-web/dist/assets/andromeeda-C4gqWexZ.js +0 -1
  37. package/apps/supervisor-web/dist/assets/angular-html-CU67Zn6k.js +0 -1
  38. package/apps/supervisor-web/dist/assets/angular-ts-BwZT4LLn.js +0 -1
  39. package/apps/supervisor-web/dist/assets/apache-Pmp26Uib.js +0 -1
  40. package/apps/supervisor-web/dist/assets/apex-D8_7TLub.js +0 -1
  41. package/apps/supervisor-web/dist/assets/apl-dKokRX4l.js +0 -1
  42. package/apps/supervisor-web/dist/assets/applescript-Co6uUVPk.js +0 -1
  43. package/apps/supervisor-web/dist/assets/ara-BRHolxvo.js +0 -1
  44. package/apps/supervisor-web/dist/assets/asciidoc-Ve4PFQV2.js +0 -1
  45. package/apps/supervisor-web/dist/assets/asm-D_Q5rh1f.js +0 -1
  46. package/apps/supervisor-web/dist/assets/astro-CbQHKStN.js +0 -1
  47. package/apps/supervisor-web/dist/assets/aurora-x-D-2ljcwZ.js +0 -1
  48. package/apps/supervisor-web/dist/assets/awk-DMzUqQB5.js +0 -1
  49. package/apps/supervisor-web/dist/assets/ayu-mirage-32ctXXKs.js +0 -1
  50. package/apps/supervisor-web/dist/assets/ballerina-BFfxhgS-.js +0 -1
  51. package/apps/supervisor-web/dist/assets/bat-BkioyH1T.js +0 -1
  52. package/apps/supervisor-web/dist/assets/beancount-k_qm7-4y.js +0 -1
  53. package/apps/supervisor-web/dist/assets/berry-uYugtg8r.js +0 -1
  54. package/apps/supervisor-web/dist/assets/bibtex-CHM0blh-.js +0 -1
  55. package/apps/supervisor-web/dist/assets/bicep-Bmn6On1c.js +0 -1
  56. package/apps/supervisor-web/dist/assets/bird2-DPOp833l.js +0 -1
  57. package/apps/supervisor-web/dist/assets/blade-D4QpJJKB.js +0 -1
  58. package/apps/supervisor-web/dist/assets/bsl-BO_Y6i37.js +0 -1
  59. package/apps/supervisor-web/dist/assets/c-BIGW1oBm.js +0 -1
  60. package/apps/supervisor-web/dist/assets/c3-eo99z4R2.js +0 -1
  61. package/apps/supervisor-web/dist/assets/cadence-Bv_4Rxtq.js +0 -1
  62. package/apps/supervisor-web/dist/assets/cairo-KRGpt6FW.js +0 -1
  63. package/apps/supervisor-web/dist/assets/catppuccin-frappe-DFWUc33u.js +0 -1
  64. package/apps/supervisor-web/dist/assets/catppuccin-latte-C9dUb6Cb.js +0 -1
  65. package/apps/supervisor-web/dist/assets/catppuccin-macchiato-DQyhUUbL.js +0 -1
  66. package/apps/supervisor-web/dist/assets/catppuccin-mocha-D87Tk5Gz.js +0 -1
  67. package/apps/supervisor-web/dist/assets/clarity-D53aC0YG.js +0 -1
  68. package/apps/supervisor-web/dist/assets/clojure-P80f7IUj.js +0 -1
  69. package/apps/supervisor-web/dist/assets/cmake-D1j8_8rp.js +0 -1
  70. package/apps/supervisor-web/dist/assets/cobol-nwyudZeR.js +0 -1
  71. package/apps/supervisor-web/dist/assets/codeowners-Bp6g37R7.js +0 -1
  72. package/apps/supervisor-web/dist/assets/codeql-DsOJ9woJ.js +0 -1
  73. package/apps/supervisor-web/dist/assets/coffee-Ch7k5sss.js +0 -1
  74. package/apps/supervisor-web/dist/assets/common-lisp-Cg-RD9OK.js +0 -1
  75. package/apps/supervisor-web/dist/assets/coq-DkFqJrB1.js +0 -1
  76. package/apps/supervisor-web/dist/assets/cpp-CofmeUqb.js +0 -1
  77. package/apps/supervisor-web/dist/assets/crystal-tKQVLTB8.js +0 -1
  78. package/apps/supervisor-web/dist/assets/csharp-COcwbKMJ.js +0 -1
  79. package/apps/supervisor-web/dist/assets/cue-D82EKSYY.js +0 -1
  80. package/apps/supervisor-web/dist/assets/cypher-COkxafJQ.js +0 -1
  81. package/apps/supervisor-web/dist/assets/d-85-TOEBH.js +0 -1
  82. package/apps/supervisor-web/dist/assets/dark-plus-C3mMm8J8.js +0 -1
  83. package/apps/supervisor-web/dist/assets/dart-CF10PKvl.js +0 -1
  84. package/apps/supervisor-web/dist/assets/dax-CEL-wOlO.js +0 -1
  85. package/apps/supervisor-web/dist/assets/desktop-BmXAJ9_W.js +0 -1
  86. package/apps/supervisor-web/dist/assets/diff-D97Zzqfu.js +0 -1
  87. package/apps/supervisor-web/dist/assets/docker-BcOcwvcX.js +0 -1
  88. package/apps/supervisor-web/dist/assets/dotenv-Da5cRb03.js +0 -1
  89. package/apps/supervisor-web/dist/assets/dracula-BzJJZx-M.js +0 -1
  90. package/apps/supervisor-web/dist/assets/dracula-soft-BXkSAIEj.js +0 -1
  91. package/apps/supervisor-web/dist/assets/dream-maker-BtqSS_iP.js +0 -1
  92. package/apps/supervisor-web/dist/assets/edge-BkV0erSs.js +0 -1
  93. package/apps/supervisor-web/dist/assets/elixir-CDX3lj18.js +0 -1
  94. package/apps/supervisor-web/dist/assets/elm-DbKCFpqz.js +0 -1
  95. package/apps/supervisor-web/dist/assets/emacs-lisp-C9XAeP06.js +0 -1
  96. package/apps/supervisor-web/dist/assets/erb-B12qg9BL.js +0 -1
  97. package/apps/supervisor-web/dist/assets/erlang-DsQrWhSR.js +0 -1
  98. package/apps/supervisor-web/dist/assets/everforest-dark-BgDCqdQA.js +0 -1
  99. package/apps/supervisor-web/dist/assets/everforest-light-C8M2exoo.js +0 -1
  100. package/apps/supervisor-web/dist/assets/fennel-BYunw83y.js +0 -1
  101. package/apps/supervisor-web/dist/assets/fish-BvzEVeQv.js +0 -1
  102. package/apps/supervisor-web/dist/assets/fluent-C4IJs8-o.js +0 -1
  103. package/apps/supervisor-web/dist/assets/fortran-fixed-form-CkoXwp7k.js +0 -1
  104. package/apps/supervisor-web/dist/assets/fortran-free-form-BxgE0vQu.js +0 -1
  105. package/apps/supervisor-web/dist/assets/fsharp-CXgrBDvD.js +0 -1
  106. package/apps/supervisor-web/dist/assets/gdresource-BOOCDP_w.js +0 -1
  107. package/apps/supervisor-web/dist/assets/gdscript-C5YyOfLZ.js +0 -1
  108. package/apps/supervisor-web/dist/assets/gdshader-DkwncUOv.js +0 -1
  109. package/apps/supervisor-web/dist/assets/genie-D0YGMca9.js +0 -1
  110. package/apps/supervisor-web/dist/assets/gherkin-DyxjwDmM.js +0 -1
  111. package/apps/supervisor-web/dist/assets/git-commit-F4YmCXRG.js +0 -1
  112. package/apps/supervisor-web/dist/assets/git-rebase-r7XF79zn.js +0 -1
  113. package/apps/supervisor-web/dist/assets/github-dark-DHJKELXO.js +0 -1
  114. package/apps/supervisor-web/dist/assets/github-dark-default-Cuk6v7N8.js +0 -1
  115. package/apps/supervisor-web/dist/assets/github-dark-dimmed-DH5Ifo-i.js +0 -1
  116. package/apps/supervisor-web/dist/assets/github-dark-high-contrast-E3gJ1_iC.js +0 -1
  117. package/apps/supervisor-web/dist/assets/github-light-DAi9KRSo.js +0 -1
  118. package/apps/supervisor-web/dist/assets/github-light-default-D7oLnXFd.js +0 -1
  119. package/apps/supervisor-web/dist/assets/github-light-high-contrast-BfjtVDDH.js +0 -1
  120. package/apps/supervisor-web/dist/assets/gleam-BspZqrRM.js +0 -1
  121. package/apps/supervisor-web/dist/assets/glimmer-js-Rg0-pVw9.js +0 -1
  122. package/apps/supervisor-web/dist/assets/glimmer-ts-U6CK756n.js +0 -1
  123. package/apps/supervisor-web/dist/assets/glsl-DplSGwfg.js +0 -1
  124. package/apps/supervisor-web/dist/assets/gn-n2N0HUVH.js +0 -1
  125. package/apps/supervisor-web/dist/assets/gnuplot-DdkO51Og.js +0 -1
  126. package/apps/supervisor-web/dist/assets/go-CxLEBnE3.js +0 -1
  127. package/apps/supervisor-web/dist/assets/graphql-ChdNCCLP.js +0 -1
  128. package/apps/supervisor-web/dist/assets/groovy-gcz8RCvz.js +0 -1
  129. package/apps/supervisor-web/dist/assets/gruvbox-dark-hard-CFHQjOhq.js +0 -1
  130. package/apps/supervisor-web/dist/assets/gruvbox-dark-medium-GsRaNv29.js +0 -1
  131. package/apps/supervisor-web/dist/assets/gruvbox-dark-soft-CVdnzihN.js +0 -1
  132. package/apps/supervisor-web/dist/assets/gruvbox-light-hard-CH1njM8p.js +0 -1
  133. package/apps/supervisor-web/dist/assets/gruvbox-light-medium-DRw_LuNl.js +0 -1
  134. package/apps/supervisor-web/dist/assets/gruvbox-light-soft-hJgmCMqR.js +0 -1
  135. package/apps/supervisor-web/dist/assets/hack-CaT9iCJl.js +0 -1
  136. package/apps/supervisor-web/dist/assets/haml-B8DHNrY2.js +0 -1
  137. package/apps/supervisor-web/dist/assets/handlebars-BL8al0AC.js +0 -1
  138. package/apps/supervisor-web/dist/assets/haskell-Df6bDoY_.js +0 -1
  139. package/apps/supervisor-web/dist/assets/haxe-CzTSHFRz.js +0 -1
  140. package/apps/supervisor-web/dist/assets/hcl-BWvSN4gD.js +0 -1
  141. package/apps/supervisor-web/dist/assets/highlighted-body-OFNGDK62-BRQR8o0F.js +0 -1
  142. package/apps/supervisor-web/dist/assets/hjson-D5-asLiD.js +0 -1
  143. package/apps/supervisor-web/dist/assets/hlsl-D3lLCCz7.js +0 -1
  144. package/apps/supervisor-web/dist/assets/horizon-BUw7H-hv.js +0 -1
  145. package/apps/supervisor-web/dist/assets/horizon-bright-Cn-bp-IR.js +0 -1
  146. package/apps/supervisor-web/dist/assets/houston-DnULxvSX.js +0 -1
  147. package/apps/supervisor-web/dist/assets/html-derivative-BFtXZ54Q.js +0 -1
  148. package/apps/supervisor-web/dist/assets/http-jrhK8wxY.js +0 -1
  149. package/apps/supervisor-web/dist/assets/hurl-irOxFIW8.js +0 -1
  150. package/apps/supervisor-web/dist/assets/hxml-Bvhsp5Yf.js +0 -1
  151. package/apps/supervisor-web/dist/assets/hy-DFXneXwc.js +0 -1
  152. package/apps/supervisor-web/dist/assets/imba-DGztddWO.js +0 -1
  153. package/apps/supervisor-web/dist/assets/index-APXuQABa.js +0 -5
  154. package/apps/supervisor-web/dist/assets/index-Dh2-KXLR.css +0 -1
  155. package/apps/supervisor-web/dist/assets/ini-BEwlwnbL.js +0 -1
  156. package/apps/supervisor-web/dist/assets/java-CylS5w8V.js +0 -1
  157. package/apps/supervisor-web/dist/assets/jinja-4LBKfQ-Z.js +0 -1
  158. package/apps/supervisor-web/dist/assets/jison-wvAkD_A8.js +0 -1
  159. package/apps/supervisor-web/dist/assets/json5-C9tS-k6U.js +0 -1
  160. package/apps/supervisor-web/dist/assets/jsonc-Des-eS-w.js +0 -1
  161. package/apps/supervisor-web/dist/assets/jsonl-DcaNXYhu.js +0 -1
  162. package/apps/supervisor-web/dist/assets/jsonnet-DFQXde-d.js +0 -1
  163. package/apps/supervisor-web/dist/assets/jssm-C2t-YnRu.js +0 -1
  164. package/apps/supervisor-web/dist/assets/julia-CxzCAyBv.js +0 -1
  165. package/apps/supervisor-web/dist/assets/just-Cw27pwNe.js +0 -1
  166. package/apps/supervisor-web/dist/assets/kanagawa-dragon-CkXjmgJE.js +0 -1
  167. package/apps/supervisor-web/dist/assets/kanagawa-lotus-CfQXZHmo.js +0 -1
  168. package/apps/supervisor-web/dist/assets/kanagawa-wave-DWedfzmr.js +0 -1
  169. package/apps/supervisor-web/dist/assets/kdl-DV7GczEv.js +0 -1
  170. package/apps/supervisor-web/dist/assets/kotlin-BdnUsdx6.js +0 -1
  171. package/apps/supervisor-web/dist/assets/kusto-DZf3V79B.js +0 -1
  172. package/apps/supervisor-web/dist/assets/laserwave-DUszq2jm.js +0 -1
  173. package/apps/supervisor-web/dist/assets/latex-CWtU0Tv5.js +0 -1
  174. package/apps/supervisor-web/dist/assets/lean-BZvkOJ9d.js +0 -1
  175. package/apps/supervisor-web/dist/assets/less-B1dDrJ26.js +0 -1
  176. package/apps/supervisor-web/dist/assets/light-plus-B7mTdjB0.js +0 -1
  177. package/apps/supervisor-web/dist/assets/liquid-DYVedYrR.js +0 -1
  178. package/apps/supervisor-web/dist/assets/llvm-DjAJT7YJ.js +0 -1
  179. package/apps/supervisor-web/dist/assets/log-2UxHyX5q.js +0 -1
  180. package/apps/supervisor-web/dist/assets/logo-BtOb2qkB.js +0 -1
  181. package/apps/supervisor-web/dist/assets/lua-BaeVxFsk.js +0 -1
  182. package/apps/supervisor-web/dist/assets/luau-C-HG3fhB.js +0 -1
  183. package/apps/supervisor-web/dist/assets/make-CHLpvVh8.js +0 -1
  184. package/apps/supervisor-web/dist/assets/markdown-vendor-C22AWDSP.js +0 -29
  185. package/apps/supervisor-web/dist/assets/marko-CnJfTvn9.js +0 -1
  186. package/apps/supervisor-web/dist/assets/material-theme-D5KoaKCx.js +0 -1
  187. package/apps/supervisor-web/dist/assets/material-theme-darker-BfHTSMKl.js +0 -1
  188. package/apps/supervisor-web/dist/assets/material-theme-lighter-B0m2ddpp.js +0 -1
  189. package/apps/supervisor-web/dist/assets/material-theme-ocean-CyktbL80.js +0 -1
  190. package/apps/supervisor-web/dist/assets/material-theme-palenight-Csfq5Kiy.js +0 -1
  191. package/apps/supervisor-web/dist/assets/matlab-D7o27uSR.js +0 -1
  192. package/apps/supervisor-web/dist/assets/mdc-BMNejdWA.js +0 -1
  193. package/apps/supervisor-web/dist/assets/mdx-Cmh6b_Ma.js +0 -1
  194. package/apps/supervisor-web/dist/assets/mermaid-mWjccvbQ.js +0 -1
  195. package/apps/supervisor-web/dist/assets/min-dark-CafNBF8u.js +0 -1
  196. package/apps/supervisor-web/dist/assets/min-light-CTRr51gU.js +0 -1
  197. package/apps/supervisor-web/dist/assets/mipsasm-CKIfxQSi.js +0 -1
  198. package/apps/supervisor-web/dist/assets/mojo-rZm6bMo-.js +0 -1
  199. package/apps/supervisor-web/dist/assets/monokai-D4h5O-jR.js +0 -1
  200. package/apps/supervisor-web/dist/assets/moonbit-_H4v1dQx.js +0 -1
  201. package/apps/supervisor-web/dist/assets/move-IF9eRakj.js +0 -1
  202. package/apps/supervisor-web/dist/assets/narrat-DRg8JJMk.js +0 -1
  203. package/apps/supervisor-web/dist/assets/nextflow-Zz6hmt5N.js +0 -1
  204. package/apps/supervisor-web/dist/assets/nextflow-groovy-BeH2EWoN.js +0 -1
  205. package/apps/supervisor-web/dist/assets/nginx-BpAMiNFr.js +0 -1
  206. package/apps/supervisor-web/dist/assets/night-owl-C39BiMTA.js +0 -1
  207. package/apps/supervisor-web/dist/assets/night-owl-light-CMTm3GFP.js +0 -1
  208. package/apps/supervisor-web/dist/assets/nim-CVrawwO9.js +0 -1
  209. package/apps/supervisor-web/dist/assets/nix-CwoSXNpI.js +0 -1
  210. package/apps/supervisor-web/dist/assets/nord-Ddv68eIx.js +0 -1
  211. package/apps/supervisor-web/dist/assets/nushell-Cz2AlsmD.js +0 -1
  212. package/apps/supervisor-web/dist/assets/objective-c-DXmwc3jG.js +0 -1
  213. package/apps/supervisor-web/dist/assets/objective-cpp-CLxacb5B.js +0 -1
  214. package/apps/supervisor-web/dist/assets/ocaml-C0hk2d4L.js +0 -1
  215. package/apps/supervisor-web/dist/assets/odin-BBf5iR-q.js +0 -1
  216. package/apps/supervisor-web/dist/assets/one-dark-pro-DVMEJ2y_.js +0 -1
  217. package/apps/supervisor-web/dist/assets/one-light-C3Wv6jpd.js +0 -1
  218. package/apps/supervisor-web/dist/assets/openscad-C4EeE6gA.js +0 -1
  219. package/apps/supervisor-web/dist/assets/pascal-D93ZcfNL.js +0 -1
  220. package/apps/supervisor-web/dist/assets/perl-C0TMdlhV.js +0 -1
  221. package/apps/supervisor-web/dist/assets/php-Dhbhpdrm.js +0 -1
  222. package/apps/supervisor-web/dist/assets/pkl-u5AG7uiY.js +0 -1
  223. package/apps/supervisor-web/dist/assets/plastic-3e1v2bzS.js +0 -1
  224. package/apps/supervisor-web/dist/assets/plsql-ChMvpjG-.js +0 -1
  225. package/apps/supervisor-web/dist/assets/po-BTJTHyun.js +0 -1
  226. package/apps/supervisor-web/dist/assets/poimandres-CS3Unz2-.js +0 -1
  227. package/apps/supervisor-web/dist/assets/polar-C0HS_06l.js +0 -1
  228. package/apps/supervisor-web/dist/assets/postcss-CXtECtnM.js +0 -1
  229. package/apps/supervisor-web/dist/assets/powerquery-CEu0bR-o.js +0 -1
  230. package/apps/supervisor-web/dist/assets/powershell-Dpen1YoG.js +0 -1
  231. package/apps/supervisor-web/dist/assets/prisma-Dd19v3D-.js +0 -1
  232. package/apps/supervisor-web/dist/assets/prolog-CbFg5uaA.js +0 -1
  233. package/apps/supervisor-web/dist/assets/proto-C7zT0LnQ.js +0 -1
  234. package/apps/supervisor-web/dist/assets/pug-CGlum2m_.js +0 -1
  235. package/apps/supervisor-web/dist/assets/puppet-BMWR74SV.js +0 -1
  236. package/apps/supervisor-web/dist/assets/purescript-CklMAg4u.js +0 -1
  237. package/apps/supervisor-web/dist/assets/qml-3beO22l8.js +0 -1
  238. package/apps/supervisor-web/dist/assets/qmldir-C8lEn-DE.js +0 -1
  239. package/apps/supervisor-web/dist/assets/qss-IeuSbFQv.js +0 -1
  240. package/apps/supervisor-web/dist/assets/r-Dspwwk_N.js +0 -1
  241. package/apps/supervisor-web/dist/assets/racket-BqYA7rlc.js +0 -1
  242. package/apps/supervisor-web/dist/assets/raku-DXvB9xmW.js +0 -1
  243. package/apps/supervisor-web/dist/assets/razor-Uh8Bk_45.js +0 -1
  244. package/apps/supervisor-web/dist/assets/react-vendor-5VdTO_Bg.js +0 -60
  245. package/apps/supervisor-web/dist/assets/red-bN70gL4F.js +0 -1
  246. package/apps/supervisor-web/dist/assets/reg-C-SQnVFl.js +0 -1
  247. package/apps/supervisor-web/dist/assets/regexp-CDVJQ6XC.js +0 -1
  248. package/apps/supervisor-web/dist/assets/rel-C3B-1QV4.js +0 -1
  249. package/apps/supervisor-web/dist/assets/riscv-BM1_JUlF.js +0 -1
  250. package/apps/supervisor-web/dist/assets/ron-D8l8udqQ.js +0 -1
  251. package/apps/supervisor-web/dist/assets/rose-pine-dawn-DHQR4-dF.js +0 -1
  252. package/apps/supervisor-web/dist/assets/rose-pine-moon-D4_iv3hh.js +0 -1
  253. package/apps/supervisor-web/dist/assets/rose-pine-qdsjHGoJ.js +0 -1
  254. package/apps/supervisor-web/dist/assets/rosmsg-BJDFO7_C.js +0 -1
  255. package/apps/supervisor-web/dist/assets/rst-BrH8l1NY.js +0 -1
  256. package/apps/supervisor-web/dist/assets/ruby-Dw2BHqvy.js +0 -1
  257. package/apps/supervisor-web/dist/assets/rust-B1yitclQ.js +0 -1
  258. package/apps/supervisor-web/dist/assets/sas-cz2c8ADy.js +0 -1
  259. package/apps/supervisor-web/dist/assets/sass-Cj5Yp3dK.js +0 -1
  260. package/apps/supervisor-web/dist/assets/scala-C151Ov-r.js +0 -1
  261. package/apps/supervisor-web/dist/assets/scheme-C98Dy4si.js +0 -1
  262. package/apps/supervisor-web/dist/assets/scss-OYdSNvt2.js +0 -1
  263. package/apps/supervisor-web/dist/assets/sdbl-DVxCFoDh.js +0 -1
  264. package/apps/supervisor-web/dist/assets/shaderlab-Dg9Lc6iA.js +0 -1
  265. package/apps/supervisor-web/dist/assets/shellsession-BADoaaVG.js +0 -1
  266. package/apps/supervisor-web/dist/assets/slack-dark-BthQWCQV.js +0 -1
  267. package/apps/supervisor-web/dist/assets/slack-ochin-DqwNpetd.js +0 -1
  268. package/apps/supervisor-web/dist/assets/smalltalk-BERRCDM3.js +0 -1
  269. package/apps/supervisor-web/dist/assets/snazzy-light-Bw305WKR.js +0 -1
  270. package/apps/supervisor-web/dist/assets/solarized-dark-DXbdFlpD.js +0 -1
  271. package/apps/supervisor-web/dist/assets/solarized-light-L9t79GZl.js +0 -1
  272. package/apps/supervisor-web/dist/assets/solidity-rGO070M0.js +0 -1
  273. package/apps/supervisor-web/dist/assets/soy-Brmx7dQM.js +0 -1
  274. package/apps/supervisor-web/dist/assets/sparql-rVzFXLq3.js +0 -1
  275. package/apps/supervisor-web/dist/assets/splunk-BtCnVYZw.js +0 -1
  276. package/apps/supervisor-web/dist/assets/ssh-config-_ykCGR6B.js +0 -1
  277. package/apps/supervisor-web/dist/assets/stata-BH5u7GGu.js +0 -1
  278. package/apps/supervisor-web/dist/assets/stylus-BEDo0Tqx.js +0 -1
  279. package/apps/supervisor-web/dist/assets/surrealql-Bq5Q-fJD.js +0 -1
  280. package/apps/supervisor-web/dist/assets/svelte-C_ipcX3V.js +0 -1
  281. package/apps/supervisor-web/dist/assets/swift-D82vCrfD.js +0 -1
  282. package/apps/supervisor-web/dist/assets/synthwave-84-CbfX1IO0.js +0 -1
  283. package/apps/supervisor-web/dist/assets/system-verilog-CnnmHF94.js +0 -1
  284. package/apps/supervisor-web/dist/assets/systemd-4A_iFExJ.js +0 -1
  285. package/apps/supervisor-web/dist/assets/talonscript-CkByrt1z.js +0 -1
  286. package/apps/supervisor-web/dist/assets/tasl-QIJgUcNo.js +0 -1
  287. package/apps/supervisor-web/dist/assets/tcl-dwOrl1Do.js +0 -1
  288. package/apps/supervisor-web/dist/assets/templ-P3uqSqPl.js +0 -1
  289. package/apps/supervisor-web/dist/assets/terraform-BETggiCN.js +0 -1
  290. package/apps/supervisor-web/dist/assets/tex-idrVyKtj.js +0 -1
  291. package/apps/supervisor-web/dist/assets/thread-ui-BEieA99i.css +0 -1
  292. package/apps/supervisor-web/dist/assets/thread-ui-LDojdlO_.js +0 -1997
  293. package/apps/supervisor-web/dist/assets/tokyo-night-hegEt444.js +0 -1
  294. package/apps/supervisor-web/dist/assets/ts-tags-zn1MmPIZ.js +0 -1
  295. package/apps/supervisor-web/dist/assets/tsv-B_m7g4N7.js +0 -1
  296. package/apps/supervisor-web/dist/assets/turtle-BsS91CYL.js +0 -1
  297. package/apps/supervisor-web/dist/assets/twig-DNn4PbVi.js +0 -1
  298. package/apps/supervisor-web/dist/assets/typespec-BGHnOYBU.js +0 -1
  299. package/apps/supervisor-web/dist/assets/typst-DHCkPAjA.js +0 -1
  300. package/apps/supervisor-web/dist/assets/ui-vendor-xVD8_rhm.js +0 -6
  301. package/apps/supervisor-web/dist/assets/v-BcVCzyr7.js +0 -1
  302. package/apps/supervisor-web/dist/assets/vala-CsfeWuGM.js +0 -1
  303. package/apps/supervisor-web/dist/assets/vb-D17OF-Vu.js +0 -1
  304. package/apps/supervisor-web/dist/assets/verilog-BQ8w6xss.js +0 -1
  305. package/apps/supervisor-web/dist/assets/vesper-DU1UobuO.js +0 -1
  306. package/apps/supervisor-web/dist/assets/vhdl-CeAyd5Ju.js +0 -1
  307. package/apps/supervisor-web/dist/assets/viml-CJc9bBzg.js +0 -1
  308. package/apps/supervisor-web/dist/assets/vitesse-black-Bkuqu6BP.js +0 -1
  309. package/apps/supervisor-web/dist/assets/vitesse-dark-D0r3Knsf.js +0 -1
  310. package/apps/supervisor-web/dist/assets/vitesse-light-CVO1_9PV.js +0 -1
  311. package/apps/supervisor-web/dist/assets/vue-DN_0RTcg.js +0 -1
  312. package/apps/supervisor-web/dist/assets/vue-html-AaS7Mt5G.js +0 -1
  313. package/apps/supervisor-web/dist/assets/vue-vine-CQOfvN7w.js +0 -1
  314. package/apps/supervisor-web/dist/assets/vyper-CDx5xZoG.js +0 -1
  315. package/apps/supervisor-web/dist/assets/wasm-CG6Dc4jp.js +0 -1
  316. package/apps/supervisor-web/dist/assets/wasm-MzD3tlZU.js +0 -1
  317. package/apps/supervisor-web/dist/assets/wenyan-BV7otONQ.js +0 -1
  318. package/apps/supervisor-web/dist/assets/wgsl-Dx-B1_4e.js +0 -1
  319. package/apps/supervisor-web/dist/assets/wikitext-BhOHFoWU.js +0 -1
  320. package/apps/supervisor-web/dist/assets/wit-5i3qLPDT.js +0 -1
  321. package/apps/supervisor-web/dist/assets/wolfram-lXgVvXCa.js +0 -1
  322. package/apps/supervisor-web/dist/assets/xml-sdJ4AIDG.js +0 -1
  323. package/apps/supervisor-web/dist/assets/xsl-CtQFsRM5.js +0 -1
  324. package/apps/supervisor-web/dist/assets/zenscript-DVFEvuxE.js +0 -1
  325. package/apps/supervisor-web/dist/assets/zig-VOosw3JB.js +0 -1
@@ -10,7 +10,7 @@ import multipart from "@fastify/multipart";
10
10
  import websocket from "@fastify/websocket";
11
11
  import { spawn as spawn5 } from "child_process";
12
12
  import fs26 from "fs";
13
- import path24 from "path";
13
+ import path25 from "path";
14
14
  import { ZodError } from "zod";
15
15
 
16
16
  // ../../packages/config/src/index.ts
@@ -176,7 +176,7 @@ function loadRuntimeConfig(env = process.env) {
176
176
  nodeEnv === "production"
177
177
  );
178
178
  const enabledProviders = new Set(
179
- (parsed.REMOTE_CODEX_ENABLED_AGENT_PROVIDERS ?? agentBackendIds.join(",")).split(",").map((provider) => provider.trim().toLowerCase()).filter(Boolean)
179
+ (parsed.REMOTE_CODEX_ENABLED_AGENT_PROVIDERS ?? agentBackendIds.join(",")).split(",").map((provider2) => provider2.trim().toLowerCase()).filter(Boolean)
180
180
  );
181
181
  const defaultAgentHomeRoot = runtimeRole === "worker" ? "/home/agent" : os.homedir();
182
182
  const codexHome = parsed.CODEX_HOME?.trim() ? path.resolve(parsed.CODEX_HOME) : path.join(defaultAgentHomeRoot, agentBackendMetadata.codex.defaultHomeDir);
@@ -465,15 +465,15 @@ var AgentRuntimeRegistry = class {
465
465
  }
466
466
  defaultProvider;
467
467
  runtimes = /* @__PURE__ */ new Map();
468
- get(provider) {
469
- const runtime = this.runtimes.get(provider);
468
+ get(provider2) {
469
+ const runtime = this.runtimes.get(provider2);
470
470
  if (!runtime) {
471
- throw new Error(`Agent runtime provider is not configured: ${provider}`);
471
+ throw new Error(`Agent runtime provider is not configured: ${provider2}`);
472
472
  }
473
473
  return runtime;
474
474
  }
475
- getOptional(provider) {
476
- return this.runtimes.get(provider) ?? null;
475
+ getOptional(provider2) {
476
+ return this.runtimes.get(provider2) ?? null;
477
477
  }
478
478
  all() {
479
479
  return [...this.runtimes.values()];
@@ -501,9 +501,9 @@ var transientAgentHistoryItemSymbol = /* @__PURE__ */ Symbol(
501
501
  "remoteCodex.transientAgentHistoryItem"
502
502
  );
503
503
  var AgentRuntimeError = class extends Error {
504
- constructor(message, provider, code = "request_failed", details, cause) {
504
+ constructor(message, provider2, code = "request_failed", details, cause) {
505
505
  super(message);
506
- this.provider = provider;
506
+ this.provider = provider2;
507
507
  this.code = code;
508
508
  this.details = details;
509
509
  this.cause = cause;
@@ -2316,7 +2316,7 @@ Subquery.prototype.getSQL = function() {
2316
2316
  function mapResultRow(columns, row, joinsNotNullableMap) {
2317
2317
  const nullifyMap = {};
2318
2318
  const result = columns.reduce(
2319
- (result2, { path: path25, field }, columnIndex) => {
2319
+ (result2, { path: path26, field }, columnIndex) => {
2320
2320
  let decoder;
2321
2321
  if (is(field, Column)) {
2322
2322
  decoder = field;
@@ -2326,8 +2326,8 @@ function mapResultRow(columns, row, joinsNotNullableMap) {
2326
2326
  decoder = field.sql.decoder;
2327
2327
  }
2328
2328
  let node = result2;
2329
- for (const [pathChunkIndex, pathChunk] of path25.entries()) {
2330
- if (pathChunkIndex < path25.length - 1) {
2329
+ for (const [pathChunkIndex, pathChunk] of path26.entries()) {
2330
+ if (pathChunkIndex < path26.length - 1) {
2331
2331
  if (!(pathChunk in node)) {
2332
2332
  node[pathChunk] = {};
2333
2333
  }
@@ -2335,8 +2335,8 @@ function mapResultRow(columns, row, joinsNotNullableMap) {
2335
2335
  } else {
2336
2336
  const rawValue = row[columnIndex];
2337
2337
  const value = node[pathChunk] = rawValue === null ? null : decoder.mapFromDriverValue(rawValue);
2338
- if (joinsNotNullableMap && is(field, Column) && path25.length === 2) {
2339
- const objectName = path25[0];
2338
+ if (joinsNotNullableMap && is(field, Column) && path26.length === 2) {
2339
+ const objectName = path26[0];
2340
2340
  if (!(objectName in nullifyMap)) {
2341
2341
  nullifyMap[objectName] = value === null ? getTableName(field.table) : false;
2342
2342
  } else if (typeof nullifyMap[objectName] === "string" && nullifyMap[objectName] !== getTableName(field.table)) {
@@ -7008,10 +7008,10 @@ function listThreadRecordsByWorkspaceId(db, workspaceId) {
7008
7008
  function getThreadRecordById(db, id) {
7009
7009
  return db.select().from(threads).where(eq(threads.id, id)).get();
7010
7010
  }
7011
- function getThreadRecordByProviderSessionId(db, provider, providerSessionId) {
7011
+ function getThreadRecordByProviderSessionId(db, provider2, providerSessionId) {
7012
7012
  return db.select().from(threads).where(
7013
7013
  and(
7014
- eq(threads.provider, provider),
7014
+ eq(threads.provider, provider2),
7015
7015
  eq(threads.providerSessionId, providerSessionId)
7016
7016
  )
7017
7017
  ).get();
@@ -7956,6 +7956,15 @@ function mapTurn(record) {
7956
7956
  items: Array.isArray(record.items) ? record.items : []
7957
7957
  };
7958
7958
  }
7959
+ function textOnlyUserInput(prompt) {
7960
+ return [
7961
+ {
7962
+ type: "text",
7963
+ text: prompt,
7964
+ text_elements: []
7965
+ }
7966
+ ];
7967
+ }
7959
7968
  function mapModel(record) {
7960
7969
  return {
7961
7970
  id: record.id,
@@ -8279,13 +8288,7 @@ var CodexAppServerManager = class extends EventEmitter3 {
8279
8288
  await this.ensureReady();
8280
8289
  const response = await this.client.request("turn/start", {
8281
8290
  threadId: input.threadId,
8282
- input: [
8283
- {
8284
- type: "text",
8285
- text: input.prompt,
8286
- text_elements: []
8287
- }
8288
- ],
8291
+ input: input.input ?? textOnlyUserInput(input.prompt),
8289
8292
  model: input.model ?? null,
8290
8293
  serviceTier: input.serviceTier === void 0 ? void 0 : input.serviceTier,
8291
8294
  effort: input.effort ?? null,
@@ -8306,13 +8309,7 @@ var CodexAppServerManager = class extends EventEmitter3 {
8306
8309
  const response = await this.client.request("turn/steer", {
8307
8310
  threadId: input.threadId,
8308
8311
  expectedTurnId: input.turnId,
8309
- input: [
8310
- {
8311
- type: "text",
8312
- text: input.prompt,
8313
- text_elements: []
8314
- }
8315
- ]
8312
+ input: input.input ?? textOnlyUserInput(input.prompt)
8316
8313
  });
8317
8314
  return response.turn ? mapTurn(response.turn) : null;
8318
8315
  }
@@ -8614,12 +8611,58 @@ ${entryPreview}` : null
8614
8611
  var DEFERRED_COMMAND_DETAIL_TITLE = "Command Output";
8615
8612
  var DEFERRED_TOOL_DETAIL_TITLE = "Tool Call Details";
8616
8613
  var DEFERRED_AGENT_TOOL_DETAIL_TITLE = "Agent Details";
8614
+ function parseUuidV7Timestamp(id) {
8615
+ const normalized = id.replace(/-/g, "");
8616
+ if (!/^[0-9a-f]{32}$/i.test(normalized) || normalized[12]?.toLowerCase() !== "7") {
8617
+ return null;
8618
+ }
8619
+ const millis = Number.parseInt(normalized.slice(0, 12), 16);
8620
+ if (!Number.isFinite(millis)) {
8621
+ return null;
8622
+ }
8623
+ return new Date(millis).toISOString();
8624
+ }
8617
8625
  function isRecord4(value) {
8618
8626
  return typeof value === "object" && value !== null && !Array.isArray(value);
8619
8627
  }
8620
8628
  function stringOrNull(value) {
8621
8629
  return typeof value === "string" && value.trim() ? value.trim() : null;
8622
8630
  }
8631
+ function isoTimestampOrNull(value) {
8632
+ if (typeof value === "number" && Number.isFinite(value)) {
8633
+ const epochMs = value < 1e10 ? value * 1e3 : value;
8634
+ return new Date(epochMs).toISOString();
8635
+ }
8636
+ const text2 = stringOrNull(value);
8637
+ if (!text2) {
8638
+ return null;
8639
+ }
8640
+ const parsed = Date.parse(text2);
8641
+ return Number.isFinite(parsed) ? new Date(parsed).toISOString() : null;
8642
+ }
8643
+ function codexItemCreatedAt(item) {
8644
+ const candidates = [
8645
+ item.createdAt,
8646
+ item.created_at,
8647
+ item.startedAt,
8648
+ item.started_at,
8649
+ item.completedAt,
8650
+ item.completed_at
8651
+ ];
8652
+ for (const candidate of candidates) {
8653
+ const timestamp = isoTimestampOrNull(candidate);
8654
+ if (timestamp) {
8655
+ return timestamp;
8656
+ }
8657
+ }
8658
+ return parseUuidV7Timestamp(item.id);
8659
+ }
8660
+ function withCodexItemTimestamp(item, historyItem) {
8661
+ return {
8662
+ ...historyItem,
8663
+ createdAt: historyItem.createdAt ?? codexItemCreatedAt(item)
8664
+ };
8665
+ }
8623
8666
  function numberOrNull(value) {
8624
8667
  if (typeof value === "number" && Number.isFinite(value)) {
8625
8668
  return value;
@@ -9108,7 +9151,7 @@ function extractFileChangeEntries(item) {
9108
9151
  isRecord4(entry.summary) ? entry.summary : null,
9109
9152
  isRecord4(entry.diff) ? entry.diff : null
9110
9153
  ].filter((candidate) => Boolean(candidate));
9111
- const path25 = uniqueStrings([
9154
+ const path26 = uniqueStrings([
9112
9155
  stringOrNull(valueFromRecords(nestedRecords, ["path", "filePath", "targetPath"])),
9113
9156
  stringOrNull(
9114
9157
  valueFromRecords(nestedRecords, [
@@ -9155,7 +9198,7 @@ function extractFileChangeEntries(item) {
9155
9198
  const diffStats = explicitAdditions === 0 && explicitDeletions === 0 && diffText ? countUnifiedDiffStats(diffText) : null;
9156
9199
  const additions = explicitAdditions || diffStats?.additions || 0;
9157
9200
  const deletions = explicitDeletions || diffStats?.deletions || 0;
9158
- const normalizedPath = path25 ?? (diffText ? projectRelativePathLabel(extractPathFromDiffText(diffText)) : null);
9201
+ const normalizedPath = path26 ?? (diffText ? projectRelativePathLabel(extractPathFromDiffText(diffText)) : null);
9159
9202
  if (!normalizedPath && additions === 0 && deletions === 0) {
9160
9203
  return null;
9161
9204
  }
@@ -9320,7 +9363,7 @@ function itemToHistoryItem(item, deferredDetails) {
9320
9363
  }
9321
9364
  }
9322
9365
  function liveCodexItemToHistoryItem(item, phase) {
9323
- const historyItem = itemToHistoryItem(item);
9366
+ const historyItem = withCodexItemTimestamp(item, itemToHistoryItem(item));
9324
9367
  if (historyItem.kind !== "commandExecution" && historyItem.kind !== "toolCall" && historyItem.kind !== "agentToolCall" && historyItem.kind !== "skillToolCall" && historyItem.kind !== "fileChange" && historyItem.kind !== "webSearch") {
9325
9368
  return null;
9326
9369
  }
@@ -9335,7 +9378,9 @@ function codexTurnToAgentTurn(turn) {
9335
9378
  rawTurnId: turn.id,
9336
9379
  status: turn.status,
9337
9380
  error: turn.error,
9338
- items: turn.items.map((item) => itemToHistoryItem(item)),
9381
+ items: turn.items.map(
9382
+ (item) => withCodexItemTimestamp(item, itemToHistoryItem(item))
9383
+ ),
9339
9384
  rawTurn: turn
9340
9385
  };
9341
9386
  }
@@ -9940,8 +9985,8 @@ var CodexManagementService = class {
9940
9985
  isRuntimeRequestError(error) {
9941
9986
  return isCodexRuntimeRequestError(error);
9942
9987
  }
9943
- canManageHookFiles(provider) {
9944
- return !provider || provider === "codex";
9988
+ canManageHookFiles(provider2) {
9989
+ return !provider2 || provider2 === "codex";
9945
9990
  }
9946
9991
  isUnsupportedHooksListError(error) {
9947
9992
  return isUnsupportedHooksListError(error);
@@ -10110,6 +10155,7 @@ var CodexManagementService = class {
10110
10155
 
10111
10156
  // ../../packages/codex/src/runtimeAdapter.ts
10112
10157
  import { EventEmitter as EventEmitter4 } from "events";
10158
+ import path9 from "path";
10113
10159
 
10114
10160
  // ../../packages/codex/src/requestMapper.ts
10115
10161
  function isRecord6(value) {
@@ -10447,6 +10493,50 @@ function mapCodexProviderRequest(providerRequest, approvalMode) {
10447
10493
  }
10448
10494
 
10449
10495
  // ../../packages/codex/src/runtimeAdapter.ts
10496
+ var promptPhotoTokenPattern = /\[PHOTO\s+([^\]]+)\]/g;
10497
+ function resolvePromptAssetPath(assetPath, cwd) {
10498
+ if (!assetPath) {
10499
+ return null;
10500
+ }
10501
+ if (path9.isAbsolute(assetPath)) {
10502
+ return path9.normalize(assetPath);
10503
+ }
10504
+ if (!cwd) {
10505
+ return null;
10506
+ }
10507
+ return path9.resolve(cwd, assetPath);
10508
+ }
10509
+ function codexUserInputFromPrompt(prompt, cwd) {
10510
+ const matches = [...prompt.matchAll(promptPhotoTokenPattern)];
10511
+ if (matches.length === 0) {
10512
+ return void 0;
10513
+ }
10514
+ const input = [];
10515
+ let cursor = 0;
10516
+ let includedImage = false;
10517
+ for (const match of matches) {
10518
+ const token = match[0];
10519
+ const assetPath = match[1]?.trim() ?? "";
10520
+ const start = match.index ?? 0;
10521
+ const precedingText = prompt.slice(cursor, start);
10522
+ if (precedingText) {
10523
+ input.push({ type: "text", text: precedingText, text_elements: [] });
10524
+ }
10525
+ const resolvedPath = resolvePromptAssetPath(assetPath, cwd);
10526
+ if (resolvedPath) {
10527
+ input.push({ type: "localImage", path: resolvedPath });
10528
+ includedImage = true;
10529
+ } else {
10530
+ input.push({ type: "text", text: token, text_elements: [] });
10531
+ }
10532
+ cursor = start + token.length;
10533
+ }
10534
+ const trailingText = prompt.slice(cursor);
10535
+ if (trailingText) {
10536
+ input.push({ type: "text", text: trailingText, text_elements: [] });
10537
+ }
10538
+ return includedImage ? input : void 0;
10539
+ }
10450
10540
  var codexCapabilities = {
10451
10541
  sessions: {
10452
10542
  list: true,
@@ -10961,6 +11051,13 @@ var CodexRuntimeAdapter = class extends EventEmitter4 {
10961
11051
  threadId: input.providerSessionId,
10962
11052
  prompt: input.prompt
10963
11053
  };
11054
+ const structuredInput = codexUserInputFromPrompt(
11055
+ input.prompt,
11056
+ input.workspacePath
11057
+ );
11058
+ if (structuredInput) {
11059
+ turnInput.input = structuredInput;
11060
+ }
10964
11061
  if (input.developerInstructions !== void 0) {
10965
11062
  turnInput.developerInstructions = input.developerInstructions;
10966
11063
  }
@@ -10987,11 +11084,17 @@ var CodexRuntimeAdapter = class extends EventEmitter4 {
10987
11084
  return mapTurn2(await codexRuntimeCall(() => this.manager.startTurn(turnInput)));
10988
11085
  }
10989
11086
  async sendInput(input) {
10990
- const turn = await codexRuntimeCall(() => this.manager.steerTurn({
11087
+ const structuredInput = codexUserInputFromPrompt(
11088
+ input.prompt,
11089
+ input.workspacePath
11090
+ );
11091
+ const steerInput = {
10991
11092
  threadId: input.providerSessionId,
10992
11093
  turnId: input.providerTurnId,
10993
- prompt: input.prompt
10994
- }));
11094
+ prompt: input.prompt,
11095
+ ...structuredInput ? { input: structuredInput } : {}
11096
+ };
11097
+ const turn = await codexRuntimeCall(() => this.manager.steerTurn(steerInput));
10995
11098
  return turn ? mapTurn2(turn) : null;
10996
11099
  }
10997
11100
  async interruptTurn(input) {
@@ -11640,13 +11743,13 @@ import { EventEmitter as EventEmitter5 } from "events";
11640
11743
  import { execFile } from "child_process";
11641
11744
  import fs8 from "fs/promises";
11642
11745
  import { createRequire } from "module";
11643
- import path9 from "path";
11746
+ import path10 from "path";
11644
11747
  import { pathToFileURL } from "url";
11645
11748
  import { promisify } from "util";
11646
11749
  var execFileAsync = promisify(execFile);
11647
- var promptPhotoTokenPattern = /\[PHOTO\s+([^\]]+)\]/g;
11750
+ var promptPhotoTokenPattern2 = /\[PHOTO\s+([^\]]+)\]/g;
11648
11751
  function mimeTypeForImagePath(filePath) {
11649
- const extension = path9.extname(filePath).toLowerCase();
11752
+ const extension = path10.extname(filePath).toLowerCase();
11650
11753
  switch (extension) {
11651
11754
  case ".jpg":
11652
11755
  case ".jpeg":
@@ -11676,13 +11779,13 @@ function extensionForImageMediaType(mediaType) {
11676
11779
  return null;
11677
11780
  }
11678
11781
  }
11679
- function resolvePromptAssetPath(assetPath, cwd) {
11782
+ function resolvePromptAssetPath2(assetPath, cwd) {
11680
11783
  if (!cwd) {
11681
11784
  return null;
11682
11785
  }
11683
- const resolvedPath = path9.isAbsolute(assetPath) ? path9.normalize(assetPath) : path9.resolve(cwd, assetPath);
11684
- const relativePath = path9.relative(cwd, resolvedPath);
11685
- if (relativePath === "" || !relativePath.startsWith("..") && !path9.isAbsolute(relativePath)) {
11786
+ const resolvedPath = path10.isAbsolute(assetPath) ? path10.normalize(assetPath) : path10.resolve(cwd, assetPath);
11787
+ const relativePath = path10.relative(cwd, resolvedPath);
11788
+ if (relativePath === "" || !relativePath.startsWith("..") && !path10.isAbsolute(relativePath)) {
11686
11789
  return resolvedPath;
11687
11790
  }
11688
11791
  return null;
@@ -11701,7 +11804,7 @@ async function* singleUserMessage(content) {
11701
11804
  };
11702
11805
  }
11703
11806
  async function promptWithImageBlocks(prompt, cwd) {
11704
- const matches = [...prompt.matchAll(promptPhotoTokenPattern)];
11807
+ const matches = [...prompt.matchAll(promptPhotoTokenPattern2)];
11705
11808
  if (matches.length === 0) {
11706
11809
  return prompt;
11707
11810
  }
@@ -11716,7 +11819,7 @@ async function promptWithImageBlocks(prompt, cwd) {
11716
11819
  if (precedingText) {
11717
11820
  blocks.push({ type: "text", text: precedingText });
11718
11821
  }
11719
- const resolvedPath = resolvePromptAssetPath(assetPath, cwd);
11822
+ const resolvedPath = resolvePromptAssetPath2(assetPath, cwd);
11720
11823
  const mediaType = resolvedPath ? mimeTypeForImagePath(resolvedPath) : null;
11721
11824
  if (!resolvedPath || !mediaType) {
11722
11825
  blocks.push({ type: "text", text: token });
@@ -13099,13 +13202,13 @@ var ClaudeRuntimeAdapter = class extends EventEmitter5 {
13099
13202
  return null;
13100
13203
  }
13101
13204
  const relativePath = `./.temp/threads/${input.localThreadId}/claude-history-${safeAssetFilePart(input.messageId)}-${input.blockIndex}.${extension}`;
13102
- const targetPath = path9.resolve(input.workspacePath, relativePath);
13103
- const relativeToWorkspace = path9.relative(input.workspacePath, targetPath);
13104
- if (relativeToWorkspace === "" || relativeToWorkspace.startsWith("..") || path9.isAbsolute(relativeToWorkspace)) {
13205
+ const targetPath = path10.resolve(input.workspacePath, relativePath);
13206
+ const relativeToWorkspace = path10.relative(input.workspacePath, targetPath);
13207
+ if (relativeToWorkspace === "" || relativeToWorkspace.startsWith("..") || path10.isAbsolute(relativeToWorkspace)) {
13105
13208
  return null;
13106
13209
  }
13107
13210
  try {
13108
- await fs8.mkdir(path9.dirname(targetPath), { recursive: true });
13211
+ await fs8.mkdir(path10.dirname(targetPath), { recursive: true });
13109
13212
  await fs8.writeFile(targetPath, Buffer.from(data, "base64"));
13110
13213
  return `[PHOTO ${relativePath}]`;
13111
13214
  } catch {
@@ -13264,7 +13367,7 @@ async function importOptionalPackage(specifier) {
13264
13367
  throw localError;
13265
13368
  }
13266
13369
  try {
13267
- const requireFromGlobal = createRequire(path9.join(globalRoot, "remote-codex-global.cjs"));
13370
+ const requireFromGlobal = createRequire(path10.join(globalRoot, "remote-codex-global.cjs"));
13268
13371
  const resolved = requireFromGlobal.resolve(specifier);
13269
13372
  return await dynamicImport(pathToFileURL(resolved).href);
13270
13373
  } catch {
@@ -13284,7 +13387,7 @@ async function npmGlobalRoot() {
13284
13387
  }
13285
13388
 
13286
13389
  // ../../packages/opencode/src/historyItems.ts
13287
- import path10 from "path";
13390
+ import path11 from "path";
13288
13391
  function isRecord9(value) {
13289
13392
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
13290
13393
  }
@@ -13394,25 +13497,25 @@ function displayPath(pathValue, options) {
13394
13497
  if (!pathValue) {
13395
13498
  return null;
13396
13499
  }
13397
- if (!path10.isAbsolute(pathValue) || !options.workspacePath) {
13500
+ if (!path11.isAbsolute(pathValue) || !options.workspacePath) {
13398
13501
  return pathValue;
13399
13502
  }
13400
- const root = path10.resolve(options.workspacePath);
13401
- const absolutePath = path10.resolve(pathValue);
13402
- const relativePath = path10.relative(root, absolutePath);
13403
- if (!relativePath || relativePath.startsWith("..") || path10.isAbsolute(relativePath)) {
13503
+ const root = path11.resolve(options.workspacePath);
13504
+ const absolutePath = path11.resolve(pathValue);
13505
+ const relativePath = path11.relative(root, absolutePath);
13506
+ if (!relativePath || relativePath.startsWith("..") || path11.isAbsolute(relativePath)) {
13404
13507
  return pathValue;
13405
13508
  }
13406
13509
  return relativePath;
13407
13510
  }
13408
- function toolIsLowInformationPatch(normalized, state, input, patchText, path25, metadataStats) {
13511
+ function toolIsLowInformationPatch(normalized, state, input, patchText, path26, metadataStats) {
13409
13512
  if (normalized !== "applypatch" && normalized !== "patch") {
13410
13513
  return false;
13411
13514
  }
13412
13515
  if (toolStateStatus(state) !== "running") {
13413
13516
  return false;
13414
13517
  }
13415
- if (path25 || patchText || metadataStats || stringValue2(state.output)) {
13518
+ if (path26 || patchText || metadataStats || stringValue2(state.output)) {
13416
13519
  return false;
13417
13520
  }
13418
13521
  return !isRecord9(input) || Object.keys(input).length === 0;
@@ -13455,7 +13558,7 @@ function fileChangeStatsFromMetadata(metadata) {
13455
13558
  if (files.length === 0) {
13456
13559
  return null;
13457
13560
  }
13458
- const paths = files.map((file) => stringValue2(file.filePath) ?? stringValue2(file.path) ?? stringValue2(file.relativePath)).filter((path25) => Boolean(path25));
13561
+ const paths = files.map((file) => stringValue2(file.filePath) ?? stringValue2(file.path) ?? stringValue2(file.relativePath)).filter((path26) => Boolean(path26));
13459
13562
  const addedLines = files.reduce((total, file) => total + (numberValue(file.additions) ?? numberValue(file.addedLines) ?? numberValue(file.added) ?? 0), 0);
13460
13563
  const removedLines = files.reduce((total, file) => total + (numberValue(file.deletions) ?? numberValue(file.removedLines) ?? numberValue(file.removed) ?? 0), 0);
13461
13564
  return {
@@ -13603,28 +13706,28 @@ function mapAssistantTool(messageId2, tool, options) {
13603
13706
  ].includes(normalized)) {
13604
13707
  const metadataStats = fileChangeStatsFromMetadata(state.metadata);
13605
13708
  const patchText = isRecord9(input) ? stringValue2(input.patchText) ?? stringValue2(input.patch) ?? stringValue2(input.diff) : null;
13606
- const path25 = metadataStats?.path ?? filePathFromInput(input) ?? extractPathFromPatchText(patchText);
13607
- if (toolIsLowInformationPatch(normalized, state, input, patchText, path25, metadataStats)) {
13709
+ const path26 = metadataStats?.path ?? filePathFromInput(input) ?? extractPathFromPatchText(patchText);
13710
+ if (toolIsLowInformationPatch(normalized, state, input, patchText, path26, metadataStats)) {
13608
13711
  return null;
13609
13712
  }
13610
13713
  const output = stringValue2(state.output);
13611
13714
  const diffStats = countUnifiedDiffStats2(patchText);
13612
- const displayFilePath = displayPath(path25, options);
13715
+ const displayFilePath = displayPath(path26, options);
13613
13716
  return {
13614
13717
  id,
13615
13718
  kind: "fileChange",
13616
13719
  text: metadataStats ? metadataStats.changedFiles > 1 ? `${metadataStats.changedFiles} changed files` : displayFilePath ?? metadataStats.previewText : displayFilePath ?? output ?? summary ?? name,
13617
13720
  previewText: metadataStats ? metadataStats.changedFiles > 1 ? `${metadataStats.changedFiles} changed files` : displayFilePath ?? metadataStats.previewText : displayFilePath ? `${name}: ${displayFilePath}` : output ?? summary ?? name,
13618
13721
  detailText,
13619
- changedFiles: metadataStats?.changedFiles ?? (path25 ? 1 : null),
13722
+ changedFiles: metadataStats?.changedFiles ?? (path26 ? 1 : null),
13620
13723
  addedLines: metadataStats?.addedLines ?? diffStats?.addedLines ?? null,
13621
13724
  removedLines: metadataStats?.removedLines ?? diffStats?.removedLines ?? null,
13622
13725
  status: toolStateStatus(state)
13623
13726
  };
13624
13727
  }
13625
13728
  if (["read", "grep", "glob", "list", "ls", "bashoutput"].includes(normalized)) {
13626
- const path25 = filePathFromInput(input);
13627
- const text2 = displayPath(path25, options) ?? summary ?? name;
13729
+ const path26 = filePathFromInput(input);
13730
+ const text2 = displayPath(path26, options) ?? summary ?? name;
13628
13731
  return {
13629
13732
  id,
13630
13733
  kind: "fileRead",
@@ -13970,7 +14073,7 @@ import { execFile as execFile2 } from "child_process";
13970
14073
  import fs9 from "fs/promises";
13971
14074
  import net from "net";
13972
14075
  import { createRequire as createRequire2 } from "module";
13973
- import path11 from "path";
14076
+ import path12 from "path";
13974
14077
  import { pathToFileURL as pathToFileURL2 } from "url";
13975
14078
  import { promisify as promisify2 } from "util";
13976
14079
  var execFileAsync2 = promisify2(execFile2);
@@ -14102,21 +14205,21 @@ function configuredProviderModelRecords(config) {
14102
14205
  if (!providerConfig) {
14103
14206
  return configured;
14104
14207
  }
14105
- Object.entries(providerConfig).forEach(([providerID, provider]) => {
14106
- if (!isRecord10(provider) || !isRecord10(provider.models)) {
14208
+ Object.entries(providerConfig).forEach(([providerID, provider2]) => {
14209
+ if (!isRecord10(provider2) || !isRecord10(provider2.models)) {
14107
14210
  return;
14108
14211
  }
14109
- Object.entries(provider.models).forEach(([modelID, model]) => {
14212
+ Object.entries(provider2.models).forEach(([modelID, model]) => {
14110
14213
  configured.set(providerModelKey(providerID, modelID), isRecord10(model) ? model : {});
14111
14214
  });
14112
14215
  });
14113
14216
  return configured;
14114
14217
  }
14115
- function mapProviderModel(provider, record, index, configuredRecord) {
14116
- if (!isRecord10(provider) || !isRecord10(record)) {
14218
+ function mapProviderModel(provider2, record, index, configuredRecord) {
14219
+ if (!isRecord10(provider2) || !isRecord10(record)) {
14117
14220
  return null;
14118
14221
  }
14119
- const providerID = stringValue3(record.providerID) ?? stringValue3(provider.id);
14222
+ const providerID = stringValue3(record.providerID) ?? stringValue3(provider2.id);
14120
14223
  const id = stringValue3(record.id);
14121
14224
  if (!providerID || !id) {
14122
14225
  return null;
@@ -14124,8 +14227,8 @@ function mapProviderModel(provider, record, index, configuredRecord) {
14124
14227
  const name = stringValue3(configuredRecord?.name) ?? stringValue3(record.name) ?? id;
14125
14228
  const variants = configuredRecord ? isRecord10(configuredRecord.variants) ? Object.keys(configuredRecord.variants) : [] : isRecord10(record.variants) ? Object.keys(record.variants) : [];
14126
14229
  const model = providerModelKey(providerID, id);
14127
- const providerName = stringValue3(provider.name) ?? providerID;
14128
- const disabled = configuredRecord?.status === "disabled" || record.status === "disabled" || provider.disabled === true;
14230
+ const providerName = stringValue3(provider2.name) ?? providerID;
14231
+ const disabled = configuredRecord?.status === "disabled" || record.status === "disabled" || provider2.disabled === true;
14129
14232
  const reasoningEfforts = variants.map((variant) => ({
14130
14233
  reasoningEffort: variant,
14131
14234
  description: variant === "none" ? "No reasoning" : variant === "xhigh" ? "Maximum reasoning" : `${variant[0]?.toUpperCase() ?? ""}${variant.slice(1)} reasoning`
@@ -14145,15 +14248,15 @@ function providerModels(result, configuredModels) {
14145
14248
  const data = isRecord10(result) && Array.isArray(result.providers) ? result : isRecord10(result) && isRecord10(result.data) && Array.isArray(result.data.providers) ? result.data : null;
14146
14249
  const providers = Array.isArray(data?.providers) ? data.providers : [];
14147
14250
  const models = [];
14148
- providers.forEach((provider) => {
14149
- if (!isRecord10(provider) || !isRecord10(provider.models)) {
14251
+ providers.forEach((provider2) => {
14252
+ if (!isRecord10(provider2) || !isRecord10(provider2.models)) {
14150
14253
  return;
14151
14254
  }
14152
- Object.values(provider.models).forEach((model) => {
14255
+ Object.values(provider2.models).forEach((model) => {
14153
14256
  if (!isRecord10(model)) {
14154
14257
  return;
14155
14258
  }
14156
- const providerID = stringValue3(model.providerID) ?? stringValue3(provider.id);
14259
+ const providerID = stringValue3(model.providerID) ?? stringValue3(provider2.id);
14157
14260
  const modelID = stringValue3(model.id);
14158
14261
  if (!providerID || !modelID) {
14159
14262
  return;
@@ -14162,7 +14265,7 @@ function providerModels(result, configuredModels) {
14162
14265
  if (configuredModels && configuredModels.size > 0 && !configuredRecord) {
14163
14266
  return;
14164
14267
  }
14165
- const mapped = mapProviderModel(provider, model, models.length, configuredRecord);
14268
+ const mapped = mapProviderModel(provider2, model, models.length, configuredRecord);
14166
14269
  if (mapped) {
14167
14270
  models.push(mapped);
14168
14271
  }
@@ -15045,7 +15148,7 @@ async function importOptionalPackage2(specifier) {
15045
15148
  throw localError;
15046
15149
  }
15047
15150
  try {
15048
- const requireFromGlobal = createRequire2(path11.join(globalRoot, "remote-codex-global.cjs"));
15151
+ const requireFromGlobal = createRequire2(path12.join(globalRoot, "remote-codex-global.cjs"));
15049
15152
  const resolved = resolveOptionalPackage(requireFromGlobal, globalRoot, specifier);
15050
15153
  return await dynamicImport(pathToFileURL2(resolved).href);
15051
15154
  } catch {
@@ -15058,7 +15161,7 @@ function resolveOptionalPackage(requireFromGlobal, globalRoot, specifier) {
15058
15161
  return requireFromGlobal.resolve(specifier);
15059
15162
  } catch (error) {
15060
15163
  if (error.code === "ERR_PACKAGE_PATH_NOT_EXPORTED" && specifier === "@opencode-ai/sdk/v2") {
15061
- return path11.join(globalRoot, "@opencode-ai", "sdk", "dist", "v2", "index.js");
15164
+ return path12.join(globalRoot, "@opencode-ai", "sdk", "dist", "v2", "index.js");
15062
15165
  }
15063
15166
  throw error;
15064
15167
  }
@@ -15074,6 +15177,498 @@ async function npmGlobalRoot2() {
15074
15177
  }
15075
15178
  }
15076
15179
 
15180
+ // src/e2e-fake-runtime.ts
15181
+ import { EventEmitter as EventEmitter7 } from "events";
15182
+ var provider = "claude";
15183
+ var firstDelta = "IOS_STREAM_DELTA_READY";
15184
+ var secondDelta = " IOS_STREAM_COMPLETED";
15185
+ var approvalPromptMarker = "IOS_PENDING_APPROVAL";
15186
+ var questionPromptMarker = "IOS_PENDING_QUESTION";
15187
+ var planPromptMarker = "IOS_PENDING_PLAN";
15188
+ var E2EFakeRuntime = class extends EventEmitter7 {
15189
+ provider = provider;
15190
+ displayName = "E2E Fake Runtime";
15191
+ description = "Deterministic runtime for live iOS and web end-to-end tests.";
15192
+ capabilities = {
15193
+ sessions: { list: true, read: true, resume: true, importLocal: false },
15194
+ turns: { start: true, streamInput: false, steer: false, interrupt: true, compact: false },
15195
+ branching: { fork: false, hardRollback: false, resumeAt: false, rewindFiles: false },
15196
+ controls: {
15197
+ planMode: false,
15198
+ permissionRequests: false,
15199
+ sandboxMode: true,
15200
+ performanceMode: false,
15201
+ goals: false
15202
+ },
15203
+ management: {
15204
+ models: true,
15205
+ mcpStatus: true,
15206
+ skills: false,
15207
+ hooks: false,
15208
+ hookTrust: false,
15209
+ hostConfigFiles: false,
15210
+ providerSettings: false
15211
+ },
15212
+ usage: { contextWindow: true, tokenUsage: true, costUsd: true }
15213
+ };
15214
+ managementSchema = {
15215
+ hostConfigFiles: [],
15216
+ toolboxItems: [],
15217
+ hookCommandTemplates: [],
15218
+ providerConfigFormat: "none",
15219
+ mcpConfigFormat: "none",
15220
+ configArchives: false,
15221
+ buildRestart: false
15222
+ };
15223
+ installation = {
15224
+ packageName: "remote-codex-e2e-fake-runtime",
15225
+ installed: true,
15226
+ installedVersion: "test",
15227
+ latestVersion: null,
15228
+ installCommand: "",
15229
+ updateCommand: "",
15230
+ busy: false,
15231
+ lastError: null
15232
+ };
15233
+ sessions = /* @__PURE__ */ new Map();
15234
+ providerRequests = /* @__PURE__ */ new Map();
15235
+ activeTurnId = null;
15236
+ startedAt = null;
15237
+ getStatus() {
15238
+ return {
15239
+ state: "ready",
15240
+ transport: "none",
15241
+ lastStartedAt: this.startedAt,
15242
+ lastError: null,
15243
+ restartCount: 0
15244
+ };
15245
+ }
15246
+ async start() {
15247
+ this.startedAt = (/* @__PURE__ */ new Date()).toISOString();
15248
+ }
15249
+ async stop() {
15250
+ this.activeTurnId = null;
15251
+ }
15252
+ async listModels() {
15253
+ return [
15254
+ {
15255
+ id: "ios-e2e-stream",
15256
+ model: "ios-e2e-stream",
15257
+ displayName: "iOS E2E Stream",
15258
+ description: "Deterministic streaming test model.",
15259
+ isDefault: true,
15260
+ hidden: false,
15261
+ supportedReasoningEfforts: [
15262
+ { reasoningEffort: "low", description: "Low" },
15263
+ { reasoningEffort: "medium", description: "Medium" },
15264
+ { reasoningEffort: "high", description: "High" }
15265
+ ],
15266
+ defaultReasoningEffort: "medium"
15267
+ }
15268
+ ];
15269
+ }
15270
+ async listSessions() {
15271
+ return [...this.sessions.values()].map((session) => ({
15272
+ provider,
15273
+ providerSessionId: session.providerSessionId,
15274
+ cwd: session.cwd,
15275
+ title: session.title,
15276
+ preview: session.preview,
15277
+ createdAt: session.createdAt,
15278
+ updatedAt: session.updatedAt,
15279
+ status: session.status,
15280
+ rawSession: session
15281
+ }));
15282
+ }
15283
+ async listLoadedSessions() {
15284
+ return [...this.sessions.keys()];
15285
+ }
15286
+ async readSession(providerSessionId) {
15287
+ const session = this.sessions.get(providerSessionId);
15288
+ if (!session) {
15289
+ throw new Error(`E2E fake session missing: ${providerSessionId}`);
15290
+ }
15291
+ return session;
15292
+ }
15293
+ async startSession(input) {
15294
+ const providerSessionId = `e2e-session-${this.sessions.size + 1}`;
15295
+ const now = (/* @__PURE__ */ new Date()).toISOString();
15296
+ const session = {
15297
+ provider,
15298
+ providerSessionId,
15299
+ cwd: input.cwd,
15300
+ title: null,
15301
+ preview: null,
15302
+ createdAt: now,
15303
+ updatedAt: now,
15304
+ status: "idle",
15305
+ turns: [],
15306
+ totalTurnCount: 0,
15307
+ rawSession: null
15308
+ };
15309
+ this.sessions.set(providerSessionId, session);
15310
+ return {
15311
+ provider,
15312
+ providerSessionId,
15313
+ model: input.model,
15314
+ reasoningEffort: input.reasoningEffort ?? null,
15315
+ sandboxMode: input.sandboxMode ?? null,
15316
+ session,
15317
+ rawSession: session
15318
+ };
15319
+ }
15320
+ async resumeSession(input) {
15321
+ const session = await this.readSession(input.providerSessionId);
15322
+ return {
15323
+ provider,
15324
+ providerSessionId: input.providerSessionId,
15325
+ model: input.model ?? null,
15326
+ reasoningEffort: null,
15327
+ sandboxMode: input.sandboxMode ?? null,
15328
+ session,
15329
+ rawSession: session
15330
+ };
15331
+ }
15332
+ async startTurn(input) {
15333
+ const session = await this.readSession(input.providerSessionId);
15334
+ const providerTurnId = `e2e-turn-${session.turns.length + 1}`;
15335
+ const now = (/* @__PURE__ */ new Date()).toISOString();
15336
+ const userItem = {
15337
+ id: `${providerTurnId}:user`,
15338
+ createdAt: now,
15339
+ kind: "userMessage",
15340
+ text: input.prompt
15341
+ };
15342
+ const assistantItem = {
15343
+ id: `${providerTurnId}:assistant`,
15344
+ createdAt: now,
15345
+ kind: "agentMessage",
15346
+ text: "",
15347
+ status: "running"
15348
+ };
15349
+ const turn = {
15350
+ providerTurnId,
15351
+ startedAt: now,
15352
+ status: "inProgress",
15353
+ error: null,
15354
+ items: input.hidden ? [] : [userItem],
15355
+ rawTurn: null
15356
+ };
15357
+ session.turns.push(turn);
15358
+ session.totalTurnCount = session.turns.length;
15359
+ session.status = "running";
15360
+ session.updatedAt = now;
15361
+ session.preview = input.prompt;
15362
+ this.activeTurnId = providerTurnId;
15363
+ this.emitRuntimeEvent({
15364
+ type: "turn.started",
15365
+ provider,
15366
+ providerSessionId: input.providerSessionId,
15367
+ turn
15368
+ });
15369
+ if (input.prompt.includes(approvalPromptMarker)) {
15370
+ setTimeout(() => {
15371
+ if (turn.status !== "inProgress") {
15372
+ return;
15373
+ }
15374
+ const requestId = `${providerTurnId}:approval`;
15375
+ this.providerRequests.set(requestId, {
15376
+ providerSessionId: input.providerSessionId,
15377
+ providerTurnId,
15378
+ assistantText: "IOS_PENDING_APPROVAL_RESOLVED"
15379
+ });
15380
+ this.emit("provider-request", {
15381
+ provider,
15382
+ id: requestId,
15383
+ method: "item/commandExecution/requestApproval",
15384
+ params: {
15385
+ providerSessionId: input.providerSessionId,
15386
+ providerTurnId,
15387
+ itemId: `${providerTurnId}:approval-item`,
15388
+ command: "printf ios-e2e-approval",
15389
+ cwd: session.cwd,
15390
+ reason: "iOS E2E approval request."
15391
+ }
15392
+ });
15393
+ }, 250);
15394
+ return turn;
15395
+ }
15396
+ if (input.prompt.includes(questionPromptMarker)) {
15397
+ setTimeout(() => {
15398
+ if (turn.status !== "inProgress") {
15399
+ return;
15400
+ }
15401
+ const requestId = `${providerTurnId}:question`;
15402
+ this.providerRequests.set(requestId, {
15403
+ providerSessionId: input.providerSessionId,
15404
+ providerTurnId,
15405
+ assistantText: "IOS_PENDING_QUESTION_RESOLVED"
15406
+ });
15407
+ this.emit("provider-request", {
15408
+ provider,
15409
+ id: requestId,
15410
+ method: "tool/AskUserQuestion",
15411
+ params: {
15412
+ providerSessionId: input.providerSessionId,
15413
+ providerTurnId,
15414
+ toolUseId: `${providerTurnId}:question-item`
15415
+ }
15416
+ });
15417
+ }, 250);
15418
+ return turn;
15419
+ }
15420
+ if (input.prompt.includes(planPromptMarker)) {
15421
+ const planItem = {
15422
+ id: `${providerTurnId}:plan`,
15423
+ createdAt: now,
15424
+ kind: "plan",
15425
+ text: "1. Verify the iOS pending request path.\n2. Keep plan mode active until the user decides.",
15426
+ status: "completed"
15427
+ };
15428
+ setTimeout(() => {
15429
+ if (turn.status !== "inProgress") {
15430
+ return;
15431
+ }
15432
+ turn.items.push(planItem);
15433
+ this.emitRuntimeEvent({
15434
+ type: "item.started",
15435
+ provider,
15436
+ providerSessionId: input.providerSessionId,
15437
+ providerTurnId,
15438
+ item: { ...planItem }
15439
+ });
15440
+ this.completeTurn(input.providerSessionId, providerTurnId);
15441
+ }, 250);
15442
+ return turn;
15443
+ }
15444
+ setTimeout(() => {
15445
+ if (turn.status !== "inProgress") {
15446
+ return;
15447
+ }
15448
+ assistantItem.text = firstDelta;
15449
+ turn.items.push(assistantItem);
15450
+ this.emitRuntimeEvent({
15451
+ type: "item.started",
15452
+ provider,
15453
+ providerSessionId: input.providerSessionId,
15454
+ providerTurnId,
15455
+ item: { ...assistantItem }
15456
+ });
15457
+ this.emitRuntimeEvent({
15458
+ type: "output.delta",
15459
+ provider,
15460
+ providerSessionId: input.providerSessionId,
15461
+ providerTurnId,
15462
+ itemId: assistantItem.id,
15463
+ delta: firstDelta
15464
+ });
15465
+ }, 250);
15466
+ setTimeout(() => {
15467
+ if (turn.status !== "inProgress") {
15468
+ return;
15469
+ }
15470
+ assistantItem.text = `${firstDelta}${secondDelta}`;
15471
+ assistantItem.status = "completed";
15472
+ turn.status = "completed";
15473
+ session.status = "idle";
15474
+ session.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
15475
+ this.activeTurnId = null;
15476
+ this.emitRuntimeEvent({
15477
+ type: "output.delta",
15478
+ provider,
15479
+ providerSessionId: input.providerSessionId,
15480
+ providerTurnId,
15481
+ itemId: assistantItem.id,
15482
+ delta: secondDelta
15483
+ });
15484
+ this.emitRuntimeEvent({
15485
+ type: "item.completed",
15486
+ provider,
15487
+ providerSessionId: input.providerSessionId,
15488
+ providerTurnId,
15489
+ item: { ...assistantItem }
15490
+ });
15491
+ this.emitRuntimeEvent({
15492
+ type: "turn.completed",
15493
+ provider,
15494
+ providerSessionId: input.providerSessionId,
15495
+ turn
15496
+ });
15497
+ }, 2e4);
15498
+ return turn;
15499
+ }
15500
+ async interruptTurn(input) {
15501
+ const session = await this.readSession(input.providerSessionId);
15502
+ const turn = session.turns.find((entry) => entry.providerTurnId === input.providerTurnId);
15503
+ if (!turn) {
15504
+ return null;
15505
+ }
15506
+ turn.status = "interrupted";
15507
+ session.status = "interrupted";
15508
+ this.activeTurnId = null;
15509
+ return turn;
15510
+ }
15511
+ async listMcpServers() {
15512
+ return [];
15513
+ }
15514
+ mapProviderRequest(request) {
15515
+ if (request.provider !== provider || !isRecord11(request.params)) {
15516
+ return null;
15517
+ }
15518
+ const providerSessionId = stringValue4(request.params.providerSessionId);
15519
+ const providerTurnId = stringValue4(request.params.providerTurnId);
15520
+ if (!providerSessionId) {
15521
+ return null;
15522
+ }
15523
+ if (request.method === "item/commandExecution/requestApproval") {
15524
+ const requestId = String(request.id);
15525
+ const description = [
15526
+ stringValue4(request.params.reason),
15527
+ stringValue4(request.params.command) ? `Command: ${stringValue4(request.params.command)}` : null,
15528
+ stringValue4(request.params.cwd) ? `CWD: ${stringValue4(request.params.cwd)}` : null
15529
+ ].filter(Boolean).join("\n");
15530
+ return {
15531
+ providerRequestId: request.id,
15532
+ providerSessionId,
15533
+ autoApprovedResult: null,
15534
+ pendingRequest: {
15535
+ providerRequestId: request.id,
15536
+ responseKind: "commandExecutionApproval",
15537
+ request: {
15538
+ id: requestId,
15539
+ kind: "requestUserInput",
15540
+ title: "Command approval required",
15541
+ description: description || "iOS E2E approval request.",
15542
+ turnId: providerTurnId,
15543
+ itemId: stringValue4(request.params.itemId),
15544
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
15545
+ questions: [
15546
+ {
15547
+ id: "approval",
15548
+ header: "Command approval required",
15549
+ question: description || "iOS E2E approval request.",
15550
+ isOther: false,
15551
+ isSecret: false,
15552
+ options: [
15553
+ { label: "Allow", description: "Permit this action and continue the current turn." },
15554
+ { label: "Deny", description: "Decline this action." }
15555
+ ]
15556
+ }
15557
+ ]
15558
+ }
15559
+ }
15560
+ };
15561
+ }
15562
+ if (request.method === "tool/AskUserQuestion") {
15563
+ const requestId = String(request.id);
15564
+ return {
15565
+ providerRequestId: request.id,
15566
+ providerSessionId,
15567
+ autoApprovedResult: null,
15568
+ pendingRequest: {
15569
+ providerRequestId: request.id,
15570
+ responseKind: "askUserQuestion",
15571
+ request: {
15572
+ id: requestId,
15573
+ kind: "requestUserInput",
15574
+ title: "Mode",
15575
+ description: "Which iOS E2E path should continue?",
15576
+ turnId: providerTurnId,
15577
+ itemId: stringValue4(request.params.toolUseId),
15578
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
15579
+ questions: [
15580
+ {
15581
+ id: "question-1",
15582
+ header: "Mode",
15583
+ question: "Which iOS E2E path should continue?",
15584
+ isOther: true,
15585
+ isSecret: false,
15586
+ options: [
15587
+ { label: "Short", description: "Keep the response concise." },
15588
+ { label: "Detailed", description: "Include more context." }
15589
+ ]
15590
+ }
15591
+ ]
15592
+ },
15593
+ responsePayload: {
15594
+ continueAsPrompt: false
15595
+ }
15596
+ }
15597
+ };
15598
+ }
15599
+ return null;
15600
+ }
15601
+ buildProviderRequestResponse(pending, input) {
15602
+ if (pending.responseKind === "commandExecutionApproval") {
15603
+ const answer = input.answers.approval?.answers[0]?.trim().toLowerCase();
15604
+ return { decision: answer === "allow" ? "accept" : "deny" };
15605
+ }
15606
+ return {
15607
+ kind: pending.responseKind,
15608
+ answers: input.answers
15609
+ };
15610
+ }
15611
+ respondToProviderRequest(id, result) {
15612
+ void result;
15613
+ const request = this.providerRequests.get(id);
15614
+ if (!request) {
15615
+ return;
15616
+ }
15617
+ this.providerRequests.delete(id);
15618
+ const session = this.sessions.get(request.providerSessionId);
15619
+ const turn = session?.turns.find((entry) => entry.providerTurnId === request.providerTurnId);
15620
+ if (!session || !turn || turn.status !== "inProgress") {
15621
+ return;
15622
+ }
15623
+ const assistantItem = {
15624
+ id: `${request.providerTurnId}:assistant`,
15625
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
15626
+ kind: "agentMessage",
15627
+ text: request.assistantText,
15628
+ status: "completed"
15629
+ };
15630
+ turn.items.push(assistantItem);
15631
+ this.emitRuntimeEvent({
15632
+ type: "item.started",
15633
+ provider,
15634
+ providerSessionId: request.providerSessionId,
15635
+ providerTurnId: request.providerTurnId,
15636
+ item: { ...assistantItem }
15637
+ });
15638
+ this.completeTurn(request.providerSessionId, request.providerTurnId);
15639
+ }
15640
+ completeTurn(providerSessionId, providerTurnId) {
15641
+ const session = this.sessions.get(providerSessionId);
15642
+ const turn = session?.turns.find((entry) => entry.providerTurnId === providerTurnId);
15643
+ if (!session || !turn || turn.status !== "inProgress") {
15644
+ return;
15645
+ }
15646
+ turn.status = "completed";
15647
+ session.status = "idle";
15648
+ session.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
15649
+ this.activeTurnId = null;
15650
+ this.emitRuntimeEvent({
15651
+ type: "turn.completed",
15652
+ provider,
15653
+ providerSessionId,
15654
+ turn
15655
+ });
15656
+ }
15657
+ emitRuntimeEvent(event) {
15658
+ this.emit("event", event);
15659
+ }
15660
+ };
15661
+ function isE2EFakeRuntimeEnabled(env = process.env) {
15662
+ const value = env.REMOTE_CODEX_E2E_FAKE_RUNTIME;
15663
+ return value ? ["1", "true", "yes", "on"].includes(value.toLowerCase()) : false;
15664
+ }
15665
+ function isRecord11(value) {
15666
+ return typeof value === "object" && value !== null && !Array.isArray(value);
15667
+ }
15668
+ function stringValue4(value) {
15669
+ return typeof value === "string" ? value : null;
15670
+ }
15671
+
15077
15672
  // src/agent-runtime-bootstrap.ts
15078
15673
  function createAgentRuntimeBootstrap(config) {
15079
15674
  const runtimes = [];
@@ -15104,6 +15699,10 @@ function createAgentRuntimeBootstrap(config) {
15104
15699
  runtimes.push(createOpenCodeRuntime(config));
15105
15700
  providerHostHomes.opencode = opencodeConfig.home;
15106
15701
  }
15702
+ if (isE2EFakeRuntimeEnabled()) {
15703
+ runtimes.push(new E2EFakeRuntime());
15704
+ providerHostHomes.claude = claudeConfig.home;
15705
+ }
15107
15706
  return {
15108
15707
  agentRuntimes: new AgentRuntimeRegistry(runtimes),
15109
15708
  localCodexSessionStore: new LocalCodexSessionStore(codexConfig.home),
@@ -15137,8 +15736,8 @@ function createOpenCodeRuntime(config) {
15137
15736
  }
15138
15737
 
15139
15738
  // src/event-bus.ts
15140
- import { EventEmitter as EventEmitter7 } from "events";
15141
- var SupervisorEventBus = class extends EventEmitter7 {
15739
+ import { EventEmitter as EventEmitter8 } from "events";
15740
+ var SupervisorEventBus = class extends EventEmitter8 {
15142
15741
  emitThreadEvent(event) {
15143
15742
  this.emit("thread-event", event);
15144
15743
  }
@@ -15475,8 +16074,8 @@ var ThreadGoalCoordinator = class {
15475
16074
  normalizeThreadGoalStatusForThread(goal, record) {
15476
16075
  return normalizeThreadGoalStatusForThread(goal, record);
15477
16076
  }
15478
- async ensureGoalsFeatureEnabled(provider) {
15479
- await this.goalFeatureManagement.ensureGoalsFeatureEnabled(provider);
16077
+ async ensureGoalsFeatureEnabled(provider2) {
16078
+ await this.goalFeatureManagement.ensureGoalsFeatureEnabled(provider2);
15480
16079
  }
15481
16080
  };
15482
16081
  function toIsoFromEpoch2(value) {
@@ -15590,7 +16189,7 @@ var DEFERRED_FILE_CHANGE_DETAIL_TITLE = "File Change Details";
15590
16189
  var DEFERRED_FILE_READ_DETAIL_TITLE = "File Read Details";
15591
16190
  var DEFERRED_WEB_SEARCH_DETAIL_TITLE = "Web Search Details";
15592
16191
  var DEFERRED_HOOK_DETAIL_TITLE = "Hook Details";
15593
- function parseUuidV7Timestamp(id) {
16192
+ function parseUuidV7Timestamp2(id) {
15594
16193
  const normalized = id.replace(/-/g, "");
15595
16194
  if (!/^[0-9a-f]{32}$/i.test(normalized) || normalized[12]?.toLowerCase() !== "7") {
15596
16195
  return null;
@@ -15955,7 +16554,7 @@ function mergePersistedHistoryItemsIntoTurns(turns, persistedItemsByTurnId, defe
15955
16554
  function agentTurnToThreadTurnDto(turn, deferredDetails) {
15956
16555
  const baseTurn = {
15957
16556
  id: turn.providerTurnId,
15958
- startedAt: turn.startedAt ?? parseUuidV7Timestamp(turn.providerTurnId),
16557
+ startedAt: turn.startedAt ?? parseUuidV7Timestamp2(turn.providerTurnId),
15959
16558
  status: turn.status,
15960
16559
  error: turn.error?.message ?? null,
15961
16560
  items: visibleRuntimeTurnItems(turn.items).map(
@@ -16200,6 +16799,7 @@ var ThreadLiveStateStore = class {
16200
16799
  sequence: input.sequence
16201
16800
  } : {
16202
16801
  id: input.itemId,
16802
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
16203
16803
  kind: "agentMessage",
16204
16804
  text: input.delta,
16205
16805
  sequence: input.sequence
@@ -16310,7 +16910,7 @@ function agentMessageMatchScore(finalText, liveText) {
16310
16910
 
16311
16911
  // src/thread-usage-accounting.ts
16312
16912
  var CONTEXT_BASELINE_TOKENS = 12e3;
16313
- function isRecord11(value) {
16913
+ function isRecord12(value) {
16314
16914
  return typeof value === "object" && value !== null && !Array.isArray(value);
16315
16915
  }
16316
16916
  function numberOrNull2(value) {
@@ -16358,11 +16958,11 @@ function computeContextRemainingPercent(tokensInContextWindow, contextWindow) {
16358
16958
  return clampPercentage(Math.round(remaining / effectiveWindow * 100));
16359
16959
  }
16360
16960
  function buildThreadContextUsageFromPayload(payload, model = null, timestamp = (/* @__PURE__ */ new Date()).toISOString()) {
16361
- const tokenUsage = isRecord11(payload) ? payload : null;
16961
+ const tokenUsage = isRecord12(payload) ? payload : null;
16362
16962
  const modelContextWindow = numberOrNull2(
16363
16963
  tokenUsage?.modelContextWindow ?? tokenUsage?.model_context_window
16364
16964
  ) ?? contextWindowForModel(model);
16365
- const lastUsage = isRecord11(tokenUsage?.last) ? tokenUsage.last : null;
16965
+ const lastUsage = isRecord12(tokenUsage?.last) ? tokenUsage.last : null;
16366
16966
  const tokensInContextWindow = numberOrNull2(
16367
16967
  lastUsage?.totalTokens ?? lastUsage?.total_tokens
16368
16968
  );
@@ -16394,7 +16994,7 @@ function shouldResetThreadContextUsageForTurnStart(current) {
16394
16994
  return current?.availability !== "available";
16395
16995
  }
16396
16996
  function buildTurnTokenBreakdown(payload) {
16397
- const usage = isRecord11(payload) ? payload : null;
16997
+ const usage = isRecord12(payload) ? payload : null;
16398
16998
  const totalTokens2 = numberOrNull2(usage?.totalTokens ?? usage?.total_tokens);
16399
16999
  const inputTokens = numberOrNull2(usage?.inputTokens ?? usage?.input_tokens);
16400
17000
  const cachedInputTokens = numberOrNull2(
@@ -16440,12 +17040,12 @@ function subtractTurnTokenBreakdowns(current, previous) {
16440
17040
  };
16441
17041
  }
16442
17042
  function parseThreadTurnTokenUsage(payload) {
16443
- const tokenUsage = isRecord11(payload) ? payload : null;
17043
+ const tokenUsage = isRecord12(payload) ? payload : null;
16444
17044
  const total = buildTurnTokenBreakdown(
16445
- isRecord11(tokenUsage?.total) ? tokenUsage.total : null
17045
+ isRecord12(tokenUsage?.total) ? tokenUsage.total : null
16446
17046
  );
16447
17047
  const last = buildTurnTokenBreakdown(
16448
- isRecord11(tokenUsage?.last) ? tokenUsage.last : null
17048
+ isRecord12(tokenUsage?.last) ? tokenUsage.last : null
16449
17049
  );
16450
17050
  const modelContextWindow = numberOrNull2(
16451
17051
  tokenUsage?.modelContextWindow ?? tokenUsage?.model_context_window
@@ -16469,7 +17069,7 @@ function parseStoredThreadTurnTokenUsageState(value) {
16469
17069
  try {
16470
17070
  const parsed = JSON.parse(value);
16471
17071
  const baselineTotal = buildTurnTokenBreakdown(
16472
- isRecord11(parsed?.baselineTotal) ? parsed.baselineTotal : null
17072
+ isRecord12(parsed?.baselineTotal) ? parsed.baselineTotal : null
16473
17073
  );
16474
17074
  return {
16475
17075
  baselineTotal,
@@ -16509,12 +17109,12 @@ function stringifyStoredThreadTurnTokenUsageState(state) {
16509
17109
  });
16510
17110
  }
16511
17111
  function buildThreadTurnTokenUsage(payload, baselineTotal, previous = null) {
16512
- const tokenUsage = isRecord11(payload) ? payload : null;
17112
+ const tokenUsage = isRecord12(payload) ? payload : null;
16513
17113
  const cumulativeTotal = buildTurnTokenBreakdown(
16514
- isRecord11(tokenUsage?.total) ? tokenUsage.total : null
17114
+ isRecord12(tokenUsage?.total) ? tokenUsage.total : null
16515
17115
  );
16516
17116
  const last = buildTurnTokenBreakdown(
16517
- isRecord11(tokenUsage?.last) ? tokenUsage.last : null
17117
+ isRecord12(tokenUsage?.last) ? tokenUsage.last : null
16518
17118
  );
16519
17119
  const modelContextWindow = numberOrNull2(
16520
17120
  tokenUsage?.modelContextWindow ?? tokenUsage?.model_context_window
@@ -16586,7 +17186,7 @@ var ThreadUsageAccounting = class {
16586
17186
  input.localThreadId
16587
17187
  );
16588
17188
  const currentCumulativeTotal = buildTurnTokenBreakdown(
16589
- isRecord11(input.tokenUsage?.total) ? input.tokenUsage.total : null
17189
+ isRecord12(input.tokenUsage?.total) ? input.tokenUsage.total : null
16590
17190
  );
16591
17191
  if (currentCumulativeTotal) {
16592
17192
  this.threadCumulativeTokenUsage.set(input.localThreadId, currentCumulativeTotal);
@@ -16976,10 +17576,10 @@ var ThreadRuntimeEventProjector = class {
16976
17576
  }
16977
17577
  }
16978
17578
  }
16979
- findRecordByProviderSessionId(provider, providerSessionId) {
17579
+ findRecordByProviderSessionId(provider2, providerSessionId) {
16980
17580
  return getThreadRecordByProviderSessionId(
16981
17581
  this.input.db,
16982
- provider ?? "codex",
17582
+ provider2 ?? "codex",
16983
17583
  providerSessionId
16984
17584
  );
16985
17585
  }
@@ -17069,8 +17669,8 @@ var ProviderRequestCoordinator = class {
17069
17669
  dismissedTurnId
17070
17670
  };
17071
17671
  }
17072
- respondToProviderRequest(provider, pending, input) {
17073
- const runtime = this.callbacks.runtimeForProvider(provider);
17672
+ respondToProviderRequest(provider2, pending, input) {
17673
+ const runtime = this.callbacks.runtimeForProvider(provider2);
17074
17674
  if (!runtime.buildProviderRequestResponse) {
17075
17675
  throw new HttpError(409, {
17076
17676
  code: "conflict",
@@ -17099,7 +17699,7 @@ var ProviderRequestCoordinator = class {
17099
17699
  const defaultMappedRequest = runtime.mapProviderRequest?.(request, {
17100
17700
  approvalMode: "guarded"
17101
17701
  });
17102
- const providerSessionIdFromParams = isRecord12(request.params) ? request.params.providerSessionId ?? request.params.threadId ?? request.params.conversationId ?? request.params.sessionId : null;
17702
+ const providerSessionIdFromParams = isRecord13(request.params) ? request.params.providerSessionId ?? request.params.threadId ?? request.params.conversationId ?? request.params.sessionId : null;
17103
17703
  const providerSessionId = defaultMappedRequest?.providerSessionId ?? (typeof providerSessionIdFromParams === "string" ? providerSessionIdFromParams : null);
17104
17704
  const record = providerSessionId ? this.callbacks.findRecordByProviderSessionId(request.provider, providerSessionId) : null;
17105
17705
  if (!record) {
@@ -17312,7 +17912,7 @@ function buildRequestAnswerLines(request, input) {
17312
17912
  return `- ${question.question}: ${answers.join(", ")}`;
17313
17913
  }).filter((line) => Boolean(line));
17314
17914
  }
17315
- function isRecord12(value) {
17915
+ function isRecord13(value) {
17316
17916
  return typeof value === "object" && value !== null && !Array.isArray(value);
17317
17917
  }
17318
17918
 
@@ -17702,20 +18302,20 @@ var ThreadProviderRuntimeCoordinator = class {
17702
18302
  this.agentRuntimes = agentRuntimes;
17703
18303
  }
17704
18304
  agentRuntimes;
17705
- normalizeProvider(provider) {
17706
- if (!provider) {
18305
+ normalizeProvider(provider2) {
18306
+ if (!provider2) {
17707
18307
  return defaultAgentBackendId;
17708
18308
  }
17709
- if (isAgentBackendId(provider)) {
17710
- return provider;
18309
+ if (isAgentBackendId(provider2)) {
18310
+ return provider2;
17711
18311
  }
17712
18312
  throw new HttpError(400, {
17713
18313
  code: "bad_request",
17714
- message: `Unsupported agent runtime provider: ${provider}`
18314
+ message: `Unsupported agent runtime provider: ${provider2}`
17715
18315
  });
17716
18316
  }
17717
- runtimeForProvider(provider) {
17718
- const normalizedProvider = this.normalizeProvider(provider);
18317
+ runtimeForProvider(provider2) {
18318
+ const normalizedProvider = this.normalizeProvider(provider2);
17719
18319
  const runtime = this.optionalRuntimeForProvider(normalizedProvider);
17720
18320
  if (!runtime) {
17721
18321
  throw new HttpError(501, {
@@ -17725,8 +18325,8 @@ var ThreadProviderRuntimeCoordinator = class {
17725
18325
  }
17726
18326
  return runtime;
17727
18327
  }
17728
- optionalRuntimeForProvider(provider) {
17729
- return this.agentRuntimes.getOptional(this.normalizeProvider(provider)) ?? null;
18328
+ optionalRuntimeForProvider(provider2) {
18329
+ return this.agentRuntimes.getOptional(this.normalizeProvider(provider2)) ?? null;
17730
18330
  }
17731
18331
  allRuntimes() {
17732
18332
  return this.agentRuntimes.all();
@@ -17734,22 +18334,22 @@ var ThreadProviderRuntimeCoordinator = class {
17734
18334
  providerForRecord(record) {
17735
18335
  return this.normalizeProvider(record.provider);
17736
18336
  }
17737
- isCodexProvider(provider) {
17738
- return this.providerForRecord({ provider }) === "codex";
18337
+ isCodexProvider(provider2) {
18338
+ return this.providerForRecord({ provider: provider2 }) === "codex";
17739
18339
  }
17740
- runtimeSupportsFastMode(provider) {
17741
- return this.optionalRuntimeForProvider(provider)?.capabilities.controls.performanceMode ?? false;
18340
+ runtimeSupportsFastMode(provider2) {
18341
+ return this.optionalRuntimeForProvider(provider2)?.capabilities.controls.performanceMode ?? false;
17742
18342
  }
17743
- fastModeForProvider(provider, fastMode) {
17744
- return this.runtimeSupportsFastMode(provider) ? normalizeFastMode(fastMode) : false;
18343
+ fastModeForProvider(provider2, fastMode) {
18344
+ return this.runtimeSupportsFastMode(provider2) ? normalizeFastMode(fastMode) : false;
17745
18345
  }
17746
18346
  performanceModeForRecord(record) {
17747
18347
  return performanceModeForFastMode(
17748
18348
  this.fastModeForProvider(record.provider, record.fastMode)
17749
18349
  );
17750
18350
  }
17751
- async listLoadedProviderSessionIds(provider = "codex") {
17752
- const runtime = this.optionalRuntimeForProvider(provider);
18351
+ async listLoadedProviderSessionIds(provider2 = "codex") {
18352
+ const runtime = this.optionalRuntimeForProvider(provider2);
17753
18353
  if (!runtime) {
17754
18354
  return /* @__PURE__ */ new Set();
17755
18355
  }
@@ -17757,11 +18357,11 @@ var ThreadProviderRuntimeCoordinator = class {
17757
18357
  await runtime.listLoadedSessions().catch(() => [])
17758
18358
  );
17759
18359
  }
17760
- async listProviderModels(provider = "codex") {
17761
- return this.runtimeForProvider(provider).listModels().catch(() => []);
18360
+ async listProviderModels(provider2 = "codex") {
18361
+ return this.runtimeForProvider(provider2).listModels().catch(() => []);
17762
18362
  }
17763
- async listProviderModelOptions(provider = "codex") {
17764
- const models = await this.runtimeForProvider(provider).listModels();
18363
+ async listProviderModelOptions(provider2 = "codex") {
18364
+ const models = await this.runtimeForProvider(provider2).listModels();
17765
18365
  return models.map((model) => this.modelOptionFromAgentModel(model));
17766
18366
  }
17767
18367
  normalizeReasoningForModel(modelRecords, model, requested) {
@@ -17946,15 +18546,15 @@ var ThreadManagementCoordinator = class {
17946
18546
  });
17947
18547
  }
17948
18548
  }
17949
- assertHookFileManagement(provider) {
17950
- if (!this.hookFileManagement.canManageHookFiles(provider)) {
18549
+ assertHookFileManagement(provider2) {
18550
+ if (!this.hookFileManagement.canManageHookFiles(provider2)) {
17951
18551
  throw new HttpError(409, {
17952
18552
  code: "conflict",
17953
18553
  message: "This backend does not support hooks file editing."
17954
18554
  });
17955
18555
  }
17956
18556
  }
17957
- async toThreadHooksDto(provider, workspacePath, entry, fallbackWarnings = []) {
18557
+ async toThreadHooksDto(provider2, workspacePath, entry, fallbackWarnings = []) {
17958
18558
  const { globalHooksPath, projectHooksPath } = this.hookFileManagement.hooksPaths(workspacePath);
17959
18559
  const officialHooks = (entry?.hooks ?? []).map((hook) => ({
17960
18560
  key: hook.key,
@@ -17973,7 +18573,7 @@ var ThreadManagementCoordinator = class {
17973
18573
  currentHash: hook.currentHash,
17974
18574
  trustStatus: hook.trustStatus
17975
18575
  }));
17976
- const [globalHooks, projectHooks] = this.hookFileManagement.canManageHookFiles(provider) ? await Promise.all([
18576
+ const [globalHooks, projectHooks] = this.hookFileManagement.canManageHookFiles(provider2) ? await Promise.all([
17977
18577
  this.hookFileManagement.readLocalHookDtos({
17978
18578
  hooksPath: globalHooksPath,
17979
18579
  source: "user",
@@ -18125,7 +18725,8 @@ var ThreadPromptTurnCoordinator = class {
18125
18725
  await runtime.sendInput({
18126
18726
  providerSessionId: record.providerSessionId,
18127
18727
  providerTurnId: steerTurnId,
18128
- prompt: input.prompt
18728
+ prompt: input.prompt,
18729
+ workspacePath: input.workspacePath
18129
18730
  });
18130
18731
  updateThreadRecord(this.db, localThreadId, {
18131
18732
  providerTurnId: steerTurnId,
@@ -18256,9 +18857,9 @@ var ThreadSessionCoordinator = class {
18256
18857
  performanceModeSettings;
18257
18858
  localSessionLookup;
18258
18859
  async startThreadSession(input) {
18259
- const provider = this.providerRuntime.normalizeProvider(input.threadInput.provider);
18860
+ const provider2 = this.providerRuntime.normalizeProvider(input.threadInput.provider);
18260
18861
  const normalizedTitle = input.threadInput.title?.trim() || input.defaultTitle;
18261
- const runtime = this.providerRuntime.runtimeForProvider(provider);
18862
+ const runtime = this.providerRuntime.runtimeForProvider(provider2);
18262
18863
  const modelRecords = await runtime.listModels().catch(() => []);
18263
18864
  const reasoningEffort = this.providerRuntime.normalizeReasoningForModel(
18264
18865
  modelRecords,
@@ -18266,8 +18867,8 @@ var ThreadSessionCoordinator = class {
18266
18867
  input.threadInput.reasoningEffort ?? null
18267
18868
  );
18268
18869
  const sandboxMode = defaultSandboxModeForApprovalMode(input.threadInput.approvalMode);
18269
- const fastMode = this.providerRuntime.runtimeSupportsFastMode(provider) ? this.performanceModeSettings.readFastMode() : false;
18270
- if (this.providerRuntime.runtimeSupportsFastMode(provider)) {
18870
+ const fastMode = this.providerRuntime.runtimeSupportsFastMode(provider2) ? this.performanceModeSettings.readFastMode() : false;
18871
+ if (this.providerRuntime.runtimeSupportsFastMode(provider2)) {
18271
18872
  ensureFastModeSupported(input.threadInput.model, fastMode, modelRecords);
18272
18873
  }
18273
18874
  const response = await runtime.startSession({
@@ -18279,7 +18880,7 @@ var ThreadSessionCoordinator = class {
18279
18880
  performanceMode: performanceModeForFastMode(fastMode)
18280
18881
  });
18281
18882
  return {
18282
- provider,
18883
+ provider: provider2,
18283
18884
  normalizedTitle,
18284
18885
  response,
18285
18886
  reasoningEffort,
@@ -18308,30 +18909,30 @@ var ThreadSessionCoordinator = class {
18308
18909
  return this.localSessionLookup.findSession(providerSessionId);
18309
18910
  }
18310
18911
  async resolveLocalImportSession(input) {
18311
- const provider = normalizeAgentBackendId(input.provider) ?? "codex";
18312
- if (provider !== "codex") {
18313
- return this.resolveRuntimeImportSession(provider, input.sessionId);
18912
+ const provider2 = normalizeAgentBackendId(input.provider) ?? "codex";
18913
+ if (provider2 !== "codex") {
18914
+ return this.resolveRuntimeImportSession(provider2, input.sessionId);
18314
18915
  }
18315
18916
  return this.localSessionLookup.findImportSession(input.sessionId, {
18316
18917
  fastMode: this.performanceModeSettings.readFastMode(),
18317
- provider
18918
+ provider: provider2
18318
18919
  });
18319
18920
  }
18320
- async resolveRuntimeImportSession(provider, sessionId) {
18921
+ async resolveRuntimeImportSession(provider2, sessionId) {
18321
18922
  try {
18322
- const session = await this.providerRuntime.runtimeForProvider(provider).readSession(sessionId);
18923
+ const session = await this.providerRuntime.runtimeForProvider(provider2).readSession(sessionId);
18323
18924
  if (!session.cwd) {
18324
18925
  return null;
18325
18926
  }
18326
18927
  return {
18327
- provider,
18928
+ provider: provider2,
18328
18929
  source: "supervisor",
18329
18930
  sessionId,
18330
18931
  cwd: session.cwd,
18331
18932
  title: session.title?.trim() || session.preview?.trim() || "Untitled imported session",
18332
18933
  model: null,
18333
18934
  summaryText: session.preview,
18334
- fastMode: this.providerRuntime.runtimeSupportsFastMode(provider) ? this.performanceModeSettings.readFastMode() : false
18935
+ fastMode: this.providerRuntime.runtimeSupportsFastMode(provider2) ? this.performanceModeSettings.readFastMode() : false
18335
18936
  };
18336
18937
  } catch {
18337
18938
  return null;
@@ -18703,9 +19304,9 @@ var ThreadHistoryPersistenceCoordinator = class {
18703
19304
 
18704
19305
  // src/thread-deletion-coordinator.ts
18705
19306
  import fs10 from "fs/promises";
18706
- import path12 from "path";
19307
+ import path13 from "path";
18707
19308
  function threadTempDirectoryPath(workspacePath, localThreadId) {
18708
- return path12.join(workspacePath, ".temp", "threads", localThreadId);
19309
+ return path13.join(workspacePath, ".temp", "threads", localThreadId);
18709
19310
  }
18710
19311
  var ThreadDeletionCoordinator = class {
18711
19312
  constructor(db, requestCoordinator, usageAccounting, liveState, auxiliaryState, callbacks) {
@@ -20102,7 +20703,7 @@ var ThreadForkCoordinator = class {
20102
20703
  // src/thread-attachment-coordinator.ts
20103
20704
  import { randomUUID as randomUUID3 } from "crypto";
20104
20705
  import fs12 from "fs/promises";
20105
- import path13 from "path";
20706
+ import path14 from "path";
20106
20707
  async function pathExists(absPath) {
20107
20708
  try {
20108
20709
  await fs12.access(absPath);
@@ -20112,8 +20713,8 @@ async function pathExists(absPath) {
20112
20713
  }
20113
20714
  }
20114
20715
  function sanitizeAttachmentFileName(originalName) {
20115
- const basename = path13.basename(originalName).trim() || "attachment";
20116
- const extension = path13.extname(basename).replace(/[^a-zA-Z0-9.]/g, "");
20716
+ const basename = path14.basename(originalName).trim() || "attachment";
20717
+ const extension = path14.extname(basename).replace(/[^a-zA-Z0-9.]/g, "");
20117
20718
  const rawStem = extension ? basename.slice(0, -extension.length) : basename;
20118
20719
  const sanitizedStem = rawStem.replace(/[^a-zA-Z0-9._-]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 64);
20119
20720
  const stem = sanitizedStem || "attachment";
@@ -20121,7 +20722,7 @@ function sanitizeAttachmentFileName(originalName) {
20121
20722
  return `${stem}-${randomUUID3().slice(0, 8)}${normalizedExtension}`;
20122
20723
  }
20123
20724
  function threadTempDirectoryPath2(workspacePath, localThreadId) {
20124
- return path13.join(workspacePath, ".temp", "threads", localThreadId);
20725
+ return path14.join(workspacePath, ".temp", "threads", localThreadId);
20125
20726
  }
20126
20727
  var ThreadAttachmentCoordinator = class {
20127
20728
  constructor(db) {
@@ -20162,7 +20763,7 @@ var ThreadAttachmentCoordinator = class {
20162
20763
  const savedFileName = sanitizeAttachmentFileName(
20163
20764
  attachment.manifest.originalName
20164
20765
  );
20165
- await fs12.writeFile(path13.join(tempDirectory, savedFileName), attachment.buffer);
20766
+ await fs12.writeFile(path14.join(tempDirectory, savedFileName), attachment.buffer);
20166
20767
  const relativePath = `./.temp/threads/${localThreadId}/${savedFileName}`;
20167
20768
  const replacementToken = attachment.manifest.kind === "photo" ? `[PHOTO ${relativePath}]` : `[FILE ${relativePath}]`;
20168
20769
  rewrittenPrompt = rewrittenPrompt.split(attachment.manifest.placeholder).join(replacementToken);
@@ -20176,7 +20777,7 @@ var ThreadAttachmentCoordinator = class {
20176
20777
 
20177
20778
  // src/thread-import-coordinator.ts
20178
20779
  import fs13 from "fs/promises";
20179
- import path14 from "path";
20780
+ import path15 from "path";
20180
20781
  async function pathExists2(absPath) {
20181
20782
  try {
20182
20783
  await fs13.access(absPath);
@@ -20186,19 +20787,19 @@ async function pathExists2(absPath) {
20186
20787
  }
20187
20788
  }
20188
20789
  async function resolveComparablePath2(absPath) {
20189
- const resolved = path14.resolve(absPath);
20790
+ const resolved = path15.resolve(absPath);
20190
20791
  if (await pathExists2(resolved)) {
20191
20792
  return fs13.realpath(resolved);
20192
20793
  }
20193
- const parentPath = path14.dirname(resolved);
20794
+ const parentPath = path15.dirname(resolved);
20194
20795
  if (parentPath === resolved) {
20195
20796
  return resolved;
20196
20797
  }
20197
20798
  const resolvedParent = await resolveComparablePath2(parentPath);
20198
- return path14.join(resolvedParent, path14.basename(resolved));
20799
+ return path15.join(resolvedParent, path15.basename(resolved));
20199
20800
  }
20200
20801
  async function resolveImportedWorkspacePath(workspaceRoot, candidatePath) {
20201
- if (!path14.isAbsolute(candidatePath)) {
20802
+ if (!path15.isAbsolute(candidatePath)) {
20202
20803
  throw new HttpError(400, {
20203
20804
  code: "bad_request",
20204
20805
  message: "Imported session path must be absolute."
@@ -20206,7 +20807,7 @@ async function resolveImportedWorkspacePath(workspaceRoot, candidatePath) {
20206
20807
  }
20207
20808
  const resolvedRoot = await resolveComparablePath2(workspaceRoot);
20208
20809
  const resolvedCandidate = await resolveComparablePath2(candidatePath);
20209
- const normalizedRoot = resolvedRoot.endsWith(path14.sep) ? resolvedRoot : `${resolvedRoot}${path14.sep}`;
20810
+ const normalizedRoot = resolvedRoot.endsWith(path15.sep) ? resolvedRoot : `${resolvedRoot}${path15.sep}`;
20210
20811
  if (resolvedCandidate !== resolvedRoot && !resolvedCandidate.startsWith(normalizedRoot)) {
20211
20812
  throw new HttpError(403, {
20212
20813
  code: "forbidden",
@@ -20232,17 +20833,17 @@ var ThreadImportCoordinator = class {
20232
20833
  message: "Session id is required."
20233
20834
  });
20234
20835
  }
20235
- const provider = normalizeAgentBackendId(input.provider ?? "codex") ?? "codex";
20836
+ const provider2 = normalizeAgentBackendId(input.provider ?? "codex") ?? "codex";
20236
20837
  const existingThread = getThreadRecordByProviderSessionId(
20237
20838
  this.db,
20238
- provider,
20839
+ provider2,
20239
20840
  normalizedSessionId
20240
20841
  );
20241
20842
  if (existingThread) {
20242
20843
  return existingThread.id;
20243
20844
  }
20244
20845
  const importSession = await this.sessionCoordinator.resolveLocalImportSession({
20245
- provider,
20846
+ provider: provider2,
20246
20847
  sessionId: normalizedSessionId
20247
20848
  });
20248
20849
  if (!importSession) {
@@ -20259,7 +20860,7 @@ var ThreadImportCoordinator = class {
20259
20860
  if (!workspace) {
20260
20861
  workspace = createWorkspaceRecord(this.db, {
20261
20862
  absPath: importedPath,
20262
- label: path14.basename(importedPath) || "workspace"
20863
+ label: path15.basename(importedPath) || "workspace"
20263
20864
  });
20264
20865
  }
20265
20866
  const created = createThreadRecord(this.db, {
@@ -20316,8 +20917,8 @@ var ProviderFeatureCoordinator = class {
20316
20917
  mapGoalError(error) {
20317
20918
  this.codexGoalFeatures.mapGoalError(error);
20318
20919
  }
20319
- async ensureGoalsFeatureEnabled(provider) {
20320
- if (!this.providerRuntime.isCodexProvider(provider)) {
20920
+ async ensureGoalsFeatureEnabled(provider2) {
20921
+ if (!this.providerRuntime.isCodexProvider(provider2)) {
20321
20922
  return;
20322
20923
  }
20323
20924
  await this.codexGoalFeatures.ensureGoalsFeatureEnabled(
@@ -20382,7 +20983,7 @@ var ThreadService = class {
20382
20983
  this.historyPersistence = new ThreadHistoryPersistenceCoordinator(db, this.liveState);
20383
20984
  this.attachmentCoordinator = new ThreadAttachmentCoordinator(db);
20384
20985
  this.managementCoordinator = new ThreadManagementCoordinator(providerManagement, {
20385
- runtimeForProvider: (provider) => this.runtimeForProvider(provider)
20986
+ runtimeForProvider: (provider2) => this.runtimeForProvider(provider2)
20386
20987
  });
20387
20988
  this.sessionCoordinator = new ThreadSessionCoordinator(
20388
20989
  this.providerRuntime,
@@ -20408,7 +21009,7 @@ var ThreadService = class {
20408
21009
  this.liveState,
20409
21010
  this.providerRuntime,
20410
21011
  {
20411
- runtimeForProvider: (provider) => this.runtimeForProvider(provider),
21012
+ runtimeForProvider: (provider2) => this.runtimeForProvider(provider2),
20412
21013
  resetThreadContextUsage: (localThreadId, emitEvent) => this.resetThreadContextUsage(localThreadId, emitEvent),
20413
21014
  getThreadContextUsage: (localThreadId) => this.getThreadContextUsage(localThreadId),
20414
21015
  invalidateThreadDetailCache: (localThreadId) => this.invalidateThreadDetailCache(localThreadId),
@@ -20466,7 +21067,7 @@ var ThreadService = class {
20466
21067
  emitThreadEvent: (type, threadId, payload) => this.emitThreadEvent(type, threadId, payload),
20467
21068
  ensureThreadLoaded: (record) => this.ensureThreadLoadedForProviderOperation(record),
20468
21069
  requireProviderSessionId: (record) => this.requireProviderSessionId(record),
20469
- runtimeForProvider: (provider) => this.runtimeForProvider(provider)
21070
+ runtimeForProvider: (provider2) => this.runtimeForProvider(provider2)
20470
21071
  });
20471
21072
  this.auxiliaryState = new ThreadAuxiliaryStateStore(db, {
20472
21073
  cachedTurns: (localThreadId) => this.detailAssembler.cachedTurns(localThreadId),
@@ -20478,9 +21079,9 @@ var ThreadService = class {
20478
21079
  });
20479
21080
  this.requestCoordinator = new ProviderRequestCoordinator({
20480
21081
  emitThreadEvent: (type, threadId, payload) => this.emitThreadEvent(type, threadId, payload),
20481
- findRecordByProviderSessionId: (provider, providerSessionId) => this.findRecordByProviderSessionId(provider, providerSessionId),
21082
+ findRecordByProviderSessionId: (provider2, providerSessionId) => this.findRecordByProviderSessionId(provider2, providerSessionId),
20482
21083
  normalizeCollaborationMode,
20483
- runtimeForProvider: (provider) => this.runtimeForProvider(provider)
21084
+ runtimeForProvider: (provider2) => this.runtimeForProvider(provider2)
20484
21085
  });
20485
21086
  this.deletionCoordinator = new ThreadDeletionCoordinator(
20486
21087
  db,
@@ -20506,7 +21107,7 @@ var ThreadService = class {
20506
21107
  this.sessionCoordinator,
20507
21108
  {
20508
21109
  buildThreadPatch: (remoteSession, model, reasoningEffort) => buildThreadPatch(remoteSession, model, reasoningEffort),
20509
- fastModeForProvider: (provider, fastMode) => this.fastModeForProvider(provider, fastMode),
21110
+ fastModeForProvider: (provider2, fastMode) => this.fastModeForProvider(provider2, fastMode),
20510
21111
  getThreadDetail: (localThreadId) => this.getThreadDetail(localThreadId),
20511
21112
  invalidateThreadDetailCache: (localThreadId) => this.invalidateThreadDetailCache(localThreadId),
20512
21113
  normalizeCollaborationMode,
@@ -20540,7 +21141,7 @@ var ThreadService = class {
20540
21141
  deletePersistedHistoryItemsForTurn: (localThreadId, turnId) => this.historyPersistence.deletePersistedHistoryItemsForTurn(localThreadId, turnId),
20541
21142
  dismissPlanDecisionTurn: (localThreadId) => this.requestCoordinator.dismissPlanDecisionTurn(localThreadId),
20542
21143
  emitThreadEvent: (type, threadId, payload) => this.emitThreadEvent(type, threadId, payload),
20543
- fastModeForProvider: (provider, fastMode) => this.fastModeForProvider(provider, fastMode),
21144
+ fastModeForProvider: (provider2, fastMode) => this.fastModeForProvider(provider2, fastMode),
20544
21145
  hasPendingAskUserQuestion: (localThreadId) => this.hasPendingAskUserQuestion(localThreadId),
20545
21146
  invalidateThreadDetailCache: (localThreadId) => this.invalidateThreadDetailCache(localThreadId),
20546
21147
  listThreadGoalHistory: (localThreadId) => this.goalCoordinator.listThreadGoalHistory(localThreadId),
@@ -20595,14 +21196,14 @@ var ThreadService = class {
20595
21196
  forkCoordinator;
20596
21197
  attachmentCoordinator;
20597
21198
  importCoordinator;
20598
- normalizeProvider(provider) {
20599
- return this.providerRuntime.normalizeProvider(provider);
21199
+ normalizeProvider(provider2) {
21200
+ return this.providerRuntime.normalizeProvider(provider2);
20600
21201
  }
20601
- runtimeForProvider(provider) {
20602
- return this.providerRuntime.runtimeForProvider(provider);
21202
+ runtimeForProvider(provider2) {
21203
+ return this.providerRuntime.runtimeForProvider(provider2);
20603
21204
  }
20604
- optionalRuntimeForProvider(provider) {
20605
- return this.providerRuntime.optionalRuntimeForProvider(provider);
21205
+ optionalRuntimeForProvider(provider2) {
21206
+ return this.providerRuntime.optionalRuntimeForProvider(provider2);
20606
21207
  }
20607
21208
  providerForRecord(record) {
20608
21209
  return this.providerRuntime.providerForRecord(record);
@@ -20634,18 +21235,18 @@ var ThreadService = class {
20634
21235
  );
20635
21236
  }
20636
21237
  }
20637
- findRecordByProviderSessionId(provider, providerSessionId) {
21238
+ findRecordByProviderSessionId(provider2, providerSessionId) {
20638
21239
  return getThreadRecordByProviderSessionId(
20639
21240
  this.db,
20640
- this.providerForRecord({ provider }),
21241
+ this.providerForRecord({ provider: provider2 }),
20641
21242
  providerSessionId
20642
21243
  );
20643
21244
  }
20644
- runtimeSupportsFastMode(provider) {
20645
- return this.providerRuntime.runtimeSupportsFastMode(provider);
21245
+ runtimeSupportsFastMode(provider2) {
21246
+ return this.providerRuntime.runtimeSupportsFastMode(provider2);
20646
21247
  }
20647
- fastModeForProvider(provider, fastMode) {
20648
- return this.providerRuntime.fastModeForProvider(provider, fastMode);
21248
+ fastModeForProvider(provider2, fastMode) {
21249
+ return this.providerRuntime.fastModeForProvider(provider2, fastMode);
20649
21250
  }
20650
21251
  performanceModeForRecord(record) {
20651
21252
  return this.providerRuntime.performanceModeForRecord(record);
@@ -20653,11 +21254,11 @@ var ThreadService = class {
20653
21254
  async handleProviderRequest(request) {
20654
21255
  await this.handleProviderRuntimeRequest(request);
20655
21256
  }
20656
- async listLoadedProviderSessionIds(provider = "codex") {
20657
- return this.providerRuntime.listLoadedProviderSessionIds(provider);
21257
+ async listLoadedProviderSessionIds(provider2 = "codex") {
21258
+ return this.providerRuntime.listLoadedProviderSessionIds(provider2);
20658
21259
  }
20659
- async listProviderModels(provider = "codex") {
20660
- return this.providerRuntime.listProviderModels(provider);
21260
+ async listProviderModels(provider2 = "codex") {
21261
+ return this.providerRuntime.listProviderModels(provider2);
20661
21262
  }
20662
21263
  invalidateThreadDetailCache(localThreadId) {
20663
21264
  this.detailAssembler.invalidate(localThreadId);
@@ -20938,19 +21539,18 @@ var ThreadService = class {
20938
21539
  return this.getThreadDetail(localThreadId);
20939
21540
  }
20940
21541
  async sendPrompt(localThreadId, input, options = {}) {
20941
- const record = getThreadRecordById(this.db, localThreadId);
21542
+ let record = getThreadRecordById(this.db, localThreadId);
20942
21543
  if (!record) {
20943
21544
  throw new HttpError(404, {
20944
21545
  code: "not_found",
20945
21546
  message: "Thread was not found."
20946
21547
  });
20947
21548
  }
20948
- const providerSessionId = this.requireProviderSessionId(record);
20949
21549
  await this.importCoordinator.assertImportedThreadReadyForPrompt({
20950
21550
  source: record.source,
20951
21551
  provider: record.provider,
20952
- providerSessionId,
20953
- listLoadedProviderSessionIds: (provider) => this.listLoadedProviderSessionIds(provider)
21552
+ providerSessionId: this.requireProviderSessionId(record),
21553
+ listLoadedProviderSessionIds: (provider2) => this.listLoadedProviderSessionIds(provider2)
20954
21554
  });
20955
21555
  if (record.isConnected === false) {
20956
21556
  throw new HttpError(409, {
@@ -20958,6 +21558,23 @@ var ThreadService = class {
20958
21558
  message: "Connect this thread before sending a new prompt."
20959
21559
  });
20960
21560
  }
21561
+ if (this.providerForRecord(record) === "codex") {
21562
+ const providerSessionId2 = this.requireProviderSessionId(record);
21563
+ const loadedIds = await this.listLoadedProviderSessionIds(record.provider);
21564
+ if (!loadedIds.has(providerSessionId2)) {
21565
+ await this.ensureThreadLoadedForProviderOperation(record);
21566
+ record = getThreadRecordById(this.db, localThreadId);
21567
+ const resumedProviderSessionId = this.requireProviderSessionId(record);
21568
+ const refreshedLoadedIds = await this.listLoadedProviderSessionIds(record.provider);
21569
+ if (!refreshedLoadedIds.has(resumedProviderSessionId)) {
21570
+ throw new HttpError(409, {
21571
+ code: "conflict",
21572
+ message: "Connect this thread before sending a new prompt."
21573
+ });
21574
+ }
21575
+ }
21576
+ }
21577
+ const providerSessionId = this.requireProviderSessionId(record);
20961
21578
  const prompt = input.prompt.trim();
20962
21579
  const displayPrompt = options.displayPrompt?.trim() || prompt;
20963
21580
  if (!prompt) {
@@ -21381,7 +21998,7 @@ var ThreadService = class {
21381
21998
  provider: record.provider,
21382
21999
  providerSessionId: this.requireProviderSessionId(record),
21383
22000
  model: record.model,
21384
- listLoadedProviderSessionIds: (provider) => this.listLoadedProviderSessionIds(provider),
22001
+ listLoadedProviderSessionIds: (provider2) => this.listLoadedProviderSessionIds(provider2),
21385
22002
  resumeThread: (input2) => this.resumeThread(localThreadId, input2)
21386
22003
  });
21387
22004
  await this.updateThreadSettings(localThreadId, {
@@ -21407,7 +22024,7 @@ var ThreadService = class {
21407
22024
  }
21408
22025
  toThreadDto(record, loadedIds) {
21409
22026
  return toThreadDto(record, loadedIds, {
21410
- fastModeForProvider: (provider, fastMode) => this.fastModeForProvider(provider, fastMode),
22027
+ fastModeForProvider: (provider2, fastMode) => this.fastModeForProvider(provider2, fastMode),
21411
22028
  getThreadContextUsage: (localThreadId) => this.getThreadContextUsage(localThreadId)
21412
22029
  });
21413
22030
  }
@@ -21502,7 +22119,7 @@ var ThreadService = class {
21502
22119
  // src/routes/agent-runtimes.ts
21503
22120
  import fs15 from "fs/promises";
21504
22121
  import { spawn as spawn2 } from "child_process";
21505
- import path15 from "path";
22122
+ import path16 from "path";
21506
22123
  import { z as z3 } from "zod";
21507
22124
 
21508
22125
  // src/provider-schemas.ts
@@ -21521,15 +22138,15 @@ var npmManagedPackageNames = {
21521
22138
  claude: ["@anthropic-ai/claude-code", "@anthropic-ai/claude-agent-sdk"],
21522
22139
  opencode: ["opencode-ai", "@opencode-ai/sdk"]
21523
22140
  };
21524
- function providerNotConfigured(provider) {
21525
- const error = new Error(`Agent runtime provider is not configured: ${provider}`);
22141
+ function providerNotConfigured(provider2) {
22142
+ const error = new Error(`Agent runtime provider is not configured: ${provider2}`);
21526
22143
  error.statusCode = 404;
21527
22144
  return error;
21528
22145
  }
21529
- function runtimeDto(app, provider) {
21530
- const runtime = app.services.agentRuntimes.getOptional(provider);
22146
+ function runtimeDto(app, provider2) {
22147
+ const runtime = app.services.agentRuntimes.getOptional(provider2);
21531
22148
  if (!runtime) {
21532
- throw providerNotConfigured(provider);
22149
+ throw providerNotConfigured(provider2);
21533
22150
  }
21534
22151
  const installation = {
21535
22152
  ...runtime.installation
@@ -21539,7 +22156,7 @@ function runtimeDto(app, provider) {
21539
22156
  displayName: runtime.displayName,
21540
22157
  description: runtime.description,
21541
22158
  enabled: isAgentRuntimeEnabled({ ...runtime, installation }),
21542
- isDefault: provider === defaultAgentBackendId,
22159
+ isDefault: provider2 === defaultAgentBackendId,
21543
22160
  status: runtime.getStatus(),
21544
22161
  capabilities: runtime.capabilities,
21545
22162
  managementSchema: runtime.managementSchema,
@@ -21559,18 +22176,18 @@ async function registerAgentRuntimeRoutes(app) {
21559
22176
  });
21560
22177
  });
21561
22178
  app.get("/api/agent-runtimes/:provider/status", async (request) => {
21562
- const { provider } = providerParamSchema.parse(request.params);
21563
- return runtimeDto(app, provider);
22179
+ const { provider: provider2 } = providerParamSchema.parse(request.params);
22180
+ return runtimeDto(app, provider2);
21564
22181
  });
21565
22182
  app.post("/api/agent-runtimes/:provider/restart", async (request) => {
21566
- const { provider } = providerParamSchema.parse(request.params);
21567
- const runtime = app.services.agentRuntimes.getOptional(provider);
22183
+ const { provider: provider2 } = providerParamSchema.parse(request.params);
22184
+ const runtime = app.services.agentRuntimes.getOptional(provider2);
21568
22185
  if (!runtime) {
21569
- throw providerNotConfigured(provider);
22186
+ throw providerNotConfigured(provider2);
21570
22187
  }
21571
22188
  await runtime.stop();
21572
22189
  await runtime.start();
21573
- return runtimeDto(app, provider);
22190
+ return runtimeDto(app, provider2);
21574
22191
  });
21575
22192
  app.post("/api/agent-runtimes/:provider/install", async (request) => {
21576
22193
  if (!app.services.config.agentRuntimeManagementEnabled) {
@@ -21579,11 +22196,11 @@ async function registerAgentRuntimeRoutes(app) {
21579
22196
  message: "Agent runtime install and update are disabled for this worker."
21580
22197
  });
21581
22198
  }
21582
- const { provider } = providerParamSchema.parse(request.params);
22199
+ const { provider: provider2 } = providerParamSchema.parse(request.params);
21583
22200
  const { action } = installActionSchema.parse(request.body ?? {});
21584
- const runtime = app.services.agentRuntimes.getOptional(provider);
22201
+ const runtime = app.services.agentRuntimes.getOptional(provider2);
21585
22202
  if (!runtime) {
21586
- throw providerNotConfigured(provider);
22203
+ throw providerNotConfigured(provider2);
21587
22204
  }
21588
22205
  const command = action === "install" ? runtime.installation.installCommand : runtime.installation.updateCommand;
21589
22206
  if (!command) {
@@ -21616,16 +22233,16 @@ async function registerAgentRuntimeRoutes(app) {
21616
22233
  if (updateWarning) {
21617
22234
  runtime.installation.lastError = updateWarning;
21618
22235
  }
21619
- return runtimeDto(app, provider);
22236
+ return runtimeDto(app, provider2);
21620
22237
  } finally {
21621
22238
  runtime.installation.busy = false;
21622
22239
  }
21623
22240
  });
21624
22241
  app.get("/api/agent-runtimes/:provider/models", async (request) => {
21625
- const { provider } = providerParamSchema.parse(request.params);
21626
- const runtime = app.services.agentRuntimes.getOptional(provider);
22242
+ const { provider: provider2 } = providerParamSchema.parse(request.params);
22243
+ const runtime = app.services.agentRuntimes.getOptional(provider2);
21627
22244
  if (!runtime) {
21628
- throw providerNotConfigured(provider);
22245
+ throw providerNotConfigured(provider2);
21629
22246
  }
21630
22247
  return (await runtime.listModels()).map((model) => ({
21631
22248
  id: model.id,
@@ -21649,10 +22266,10 @@ async function registerAgentRuntimeRoutes(app) {
21649
22266
  message: "Build restart is disabled for this worker."
21650
22267
  });
21651
22268
  }
21652
- const { provider } = providerParamSchema.parse(request.params);
21653
- const runtime = app.services.agentRuntimes.getOptional(provider);
22269
+ const { provider: provider2 } = providerParamSchema.parse(request.params);
22270
+ const runtime = app.services.agentRuntimes.getOptional(provider2);
21654
22271
  if (!runtime) {
21655
- throw providerNotConfigured(provider);
22272
+ throw providerNotConfigured(provider2);
21656
22273
  }
21657
22274
  if (!runtime.managementSchema.buildRestart) {
21658
22275
  const error = new Error("This backend does not support build and restart.");
@@ -21723,7 +22340,7 @@ async function refreshBackendInstallation(app, runtime) {
21723
22340
  async function installedPackageVersion(packageName) {
21724
22341
  const globalRoot = await npmGlobalRoot3();
21725
22342
  if (globalRoot) {
21726
- const global = await packageVersionFromPath(path15.join(globalRoot, packageName, "package.json"));
22343
+ const global = await packageVersionFromPath(path16.join(globalRoot, packageName, "package.json"));
21727
22344
  if (global) {
21728
22345
  return global;
21729
22346
  }
@@ -21760,8 +22377,8 @@ async function updatePathWarning(app, runtime, before, command) {
21760
22377
  `Command: ${command}`
21761
22378
  ].filter(Boolean).join(" ");
21762
22379
  }
21763
- function runtimeCommand(app, provider) {
21764
- switch (provider) {
22380
+ function runtimeCommand(app, provider2) {
22381
+ switch (provider2) {
21765
22382
  case "codex":
21766
22383
  return app.services.config.agentProviders.codex.command;
21767
22384
  case "claude":
@@ -21774,7 +22391,7 @@ function versionStringContains(installedVersion, latestVersion) {
21774
22391
  return Boolean(installedVersion && latestVersion && installedVersion.includes(latestVersion));
21775
22392
  }
21776
22393
  async function packageVersionFromNode(packageName) {
21777
- return packageVersionFromPath(path15.resolve("node_modules", packageName, "package.json"));
22394
+ return packageVersionFromPath(path16.resolve("node_modules", packageName, "package.json"));
21778
22395
  }
21779
22396
  async function packageVersionFromPath(packageJsonPath) {
21780
22397
  try {
@@ -21801,14 +22418,14 @@ async function npmGlobalBin() {
21801
22418
  return firstLine(result.stdout);
21802
22419
  }
21803
22420
  const prefix = await npmGlobalPrefix();
21804
- return prefix ? path15.join(prefix, "bin") : null;
22421
+ return prefix ? path16.join(prefix, "bin") : null;
21805
22422
  }
21806
22423
  async function npmGlobalPrefix() {
21807
22424
  const result = await runShellCommand("npm prefix -g", 3e3);
21808
22425
  return result.code === 0 ? firstLine(result.stdout) : null;
21809
22426
  }
21810
22427
  async function commandPathFor(command) {
21811
- if (path15.isAbsolute(command)) {
22428
+ if (path16.isAbsolute(command)) {
21812
22429
  return command;
21813
22430
  }
21814
22431
  const result = await runShellCommand(`command -v ${shellQuote(command)}`, 3e3);
@@ -22415,8 +23032,8 @@ async function registerSystemRoutes(app) {
22415
23032
  message: "Provider config archives are disabled for this worker."
22416
23033
  });
22417
23034
  }
22418
- const { provider } = providerParamSchema2.parse(request.params);
22419
- return app.services.providerHostConfigService.listArchives(provider);
23035
+ const { provider: provider2 } = providerParamSchema2.parse(request.params);
23036
+ return app.services.providerHostConfigService.listArchives(provider2);
22420
23037
  });
22421
23038
  app.post("/api/config/providers/:provider/archives", async (request) => {
22422
23039
  if (!app.services.config.managementRoutesEnabled) {
@@ -22425,13 +23042,13 @@ async function registerSystemRoutes(app) {
22425
23042
  message: "Provider config archives are disabled for this worker."
22426
23043
  });
22427
23044
  }
22428
- const { provider } = providerParamSchema2.parse(request.params);
23045
+ const { provider: provider2 } = providerParamSchema2.parse(request.params);
22429
23046
  const body = {};
22430
23047
  const parsedBody = createProviderHostConfigArchiveSchema.parse(request.body ?? {});
22431
23048
  if (parsedBody.label !== void 0) {
22432
23049
  body.label = parsedBody.label;
22433
23050
  }
22434
- return app.services.providerHostConfigService.createArchive(provider, body);
23051
+ return app.services.providerHostConfigService.createArchive(provider2, body);
22435
23052
  });
22436
23053
  app.patch("/api/config/providers/:provider/archives/:id", async (request) => {
22437
23054
  if (!app.services.config.managementRoutesEnabled) {
@@ -22480,7 +23097,7 @@ async function registerSystemRoutes(app) {
22480
23097
 
22481
23098
  // src/routes/threads.ts
22482
23099
  import fs17 from "fs/promises";
22483
- import path16 from "path";
23100
+ import path17 from "path";
22484
23101
  import { z as z5 } from "zod";
22485
23102
 
22486
23103
  // src/worker-identity.ts
@@ -22952,7 +23569,7 @@ async function registerThreadRoutes(app) {
22952
23569
  message: "Workspace was not found for this thread."
22953
23570
  });
22954
23571
  }
22955
- const candidatePath = path16.isAbsolute(query.path) ? query.path : path16.resolve(workspace.absPath, query.path);
23572
+ const candidatePath = path17.isAbsolute(query.path) ? query.path : path17.resolve(workspace.absPath, query.path);
22956
23573
  const requestedPath = await fs17.realpath(candidatePath).catch(() => null);
22957
23574
  if (!requestedPath) {
22958
23575
  throw new HttpError(404, {
@@ -22960,8 +23577,8 @@ async function registerThreadRoutes(app) {
22960
23577
  message: "Image file was not found."
22961
23578
  });
22962
23579
  }
22963
- const resolvedWorkspaceRoot = await fs17.realpath(app.services.config.workspaceRoot).catch(() => path16.resolve(app.services.config.workspaceRoot));
22964
- const workspacePrefix = resolvedWorkspaceRoot.endsWith(path16.sep) ? resolvedWorkspaceRoot : `${resolvedWorkspaceRoot}${path16.sep}`;
23580
+ const resolvedWorkspaceRoot = await fs17.realpath(app.services.config.workspaceRoot).catch(() => path17.resolve(app.services.config.workspaceRoot));
23581
+ const workspacePrefix = resolvedWorkspaceRoot.endsWith(path17.sep) ? resolvedWorkspaceRoot : `${resolvedWorkspaceRoot}${path17.sep}`;
22965
23582
  if (requestedPath !== resolvedWorkspaceRoot && !requestedPath.startsWith(workspacePrefix)) {
22966
23583
  throw new HttpError(403, {
22967
23584
  code: "forbidden",
@@ -23157,7 +23774,9 @@ async function registerThreadRoutes(app) {
23157
23774
 
23158
23775
  // src/routes/workspaces.ts
23159
23776
  import fs18 from "fs/promises";
23160
- import path17 from "path";
23777
+ import { createReadStream } from "fs";
23778
+ import os3 from "os";
23779
+ import path18 from "path";
23161
23780
  import { spawn as spawn3 } from "child_process";
23162
23781
  import { Readable } from "stream";
23163
23782
  import { z as z6 } from "zod";
@@ -23214,6 +23833,8 @@ var workspacePreviewQuerySchema = z6.object({
23214
23833
  });
23215
23834
  var PREVIEW_DEFAULT_LIMIT_BYTES = 5e4;
23216
23835
  var WORKSPACE_UPLOAD_MAX_BYTES = 50 * 1024 * 1024;
23836
+ var WORKSPACE_FOLDER_DOWNLOAD_MAX_BYTES = 100 * 1024 * 1024;
23837
+ var WORKSPACE_FOLDER_DOWNLOAD_MAX_FILES = 300;
23217
23838
  var WORKSPACE_TREE_IGNORED_NAMES = /* @__PURE__ */ new Set([
23218
23839
  ".git",
23219
23840
  "node_modules",
@@ -23243,7 +23864,7 @@ function toWorkspaceFileDto(file) {
23243
23864
  };
23244
23865
  }
23245
23866
  function languageForPath(filePath) {
23246
- const extension = path17.extname(filePath).slice(1).toLowerCase();
23867
+ const extension = path18.extname(filePath).slice(1).toLowerCase();
23247
23868
  switch (extension) {
23248
23869
  case "js":
23249
23870
  case "jsx":
@@ -23289,18 +23910,18 @@ function languageForPath(filePath) {
23289
23910
  }
23290
23911
  }
23291
23912
  function relativeWorkspacePath(rootPath, absPath) {
23292
- const relative = path17.relative(rootPath, absPath);
23293
- return relative === "" ? "" : relative.split(path17.sep).join("/");
23913
+ const relative = path18.relative(rootPath, absPath);
23914
+ return relative === "" ? "" : relative.split(path18.sep).join("/");
23294
23915
  }
23295
23916
  async function resolveWorkspaceItemPath(rootPath, relativePath = "") {
23296
- const candidate = path17.resolve(rootPath, relativePath || ".");
23917
+ const candidate = path18.resolve(rootPath, relativePath || ".");
23297
23918
  const comparable = await assertPathWithinRoot(rootPath, candidate);
23298
23919
  return comparable;
23299
23920
  }
23300
23921
  async function buildWorkspaceTreeNode(rootPath, absPath, depth = 0) {
23301
23922
  const stats = await fs18.stat(absPath);
23302
23923
  const relativePath = relativeWorkspacePath(rootPath, absPath);
23303
- const name = relativePath ? path17.basename(absPath) : path17.basename(rootPath);
23924
+ const name = relativePath ? path18.basename(absPath) : path18.basename(rootPath);
23304
23925
  if (!stats.isDirectory()) {
23305
23926
  return {
23306
23927
  name,
@@ -23335,7 +23956,7 @@ async function buildWorkspaceTreeNode(rootPath, absPath, depth = 0) {
23335
23956
  }).slice(0, 400);
23336
23957
  node.children = (await Promise.all(
23337
23958
  visible.map(async (entry) => {
23338
- const childPath = path17.join(absPath, entry.name);
23959
+ const childPath = path18.join(absPath, entry.name);
23339
23960
  try {
23340
23961
  if (!entry.isDirectory() && !entry.isFile()) {
23341
23962
  return null;
@@ -23359,19 +23980,19 @@ function requireWorkspaceRecord(app, workspaceId) {
23359
23980
  return record;
23360
23981
  }
23361
23982
  function artifactRoot(record) {
23362
- return path17.join(record.absPath, ".remote-codex", "artifacts");
23983
+ return path18.join(record.absPath, ".remote-codex", "artifacts");
23363
23984
  }
23364
23985
  function artifactFilePath(record, artifactId) {
23365
- return path17.join(artifactRoot(record), artifactId, "artifact.bin");
23986
+ return path18.join(artifactRoot(record), artifactId, "artifact.bin");
23366
23987
  }
23367
23988
  function artifactMetadataPath(record, artifactId) {
23368
- return path17.join(artifactRoot(record), artifactId, "metadata.json");
23989
+ return path18.join(artifactRoot(record), artifactId, "metadata.json");
23369
23990
  }
23370
23991
  function safeArtifactFileName(value) {
23371
- return path17.basename(value).replace(/[^a-zA-Z0-9_. -]/g, "_") || "artifact.bin";
23992
+ return path18.basename(value).replace(/[^a-zA-Z0-9_. -]/g, "_") || "artifact.bin";
23372
23993
  }
23373
23994
  function artifactIdFromName(name) {
23374
- const base = path17.basename(name).replace(/[^a-zA-Z0-9_.-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 96);
23995
+ const base = path18.basename(name).replace(/[^a-zA-Z0-9_.-]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 96);
23375
23996
  return `${base || "artifact"}-${Date.now().toString(36)}`;
23376
23997
  }
23377
23998
  async function readArtifactMetadata(record, artifactId) {
@@ -23414,7 +24035,7 @@ async function listWorkspaceArtifacts(record) {
23414
24035
  return artifacts.sort((left, right) => right.createdAt.localeCompare(left.createdAt));
23415
24036
  }
23416
24037
  function contentTypeForPath(filePath) {
23417
- switch (path17.extname(filePath).slice(1).toLowerCase()) {
24038
+ switch (path18.extname(filePath).slice(1).toLowerCase()) {
23418
24039
  case "png":
23419
24040
  return "image/png";
23420
24041
  case "jpg":
@@ -23443,8 +24064,135 @@ function contentTypeForPath(filePath) {
23443
24064
  return "application/octet-stream";
23444
24065
  }
23445
24066
  }
24067
+ async function collectFolderZipEntries(rootPath, folderPath) {
24068
+ const folderName = path18.basename(folderPath) || "workspace-folder";
24069
+ const entries = [];
24070
+ let totalBytes = 0;
24071
+ const pending = [folderPath];
24072
+ while (pending.length > 0) {
24073
+ const current = pending.pop();
24074
+ const children = await fs18.readdir(current, { withFileTypes: true });
24075
+ for (const child of children) {
24076
+ const childPath = await resolveWorkspaceItemPath(rootPath, path18.relative(rootPath, path18.join(current, child.name)));
24077
+ if (child.isDirectory()) {
24078
+ pending.push(childPath);
24079
+ continue;
24080
+ }
24081
+ if (!child.isFile()) {
24082
+ continue;
24083
+ }
24084
+ const stats = await fs18.stat(childPath);
24085
+ totalBytes += stats.size;
24086
+ entries.push({
24087
+ absPath: childPath,
24088
+ archivePath: `${folderName}/${relativeWorkspacePath(folderPath, childPath)}`,
24089
+ size: stats.size,
24090
+ updatedAt: stats.mtime
24091
+ });
24092
+ if (entries.length >= WORKSPACE_FOLDER_DOWNLOAD_MAX_FILES) {
24093
+ throw new HttpError(400, {
24094
+ code: "bad_request",
24095
+ message: "Folder downloads must contain fewer than 300 files."
24096
+ });
24097
+ }
24098
+ if (totalBytes >= WORKSPACE_FOLDER_DOWNLOAD_MAX_BYTES) {
24099
+ throw new HttpError(400, {
24100
+ code: "bad_request",
24101
+ message: "Folder downloads must be smaller than 100 MB."
24102
+ });
24103
+ }
24104
+ }
24105
+ }
24106
+ return entries.sort((left, right) => left.archivePath.localeCompare(right.archivePath));
24107
+ }
24108
+ var crc32Table = new Uint32Array(256);
24109
+ for (let index = 0; index < 256; index += 1) {
24110
+ let value = index;
24111
+ for (let bit = 0; bit < 8; bit += 1) {
24112
+ value = value & 1 ? 3988292384 ^ value >>> 1 : value >>> 1;
24113
+ }
24114
+ crc32Table[index] = value >>> 0;
24115
+ }
24116
+ function crc32(buffer) {
24117
+ let value = 4294967295;
24118
+ for (const byte of buffer) {
24119
+ value = crc32Table[(value ^ byte) & 255] ^ value >>> 8;
24120
+ }
24121
+ return (value ^ 4294967295) >>> 0;
24122
+ }
24123
+ function zipDosDateTime(updatedAt) {
24124
+ const year = Math.max(1980, updatedAt.getFullYear());
24125
+ const dosTime = updatedAt.getHours() << 11 | updatedAt.getMinutes() << 5 | Math.floor(updatedAt.getSeconds() / 2);
24126
+ const dosDate = year - 1980 << 9 | updatedAt.getMonth() + 1 << 5 | updatedAt.getDate();
24127
+ return { dosDate, dosTime };
24128
+ }
24129
+ async function createFolderZipFile(rootPath, folderPath) {
24130
+ const entries = await collectFolderZipEntries(rootPath, folderPath);
24131
+ const localParts = [];
24132
+ const centralParts = [];
24133
+ let offset = 0;
24134
+ for (const entry of entries) {
24135
+ const data = await fs18.readFile(entry.absPath);
24136
+ const name = Buffer.from(entry.archivePath.split(path18.sep).join("/"), "utf8");
24137
+ const checksum = crc32(data);
24138
+ const { dosDate, dosTime } = zipDosDateTime(entry.updatedAt);
24139
+ const localHeader = Buffer.alloc(30);
24140
+ localHeader.writeUInt32LE(67324752, 0);
24141
+ localHeader.writeUInt16LE(20, 4);
24142
+ localHeader.writeUInt16LE(0, 6);
24143
+ localHeader.writeUInt16LE(0, 8);
24144
+ localHeader.writeUInt16LE(dosTime, 10);
24145
+ localHeader.writeUInt16LE(dosDate, 12);
24146
+ localHeader.writeUInt32LE(checksum, 14);
24147
+ localHeader.writeUInt32LE(data.length, 18);
24148
+ localHeader.writeUInt32LE(data.length, 22);
24149
+ localHeader.writeUInt16LE(name.length, 26);
24150
+ localHeader.writeUInt16LE(0, 28);
24151
+ localParts.push(localHeader, name, data);
24152
+ const centralHeader = Buffer.alloc(46);
24153
+ centralHeader.writeUInt32LE(33639248, 0);
24154
+ centralHeader.writeUInt16LE(20, 4);
24155
+ centralHeader.writeUInt16LE(20, 6);
24156
+ centralHeader.writeUInt16LE(0, 8);
24157
+ centralHeader.writeUInt16LE(0, 10);
24158
+ centralHeader.writeUInt16LE(dosTime, 12);
24159
+ centralHeader.writeUInt16LE(dosDate, 14);
24160
+ centralHeader.writeUInt32LE(checksum, 16);
24161
+ centralHeader.writeUInt32LE(data.length, 20);
24162
+ centralHeader.writeUInt32LE(data.length, 24);
24163
+ centralHeader.writeUInt16LE(name.length, 28);
24164
+ centralHeader.writeUInt16LE(0, 30);
24165
+ centralHeader.writeUInt16LE(0, 32);
24166
+ centralHeader.writeUInt16LE(0, 34);
24167
+ centralHeader.writeUInt16LE(0, 36);
24168
+ centralHeader.writeUInt32LE(0, 38);
24169
+ centralHeader.writeUInt32LE(offset, 42);
24170
+ centralParts.push(centralHeader, name);
24171
+ offset += localHeader.length + name.length + data.length;
24172
+ }
24173
+ const centralSize = centralParts.reduce((sum, part) => sum + part.length, 0);
24174
+ const endRecord = Buffer.alloc(22);
24175
+ endRecord.writeUInt32LE(101010256, 0);
24176
+ endRecord.writeUInt16LE(0, 4);
24177
+ endRecord.writeUInt16LE(0, 6);
24178
+ endRecord.writeUInt16LE(entries.length, 8);
24179
+ endRecord.writeUInt16LE(entries.length, 10);
24180
+ endRecord.writeUInt32LE(centralSize, 12);
24181
+ endRecord.writeUInt32LE(offset, 16);
24182
+ endRecord.writeUInt16LE(0, 20);
24183
+ const tempDir = await fs18.mkdtemp(path18.join(os3.tmpdir(), "remote-codex-folder-download-"));
24184
+ const zipPath = path18.join(tempDir, `${path18.basename(folderPath) || "workspace-folder"}.zip`);
24185
+ await fs18.writeFile(zipPath, Buffer.concat([...localParts, ...centralParts, endRecord]));
24186
+ return { zipPath, tempDir };
24187
+ }
24188
+ function cleanupTemporaryZip(zipPath, tempDir) {
24189
+ return async () => {
24190
+ await fs18.rm(zipPath, { force: true }).catch(() => void 0);
24191
+ await fs18.rm(tempDir, { recursive: true, force: true }).catch(() => void 0);
24192
+ };
24193
+ }
23446
24194
  function sanitizeUploadFilename(filename) {
23447
- const baseName = path17.basename(filename?.trim() || "upload");
24195
+ const baseName = path18.basename(filename?.trim() || "upload");
23448
24196
  if (!baseName || baseName === "." || baseName === "..") {
23449
24197
  return "upload";
23450
24198
  }
@@ -23456,7 +24204,7 @@ function inferGitRepoName(gitUrl) {
23456
24204
  const normalized = withoutQuery.replace(/[\\/]+$/, "");
23457
24205
  const rawName = normalized.split(/[/:]/).filter(Boolean).at(-1) ?? "";
23458
24206
  const repoName = rawName.endsWith(".git") ? rawName.slice(0, -4) : rawName;
23459
- if (!repoName || repoName === "." || repoName === ".." || repoName.includes(path17.sep)) {
24207
+ if (!repoName || repoName === "." || repoName === ".." || repoName.includes(path18.sep)) {
23460
24208
  throw new HttpError(400, {
23461
24209
  code: "bad_request",
23462
24210
  message: "Unable to infer a target directory from the Git URL."
@@ -23521,7 +24269,7 @@ async function registerWorkspaceRoutes(app) {
23521
24269
  });
23522
24270
  app.get("/api/workspaces/tree", async (request) => {
23523
24271
  const query = treeQuerySchema.parse(request.query);
23524
- const requestedPath = query.path ? path17.resolve(query.path) : app.services.config.workspaceRoot;
24272
+ const requestedPath = query.path ? path18.resolve(query.path) : app.services.config.workspaceRoot;
23525
24273
  const tree = await readWorkspaceTree({
23526
24274
  rootPath: app.services.config.workspaceRoot,
23527
24275
  targetPath: requestedPath,
@@ -23587,7 +24335,7 @@ async function registerWorkspaceRoutes(app) {
23587
24335
  const nextOffset = offset + read.bytesRead;
23588
24336
  return {
23589
24337
  path: relativeWorkspacePath(rootPath, filePath),
23590
- name: path17.basename(filePath),
24338
+ name: path18.basename(filePath),
23591
24339
  content: buffer.subarray(0, read.bytesRead).toString("utf8"),
23592
24340
  language: languageForPath(filePath),
23593
24341
  size: stats.size,
@@ -23621,13 +24369,25 @@ async function registerWorkspaceRoutes(app) {
23621
24369
  const rootPath = await fs18.realpath(record.absPath);
23622
24370
  const itemPath = await resolveWorkspaceItemPath(rootPath, query.path);
23623
24371
  const stats = await fs18.stat(itemPath);
24372
+ if (stats.isDirectory()) {
24373
+ const { zipPath, tempDir } = await createFolderZipFile(rootPath, itemPath);
24374
+ const filename2 = `${path18.basename(itemPath) || "workspace-folder"}.zip`;
24375
+ const cleanup = cleanupTemporaryZip(zipPath, tempDir);
24376
+ reply.raw.once("finish", () => void cleanup());
24377
+ reply.raw.once("close", () => void cleanup());
24378
+ reply.header("content-type", "application/zip").header(
24379
+ "content-disposition",
24380
+ `attachment; filename="${filename2}"; filename*=UTF-8''${encodeURIComponent(filename2)}`
24381
+ );
24382
+ return reply.send(createReadStream(zipPath));
24383
+ }
23624
24384
  if (!stats.isFile()) {
23625
24385
  throw new HttpError(400, {
23626
24386
  code: "bad_request",
23627
- message: "Only file downloads are supported from this endpoint."
24387
+ message: "Only file and folder downloads are supported from this endpoint."
23628
24388
  });
23629
24389
  }
23630
- const filename = path17.basename(itemPath);
24390
+ const filename = path18.basename(itemPath);
23631
24391
  reply.header("content-type", contentTypeForPath(itemPath)).header(
23632
24392
  "content-disposition",
23633
24393
  `attachment; filename="${filename}"; filename*=UTF-8''${encodeURIComponent(filename)}`
@@ -23693,7 +24453,7 @@ async function registerWorkspaceRoutes(app) {
23693
24453
  kind: "file",
23694
24454
  file: {
23695
24455
  path: file.path,
23696
- name: path17.basename(file.path),
24456
+ name: path18.basename(file.path),
23697
24457
  size: file.size
23698
24458
  }
23699
24459
  };
@@ -23735,7 +24495,7 @@ async function registerWorkspaceRoutes(app) {
23735
24495
  message: "Artifact content must not be empty."
23736
24496
  });
23737
24497
  }
23738
- const dir = path17.dirname(artifactFilePath(record, artifactId));
24498
+ const dir = path18.dirname(artifactFilePath(record, artifactId));
23739
24499
  await fs18.mkdir(dir, { recursive: true, mode: 448 });
23740
24500
  const filePath = artifactFilePath(record, artifactId);
23741
24501
  await fs18.writeFile(filePath, content, { flag: "wx" }).catch((error) => {
@@ -23798,7 +24558,7 @@ async function registerWorkspaceRoutes(app) {
23798
24558
  const params = z6.object({ id: z6.string().uuid(), artifactId: workspaceArtifactIdSchema }).parse(request.params);
23799
24559
  const record = requireWorkspaceRecord(app, params.id);
23800
24560
  const artifact = await readArtifactMetadata(record, params.artifactId);
23801
- await fs18.rm(path17.dirname(artifactFilePath(record, params.artifactId)), {
24561
+ await fs18.rm(path18.dirname(artifactFilePath(record, params.artifactId)), {
23802
24562
  recursive: true,
23803
24563
  force: true
23804
24564
  });
@@ -23813,7 +24573,7 @@ async function registerWorkspaceRoutes(app) {
23813
24573
  let validated;
23814
24574
  if ("gitUrl" in body) {
23815
24575
  const repoName = inferGitRepoName(body.gitUrl);
23816
- const targetPath = path17.join(settings.devHome, repoName);
24576
+ const targetPath = path18.join(settings.devHome, repoName);
23817
24577
  if (await pathExists4(targetPath)) {
23818
24578
  throw new HttpError(409, {
23819
24579
  code: "conflict",
@@ -24077,7 +24837,7 @@ async function registerAuthRoutes(app) {
24077
24837
 
24078
24838
  // src/provider-host-config-service.ts
24079
24839
  import fs19 from "fs/promises";
24080
- import path18 from "path";
24840
+ import path19 from "path";
24081
24841
  import { randomUUID as randomUUID4 } from "crypto";
24082
24842
  function providerError(message, statusCode = 404) {
24083
24843
  const error = new Error(message);
@@ -24085,16 +24845,16 @@ function providerError(message, statusCode = 404) {
24085
24845
  return error;
24086
24846
  }
24087
24847
  function resolveProviderHostFilePath(providerHome, name) {
24088
- return path18.join(providerHome, name);
24848
+ return path19.join(providerHome, name);
24089
24849
  }
24090
24850
  function resolveArchiveRoot(providerHome) {
24091
- return path18.join(providerHome, "supervisor-config-archives");
24851
+ return path19.join(providerHome, "supervisor-config-archives");
24092
24852
  }
24093
24853
  function resolveArchiveIndexPath(providerHome) {
24094
- return path18.join(resolveArchiveRoot(providerHome), "index.json");
24854
+ return path19.join(resolveArchiveRoot(providerHome), "index.json");
24095
24855
  }
24096
24856
  function resolveArchivePath(providerHome, archiveId) {
24097
- return path18.join(resolveArchiveRoot(providerHome), archiveId);
24857
+ return path19.join(resolveArchiveRoot(providerHome), archiveId);
24098
24858
  }
24099
24859
  function defaultArchiveLabel(createdAt) {
24100
24860
  return `Backup ${createdAt.replace("T", " ").replace(/\.\d{3}Z$/, " UTC")}`;
@@ -24147,44 +24907,44 @@ var ProviderHostConfigService = class {
24147
24907
  }
24148
24908
  agentRuntimes;
24149
24909
  providerHomes;
24150
- runtime(provider) {
24151
- const runtime = this.agentRuntimes.getOptional(provider);
24910
+ runtime(provider2) {
24911
+ const runtime = this.agentRuntimes.getOptional(provider2);
24152
24912
  if (!runtime) {
24153
- throw providerError(`Agent runtime provider is not configured: ${provider}`);
24913
+ throw providerError(`Agent runtime provider is not configured: ${provider2}`);
24154
24914
  }
24155
24915
  return runtime;
24156
24916
  }
24157
- providerHome(provider) {
24158
- const home = this.providerHomes[provider];
24917
+ providerHome(provider2) {
24918
+ const home = this.providerHomes[provider2];
24159
24919
  if (!home) {
24160
24920
  throw providerError("This backend does not expose host config files.");
24161
24921
  }
24162
24922
  return home;
24163
24923
  }
24164
- hostFileNames(provider) {
24165
- const runtime = this.runtime(provider);
24924
+ hostFileNames(provider2) {
24925
+ const runtime = this.runtime(provider2);
24166
24926
  if (!runtime.capabilities.management.hostConfigFiles) {
24167
24927
  throw providerError("This backend does not expose host config files.");
24168
24928
  }
24169
24929
  return runtime.managementSchema.hostConfigFiles.map((file) => file.name);
24170
24930
  }
24171
- assertHostFile(provider, name) {
24172
- const fileNames = this.hostFileNames(provider);
24931
+ assertHostFile(provider2, name) {
24932
+ const fileNames = this.hostFileNames(provider2);
24173
24933
  if (!fileNames.includes(name)) {
24174
24934
  throw providerError("Host config file is not exposed by this backend.", 400);
24175
24935
  }
24176
24936
  return name;
24177
24937
  }
24178
- archiveFileNames(provider) {
24179
- const runtime = this.runtime(provider);
24938
+ archiveFileNames(provider2) {
24939
+ const runtime = this.runtime(provider2);
24180
24940
  if (!runtime.managementSchema.configArchives) {
24181
24941
  throw providerError("This backend does not support config archives.");
24182
24942
  }
24183
- return this.hostFileNames(provider);
24943
+ return this.hostFileNames(provider2);
24184
24944
  }
24185
- async readFile(provider, name) {
24186
- const providerHome = this.providerHome(provider);
24187
- const fileName = this.assertHostFile(provider, name);
24945
+ async readFile(provider2, name) {
24946
+ const providerHome = this.providerHome(provider2);
24947
+ const fileName = this.assertHostFile(provider2, name);
24188
24948
  const filePath = resolveProviderHostFilePath(providerHome, fileName);
24189
24949
  try {
24190
24950
  const content = await fs19.readFile(filePath, "utf8");
@@ -24206,25 +24966,25 @@ var ProviderHostConfigService = class {
24206
24966
  };
24207
24967
  }
24208
24968
  }
24209
- async updateFile(provider, name, input) {
24210
- const providerHome = this.providerHome(provider);
24211
- const fileName = this.assertHostFile(provider, name);
24969
+ async updateFile(provider2, name, input) {
24970
+ const providerHome = this.providerHome(provider2);
24971
+ const fileName = this.assertHostFile(provider2, name);
24212
24972
  const filePath = resolveProviderHostFilePath(providerHome, fileName);
24213
- await fs19.mkdir(path18.dirname(filePath), { recursive: true });
24973
+ await fs19.mkdir(path19.dirname(filePath), { recursive: true });
24214
24974
  await fs19.writeFile(filePath, input.content, "utf8");
24215
- return this.readFile(provider, fileName);
24975
+ return this.readFile(provider2, fileName);
24216
24976
  }
24217
- async listArchives(provider) {
24218
- const runtime = this.runtime(provider);
24977
+ async listArchives(provider2) {
24978
+ const runtime = this.runtime(provider2);
24219
24979
  if (!runtime.managementSchema.configArchives) {
24220
24980
  return [];
24221
24981
  }
24222
- const index = await readArchiveIndex(this.providerHome(provider));
24982
+ const index = await readArchiveIndex(this.providerHome(provider2));
24223
24983
  return index.archives;
24224
24984
  }
24225
- async createArchive(provider, input) {
24226
- const providerHome = this.providerHome(provider);
24227
- const fileNames = this.archiveFileNames(provider);
24985
+ async createArchive(provider2, input) {
24986
+ const providerHome = this.providerHome(provider2);
24987
+ const fileNames = this.archiveFileNames(provider2);
24228
24988
  const createdAt = (/* @__PURE__ */ new Date()).toISOString();
24229
24989
  const id = `${createdAt.replace(/[-:.TZ]/g, "").slice(0, 14)}-${randomUUID4().slice(0, 8)}`;
24230
24990
  const archivePath = resolveArchivePath(providerHome, id);
@@ -24239,13 +24999,13 @@ var ProviderHostConfigService = class {
24239
24999
  );
24240
25000
  await fs19.mkdir(archivePath, { recursive: true });
24241
25001
  for (const name of fileNames) {
24242
- const hostFile = await this.readFile(provider, name);
25002
+ const hostFile = await this.readFile(provider2, name);
24243
25003
  files[name] = {
24244
25004
  name,
24245
25005
  exists: hostFile.exists
24246
25006
  };
24247
25007
  if (hostFile.exists) {
24248
- await fs19.writeFile(path18.join(archivePath, name), hostFile.content, "utf8");
25008
+ await fs19.writeFile(path19.join(archivePath, name), hostFile.content, "utf8");
24249
25009
  }
24250
25010
  }
24251
25011
  const archive = {
@@ -24261,9 +25021,9 @@ var ProviderHostConfigService = class {
24261
25021
  });
24262
25022
  return archive;
24263
25023
  }
24264
- async renameArchive(provider, id, input) {
24265
- const providerHome = this.providerHome(provider);
24266
- this.archiveFileNames(provider);
25024
+ async renameArchive(provider2, id, input) {
25025
+ const providerHome = this.providerHome(provider2);
25026
+ this.archiveFileNames(provider2);
24267
25027
  const { index, archive } = await findArchiveOrThrow(providerHome, id);
24268
25028
  const updated = {
24269
25029
  ...archive,
@@ -24275,17 +25035,17 @@ var ProviderHostConfigService = class {
24275
25035
  });
24276
25036
  return updated;
24277
25037
  }
24278
- async applyArchive(provider, id) {
24279
- const runtime = this.runtime(provider);
24280
- const providerHome = this.providerHome(provider);
24281
- const fileNames = this.archiveFileNames(provider);
25038
+ async applyArchive(provider2, id) {
25039
+ const runtime = this.runtime(provider2);
25040
+ const providerHome = this.providerHome(provider2);
25041
+ const fileNames = this.archiveFileNames(provider2);
24282
25042
  const { archive } = await findArchiveOrThrow(providerHome, id);
24283
25043
  const archivePath = resolveArchivePath(providerHome, archive.id);
24284
25044
  await fs19.mkdir(providerHome, { recursive: true });
24285
25045
  for (const name of fileNames) {
24286
25046
  const hostPath = resolveProviderHostFilePath(providerHome, name);
24287
25047
  if (archive.files[name]?.exists) {
24288
- const content = await fs19.readFile(path18.join(archivePath, name), "utf8");
25048
+ const content = await fs19.readFile(path19.join(archivePath, name), "utf8");
24289
25049
  await fs19.writeFile(hostPath, content, "utf8");
24290
25050
  } else {
24291
25051
  await fs19.rm(hostPath, { force: true });
@@ -24305,8 +25065,8 @@ import fs21 from "fs/promises";
24305
25065
 
24306
25066
  // src/shell/shell-prompt.ts
24307
25067
  import fs20 from "fs/promises";
24308
- import os3 from "os";
24309
- import path19 from "path";
25068
+ import os4 from "os";
25069
+ import path20 from "path";
24310
25070
  function basenameFromPath2(filePath) {
24311
25071
  if (!filePath) {
24312
25072
  return "";
@@ -24315,7 +25075,7 @@ function basenameFromPath2(filePath) {
24315
25075
  if (!normalized) {
24316
25076
  return "";
24317
25077
  }
24318
- return path19.basename(normalized) || normalized;
25078
+ return path20.basename(normalized) || normalized;
24319
25079
  }
24320
25080
  function isInteractiveShellCommand(command) {
24321
25081
  const normalized = (command ?? "").trim().toLowerCase();
@@ -24476,8 +25236,8 @@ function buildShellPromptInitScriptContents(command) {
24476
25236
  async function ensureShellPromptInitScript(command) {
24477
25237
  const normalized = command.trim().toLowerCase();
24478
25238
  const extension = normalized === "zsh" ? "zsh" : "sh";
24479
- const filePath = path19.join(
24480
- os3.tmpdir(),
25239
+ const filePath = path20.join(
25240
+ os4.tmpdir(),
24481
25241
  `remote-codex-shell-prompt.${extension}`
24482
25242
  );
24483
25243
  await fs20.writeFile(filePath, buildShellPromptInitScriptContents(command), "utf8");
@@ -25100,7 +25860,7 @@ var terminalPluginManifest = {
25100
25860
  }
25101
25861
  };
25102
25862
 
25103
- // ../../packages/plugin-xyz-viewer/src/manifest.ts
25863
+ // ../../node_modules/.pnpm/@remote-codex+plugin-xyz-viewer@file+..+remote-codex-thread-ui+packages+plugin-xyz-view_5227bf80a742872b523d08ba646669ff/node_modules/@remote-codex/plugin-xyz-viewer/dist/chunk-6FS7BLJV.js
25104
25864
  var XYZ_MOLECULE_ARTIFACT_TYPE = "chemistry.molecule3d";
25105
25865
  var xyzViewerPluginManifest = {
25106
25866
  id: "remote-codex.xyz-viewer",
@@ -25159,7 +25919,7 @@ var builtinPlugins = [
25159
25919
 
25160
25920
  // src/plugins/plugin-service.ts
25161
25921
  import fs22 from "fs/promises";
25162
- import path20 from "path";
25922
+ import path21 from "path";
25163
25923
  var MANAGED_CODEX_MCP_BEGIN = "# BEGIN remote-codex managed plugin MCP servers";
25164
25924
  var MANAGED_CODEX_MCP_END = "# END remote-codex managed plugin MCP servers";
25165
25925
  var REMOTE_CODEX_MOLECULE_MCP_TOOL_NAME = "remote_codex_render_molecule";
@@ -25171,7 +25931,7 @@ function normalizeManagedCommand(server, repoRoot) {
25171
25931
  if (server.name === "remote_codex_plugins") {
25172
25932
  return {
25173
25933
  command: process.execPath,
25174
- args: [path20.join(repoRoot, "bin", "remote-codex-plugin-mcp.mjs")]
25934
+ args: [path21.join(repoRoot, "bin", "remote-codex-plugin-mcp.mjs")]
25175
25935
  };
25176
25936
  }
25177
25937
  return {
@@ -25358,7 +26118,7 @@ var PluginService = class {
25358
26118
  if (!input.codexHome) {
25359
26119
  return;
25360
26120
  }
25361
- const configPath = path20.join(input.codexHome, "config.toml");
26121
+ const configPath = path21.join(input.codexHome, "config.toml");
25362
26122
  let current = "";
25363
26123
  try {
25364
26124
  current = await fs22.readFile(configPath, "utf8");
@@ -25376,7 +26136,7 @@ var PluginService = class {
25376
26136
  if (next === current) {
25377
26137
  return;
25378
26138
  }
25379
- await fs22.mkdir(path20.dirname(configPath), { recursive: true });
26139
+ await fs22.mkdir(path21.dirname(configPath), { recursive: true });
25380
26140
  await fs22.writeFile(configPath, next, "utf8");
25381
26141
  }
25382
26142
  async importPlugin(input) {
@@ -25617,7 +26377,7 @@ var PluginSettingsStore = class {
25617
26377
 
25618
26378
  // src/worker-bootstrap.ts
25619
26379
  import fs23 from "fs/promises";
25620
- import path21 from "path";
26380
+ import path22 from "path";
25621
26381
  function trimTrailingSlash(value) {
25622
26382
  return value.replace(/\/+$/, "");
25623
26383
  }
@@ -25628,7 +26388,7 @@ function tomlString(value) {
25628
26388
  return JSON.stringify(value);
25629
26389
  }
25630
26390
  async function writePrivateFile(filePath, content) {
25631
- await fs23.mkdir(path21.dirname(filePath), { recursive: true, mode: 448 });
26391
+ await fs23.mkdir(path22.dirname(filePath), { recursive: true, mode: 448 });
25632
26392
  await fs23.writeFile(filePath, content, { encoding: "utf8", mode: 384 });
25633
26393
  await fs23.chmod(filePath, 384);
25634
26394
  }
@@ -25644,7 +26404,7 @@ async function configureWorkerProviderGateway(config) {
25644
26404
  process.env.ANTHROPIC_BASE_URL = anthropicBaseUrl;
25645
26405
  if (config.agentProviders.codex.enabled) {
25646
26406
  await writePrivateFile(
25647
- path21.join(config.agentProviders.codex.home, "config.toml"),
26407
+ path22.join(config.agentProviders.codex.home, "config.toml"),
25648
26408
  [
25649
26409
  'model_provider = "sub2api"',
25650
26410
  'forced_login_method = "api"',
@@ -25660,7 +26420,7 @@ async function configureWorkerProviderGateway(config) {
25660
26420
  ].join("\n")
25661
26421
  );
25662
26422
  await writePrivateFile(
25663
- path21.join(config.agentProviders.codex.home, "auth.json"),
26423
+ path22.join(config.agentProviders.codex.home, "auth.json"),
25664
26424
  `${JSON.stringify(
25665
26425
  {
25666
26426
  OPENAI_API_KEY: config.llmGatewayToken
@@ -25673,7 +26433,7 @@ async function configureWorkerProviderGateway(config) {
25673
26433
  }
25674
26434
  if (config.agentProviders.claude.enabled) {
25675
26435
  await writePrivateFile(
25676
- path21.join(config.agentProviders.claude.home, "settings.json"),
26436
+ path22.join(config.agentProviders.claude.home, "settings.json"),
25677
26437
  `${JSON.stringify(
25678
26438
  {
25679
26439
  env: {
@@ -25689,7 +26449,7 @@ async function configureWorkerProviderGateway(config) {
25689
26449
  }
25690
26450
  if (config.agentProviders.opencode.enabled) {
25691
26451
  await writePrivateFile(
25692
- path21.join(config.agentProviders.opencode.home, "opencode.json"),
26452
+ path22.join(config.agentProviders.opencode.home, "opencode.json"),
25693
26453
  `${JSON.stringify(
25694
26454
  {
25695
26455
  provider: {
@@ -25736,7 +26496,7 @@ var BackendPluginHost = class {
25736
26496
  };
25737
26497
 
25738
26498
  // src/shell/pty-shell-backend.ts
25739
- import path22 from "path";
26499
+ import path23 from "path";
25740
26500
  import { spawn as spawn4 } from "@homebridge/node-pty-prebuilt-multiarch";
25741
26501
 
25742
26502
  // src/shell/default-shell.ts
@@ -25756,7 +26516,7 @@ function resolveDefaultShell(env = process.env) {
25756
26516
  var MAX_SCROLLBACK_BYTES = 512 * 1024;
25757
26517
  var ANSI_ESCAPE_PATTERN = new RegExp(String.raw`\u001B\[[0-?]*[ -/]*[@-~]`, "g");
25758
26518
  function shellArgs(shell) {
25759
- const shellName = path22.basename(shell).toLowerCase();
26519
+ const shellName = path23.basename(shell).toLowerCase();
25760
26520
  if (process.platform === "win32") {
25761
26521
  return [];
25762
26522
  }
@@ -25778,7 +26538,7 @@ function lastVisibleLine(snapshot) {
25778
26538
  }
25779
26539
  function inferRuntime(session) {
25780
26540
  const promptLine = lastVisibleLine(session.scrollback);
25781
- const shell = path22.basename(session.shell);
26541
+ const shell = path23.basename(session.shell);
25782
26542
  const isCommandRunning = session.exitCode !== null ? false : !/[$#>]\s*$/.test(promptLine.trimEnd());
25783
26543
  return {
25784
26544
  panePid: session.pty.pid,
@@ -25925,7 +26685,7 @@ var PtyShellBackend = class {
25925
26685
 
25926
26686
  // src/shell/tmux-manager.ts
25927
26687
  import fs25 from "fs";
25928
- import path23 from "path";
26688
+ import path24 from "path";
25929
26689
  import { spawn as spawnChild } from "child_process";
25930
26690
  async function defaultExecCommand(command, args) {
25931
26691
  return await new Promise((resolve, reject) => {
@@ -25952,16 +26712,16 @@ async function defaultExecCommand(command, args) {
25952
26712
  });
25953
26713
  }
25954
26714
  function resolveExecutablePath(command) {
25955
- if (command.includes(path23.sep)) {
26715
+ if (command.includes(path24.sep)) {
25956
26716
  return command;
25957
26717
  }
25958
26718
  const searchPath = process.env.PATH ?? "";
25959
- for (const entry of searchPath.split(path23.delimiter)) {
26719
+ for (const entry of searchPath.split(path24.delimiter)) {
25960
26720
  const trimmed = entry.trim();
25961
26721
  if (!trimmed) {
25962
26722
  continue;
25963
26723
  }
25964
- const candidate = path23.join(trimmed, command);
26724
+ const candidate = path24.join(trimmed, command);
25965
26725
  if (fs25.existsSync(candidate)) {
25966
26726
  return candidate;
25967
26727
  }
@@ -26720,22 +27480,22 @@ function payloadItems(payload, fields) {
26720
27480
  const record = recordFrom(payload);
26721
27481
  return arrayField(record, fields) ?? (record ? [record] : []);
26722
27482
  }
26723
- function artifactPreviewKind(type, format, path25) {
27483
+ function artifactPreviewKind(type, format, path26) {
26724
27484
  const candidates = [
26725
27485
  type,
26726
27486
  format,
26727
- path25?.split(".").pop() ?? null
27487
+ path26?.split(".").pop() ?? null
26728
27488
  ].map((value) => value?.trim().toLowerCase()).filter(Boolean);
26729
27489
  return candidates.some((value) => MOLECULE_ARTIFACT_TYPES.has(value)) ? "molecule" : "file";
26730
27490
  }
26731
27491
  function normalizeArtifactRef(value) {
26732
27492
  const record = recordFrom(value);
26733
- const path25 = stringField3(record, ["path", "filePath", "file_path", "filename", "fileName", "name"]);
27493
+ const path26 = stringField3(record, ["path", "filePath", "file_path", "filename", "fileName", "name"]);
26734
27494
  const type = stringField3(record, ["type", "artifactType", "artifact_type", "format", "extension"]);
26735
- const title = stringField3(record, ["title", "label", "name", "filename", "fileName"]) ?? path25 ?? "artifact";
27495
+ const title = stringField3(record, ["title", "label", "name", "filename", "fileName"]) ?? path26 ?? "artifact";
26736
27496
  return {
26737
27497
  title,
26738
- path: path25,
27498
+ path: path26,
26739
27499
  type,
26740
27500
  downloadUrl: stringField3(record, ["downloadUrl", "download_url", "url", "href"])
26741
27501
  };
@@ -26769,21 +27529,21 @@ function normalizeArtifact(module, runId, value) {
26769
27529
  if (!record) {
26770
27530
  return null;
26771
27531
  }
26772
- const path25 = stringField3(record, ["path", "filePath", "file_path", "filename", "fileName", "name"]);
27532
+ const path26 = stringField3(record, ["path", "filePath", "file_path", "filename", "fileName", "name"]);
26773
27533
  const type = stringField3(record, ["type", "artifactType", "artifact_type"]);
26774
27534
  const format = stringField3(record, ["format", "fileFormat", "file_format", "extension"]) ?? type;
26775
- const title = stringField3(record, ["title", "label", "name", "filename", "fileName"]) ?? path25 ?? `${module} artifact`;
27535
+ const title = stringField3(record, ["title", "label", "name", "filename", "fileName"]) ?? path26 ?? `${module} artifact`;
26776
27536
  return {
26777
27537
  module,
26778
27538
  runId,
26779
27539
  title,
26780
- path: path25,
27540
+ path: path26,
26781
27541
  type,
26782
27542
  format,
26783
27543
  mimeType: stringField3(record, ["mimeType", "mime_type", "contentType", "content_type"]),
26784
27544
  sizeBytes: numberField2(record, ["sizeBytes", "size_bytes", "bytes"]),
26785
27545
  downloadUrl: stringField3(record, ["downloadUrl", "download_url", "url", "href"]),
26786
- previewKind: artifactPreviewKind(type, format, path25)
27546
+ previewKind: artifactPreviewKind(type, format, path26)
26787
27547
  };
26788
27548
  }
26789
27549
  function normalizeRuns(module, result) {
@@ -26910,9 +27670,9 @@ var WorkerHarnessClient = class {
26910
27670
  }
26911
27671
  return { baseUrl, apiKey };
26912
27672
  }
26913
- async fetchText(path25) {
27673
+ async fetchText(path26) {
26914
27674
  const config = this.requireHarnessConfig();
26915
- const response = await this.fetchImpl(`${config.baseUrl}${path25}`, {
27675
+ const response = await this.fetchImpl(`${config.baseUrl}${path26}`, {
26916
27676
  headers: {
26917
27677
  "x-api-key": config.apiKey
26918
27678
  }
@@ -26923,11 +27683,11 @@ var WorkerHarnessClient = class {
26923
27683
  }
26924
27684
  return { text: text2 };
26925
27685
  }
26926
- async fetchPayload(path25, init = {}) {
27686
+ async fetchPayload(path26, init = {}) {
26927
27687
  const config = this.requireHarnessConfig();
26928
27688
  const headers = new Headers(init.headers);
26929
27689
  headers.set("x-api-key", config.apiKey);
26930
- const response = await this.fetchImpl(`${config.baseUrl}${path25}`, {
27690
+ const response = await this.fetchImpl(`${config.baseUrl}${path26}`, {
26931
27691
  ...init,
26932
27692
  headers
26933
27693
  });
@@ -26941,9 +27701,9 @@ var WorkerHarnessClient = class {
26941
27701
  return { text: text2 };
26942
27702
  }
26943
27703
  }
26944
- async fetchBinary(path25) {
27704
+ async fetchBinary(path26) {
26945
27705
  const config = this.requireHarnessConfig();
26946
- const response = await this.fetchImpl(`${config.baseUrl}${path25}`, {
27706
+ const response = await this.fetchImpl(`${config.baseUrl}${path26}`, {
26947
27707
  headers: {
26948
27708
  "x-api-key": config.apiKey
26949
27709
  }
@@ -27488,16 +28248,16 @@ var HttpError = class extends Error {
27488
28248
  };
27489
28249
  function findRepoRoot(start = process.cwd()) {
27490
28250
  if (process.env.REMOTE_CODEX_REPO_ROOT) {
27491
- return path24.resolve(process.env.REMOTE_CODEX_REPO_ROOT);
28251
+ return path25.resolve(process.env.REMOTE_CODEX_REPO_ROOT);
27492
28252
  }
27493
- let current = path24.resolve(start);
27494
- while (current !== path24.dirname(current)) {
27495
- if (fs26.existsSync(path24.join(current, "pnpm-workspace.yaml")) && fs26.existsSync(path24.join(current, "scripts", "service-restart.mjs"))) {
28253
+ let current = path25.resolve(start);
28254
+ while (current !== path25.dirname(current)) {
28255
+ if (fs26.existsSync(path25.join(current, "pnpm-workspace.yaml")) && fs26.existsSync(path25.join(current, "scripts", "service-restart.mjs"))) {
27496
28256
  return current;
27497
28257
  }
27498
- current = path24.dirname(current);
28258
+ current = path25.dirname(current);
27499
28259
  }
27500
- return path24.resolve(process.cwd());
28260
+ return path25.resolve(process.cwd());
27501
28261
  }
27502
28262
  function createServiceLifecycle() {
27503
28263
  return {
@@ -27509,8 +28269,8 @@ function createServiceLifecycle() {
27509
28269
  });
27510
28270
  }
27511
28271
  const repoRoot = findRepoRoot();
27512
- const restartScript = path24.join(repoRoot, "scripts", "service-restart.mjs");
27513
- if (!fs26.existsSync(restartScript) || !fs26.existsSync(path24.join(repoRoot, "pnpm-workspace.yaml"))) {
28272
+ const restartScript = path25.join(repoRoot, "scripts", "service-restart.mjs");
28273
+ if (!fs26.existsSync(restartScript) || !fs26.existsSync(path25.join(repoRoot, "pnpm-workspace.yaml"))) {
27514
28274
  throw new HttpError(503, {
27515
28275
  code: "service_unavailable",
27516
28276
  message: "Build and restart requires a Remote Codex source checkout. Set REMOTE_CODEX_REPO_ROOT to the checkout path, or update the npm package with npm install -g remote-codex@latest."
@@ -27652,9 +28412,10 @@ function buildApp(options = {}) {
27652
28412
  });
27653
28413
  },
27654
28414
  wsHandler: (socket, request) => {
28415
+ const supervisorSocket = socket;
27655
28416
  const session = authService.verifyRequest(request);
27656
28417
  if (!session.authenticated) {
27657
- socket.close(1008, "Authentication is required.");
28418
+ supervisorSocket.close(1008, "Authentication is required.");
27658
28419
  return;
27659
28420
  }
27660
28421
  const supervisorSession = createSupervisorSocketSession({
@@ -27662,15 +28423,15 @@ function buildApp(options = {}) {
27662
28423
  eventBus,
27663
28424
  backendPluginHost,
27664
28425
  send(message) {
27665
- if (socket.readyState === 1) {
27666
- socket.send(JSON.stringify(message));
28426
+ if (supervisorSocket.readyState === 1) {
28427
+ supervisorSocket.send(JSON.stringify(message));
27667
28428
  }
27668
28429
  }
27669
28430
  });
27670
- socket.on("message", async (rawMessage) => {
28431
+ supervisorSocket.on("message", async (rawMessage) => {
27671
28432
  await supervisorSession.handleMessage(rawMessage.toString());
27672
28433
  });
27673
- socket.on("close", () => {
28434
+ supervisorSocket.on("close", () => {
27674
28435
  supervisorSession.close();
27675
28436
  });
27676
28437
  }
@@ -27819,6 +28580,7 @@ function requestLog(app, error) {
27819
28580
  }
27820
28581
  function createRelayRequestHandler(app) {
27821
28582
  return async function handleRelayRequest(request) {
28583
+ const payload = request.body === null ? void 0 : request.bodyEncoding === "base64" ? Buffer.from(request.body, "base64") : request.body;
27822
28584
  const response = await app.inject({
27823
28585
  method: request.method,
27824
28586
  url: request.path,
@@ -27826,15 +28588,41 @@ function createRelayRequestHandler(app) {
27826
28588
  ...request.headers,
27827
28589
  [RELAY_FORWARD_HEADER]: "1"
27828
28590
  },
27829
- ...request.body !== null ? { payload: request.body } : {}
28591
+ ...payload !== void 0 ? { payload } : {}
27830
28592
  });
28593
+ const responseBody = relayResponseBody(response);
27831
28594
  return {
27832
28595
  statusCode: response.statusCode,
27833
28596
  headers: relayResponseHeaders(response.headers),
27834
- body: response.body
28597
+ body: responseBody.body,
28598
+ ...responseBody.bodyEncoding ? { bodyEncoding: responseBody.bodyEncoding } : {}
27835
28599
  };
27836
28600
  };
27837
28601
  }
28602
+ function relayResponseBody(response) {
28603
+ const contentType = responseHeader(response.headers, "content-type");
28604
+ if (isTextRelayResponse(contentType)) {
28605
+ return { body: response.body };
28606
+ }
28607
+ return {
28608
+ body: response.rawPayload.toString("base64"),
28609
+ bodyEncoding: "base64"
28610
+ };
28611
+ }
28612
+ function responseHeader(headers, name) {
28613
+ const lowerName = name.toLowerCase();
28614
+ for (const [key, value] of Object.entries(headers)) {
28615
+ if (key.toLowerCase() !== lowerName || value === void 0) {
28616
+ continue;
28617
+ }
28618
+ return Array.isArray(value) ? value.join(", ") : String(value);
28619
+ }
28620
+ return "";
28621
+ }
28622
+ function isTextRelayResponse(contentType) {
28623
+ const lower = contentType.toLowerCase();
28624
+ return lower.startsWith("text/") || lower.includes("application/json") || lower.includes("+json") || lower.includes("application/javascript") || lower.includes("application/xml") || lower.includes("+xml") || lower.includes("image/svg+xml");
28625
+ }
27838
28626
  function createSupervisorSocketSession(input) {
27839
28627
  const closeHandlers = [];
27840
28628
  const socketState = /* @__PURE__ */ new Map();