@bryanhu/codexly 0.22.1 → 0.24.0

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 (222) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +45 -3
  3. package/README.zh-CN.md +49 -7
  4. package/dist/{chunk-4VM2ZUPT.js → chunk-MDJUQPOL.js} +179 -125
  5. package/dist/{chunk-NUJPWN62.js → chunk-YG3QMLCD.js} +433 -43
  6. package/dist/cli.js +49 -21
  7. package/dist/providers/codex/index.js +1 -1
  8. package/dist/server/index.js +2 -2
  9. package/dist/web/.vite/manifest.json +111 -111
  10. package/dist/web/.vite/manifest.json.br +0 -0
  11. package/dist/web/.vite/manifest.json.gz +0 -0
  12. package/dist/web/assets/{agent-settings-panel-Ci9mJOS-.js → agent-settings-panel-STxloEc6.js} +1 -1
  13. package/dist/web/assets/agent-settings-panel-STxloEc6.js.br +0 -0
  14. package/dist/web/assets/agent-settings-panel-STxloEc6.js.gz +0 -0
  15. package/dist/web/assets/{attachments-uWbRsPJj.js → attachments-CSV8KBYa.js} +1 -1
  16. package/dist/web/assets/attachments-CSV8KBYa.js.br +0 -0
  17. package/dist/web/assets/attachments-CSV8KBYa.js.gz +0 -0
  18. package/dist/web/assets/{background-image-picker-qGpdQPQi.js → background-image-picker-JDrclQ6O.js} +1 -1
  19. package/dist/web/assets/background-image-picker-JDrclQ6O.js.br +0 -0
  20. package/dist/web/assets/background-image-picker-JDrclQ6O.js.gz +0 -0
  21. package/dist/web/assets/{bing-wallpaper-queries-uesKD16x.js → bing-wallpaper-queries-BqjgHv5k.js} +1 -1
  22. package/dist/web/assets/bing-wallpaper-queries-BqjgHv5k.js.br +0 -0
  23. package/dist/web/assets/bing-wallpaper-queries-BqjgHv5k.js.gz +0 -0
  24. package/dist/web/assets/{button-group-075rCj_f.js → button-group-mjeW2BTr.js} +1 -1
  25. package/dist/web/assets/button-group-mjeW2BTr.js.br +0 -0
  26. package/dist/web/assets/button-group-mjeW2BTr.js.gz +0 -0
  27. package/dist/web/assets/{code-block-C9eTeWWd.js → code-block-CmzWecTa.js} +1 -1
  28. package/dist/web/assets/code-block-CmzWecTa.js.br +0 -0
  29. package/dist/web/assets/code-block-CmzWecTa.js.gz +0 -0
  30. package/dist/web/assets/{commit-settings-panel-CaMMU0oA.js → commit-settings-panel-BQRIgAaq.js} +1 -1
  31. package/dist/web/assets/commit-settings-panel-BQRIgAaq.js.br +0 -0
  32. package/dist/web/assets/commit-settings-panel-BQRIgAaq.js.gz +0 -0
  33. package/dist/web/assets/{context-menu-Dj3lnor1.js → context-menu-Dfbnk16V.js} +1 -1
  34. package/dist/web/assets/context-menu-Dfbnk16V.js.br +0 -0
  35. package/dist/web/assets/context-menu-Dfbnk16V.js.gz +0 -0
  36. package/dist/web/assets/{file-review-dialog-D8XVZ21M.js → file-review-dialog-Bv3Hor8O.js} +1 -1
  37. package/dist/web/assets/file-review-dialog-Bv3Hor8O.js.br +0 -0
  38. package/dist/web/assets/file-review-dialog-Bv3Hor8O.js.gz +0 -0
  39. package/dist/web/assets/{git-history-panel-D2fKSR66.js → git-history-panel-CofR8yva.js} +1 -1
  40. package/dist/web/assets/git-history-panel-CofR8yva.js.br +0 -0
  41. package/dist/web/assets/git-history-panel-CofR8yva.js.gz +0 -0
  42. package/dist/web/assets/{global-search-dialog-BxT-UjpZ.js → global-search-dialog-m_blFw9z.js} +2 -2
  43. package/dist/web/assets/global-search-dialog-m_blFw9z.js.br +0 -0
  44. package/dist/web/assets/global-search-dialog-m_blFw9z.js.gz +0 -0
  45. package/dist/web/assets/{global-settings-about-DiblprcD.js → global-settings-about-CJkWRRdz.js} +1 -1
  46. package/dist/web/assets/global-settings-about-CJkWRRdz.js.br +0 -0
  47. package/dist/web/assets/global-settings-about-CJkWRRdz.js.gz +0 -0
  48. package/dist/web/assets/{global-settings-fields-D5T5SPXY.js → global-settings-fields-DqWp3WpN.js} +1 -1
  49. package/dist/web/assets/global-settings-fields-DqWp3WpN.js.br +0 -0
  50. package/dist/web/assets/global-settings-fields-DqWp3WpN.js.gz +0 -0
  51. package/dist/web/assets/{global-settings-model-COz331Sr.js → global-settings-model-CqgHQlxF.js} +1 -1
  52. package/dist/web/assets/global-settings-model-CqgHQlxF.js.br +0 -0
  53. package/dist/web/assets/global-settings-model-CqgHQlxF.js.gz +0 -0
  54. package/dist/web/assets/{global-settings-page-DEBGBxSg.js → global-settings-page-BiVZofyf.js} +2 -2
  55. package/dist/web/assets/global-settings-page-BiVZofyf.js.br +0 -0
  56. package/dist/web/assets/global-settings-page-BiVZofyf.js.gz +0 -0
  57. package/dist/web/assets/{global-settings-pets-DwJnj_6N.js → global-settings-pets-DkdiEzFY.js} +1 -1
  58. package/dist/web/assets/global-settings-pets-DkdiEzFY.js.br +0 -0
  59. package/dist/web/assets/global-settings-pets-DkdiEzFY.js.gz +0 -0
  60. package/dist/web/assets/{history-task-timeline-oQRRdMbY.js → history-task-timeline-BrLtwo5_.js} +1 -1
  61. package/dist/web/assets/history-task-timeline-BrLtwo5_.js.br +0 -0
  62. package/dist/web/assets/history-task-timeline-BrLtwo5_.js.gz +0 -0
  63. package/dist/web/assets/{index-DRfXjZ2a.js → index-D9lOU2_n.js} +3 -3
  64. package/dist/web/assets/index-D9lOU2_n.js.br +0 -0
  65. package/dist/web/assets/index-D9lOU2_n.js.gz +0 -0
  66. package/dist/web/assets/{installed-skills-pane-v1IcvRKL.js → installed-skills-pane-BRcMSvrv.js} +1 -1
  67. package/dist/web/assets/installed-skills-pane-BRcMSvrv.js.br +0 -0
  68. package/dist/web/assets/installed-skills-pane-BRcMSvrv.js.gz +0 -0
  69. package/dist/web/assets/{lazy-message-response-B6dT9kbf.js → lazy-message-response-C3PwDwxE.js} +2 -2
  70. package/dist/web/assets/lazy-message-response-C3PwDwxE.js.br +0 -0
  71. package/dist/web/assets/lazy-message-response-C3PwDwxE.js.gz +0 -0
  72. package/dist/web/assets/{mcp-management-pane-DiPUaZAO.js → mcp-management-pane-CIXkOpXu.js} +1 -1
  73. package/dist/web/assets/mcp-management-pane-CIXkOpXu.js.br +0 -0
  74. package/dist/web/assets/mcp-management-pane-CIXkOpXu.js.gz +0 -0
  75. package/dist/web/assets/message-response-AwJefMK2.js +7 -0
  76. package/dist/web/assets/message-response-AwJefMK2.js.br +0 -0
  77. package/dist/web/assets/message-response-AwJefMK2.js.gz +0 -0
  78. package/dist/web/assets/{official-plugins-pane-Cis1hRgm.js → official-plugins-pane-C4i4LhS5.js} +1 -1
  79. package/dist/web/assets/official-plugins-pane-C4i4LhS5.js.br +0 -0
  80. package/dist/web/assets/official-plugins-pane-C4i4LhS5.js.gz +0 -0
  81. package/dist/web/assets/{personalization-settings-panel-BB5nguhA.js → personalization-settings-panel-BVty2pDz.js} +1 -1
  82. package/dist/web/assets/personalization-settings-panel-BVty2pDz.js.br +0 -0
  83. package/dist/web/assets/personalization-settings-panel-BVty2pDz.js.gz +0 -0
  84. package/dist/web/assets/{project-file-popup-page-CAcF7DIa.js → project-file-popup-page-hTRv5v3H.js} +1 -1
  85. package/dist/web/assets/project-file-popup-page-hTRv5v3H.js.br +0 -0
  86. package/dist/web/assets/project-file-popup-page-hTRv5v3H.js.gz +0 -0
  87. package/dist/web/assets/{project-source-dialog-DbOmvJBS.js → project-source-dialog-wuXJolJb.js} +1 -1
  88. package/dist/web/assets/project-source-dialog-wuXJolJb.js.br +0 -0
  89. package/dist/web/assets/project-source-dialog-wuXJolJb.js.gz +0 -0
  90. package/dist/web/assets/{project-source-panel-DGafRUDi.js → project-source-panel-PKAa_dbo.js} +1 -1
  91. package/dist/web/assets/project-source-panel-PKAa_dbo.js.br +0 -0
  92. package/dist/web/assets/project-source-panel-PKAa_dbo.js.gz +0 -0
  93. package/dist/web/assets/{prompt-input-DwT-XwSc.js → prompt-input-BHn4OExn.js} +1 -1
  94. package/dist/web/assets/prompt-input-BHn4OExn.js.br +0 -0
  95. package/dist/web/assets/prompt-input-BHn4OExn.js.gz +0 -0
  96. package/dist/web/assets/{prompt-input-controls-CLasQrSj.js → prompt-input-controls-D4wqb_zQ.js} +1 -1
  97. package/dist/web/assets/prompt-input-controls-D4wqb_zQ.js.br +0 -0
  98. package/dist/web/assets/prompt-input-controls-D4wqb_zQ.js.gz +0 -0
  99. package/dist/web/assets/{scheduled-task-date-time-picker-CnSPVHna.js → scheduled-task-date-time-picker-jo6dkC-Z.js} +1 -1
  100. package/dist/web/assets/scheduled-task-date-time-picker-jo6dkC-Z.js.br +0 -0
  101. package/dist/web/assets/scheduled-task-date-time-picker-jo6dkC-Z.js.gz +0 -0
  102. package/dist/web/assets/{scheduled-task-schedule-BnMdRADi.js → scheduled-task-schedule-DD3Zt60h.js} +1 -1
  103. package/dist/web/assets/scheduled-task-schedule-DD3Zt60h.js.br +0 -0
  104. package/dist/web/assets/{scheduled-task-schedule-BnMdRADi.js.gz → scheduled-task-schedule-DD3Zt60h.js.gz} +0 -0
  105. package/dist/web/assets/{scheduled-tasks-container-CNCzsjiP.js → scheduled-tasks-container-CDsipwUR.js} +2 -2
  106. package/dist/web/assets/scheduled-tasks-container-CDsipwUR.js.br +0 -0
  107. package/dist/web/assets/scheduled-tasks-container-CDsipwUR.js.gz +0 -0
  108. package/dist/web/assets/{settings-personalization-CB_nnUys.js → settings-personalization-BbAIVND-.js} +1 -1
  109. package/dist/web/assets/settings-personalization-BbAIVND-.js.br +0 -0
  110. package/dist/web/assets/settings-personalization-BbAIVND-.js.gz +0 -0
  111. package/dist/web/assets/{sheet-JpH2S7eZ.js → sheet-C6eLtEHx.js} +1 -1
  112. package/dist/web/assets/sheet-C6eLtEHx.js.br +0 -0
  113. package/dist/web/assets/sheet-C6eLtEHx.js.gz +0 -0
  114. package/dist/web/assets/{skills-market-container-BgtnwdI7.js → skills-market-container-DFzLg008.js} +2 -2
  115. package/dist/web/assets/skills-market-container-DFzLg008.js.br +0 -0
  116. package/dist/web/assets/skills-market-container-DFzLg008.js.gz +0 -0
  117. package/dist/web/assets/{task-timeline-store-BN41mX3t.js → task-timeline-store-Cj_Bcaqi.js} +1 -1
  118. package/dist/web/assets/task-timeline-store-Cj_Bcaqi.js.br +0 -0
  119. package/dist/web/assets/task-timeline-store-Cj_Bcaqi.js.gz +0 -0
  120. package/dist/web/assets/{third-party-marketplace-pane-CAI6XIWR.js → third-party-marketplace-pane-CoP9DTWX.js} +1 -1
  121. package/dist/web/assets/third-party-marketplace-pane-CoP9DTWX.js.br +0 -0
  122. package/dist/web/assets/third-party-marketplace-pane-CoP9DTWX.js.gz +0 -0
  123. package/dist/web/assets/workbench-composer-C6Sv8xDL.js +8 -0
  124. package/dist/web/assets/workbench-composer-C6Sv8xDL.js.br +0 -0
  125. package/dist/web/assets/workbench-composer-C6Sv8xDL.js.gz +0 -0
  126. package/dist/web/assets/{workbench-inspector-changes-Bl5nS-_2.js → workbench-inspector-changes-7z5diDTC.js} +1 -1
  127. package/dist/web/assets/workbench-inspector-changes-7z5diDTC.js.br +0 -0
  128. package/dist/web/assets/workbench-inspector-changes-7z5diDTC.js.gz +0 -0
  129. package/dist/web/assets/{workbench-pet-canvas-CnwZR5HG.js → workbench-pet-canvas-dWliFlKE.js} +1 -1
  130. package/dist/web/assets/workbench-pet-canvas-dWliFlKE.js.br +0 -0
  131. package/dist/web/assets/workbench-pet-canvas-dWliFlKE.js.gz +0 -0
  132. package/dist/web/assets/workbench-shell-fA7tfnac.js +3 -0
  133. package/dist/web/assets/workbench-shell-fA7tfnac.js.br +0 -0
  134. package/dist/web/assets/workbench-shell-fA7tfnac.js.gz +0 -0
  135. package/dist/web/index.html +1 -1
  136. package/dist/web/index.html.br +0 -0
  137. package/dist/web/index.html.gz +0 -0
  138. package/package.json +4 -2
  139. package/dist/web/assets/agent-settings-panel-Ci9mJOS-.js.br +0 -0
  140. package/dist/web/assets/agent-settings-panel-Ci9mJOS-.js.gz +0 -0
  141. package/dist/web/assets/attachments-uWbRsPJj.js.br +0 -0
  142. package/dist/web/assets/attachments-uWbRsPJj.js.gz +0 -0
  143. package/dist/web/assets/background-image-picker-qGpdQPQi.js.br +0 -0
  144. package/dist/web/assets/background-image-picker-qGpdQPQi.js.gz +0 -0
  145. package/dist/web/assets/bing-wallpaper-queries-uesKD16x.js.br +0 -0
  146. package/dist/web/assets/bing-wallpaper-queries-uesKD16x.js.gz +0 -0
  147. package/dist/web/assets/button-group-075rCj_f.js.br +0 -0
  148. package/dist/web/assets/button-group-075rCj_f.js.gz +0 -0
  149. package/dist/web/assets/code-block-C9eTeWWd.js.br +0 -0
  150. package/dist/web/assets/code-block-C9eTeWWd.js.gz +0 -0
  151. package/dist/web/assets/commit-settings-panel-CaMMU0oA.js.br +0 -0
  152. package/dist/web/assets/commit-settings-panel-CaMMU0oA.js.gz +0 -0
  153. package/dist/web/assets/context-menu-Dj3lnor1.js.br +0 -0
  154. package/dist/web/assets/context-menu-Dj3lnor1.js.gz +0 -0
  155. package/dist/web/assets/file-review-dialog-D8XVZ21M.js.br +0 -0
  156. package/dist/web/assets/file-review-dialog-D8XVZ21M.js.gz +0 -0
  157. package/dist/web/assets/git-history-panel-D2fKSR66.js.br +0 -0
  158. package/dist/web/assets/git-history-panel-D2fKSR66.js.gz +0 -0
  159. package/dist/web/assets/global-search-dialog-BxT-UjpZ.js.br +0 -0
  160. package/dist/web/assets/global-search-dialog-BxT-UjpZ.js.gz +0 -0
  161. package/dist/web/assets/global-settings-about-DiblprcD.js.br +0 -0
  162. package/dist/web/assets/global-settings-about-DiblprcD.js.gz +0 -0
  163. package/dist/web/assets/global-settings-fields-D5T5SPXY.js.br +0 -0
  164. package/dist/web/assets/global-settings-fields-D5T5SPXY.js.gz +0 -0
  165. package/dist/web/assets/global-settings-model-COz331Sr.js.br +0 -0
  166. package/dist/web/assets/global-settings-model-COz331Sr.js.gz +0 -0
  167. package/dist/web/assets/global-settings-page-DEBGBxSg.js.br +0 -0
  168. package/dist/web/assets/global-settings-page-DEBGBxSg.js.gz +0 -0
  169. package/dist/web/assets/global-settings-pets-DwJnj_6N.js.br +0 -0
  170. package/dist/web/assets/global-settings-pets-DwJnj_6N.js.gz +0 -0
  171. package/dist/web/assets/history-task-timeline-oQRRdMbY.js.br +0 -0
  172. package/dist/web/assets/history-task-timeline-oQRRdMbY.js.gz +0 -0
  173. package/dist/web/assets/index-DRfXjZ2a.js.br +0 -0
  174. package/dist/web/assets/index-DRfXjZ2a.js.gz +0 -0
  175. package/dist/web/assets/installed-skills-pane-v1IcvRKL.js.br +0 -0
  176. package/dist/web/assets/installed-skills-pane-v1IcvRKL.js.gz +0 -0
  177. package/dist/web/assets/lazy-message-response-B6dT9kbf.js.br +0 -0
  178. package/dist/web/assets/lazy-message-response-B6dT9kbf.js.gz +0 -0
  179. package/dist/web/assets/mcp-management-pane-DiPUaZAO.js.br +0 -0
  180. package/dist/web/assets/mcp-management-pane-DiPUaZAO.js.gz +0 -0
  181. package/dist/web/assets/message-response-BZZGbaVm.js +0 -7
  182. package/dist/web/assets/message-response-BZZGbaVm.js.br +0 -0
  183. package/dist/web/assets/message-response-BZZGbaVm.js.gz +0 -0
  184. package/dist/web/assets/official-plugins-pane-Cis1hRgm.js.br +0 -0
  185. package/dist/web/assets/official-plugins-pane-Cis1hRgm.js.gz +0 -0
  186. package/dist/web/assets/personalization-settings-panel-BB5nguhA.js.br +0 -0
  187. package/dist/web/assets/personalization-settings-panel-BB5nguhA.js.gz +0 -0
  188. package/dist/web/assets/project-file-popup-page-CAcF7DIa.js.br +0 -0
  189. package/dist/web/assets/project-file-popup-page-CAcF7DIa.js.gz +0 -0
  190. package/dist/web/assets/project-source-dialog-DbOmvJBS.js.br +0 -0
  191. package/dist/web/assets/project-source-dialog-DbOmvJBS.js.gz +0 -0
  192. package/dist/web/assets/project-source-panel-DGafRUDi.js.br +0 -0
  193. package/dist/web/assets/project-source-panel-DGafRUDi.js.gz +0 -0
  194. package/dist/web/assets/prompt-input-DwT-XwSc.js.br +0 -0
  195. package/dist/web/assets/prompt-input-DwT-XwSc.js.gz +0 -0
  196. package/dist/web/assets/prompt-input-controls-CLasQrSj.js.br +0 -0
  197. package/dist/web/assets/prompt-input-controls-CLasQrSj.js.gz +0 -0
  198. package/dist/web/assets/scheduled-task-date-time-picker-CnSPVHna.js.br +0 -0
  199. package/dist/web/assets/scheduled-task-date-time-picker-CnSPVHna.js.gz +0 -0
  200. package/dist/web/assets/scheduled-task-schedule-BnMdRADi.js.br +0 -0
  201. package/dist/web/assets/scheduled-tasks-container-CNCzsjiP.js.br +0 -0
  202. package/dist/web/assets/scheduled-tasks-container-CNCzsjiP.js.gz +0 -0
  203. package/dist/web/assets/settings-personalization-CB_nnUys.js.br +0 -0
  204. package/dist/web/assets/settings-personalization-CB_nnUys.js.gz +0 -0
  205. package/dist/web/assets/sheet-JpH2S7eZ.js.br +0 -0
  206. package/dist/web/assets/sheet-JpH2S7eZ.js.gz +0 -0
  207. package/dist/web/assets/skills-market-container-BgtnwdI7.js.br +0 -0
  208. package/dist/web/assets/skills-market-container-BgtnwdI7.js.gz +0 -0
  209. package/dist/web/assets/task-timeline-store-BN41mX3t.js.br +0 -0
  210. package/dist/web/assets/task-timeline-store-BN41mX3t.js.gz +0 -0
  211. package/dist/web/assets/third-party-marketplace-pane-CAI6XIWR.js.br +0 -0
  212. package/dist/web/assets/third-party-marketplace-pane-CAI6XIWR.js.gz +0 -0
  213. package/dist/web/assets/workbench-composer-dKix0zGK.js +0 -8
  214. package/dist/web/assets/workbench-composer-dKix0zGK.js.br +0 -0
  215. package/dist/web/assets/workbench-composer-dKix0zGK.js.gz +0 -0
  216. package/dist/web/assets/workbench-inspector-changes-Bl5nS-_2.js.br +0 -0
  217. package/dist/web/assets/workbench-inspector-changes-Bl5nS-_2.js.gz +0 -0
  218. package/dist/web/assets/workbench-pet-canvas-CnwZR5HG.js.br +0 -0
  219. package/dist/web/assets/workbench-pet-canvas-CnwZR5HG.js.gz +0 -0
  220. package/dist/web/assets/workbench-shell-B8lBrj2O.js +0 -3
  221. package/dist/web/assets/workbench-shell-B8lBrj2O.js.br +0 -0
  222. package/dist/web/assets/workbench-shell-B8lBrj2O.js.gz +0 -0
@@ -1,12 +1,12 @@
1
1
  import { createRequire } from 'node:module';
2
2
  import { WorkbenchPetProviderError, PendingRequestResolutionError } from './chunk-B2673ODM.js';
3
- import { TEMPORARY_TASK_SCOPE_ID, MAX_AGENT_HISTORY_IMAGE_TOTAL_BYTES, isAgentFastModeAvailable, MAX_REALTIME_FILE_CHANGES, MAX_REALTIME_DIFF_BYTES, stripLeadingAgentSkillReferences, MAX_AGENT_HISTORY_IMAGES, MAX_AGENT_TEXT_BYTES } from './chunk-ZXTTTT25.js';
3
+ import { TEMPORARY_TASK_SCOPE_ID, MAX_AGENT_HISTORY_IMAGE_TOTAL_BYTES, isAgentFastModeAvailable, MAX_REALTIME_FILE_CHANGES, MAX_REALTIME_DIFF_BYTES, stripLeadingAgentSkillReferences, MAX_AGENT_HISTORY_IMAGES, MAX_AGENT_IMAGE_BYTES, MAX_AGENT_TEXT_BYTES, MAX_AGENT_FILE_BYTES } from './chunk-ZXTTTT25.js';
4
4
  import { __commonJS, __require, __toESM } from './chunk-K6J42667.js';
5
5
  import { execFile, spawn } from 'child_process';
6
- import { constants, mkdtempSync, rmSync, createReadStream, mkdirSync, unlinkSync, renameSync, writeFileSync, openSync, readSync, closeSync, statSync } from 'fs';
6
+ import { constants, mkdtempSync, rmSync, createReadStream, mkdirSync, unlinkSync, renameSync, writeFileSync, readFileSync, statSync, existsSync, openSync, readSync, closeSync } from 'fs';
7
7
  import { readFile, mkdir, writeFile, rename, rm, readdir, realpath, stat, access, open, unlink, lstat, opendir } from 'fs/promises';
8
8
  import { createRequire as createRequire$1 } from 'module';
9
- import { resolve, basename, dirname, join, relative, sep, win32, posix, isAbsolute, extname } from 'path';
9
+ import { resolve, join, basename, dirname, relative, sep, win32, posix, isAbsolute, extname } from 'path';
10
10
  import { promisify } from 'util';
11
11
  import { randomUUID, createHash } from 'crypto';
12
12
  import { Buffer as Buffer$1 } from 'buffer';
@@ -1983,7 +1983,7 @@ var require_thread_stream = __commonJS({
1983
1983
  var { version } = require_package();
1984
1984
  var { EventEmitter } = __require("events");
1985
1985
  var { Worker: Worker2 } = __require("worker_threads");
1986
- var { join: join7 } = __require("path");
1986
+ var { join: join9 } = __require("path");
1987
1987
  var { pathToFileURL } = __require("url");
1988
1988
  var { wait } = require_wait();
1989
1989
  var {
@@ -2034,7 +2034,7 @@ var require_thread_stream = __commonJS({
2034
2034
  function createWorker(stream, opts) {
2035
2035
  const { filename, workerData } = opts;
2036
2036
  const bundlerOverrides = "__bundlerPathsOverrides" in globalThis ? globalThis.__bundlerPathsOverrides : {};
2037
- const toExecute = bundlerOverrides["thread-stream-worker"] || join7(__dirname, "lib", "worker.js");
2037
+ const toExecute = bundlerOverrides["thread-stream-worker"] || join9(__dirname, "lib", "worker.js");
2038
2038
  const worker = new Worker2(toExecute, {
2039
2039
  ...opts.workerOpts,
2040
2040
  name: opts.workerOpts?.name || "thread-stream",
@@ -2499,9 +2499,9 @@ var require_thread_stream = __commonJS({
2499
2499
  var require_transport = __commonJS({
2500
2500
  "node_modules/.pnpm/pino@10.3.1/node_modules/pino/lib/transport.js"(exports, module) {
2501
2501
  var { createRequire: createRequire2 } = __require("module");
2502
- var { existsSync } = __require("fs");
2502
+ var { existsSync: existsSync2 } = __require("fs");
2503
2503
  var getCallers = require_caller();
2504
- var { join: join7, isAbsolute: isAbsolute7, sep: sep3 } = __require("path");
2504
+ var { join: join9, isAbsolute: isAbsolute8, sep: sep3 } = __require("path");
2505
2505
  var { fileURLToPath } = __require("url");
2506
2506
  var sleep = require_atomic_sleep();
2507
2507
  var onExit = require_on_exit_leak_free();
@@ -2573,7 +2573,7 @@ var require_transport = __commonJS({
2573
2573
  return false;
2574
2574
  }
2575
2575
  }
2576
- return isAbsolute7(path) && !existsSync(path);
2576
+ return isAbsolute8(path) && !existsSync2(path);
2577
2577
  }
2578
2578
  function stripQuotes(value) {
2579
2579
  const first = value[0];
@@ -2654,7 +2654,7 @@ var require_transport = __commonJS({
2654
2654
  throw new Error("only one of target or targets can be specified");
2655
2655
  }
2656
2656
  if (targets) {
2657
- target = bundlerOverrides["pino-worker"] || join7(__dirname, "worker.js");
2657
+ target = bundlerOverrides["pino-worker"] || join9(__dirname, "worker.js");
2658
2658
  options.targets = targets.filter((dest) => dest.target).map((dest) => {
2659
2659
  return {
2660
2660
  ...dest,
@@ -2672,7 +2672,7 @@ var require_transport = __commonJS({
2672
2672
  });
2673
2673
  });
2674
2674
  } else if (pipeline) {
2675
- target = bundlerOverrides["pino-worker"] || join7(__dirname, "worker.js");
2675
+ target = bundlerOverrides["pino-worker"] || join9(__dirname, "worker.js");
2676
2676
  options.pipelines = [pipeline.map((dest) => {
2677
2677
  return {
2678
2678
  ...dest,
@@ -2691,11 +2691,11 @@ var require_transport = __commonJS({
2691
2691
  return buildStream(fixTarget(target), options, worker, sync, name);
2692
2692
  function fixTarget(origin) {
2693
2693
  origin = bundlerOverrides[origin] || origin;
2694
- if (isAbsolute7(origin) || origin.indexOf("file://") === 0) {
2694
+ if (isAbsolute8(origin) || origin.indexOf("file://") === 0) {
2695
2695
  return origin;
2696
2696
  }
2697
2697
  if (origin === "pino/file") {
2698
- return join7(__dirname, "..", "file.js");
2698
+ return join9(__dirname, "..", "file.js");
2699
2699
  }
2700
2700
  let fixTarget2;
2701
2701
  for (const filePath of callers) {
@@ -3670,7 +3670,7 @@ var require_safe_stable_stringify = __commonJS({
3670
3670
  return circularValue;
3671
3671
  }
3672
3672
  let res = "";
3673
- let join7 = ",";
3673
+ let join9 = ",";
3674
3674
  const originalIndentation = indentation;
3675
3675
  if (Array.isArray(value)) {
3676
3676
  if (value.length === 0) {
@@ -3684,7 +3684,7 @@ var require_safe_stable_stringify = __commonJS({
3684
3684
  indentation += spacer;
3685
3685
  res += `
3686
3686
  ${indentation}`;
3687
- join7 = `,
3687
+ join9 = `,
3688
3688
  ${indentation}`;
3689
3689
  }
3690
3690
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
@@ -3692,13 +3692,13 @@ ${indentation}`;
3692
3692
  for (; i < maximumValuesToStringify - 1; i++) {
3693
3693
  const tmp2 = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
3694
3694
  res += tmp2 !== void 0 ? tmp2 : "null";
3695
- res += join7;
3695
+ res += join9;
3696
3696
  }
3697
3697
  const tmp = stringifyFnReplacer(String(i), value, stack, replacer, spacer, indentation);
3698
3698
  res += tmp !== void 0 ? tmp : "null";
3699
3699
  if (value.length - 1 > maximumBreadth) {
3700
3700
  const removedKeys = value.length - maximumBreadth - 1;
3701
- res += `${join7}"... ${getItemCount(removedKeys)} not stringified"`;
3701
+ res += `${join9}"... ${getItemCount(removedKeys)} not stringified"`;
3702
3702
  }
3703
3703
  if (spacer !== "") {
3704
3704
  res += `
@@ -3719,7 +3719,7 @@ ${originalIndentation}`;
3719
3719
  let separator = "";
3720
3720
  if (spacer !== "") {
3721
3721
  indentation += spacer;
3722
- join7 = `,
3722
+ join9 = `,
3723
3723
  ${indentation}`;
3724
3724
  whitespace = " ";
3725
3725
  }
@@ -3733,13 +3733,13 @@ ${indentation}`;
3733
3733
  const tmp = stringifyFnReplacer(key2, value, stack, replacer, spacer, indentation);
3734
3734
  if (tmp !== void 0) {
3735
3735
  res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
3736
- separator = join7;
3736
+ separator = join9;
3737
3737
  }
3738
3738
  }
3739
3739
  if (keyLength > maximumBreadth) {
3740
3740
  const removedKeys = keyLength - maximumBreadth;
3741
3741
  res += `${separator}"...":${whitespace}"${getItemCount(removedKeys)} not stringified"`;
3742
- separator = join7;
3742
+ separator = join9;
3743
3743
  }
3744
3744
  if (spacer !== "" && separator.length > 1) {
3745
3745
  res = `
@@ -3780,7 +3780,7 @@ ${originalIndentation}`;
3780
3780
  }
3781
3781
  const originalIndentation = indentation;
3782
3782
  let res = "";
3783
- let join7 = ",";
3783
+ let join9 = ",";
3784
3784
  if (Array.isArray(value)) {
3785
3785
  if (value.length === 0) {
3786
3786
  return "[]";
@@ -3793,7 +3793,7 @@ ${originalIndentation}`;
3793
3793
  indentation += spacer;
3794
3794
  res += `
3795
3795
  ${indentation}`;
3796
- join7 = `,
3796
+ join9 = `,
3797
3797
  ${indentation}`;
3798
3798
  }
3799
3799
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
@@ -3801,13 +3801,13 @@ ${indentation}`;
3801
3801
  for (; i < maximumValuesToStringify - 1; i++) {
3802
3802
  const tmp2 = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
3803
3803
  res += tmp2 !== void 0 ? tmp2 : "null";
3804
- res += join7;
3804
+ res += join9;
3805
3805
  }
3806
3806
  const tmp = stringifyArrayReplacer(String(i), value[i], stack, replacer, spacer, indentation);
3807
3807
  res += tmp !== void 0 ? tmp : "null";
3808
3808
  if (value.length - 1 > maximumBreadth) {
3809
3809
  const removedKeys = value.length - maximumBreadth - 1;
3810
- res += `${join7}"... ${getItemCount(removedKeys)} not stringified"`;
3810
+ res += `${join9}"... ${getItemCount(removedKeys)} not stringified"`;
3811
3811
  }
3812
3812
  if (spacer !== "") {
3813
3813
  res += `
@@ -3820,7 +3820,7 @@ ${originalIndentation}`;
3820
3820
  let whitespace = "";
3821
3821
  if (spacer !== "") {
3822
3822
  indentation += spacer;
3823
- join7 = `,
3823
+ join9 = `,
3824
3824
  ${indentation}`;
3825
3825
  whitespace = " ";
3826
3826
  }
@@ -3829,7 +3829,7 @@ ${indentation}`;
3829
3829
  const tmp = stringifyArrayReplacer(key2, value[key2], stack, replacer, spacer, indentation);
3830
3830
  if (tmp !== void 0) {
3831
3831
  res += `${separator}${strEscape(key2)}:${whitespace}${tmp}`;
3832
- separator = join7;
3832
+ separator = join9;
3833
3833
  }
3834
3834
  }
3835
3835
  if (spacer !== "" && separator.length > 1) {
@@ -3887,20 +3887,20 @@ ${originalIndentation}`;
3887
3887
  indentation += spacer;
3888
3888
  let res2 = `
3889
3889
  ${indentation}`;
3890
- const join8 = `,
3890
+ const join10 = `,
3891
3891
  ${indentation}`;
3892
3892
  const maximumValuesToStringify = Math.min(value.length, maximumBreadth);
3893
3893
  let i = 0;
3894
3894
  for (; i < maximumValuesToStringify - 1; i++) {
3895
3895
  const tmp2 = stringifyIndent(String(i), value[i], stack, spacer, indentation);
3896
3896
  res2 += tmp2 !== void 0 ? tmp2 : "null";
3897
- res2 += join8;
3897
+ res2 += join10;
3898
3898
  }
3899
3899
  const tmp = stringifyIndent(String(i), value[i], stack, spacer, indentation);
3900
3900
  res2 += tmp !== void 0 ? tmp : "null";
3901
3901
  if (value.length - 1 > maximumBreadth) {
3902
3902
  const removedKeys = value.length - maximumBreadth - 1;
3903
- res2 += `${join8}"... ${getItemCount(removedKeys)} not stringified"`;
3903
+ res2 += `${join10}"... ${getItemCount(removedKeys)} not stringified"`;
3904
3904
  }
3905
3905
  res2 += `
3906
3906
  ${originalIndentation}`;
@@ -3916,16 +3916,16 @@ ${originalIndentation}`;
3916
3916
  return '"[Object]"';
3917
3917
  }
3918
3918
  indentation += spacer;
3919
- const join7 = `,
3919
+ const join9 = `,
3920
3920
  ${indentation}`;
3921
3921
  let res = "";
3922
3922
  let separator = "";
3923
3923
  let maximumPropertiesToStringify = Math.min(keyLength, maximumBreadth);
3924
3924
  if (isTypedArrayWithEntries(value)) {
3925
- res += stringifyTypedArray(value, join7, maximumBreadth);
3925
+ res += stringifyTypedArray(value, join9, maximumBreadth);
3926
3926
  keys = keys.slice(value.length);
3927
3927
  maximumPropertiesToStringify -= value.length;
3928
- separator = join7;
3928
+ separator = join9;
3929
3929
  }
3930
3930
  if (deterministic) {
3931
3931
  keys = sort(keys, comparator);
@@ -3936,13 +3936,13 @@ ${indentation}`;
3936
3936
  const tmp = stringifyIndent(key2, value[key2], stack, spacer, indentation);
3937
3937
  if (tmp !== void 0) {
3938
3938
  res += `${separator}${strEscape(key2)}: ${tmp}`;
3939
- separator = join7;
3939
+ separator = join9;
3940
3940
  }
3941
3941
  }
3942
3942
  if (keyLength > maximumBreadth) {
3943
3943
  const removedKeys = keyLength - maximumBreadth;
3944
3944
  res += `${separator}"...": "${getItemCount(removedKeys)} not stringified"`;
3945
- separator = join7;
3945
+ separator = join9;
3946
3946
  }
3947
3947
  if (separator !== "") {
3948
3948
  res = `
@@ -4466,8 +4466,8 @@ var require_pino = __commonJS({
4466
4466
  }
4467
4467
  });
4468
4468
  var execFileAsync = promisify(execFile);
4469
- var SUPPORTED_CODEX_VERSION = "0.154.0";
4470
- var SUPPORTED_CODEX_VERSION_RANGE = ">=0.154.0,<0.155.0";
4469
+ var SUPPORTED_CODEX_VERSION = "0.155.1";
4470
+ var SUPPORTED_CODEX_VERSION_RANGE = ">=0.155.0,<0.156.0";
4471
4471
  var BUNDLED_CODEX_TARGETS = {
4472
4472
  "darwin-arm64": {
4473
4473
  executableName: "codex",
@@ -4609,7 +4609,7 @@ async function checkCodexVersion(binaryPath, options = {}) {
4609
4609
  }
4610
4610
  const [major, minor, patch] = version.split("-", 1)[0]?.split(".").map(Number) ?? [];
4611
4611
  const isPrerelease = version.includes("-");
4612
- if (major !== 0 || minor !== 154 || patch === void 0 || isPrerelease) {
4612
+ if (major !== 0 || minor !== 155 || patch === void 0 || isPrerelease) {
4613
4613
  throw new Error(
4614
4614
  `Unsupported Codex version ${version}; expected ${SUPPORTED_CODEX_VERSION_RANGE}`
4615
4615
  );
@@ -4664,6 +4664,7 @@ var CODEX_SPECIAL_NOTIFICATION_METHODS = /* @__PURE__ */ new Set([
4664
4664
  "serverRequest/resolved",
4665
4665
  "skills/changed",
4666
4666
  "thread/archived",
4667
+ "thread/attachment/updated",
4667
4668
  "thread/deleted",
4668
4669
  "thread/name/updated",
4669
4670
  "thread/started",
@@ -8295,6 +8296,373 @@ var CodexHistoricalAttachmentStore = class {
8295
8296
  }
8296
8297
  }
8297
8298
  };
8299
+ var DATA_URL_PATTERN2 = /^data:(image\/(?:gif|jpeg|png|webp));base64,([A-Za-z0-9+/]+={0,2})$/u;
8300
+ var CodexPersistentHistoricalAttachmentStore = class {
8301
+ constructor(directory) {
8302
+ this.directory = directory;
8303
+ }
8304
+ directory;
8305
+ #entries = /* @__PURE__ */ new Map();
8306
+ #pending = /* @__PURE__ */ new Map();
8307
+ #totalBytes = 0;
8308
+ addDataUrl(taskId, input, imageIndex) {
8309
+ const match = DATA_URL_PATTERN2.exec(input.url);
8310
+ const mediaType = match?.[1];
8311
+ const content = this.#decodeBase64(match?.[2]);
8312
+ if (content === void 0 || mediaType === void 0 || detectImageMediaType(content) !== mediaType) {
8313
+ return void 0;
8314
+ }
8315
+ return this.#add(
8316
+ taskId,
8317
+ "image",
8318
+ mediaType,
8319
+ normalizeAttachmentName(input.name, `\u56FE\u7247-${String(imageIndex + 1)}`),
8320
+ content
8321
+ );
8322
+ }
8323
+ addBase64Image(taskId, input, imageIndex) {
8324
+ const content = this.#decodeBase64(input.encoded);
8325
+ const mediaType = content === void 0 ? void 0 : detectImageMediaType(content);
8326
+ if (content === void 0 || mediaType === void 0) return void 0;
8327
+ return this.#add(
8328
+ taskId,
8329
+ "image",
8330
+ mediaType,
8331
+ normalizeAttachmentName(
8332
+ input.name,
8333
+ `\u751F\u6210\u56FE\u7247-${String(imageIndex + 1)}${imageExtensionsByMediaType[mediaType]}`
8334
+ ),
8335
+ content
8336
+ );
8337
+ }
8338
+ addStagedImage(taskId, staged, imageIndex, inputName) {
8339
+ if (staged.size <= 0 || staged.size > MAX_AGENT_IMAGE_BYTES) return void 0;
8340
+ try {
8341
+ const content = readFileSync(staged.path);
8342
+ if (content.byteLength !== staged.size || createHash("sha256").update(content).digest("hex") !== staged.contentDigest || detectImageMediaType(content) !== staged.mediaType) {
8343
+ return void 0;
8344
+ }
8345
+ const attachment = this.#add(
8346
+ taskId,
8347
+ "image",
8348
+ staged.mediaType,
8349
+ normalizeAttachmentName(
8350
+ inputName,
8351
+ `\u751F\u6210\u56FE\u7247-${String(imageIndex + 1)}${imageExtensionsByMediaType[staged.mediaType]}`
8352
+ ),
8353
+ content
8354
+ );
8355
+ if (attachment !== void 0) unlinkSync(staged.path);
8356
+ return attachment;
8357
+ } catch {
8358
+ return void 0;
8359
+ }
8360
+ }
8361
+ addLocalImage(taskId, path, imageIndex) {
8362
+ if (!isAbsolute(path)) return void 0;
8363
+ try {
8364
+ const stats = statSync(path);
8365
+ if (!stats.isFile() || stats.size <= 0 || stats.size > MAX_AGENT_IMAGE_BYTES)
8366
+ return void 0;
8367
+ const content = readFileSync(path);
8368
+ const mediaType = detectImageMediaType(content);
8369
+ if (mediaType === void 0) return void 0;
8370
+ return this.#add(
8371
+ taskId,
8372
+ "image",
8373
+ mediaType,
8374
+ normalizeAttachmentName(basename(path), `\u56FE\u7247-${String(imageIndex + 1)}`),
8375
+ content
8376
+ );
8377
+ } catch {
8378
+ return void 0;
8379
+ }
8380
+ }
8381
+ addText(taskId, input, textIndex) {
8382
+ const content = Buffer$1.from(input.text, "utf8");
8383
+ if (content.byteLength > MAX_AGENT_TEXT_BYTES) return void 0;
8384
+ return this.#add(
8385
+ taskId,
8386
+ "text",
8387
+ "text/plain",
8388
+ normalizeAttachmentName(input.name, `Pasted text-${String(textIndex + 1)}.txt`),
8389
+ content
8390
+ );
8391
+ }
8392
+ addLocalFile(taskId, input) {
8393
+ if (!isAbsolute(input.path)) return void 0;
8394
+ try {
8395
+ const stats = statSync(input.path);
8396
+ if (!stats.isFile() || stats.size <= 0 || stats.size > MAX_AGENT_FILE_BYTES) return void 0;
8397
+ return this.#add(
8398
+ taskId,
8399
+ "file",
8400
+ input.mediaType,
8401
+ normalizeAttachmentName(input.name, "Attachment"),
8402
+ readFileSync(input.path)
8403
+ );
8404
+ } catch {
8405
+ return void 0;
8406
+ }
8407
+ }
8408
+ restoreTask(taskId, metadata) {
8409
+ this.clearTask(taskId);
8410
+ for (const record of metadata) {
8411
+ const path = this.#blobPath(taskId, record.blobKey);
8412
+ try {
8413
+ const stats = statSync(path);
8414
+ if (!stats.isFile() || stats.size !== record.attachment.size) continue;
8415
+ this.#register({ attachment: record.attachment, blobKey: record.blobKey, path, taskId });
8416
+ } catch {
8417
+ }
8418
+ }
8419
+ }
8420
+ pendingMetadata(taskId) {
8421
+ return [...this.#pending.get(taskId)?.values() ?? []];
8422
+ }
8423
+ markPersisted(taskId, attachmentId) {
8424
+ const pending = this.#pending.get(taskId);
8425
+ pending?.delete(attachmentId);
8426
+ if (pending?.size === 0) this.#pending.delete(taskId);
8427
+ }
8428
+ async read(taskId, attachmentId) {
8429
+ const entry = this.#entries.get(attachmentId);
8430
+ if (entry?.taskId !== taskId) return void 0;
8431
+ try {
8432
+ const content = await readFile(entry.path);
8433
+ if (content.byteLength !== entry.attachment.size || createHash("sha256").update(content).digest("hex") !== entry.blobKey || entry.attachment.kind === "image" && detectImageMediaType(content) !== entry.attachment.mediaType) {
8434
+ this.#forget(attachmentId);
8435
+ rmSync(entry.path, { force: true });
8436
+ return void 0;
8437
+ }
8438
+ this.#touch(entry);
8439
+ return { ...entry.attachment, content };
8440
+ } catch {
8441
+ this.#forget(attachmentId);
8442
+ return void 0;
8443
+ }
8444
+ }
8445
+ clearTask(taskId) {
8446
+ for (const [attachmentId, entry] of this.#entries) {
8447
+ if (entry.taskId === taskId) this.#forget(attachmentId);
8448
+ }
8449
+ this.#pending.delete(taskId);
8450
+ }
8451
+ deleteTask(taskId) {
8452
+ this.clearTask(taskId);
8453
+ rmSync(this.#taskDirectory(taskId), { force: true, recursive: true });
8454
+ }
8455
+ dispose() {
8456
+ this.#entries.clear();
8457
+ this.#pending.clear();
8458
+ this.#totalBytes = 0;
8459
+ }
8460
+ #add(taskId, kind, mediaType, name, content) {
8461
+ const maxBytes = kind === "image" ? MAX_AGENT_IMAGE_BYTES : kind === "text" ? MAX_AGENT_TEXT_BYTES : MAX_AGENT_FILE_BYTES;
8462
+ if (content.byteLength === 0 || content.byteLength > maxBytes) {
8463
+ return void 0;
8464
+ }
8465
+ const blobKey = createHash("sha256").update(content).digest("hex");
8466
+ const id = `history-${createHash("sha256").update(JSON.stringify([taskId, kind, mediaType, name, content.byteLength, blobKey])).digest("hex")}`;
8467
+ const existing = this.#entries.get(id);
8468
+ if (existing?.taskId === taskId) {
8469
+ this.#touch(existing);
8470
+ return existing.attachment;
8471
+ }
8472
+ const attachment = { id, kind, mediaType, name, size: content.byteLength };
8473
+ const path = this.#blobPath(taskId, blobKey);
8474
+ mkdirSync(this.#taskDirectory(taskId), { recursive: true });
8475
+ if (!existsSync(path)) {
8476
+ const temporaryPath = `${path}.${process.pid.toString()}.${id}.tmp`;
8477
+ try {
8478
+ writeFileSync(temporaryPath, content, { flag: "wx" });
8479
+ renameSync(temporaryPath, path);
8480
+ } catch {
8481
+ rmSync(temporaryPath, { force: true });
8482
+ if (!existsSync(path)) return void 0;
8483
+ }
8484
+ }
8485
+ this.#ensureCapacity(attachment.size);
8486
+ this.#register({ attachment, blobKey, path, taskId });
8487
+ const taskPending = this.#pending.get(taskId) ?? /* @__PURE__ */ new Map();
8488
+ taskPending.set(id, { attachment, blobKey, schemaVersion: 1 });
8489
+ this.#pending.set(taskId, taskPending);
8490
+ return attachment;
8491
+ }
8492
+ #decodeBase64(encoded) {
8493
+ if (encoded === void 0 || encoded.length === 0) return void 0;
8494
+ const content = Buffer$1.from(encoded, "base64");
8495
+ return content.byteLength === 0 || content.byteLength > MAX_AGENT_IMAGE_BYTES || content.toString("base64").replace(/=+$/u, "") !== encoded.replace(/=+$/u, "") ? void 0 : content;
8496
+ }
8497
+ #taskDirectory(taskId) {
8498
+ return join(this.directory, createHash("sha256").update(taskId).digest("hex"));
8499
+ }
8500
+ #blobPath(taskId, blobKey) {
8501
+ return join(this.#taskDirectory(taskId), blobKey);
8502
+ }
8503
+ #register(entry) {
8504
+ this.#entries.set(entry.attachment.id, entry);
8505
+ this.#totalBytes += entry.attachment.size;
8506
+ }
8507
+ #touch(entry) {
8508
+ this.#entries.delete(entry.attachment.id);
8509
+ this.#entries.set(entry.attachment.id, entry);
8510
+ }
8511
+ #forget(attachmentId) {
8512
+ const entry = this.#entries.get(attachmentId);
8513
+ if (entry === void 0) return;
8514
+ this.#entries.delete(attachmentId);
8515
+ this.#totalBytes -= entry.attachment.size;
8516
+ }
8517
+ #ensureCapacity(incomingBytes) {
8518
+ while (this.#entries.size >= MAX_AGENT_HISTORY_IMAGES || this.#totalBytes + incomingBytes > MAX_AGENT_HISTORY_IMAGE_TOTAL_BYTES) {
8519
+ const oldestId = this.#entries.keys().next().value;
8520
+ if (oldestId === void 0) return;
8521
+ this.#forget(oldestId);
8522
+ }
8523
+ }
8524
+ };
8525
+
8526
+ // packages/provider-codex/src/thread-attachment-repository.ts
8527
+ var CODEXLY_THREAD_ATTACHMENT_TYPE = "codexly.history.v1";
8528
+ var THREAD_ATTACHMENT_PAGE_SIZE = 100;
8529
+ var BLOB_KEY_PATTERN = /^[a-f0-9]{64}$/u;
8530
+ function readAttachment(value) {
8531
+ const attachment = expectRecord(value, "Codexly thread attachment payload attachment");
8532
+ const id = expectString(attachment["id"], "Codexly thread attachment id");
8533
+ const kind = attachment["kind"];
8534
+ const mediaType = expectString(attachment["mediaType"], "Codexly thread attachment mediaType");
8535
+ const name = expectString(attachment["name"], "Codexly thread attachment name");
8536
+ const size = attachment["size"];
8537
+ if (kind !== "file" && kind !== "image" && kind !== "text" || id.length === 0 || id.length > 256 || mediaType.length === 0 || mediaType.length > 255 || name.length === 0 || name.length > 255 || !Number.isSafeInteger(size) || typeof size !== "number" || size <= 0 || size > MAX_AGENT_HISTORY_IMAGE_TOTAL_BYTES) {
8538
+ throw new CodexProtocolMappingError("Codexly thread attachment metadata is invalid");
8539
+ }
8540
+ return { id, kind, mediaType, name, size };
8541
+ }
8542
+ function readMetadata(value, identityKey) {
8543
+ const payload = expectRecord(value, "Codexly thread attachment payload");
8544
+ const attachment = readAttachment(payload["attachment"]);
8545
+ const blobKey = expectString(payload["blobKey"], "Codexly thread attachment blobKey");
8546
+ if (payload["schemaVersion"] !== 1 || attachment.id !== identityKey || !BLOB_KEY_PATTERN.test(blobKey)) {
8547
+ throw new CodexProtocolMappingError("Codexly thread attachment payload is invalid");
8548
+ }
8549
+ return { attachment, blobKey, schemaVersion: 1 };
8550
+ }
8551
+ var CodexThreadAttachmentRepository = class {
8552
+ constructor(client) {
8553
+ this.client = client;
8554
+ }
8555
+ client;
8556
+ #cache = /* @__PURE__ */ new Map();
8557
+ async load(threadId) {
8558
+ const cached = this.#cache.get(threadId);
8559
+ if (cached !== void 0) return cached;
8560
+ const metadata = [];
8561
+ const seenCursors = /* @__PURE__ */ new Set();
8562
+ let cursor;
8563
+ for (; ; ) {
8564
+ const response = expectRecord(
8565
+ await this.client.request("thread/attachment/list", {
8566
+ ...cursor === void 0 ? {} : { cursor },
8567
+ limit: THREAD_ATTACHMENT_PAGE_SIZE,
8568
+ threadId
8569
+ }),
8570
+ "thread/attachment/list response"
8571
+ );
8572
+ const data = response["data"];
8573
+ if (!Array.isArray(data)) {
8574
+ throw new CodexProtocolMappingError("thread/attachment/list data must be an array");
8575
+ }
8576
+ for (const value of data) {
8577
+ const attachment = expectRecord(value, "thread/attachment/list attachment");
8578
+ if (attachment["attachmentType"] !== CODEXLY_THREAD_ATTACHMENT_TYPE) continue;
8579
+ const identityKey = expectString(
8580
+ attachment["identityKey"],
8581
+ "thread/attachment/list identityKey"
8582
+ );
8583
+ metadata.push(readMetadata(attachment["payload"], identityKey));
8584
+ }
8585
+ const nextCursor = response["nextCursor"];
8586
+ if (nextCursor === null) break;
8587
+ cursor = expectString(nextCursor, "thread/attachment/list nextCursor");
8588
+ if (cursor.length === 0 || seenCursors.has(cursor)) {
8589
+ throw new CodexProtocolMappingError("thread/attachment/list returned an invalid cursor");
8590
+ }
8591
+ seenCursors.add(cursor);
8592
+ }
8593
+ this.#cache.set(threadId, metadata);
8594
+ return metadata;
8595
+ }
8596
+ async add(threadId, metadata) {
8597
+ const response = expectRecord(
8598
+ await this.client.request("thread/attachment/add", {
8599
+ attachmentType: CODEXLY_THREAD_ATTACHMENT_TYPE,
8600
+ identityKey: metadata.attachment.id,
8601
+ payload: metadata,
8602
+ threadId
8603
+ }),
8604
+ "thread/attachment/add response"
8605
+ );
8606
+ const nativeAttachment = expectRecord(
8607
+ response["attachment"],
8608
+ "thread/attachment/add attachment"
8609
+ );
8610
+ if (nativeAttachment["attachmentType"] !== CODEXLY_THREAD_ATTACHMENT_TYPE || nativeAttachment["identityKey"] !== metadata.attachment.id || !isRecord(nativeAttachment["payload"])) {
8611
+ throw new CodexProtocolMappingError("thread/attachment/add returned another attachment");
8612
+ }
8613
+ const persisted = readMetadata(nativeAttachment["payload"], metadata.attachment.id);
8614
+ if (JSON.stringify(persisted) !== JSON.stringify(metadata)) {
8615
+ throw new CodexProtocolMappingError("thread/attachment/add returned conflicting metadata");
8616
+ }
8617
+ this.#cache.delete(threadId);
8618
+ }
8619
+ invalidate(threadId) {
8620
+ this.#cache.delete(threadId);
8621
+ }
8622
+ clear() {
8623
+ this.#cache.clear();
8624
+ }
8625
+ };
8626
+
8627
+ // packages/provider-codex/src/thread-attachment-service.ts
8628
+ var CodexThreadAttachmentService = class {
8629
+ store;
8630
+ #preparedTasks = /* @__PURE__ */ new Set();
8631
+ #repository;
8632
+ constructor(client, attachmentDirectory) {
8633
+ this.#repository = new CodexThreadAttachmentRepository(client);
8634
+ this.store = new CodexPersistentHistoricalAttachmentStore(attachmentDirectory);
8635
+ }
8636
+ async prepare(taskId) {
8637
+ if (this.#preparedTasks.has(taskId)) return;
8638
+ this.store.restoreTask(taskId, await this.#repository.load(taskId));
8639
+ this.#preparedTasks.add(taskId);
8640
+ }
8641
+ async flush(taskId) {
8642
+ for (const metadata of this.store.pendingMetadata(taskId)) {
8643
+ await this.#repository.add(taskId, metadata);
8644
+ this.store.markPersisted(taskId, metadata.attachment.id);
8645
+ }
8646
+ }
8647
+ invalidate(taskId) {
8648
+ this.#preparedTasks.delete(taskId);
8649
+ this.#repository.invalidate(taskId);
8650
+ this.store.clearTask(taskId);
8651
+ }
8652
+ forget(taskId) {
8653
+ this.invalidate(taskId);
8654
+ }
8655
+ deleteTask(taskId) {
8656
+ this.#preparedTasks.delete(taskId);
8657
+ this.#repository.invalidate(taskId);
8658
+ this.store.deleteTask(taskId);
8659
+ }
8660
+ dispose() {
8661
+ this.#preparedTasks.clear();
8662
+ this.#repository.clear();
8663
+ this.store.dispose();
8664
+ }
8665
+ };
8298
8666
 
8299
8667
  // packages/provider-codex/src/pending-request-lifecycle.ts
8300
8668
  var MAX_TERMINAL_PENDING_REQUESTS = 1e3;
@@ -9425,7 +9793,8 @@ var CodexAgentProviderBase = class {
9425
9793
  taskTitles;
9426
9794
  eventListenersIncludingEphemeral = /* @__PURE__ */ new Set();
9427
9795
  eventListeners = /* @__PURE__ */ new Set();
9428
- historicalAttachments = new CodexHistoricalAttachmentStore();
9796
+ historicalAttachments;
9797
+ threadAttachments;
9429
9798
  logger;
9430
9799
  project;
9431
9800
  pendingLifecycle;
@@ -9448,7 +9817,10 @@ var CodexAgentProviderBase = class {
9448
9817
  else this.runtime.runningTaskIds.delete(event.taskId);
9449
9818
  }
9450
9819
  this.routeEvent(event);
9451
- if (event.type === "task.removed") this.clearTaskRuntimeState(event.taskId);
9820
+ if (event.type === "task.removed") {
9821
+ if (method === "thread/deleted") this.threadAttachments?.deleteTask(event.taskId);
9822
+ this.clearTaskRuntimeState(event.taskId);
9823
+ }
9452
9824
  } catch {
9453
9825
  warnDroppedCodexNotification(
9454
9826
  this.logger,
@@ -9463,6 +9835,8 @@ var CodexAgentProviderBase = class {
9463
9835
  }
9464
9836
  constructor(client, project, options = {}) {
9465
9837
  this.client = client;
9838
+ this.threadAttachments = options.attachmentDirectory === void 0 ? void 0 : new CodexThreadAttachmentService(client, options.attachmentDirectory);
9839
+ this.historicalAttachments = this.threadAttachments?.store ?? new CodexHistoricalAttachmentStore();
9466
9840
  this.taskTitles = options.taskTitles;
9467
9841
  this.logger = options.logger ?? DEFAULT_PROVIDER_LOGGER;
9468
9842
  this.project = project;
@@ -9506,7 +9880,8 @@ var CodexAgentProviderBase = class {
9506
9880
  ]);
9507
9881
  this.eventListenersIncludingEphemeral.clear();
9508
9882
  this.eventListeners.clear();
9509
- this.historicalAttachments.dispose();
9883
+ if (this.threadAttachments === void 0) this.historicalAttachments.dispose();
9884
+ else this.threadAttachments.dispose();
9510
9885
  this.pendingLifecycle.clear();
9511
9886
  this.runtime.clear();
9512
9887
  this.skillsById.clear();
@@ -9526,6 +9901,7 @@ var CodexAgentProviderBase = class {
9526
9901
  async deleteTask(taskId) {
9527
9902
  this.assertKnownProjectTask(taskId);
9528
9903
  await deleteCodexTask(this.client, taskId);
9904
+ this.threadAttachments?.deleteTask(taskId);
9529
9905
  this.clearTaskRuntimeState(taskId);
9530
9906
  }
9531
9907
  async unarchiveTask(taskId) {
@@ -10521,6 +10897,7 @@ var CodexAgentProviderTasks = class extends CodexAgentProviderTurns {
10521
10897
  cursor.reviewCursor
10522
10898
  );
10523
10899
  const transcriptSkillsByTurnId = await readCodexTranscriptTurnSkills(taskId);
10900
+ await this.threadAttachments?.prepare(taskId);
10524
10901
  const turns = this.runtime.messageIdentities.snapshot(
10525
10902
  taskId,
10526
10903
  mapAgentTurns(
@@ -10529,6 +10906,7 @@ var CodexAgentProviderTasks = class extends CodexAgentProviderTurns {
10529
10906
  (input2, textIndex) => this.mapMessageText(taskId, input2, textIndex)
10530
10907
  ).map((turn) => attachTranscriptSkills(turn, transcriptSkillsByTurnId.get(turn.id) ?? []))
10531
10908
  );
10909
+ await this.threadAttachments?.flush(taskId);
10532
10910
  const status = turns.some((turn) => turn.status === "running") ? "running" : mapThreadStatus(thread["status"]);
10533
10911
  this.runtime.skillMessages.seed(taskId, turns);
10534
10912
  const runningReviewTurn = turns.findLast(
@@ -10646,6 +11024,7 @@ var CodexAgentProviderTasks = class extends CodexAgentProviderTurns {
10646
11024
  if (!this.runtime.projectTaskIds.has(taskId)) {
10647
11025
  return void 0;
10648
11026
  }
11027
+ await this.threadAttachments?.prepare(taskId);
10649
11028
  return this.historicalAttachments.read(taskId, attachmentId);
10650
11029
  }
10651
11030
  async resolvePendingRequest(input) {
@@ -10727,6 +11106,13 @@ var CodexAgentProviderEvents = class extends CodexAgentProviderTasks {
10727
11106
  return true;
10728
11107
  }
10729
11108
  receiveNotification(method, params) {
11109
+ if (method === "thread/attachment/updated") {
11110
+ const taskId = readTaskId(params);
11111
+ if (taskId === void 0)
11112
+ this.warnDroppedNotification("invalid_notification", method, params);
11113
+ else this.threadAttachments?.invalidate(taskId);
11114
+ return;
11115
+ }
10730
11116
  if (this.handleProjectStateNotification(method, params)) return;
10731
11117
  this.handleNotification(method, params);
10732
11118
  }
@@ -10848,7 +11234,8 @@ var CodexAgentProviderEvents = class extends CodexAgentProviderTasks {
10848
11234
  }
10849
11235
  clearTaskRuntimeState(taskId) {
10850
11236
  this.taskTitles?.forget(taskId);
10851
- this.historicalAttachments.clearTask(taskId);
11237
+ if (this.threadAttachments === void 0) this.historicalAttachments.clearTask(taskId);
11238
+ else this.threadAttachments.forget(taskId);
10852
11239
  this.pendingLifecycle.clearTask(taskId);
10853
11240
  this.runtime.clearTask(taskId);
10854
11241
  }
@@ -12020,6 +12407,7 @@ var CodexProviderConnectionService = class {
12020
12407
  try {
12021
12408
  readProviderCapabilities(await this.#client.request("modelProvider/capabilities/read", {}));
12022
12409
  if (apiKey !== void 0) {
12410
+ await this.#client.request("account/logout");
12023
12411
  const loginResponse = await this.#client.request("account/login/start", {
12024
12412
  apiKey,
12025
12413
  type: "apiKey"
@@ -13196,6 +13584,7 @@ var CodexRuntimeProvider = class {
13196
13584
  fileSearch;
13197
13585
  search;
13198
13586
  #client;
13587
+ #attachmentDirectory;
13199
13588
  #taskTitles;
13200
13589
  #logger;
13201
13590
  #gitMetadataWatch;
@@ -13207,10 +13596,10 @@ var CodexRuntimeProvider = class {
13207
13596
  #reviewWorkerOwners = /* @__PURE__ */ new Map();
13208
13597
  constructor(client, logger = DEFAULT_PROVIDER_LOGGER, options = {}) {
13209
13598
  this.#client = client;
13599
+ const codexHome = options.codexHome ?? process.env["CODEX_HOME"] ?? resolve(homedir(), ".codex");
13600
+ this.#attachmentDirectory = join(codexHome, "codexly", "thread-attachments");
13210
13601
  this.#taskTitles = options.readTaskTitleModel === void 0 ? void 0 : new CodexTaskTitles(client, options.readTaskTitleModel, logger);
13211
- const instructions = createGlobalInstructionsStore(
13212
- options.codexHome ?? process.env["CODEX_HOME"] ?? resolve(homedir(), ".codex")
13213
- );
13602
+ const instructions = createGlobalInstructionsStore(codexHome);
13214
13603
  this.personalization = {
13215
13604
  getGlobalInstructions: instructions.read,
13216
13605
  saveGlobalInstructions: (input) => instructions.save(input),
@@ -13319,6 +13708,7 @@ var CodexRuntimeProvider = class {
13319
13708
  return current;
13320
13709
  }
13321
13710
  const rawProvider = new CodexAgentProvider(this.#client, project, {
13711
+ attachmentDirectory: this.#attachmentDirectory,
13322
13712
  logger: this.#logger,
13323
13713
  ...this.#taskTitles === void 0 ? {} : { taskTitles: this.#taskTitles },
13324
13714
  subscribeRpc: false