ryco-cli 0.1.13 → 0.1.15

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 (217) hide show
  1. package/dist/{AcpNativeLogging-Be1KGJfF.cjs → AcpNativeLogging-OhEq3XNp.cjs} +1 -1
  2. package/dist/{AcpNativeLogging-Ba9Nn9Re.mjs → AcpNativeLogging-qZgtIa5K.mjs} +2 -2
  3. package/dist/{AzureDevOpsSourceControlProvider-CGlK6M0b.mjs → AzureDevOpsSourceControlProvider-B0YsaJyI.mjs} +3 -3
  4. package/dist/{AzureDevOpsSourceControlProvider-CVj-F-pW.cjs → AzureDevOpsSourceControlProvider-Dyu8KQ_S.cjs} +2 -2
  5. package/dist/{BitbucketSourceControlProvider-CEZEd4PX.cjs → BitbucketSourceControlProvider-3VHGKSl1.cjs} +2 -2
  6. package/dist/{BitbucketSourceControlProvider-BV6iRDi7.mjs → BitbucketSourceControlProvider-B8IPx2Ad.mjs} +3 -3
  7. package/dist/{ClaudeDriver-lBU7EyUX.cjs → ClaudeDriver-CBCy0_WX.cjs} +176 -11
  8. package/dist/{ClaudeDriver-rooMNrJz.mjs → ClaudeDriver-DsW8yDj9.mjs} +177 -12
  9. package/dist/{CodexDriver-CZCIJSLV.cjs → CodexDriver-3TZPgrGk.cjs} +3 -3
  10. package/dist/{CodexDriver-DBz2rPXb.mjs → CodexDriver-DLwPz5sk.mjs} +4 -4
  11. package/dist/{CodexTextGeneration-BeG7ymPC.mjs → CodexTextGeneration-D1vV8grr.mjs} +2 -2
  12. package/dist/{CodexTextGeneration-BvIcyD1P.cjs → CodexTextGeneration-DLHSW4Mz.cjs} +1 -1
  13. package/dist/{CopilotDriver-CX5zhEdZ.cjs → CopilotDriver-C7a8IhyK.cjs} +20 -16
  14. package/dist/{CopilotDriver-D36vbGbn.mjs → CopilotDriver-DXvGBv-s.mjs} +21 -17
  15. package/dist/{CursorDriver-DWuuOSkJ.mjs → CursorDriver-CeB_vMKJ.mjs} +4 -4
  16. package/dist/{CursorDriver-CPBVeesr.cjs → CursorDriver-uNsDetA3.cjs} +3 -3
  17. package/dist/{ForgejoSourceControlProvider-CzmmcAZO.cjs → ForgejoSourceControlProvider-CJLksvL_.cjs} +2 -2
  18. package/dist/{ForgejoSourceControlProvider-CeN7Snfr.mjs → ForgejoSourceControlProvider-Ds0rU_PN.mjs} +3 -3
  19. package/dist/{GitHubSourceControlProvider-Dmz1LJct.mjs → GitHubSourceControlProvider-C7CJAslU.mjs} +3 -3
  20. package/dist/{GitHubSourceControlProvider-DfFR9O2o.cjs → GitHubSourceControlProvider-CrYNFu8S.cjs} +2 -2
  21. package/dist/{GitLabSourceControlProvider-DGoelNmL.cjs → GitLabSourceControlProvider-jbX5M34A.cjs} +2 -2
  22. package/dist/{GitLabSourceControlProvider-C21lwphV.mjs → GitLabSourceControlProvider-u-Y-e8PV.mjs} +3 -3
  23. package/dist/{GrokDriver-CIXj_4ry.cjs → GrokDriver-BJ00ZiYg.cjs} +3 -3
  24. package/dist/{GrokDriver-qKX1a63G.mjs → GrokDriver-CFgjwnvE.mjs} +4 -4
  25. package/dist/{OpenCodeDriver-DDEuwtXl.cjs → OpenCodeDriver-BTxd2Q3Q.cjs} +487 -207
  26. package/dist/{OpenCodeDriver-CbdswhqU.mjs → OpenCodeDriver-DNApoGdu.mjs} +487 -207
  27. package/dist/{SourceControlProviderDiscoveryCatalog-DJWDCoup.cjs → SourceControlProviderDiscoveryCatalog-CPO3a9_U.cjs} +1 -1
  28. package/dist/{SourceControlProviderDiscoveryCatalog-4_4yahsa.mjs → SourceControlProviderDiscoveryCatalog-hXWNwRMn.mjs} +1 -1
  29. package/dist/bin.cjs +1324 -340
  30. package/dist/bin.mjs +1324 -343
  31. package/dist/client/assets/{AccountSettings-Be5_48k0.js → AccountSettings-Cey-16wq.js} +1 -1
  32. package/dist/client/assets/{AiFocusSettings-DIpQXLW2.js → AiFocusSettings-CaHQXDaQ.js} +1 -1
  33. package/dist/client/assets/{AnimatedHeight-BIsV_Z3J.js → AnimatedHeight-BC-qaTJY.js} +1 -1
  34. package/dist/client/assets/AppearanceSettings-B6UaU-_a.js +1 -0
  35. package/dist/client/assets/{BranchToolbar.logic-D7slG_zJ.js → BranchToolbar.logic-DILAA3Cz.js} +1 -1
  36. package/dist/client/assets/ChatRightPanel-D-AL07IU.js +27 -0
  37. package/dist/client/assets/{ChatThreadRouteView-CocRstME.js → ChatThreadRouteView-tEo-zoCf.js} +1 -1
  38. package/dist/client/assets/CommandPaletteDialog-s7yf5Y2S.js +1 -0
  39. package/dist/client/assets/{CompositeItem-F3NGn6aG.js → CompositeItem-97y1QiiT.js} +1 -1
  40. package/dist/client/assets/{CompositeRoot-CmJGfRtc.js → CompositeRoot-C7Mz4Y_2.js} +1 -1
  41. package/dist/client/assets/{ConnectionsSettings-CXabxSaH.js → ConnectionsSettings-B0-Hkwof.js} +2 -2
  42. package/dist/client/assets/{DiagnosticsSettings-CZ3vY43G.js → DiagnosticsSettings-DX5LH9Bt.js} +1 -1
  43. package/dist/client/assets/{DialogHandle-C4uSr9wX.js → DialogHandle-Cl9dQBJp.js} +1 -1
  44. package/dist/client/assets/{DialogPopup-Dck8r8Hn.js → DialogPopup-a1M74u16.js} +1 -1
  45. package/dist/client/assets/DialogRoot-C_DO1gtO.js +1 -0
  46. package/dist/client/assets/{DialogTitle-CCedPAjV.js → DialogTitle-Bk-w3xLJ.js} +1 -1
  47. package/dist/client/assets/{DialogTrigger-CYJ7_YcV.js → DialogTrigger-D9nkMFu2.js} +1 -1
  48. package/dist/client/assets/{DialogViewport-D-CrTM-P.js → DialogViewport-tgJz2Lwn.js} +1 -1
  49. package/dist/client/assets/{DraftChatThreadRouteView-D8Bt3Qnq.js → DraftChatThreadRouteView-BU2IGTR6.js} +1 -1
  50. package/dist/client/assets/{ExternalIdentityWeb.logic-D64j70NH.js → ExternalIdentityWeb.logic-Bn1HigS9.js} +1 -1
  51. package/dist/client/assets/GlassSurface-CDok2tTN.js +1 -0
  52. package/dist/client/assets/{HostedConnectionControls-DxAXv0Hd.js → HostedConnectionControls-Cux_sRCM.js} +1 -1
  53. package/dist/client/assets/HostedHubRoot-CyySCdJV.js +1 -0
  54. package/dist/client/assets/{HostedNativeAuthorizationRoute-CTQe7Vjt.js → HostedNativeAuthorizationRoute-490iDXmk.js} +1 -1
  55. package/dist/client/assets/{HostedRelayTrustNotice-BldMySVi.js → HostedRelayTrustNotice-CcDOAwgS.js} +1 -1
  56. package/dist/client/assets/{Icons-CT3nd2MA.js → Icons-BEtED8P8.js} +1 -1
  57. package/dist/client/assets/{IntegrationsSettingsPanel-D6f3KoqM.js → IntegrationsSettingsPanel-BFTAvxtn.js} +1 -1
  58. package/dist/client/assets/KeybindingsSettings-VYgbhiZF.js +7 -0
  59. package/dist/client/assets/{McpServersSettings-B7YqVvV4.js → McpServersSettings-DSDCjoTn.js} +1 -1
  60. package/dist/client/assets/{MobileSheet-CkeG6_SP.js → MobileSheet-BDvnUC5W.js} +1 -1
  61. package/dist/client/assets/{NewWorktreeDialog-CKr2ioue.js → NewWorktreeDialog-C65Aifeb.js} +1 -1
  62. package/dist/client/assets/{NoActiveThreadState-BD-eNmfn.js → NoActiveThreadState-DehHNgAp.js} +1 -1
  63. package/dist/client/assets/{NodeSecuritySettings-FWM_SeDi.js → NodeSecuritySettings-DW9GJ-kU.js} +1 -1
  64. package/dist/client/assets/{OpinionatedPluginsSettings-BtZQF4Ze.js → OpinionatedPluginsSettings-DbxPOokL.js} +1 -1
  65. package/dist/client/assets/{PhoneGetAppInterstitial-CooQgpSw.js → PhoneGetAppInterstitial-CbyVrtDn.js} +1 -1
  66. package/dist/client/assets/{PhoneGetAppInterstitialBackdrop-B8vfJdZd.js → PhoneGetAppInterstitialBackdrop-BA4R225F.js} +1 -1
  67. package/dist/client/assets/PhoneHome-c0j_TBEC.js +1 -0
  68. package/dist/client/assets/PhoneSettingsSurface-5LFRIx_5.js +1 -0
  69. package/dist/client/assets/{ProjectFavicon-qZGdjYCM.js → ProjectFavicon-CeVJCQCy.js} +1 -1
  70. package/dist/client/assets/{ProviderModelPicker-D0w23uWo.js → ProviderModelPicker-MFRYAv_3.js} +1 -1
  71. package/dist/client/assets/{ProviderUpdateLaunchNotification.logic-BkoRegCn.js → ProviderUpdateLaunchNotification.logic-CywRitn3.js} +1 -1
  72. package/dist/client/assets/ProvidersSettingsPanel-FYBEqSr_.js +1 -0
  73. package/dist/client/assets/{RedactedSensitiveText-CxtaUiKH.js → RedactedSensitiveText-BuWSWty8.js} +1 -1
  74. package/dist/client/assets/RootAppShell-5HrP6N8H.js +6 -0
  75. package/dist/client/assets/{RycoLetterMark-Bk0kvGJ_.js → RycoLetterMark-CZYntY8t.js} +1 -1
  76. package/dist/client/assets/SettingsDialog-CpwoqGS8.js +1 -0
  77. package/dist/client/assets/{SettingsPanels-Dr4f2y9l.js → SettingsPanels-COWRB29-.js} +3 -3
  78. package/dist/client/assets/{SettingsPanels.editor-B2x4U4rW.js → SettingsPanels.editor-lbLEbllb.js} +1 -1
  79. package/dist/client/assets/SourceControlSettings-DvBNelcO.js +1 -0
  80. package/dist/client/assets/{StatisticsPage-Bjouapmf.js → StatisticsPage-DxAKqvVX.js} +1 -1
  81. package/dist/client/assets/{StatisticsPanel-D_khPph6.js → StatisticsPanel-C0xGLlMA.js} +1 -1
  82. package/dist/client/assets/{StatisticsSettingsLink-Cx43bOeo.js → StatisticsSettingsLink-B7SZerf3.js} +1 -1
  83. package/dist/client/assets/ThreadStatusIndicators-CIOM98q2.js +0 -0
  84. package/dist/client/assets/{ThreadTerminalDrawer-DDHEuRGB.js → ThreadTerminalDrawer-DRelLlEP.js} +1 -1
  85. package/dist/client/assets/{ThreadWorkspacePanel-QF3KwbGm.js → ThreadWorkspacePanel-CktVSliZ.js} +3 -3
  86. package/dist/client/assets/{ToolbarRootContext-BgqqXVly.js → ToolbarRootContext-B1g8IP6k.js} +1 -1
  87. package/dist/client/assets/{WorkItemsTab-AOVwVvb7.js → WorkItemsTab-CahU_t_S.js} +12 -12
  88. package/dist/client/assets/{alert-LqMhbdE9.js → alert-DomE7dAt.js} +1 -1
  89. package/dist/client/assets/{alert-dialog-DxoA6ky8.js → alert-dialog-9Jyh0e8u.js} +1 -1
  90. package/dist/client/assets/appearancePreferences-BhNRCg6W.js +1 -0
  91. package/dist/client/assets/authorization-D8lJzXTE.js +1 -0
  92. package/dist/client/assets/{badge-CXw6fWrB.js → badge-w43sx8eF.js} +1 -1
  93. package/dist/client/assets/{branding-BDfN6Spd.js → branding-B7DcCXjn.js} +1 -1
  94. package/dist/client/assets/{button-BAbJxRzt.js → button-DG8WqjNn.js} +1 -1
  95. package/dist/client/assets/{capabilities-3zgirmmI.js → capabilities-B1FHGoov.js} +1 -1
  96. package/dist/client/assets/{chatThreadActions-DQ8aOQ1g.js → chatThreadActions-BZvyhfKr.js} +1 -1
  97. package/dist/client/assets/{collapsible-dxy6kc2k.js → collapsible-EhAEe5S9.js} +1 -1
  98. package/dist/client/assets/{command-CGNKG_Oe.js → command-Cyn6yIEa.js} +1 -1
  99. package/dist/client/assets/composerDraftStore-TYv9j3vY.js +11 -0
  100. package/dist/client/assets/{data-list-CYKBxN62.js → data-list-DTdqWMGN.js} +1 -1
  101. package/dist/client/assets/{desktopUpdateAtoms-CyfPW2jg.js → desktopUpdateAtoms-CPlZiFRm.js} +1 -1
  102. package/dist/client/assets/{desktopWorkspace-DHUZEpfy.js → desktopWorkspace-DEZ30LlY.js} +1 -1
  103. package/dist/client/assets/device-CHdXzvhB.js +168 -0
  104. package/dist/client/assets/{dialog-DQsYchqu.js → dialog-BNmFD6Nh.js} +1 -1
  105. package/dist/client/assets/{draft-input-CkzOk8BY.js → draft-input-dP7F8odz.js} +1 -1
  106. package/dist/client/assets/editorPreferences-B4GvqMiF.js +1 -0
  107. package/dist/client/assets/{empty-DwzqNgCP.js → empty-Ccxhyvdf.js} +1 -1
  108. package/dist/client/assets/{env-B4arEvJg.js → env-Bcq9YR3B.js} +1 -1
  109. package/dist/client/assets/{getPseudoElementBounds-X62ElHN8.js → getPseudoElementBounds-CO5HJT7x.js} +1 -1
  110. package/dist/client/assets/{group-D9ER9giz.js → group-CzdKmc45.js} +1 -1
  111. package/dist/client/assets/{index-CQmEMMQH.js → index-Gre6bNC8.js} +2 -2
  112. package/dist/client/assets/{input-CHEwW3oH.js → input-BZz4eLRl.js} +1 -1
  113. package/dist/client/assets/{kbd-DCGQZk18.js → kbd-DbvN3zTb.js} +1 -1
  114. package/dist/client/assets/{keybindings-CWJ7E9ZI.js → keybindings-BPE3eEAM.js} +1 -1
  115. package/dist/client/assets/{label-CVFHsLFO.js → label-DZf4lbNF.js} +1 -1
  116. package/dist/client/assets/{lib-qiiNMGgU.js → lib-DgOYoged.js} +1 -1
  117. package/dist/client/assets/{liquidGlass-CPsvmaF0.js → liquidGlass-yFkZrRk5.js} +1 -1
  118. package/dist/client/assets/{logging-M8H3z7rQ.js → logging-81iP6Hps.js} +1 -1
  119. package/dist/client/assets/main-DlGNPwsH.css +2 -0
  120. package/dist/client/assets/main-Dz0zookE.js +9 -0
  121. package/dist/client/assets/{menu-Dvxh8sD5.js → menu-B6UEFcn0.js} +1 -1
  122. package/dist/client/assets/{popover-CuH9Yrj3.js → popover-BuYzXGwl.js} +1 -1
  123. package/dist/client/assets/primary-CiDY2oUi.js +2 -0
  124. package/dist/client/assets/projectPaths-D6fHIU1b.js +1 -0
  125. package/dist/client/assets/{providerDriverMeta-I0TSo-QI.js → providerDriverMeta-sBwZhQoN.js} +1 -1
  126. package/dist/client/assets/{providerIconUtils-X0Z3EK-Q.js → providerIconUtils-DiDJeNtT.js} +1 -1
  127. package/dist/client/assets/providerInstances-vd2eZtHx.js +1 -0
  128. package/dist/client/assets/providerModels-vd2eZtHx.js +1 -0
  129. package/dist/client/assets/{qr-code-Bddq6K7S.js → qr-code-Ie92aZvE.js} +1 -1
  130. package/dist/client/assets/{radio-group-CBZFr4C8.js → radio-group-BuuTEtdC.js} +1 -1
  131. package/dist/client/assets/{resolveAriaLabelledBy-CD_ugzhJ.js → resolveAriaLabelledBy-0FA0k4xp.js} +1 -1
  132. package/dist/client/assets/{rightPanelRouteSearch-DB5gQGHK.js → rightPanelRouteSearch-BS8CkNS6.js} +1 -1
  133. package/dist/client/assets/runtime-CPM0EUhb.js +1 -0
  134. package/dist/client/assets/{scroll-area-Drsa8bNB.js → scroll-area-C0yF015F.js} +1 -1
  135. package/dist/client/assets/{scrollEdges-B-cqxY4l.js → scrollEdges-DI5Y3mtR.js} +1 -1
  136. package/dist/client/assets/{select-BYbVr-yg.js → select-CZukJlTn.js} +1 -1
  137. package/dist/client/assets/{separator-CdS5bi4Z.js → separator-D4ckGtPe.js} +1 -1
  138. package/dist/client/assets/session-logic-BalPN1Sc.js +4 -0
  139. package/dist/client/assets/{settingsDialogStore-ygYoScKe.js → settingsDialogStore-LxRFC5hh.js} +1 -1
  140. package/dist/client/assets/{settingsLayout-D8glO7f1.js → settingsLayout-CHJT5wtl.js} +1 -1
  141. package/dist/client/assets/{sheet-BO78gIKZ.js → sheet-BNfImQ-7.js} +1 -1
  142. package/dist/client/assets/{sidebar-Dm6l2GA6.js → sidebar-CFGg5Tkr.js} +1 -1
  143. package/dist/client/assets/sidebarProjectFolders-bhNsO9Z_.js +4 -0
  144. package/dist/client/assets/{sidebarStatusText-D0HT0fek.js → sidebarStatusText-C8QBhZhZ.js} +1 -1
  145. package/dist/client/assets/{skeleton-CvQSeJbw.js → skeleton-DOgQaVXv.js} +1 -1
  146. package/dist/client/assets/{spinner-ClF0jOcX.js → spinner-ClQu8SdC.js} +1 -1
  147. package/dist/client/assets/{src-Vf4LVnMX.js → src-DmPIm3ie.js} +1 -1
  148. package/dist/client/assets/storeSelectors-Cf2WDMfx.js +1 -0
  149. package/dist/client/assets/{switch-BTGo9Yip.js → switch-BZjA7VT9.js} +1 -1
  150. package/dist/client/assets/{terminal-links-CZ3c9AbA.js → terminal-links-CzJomeox.js} +1 -1
  151. package/dist/client/assets/{textarea-RFPODxWW.js → textarea-DHdmRD1r.js} +1 -1
  152. package/dist/client/assets/threadPinning-BLqwZebi.js +1 -0
  153. package/dist/client/assets/{threadPriorityRefreshRuntime-Ct5pnIbX.js → threadPriorityRefreshRuntime-BoNAlBXK.js} +1 -1
  154. package/dist/client/assets/{toast-CcSCAm4B.js → toast-C-0Ft2jD.js} +1 -1
  155. package/dist/client/assets/{toggle-I6h33Cu5.js → toggle-DsnOFDbJ.js} +1 -1
  156. package/dist/client/assets/{toggle-group-mLIkiJtU.js → toggle-group-Chxh9G6t.js} +1 -1
  157. package/dist/client/assets/{tooltip-C8sAONBj.js → tooltip-C_-9XEfA.js} +1 -1
  158. package/dist/client/assets/types-Cf2WDMfx.js +1 -0
  159. package/dist/client/assets/{uiStateStore-B6pjzSjj.js → uiStateStore-DzUrk2GS.js} +1 -1
  160. package/dist/client/assets/useAtlassian-CoHKzu-e.js +0 -0
  161. package/dist/client/assets/{useButton-D__1LqCF.js → useButton-BmvYhoMC.js} +1 -1
  162. package/dist/client/assets/{useCompositeListItem-Cmr_nuuG.js → useCompositeListItem-D0PvH4nv.js} +1 -1
  163. package/dist/client/assets/{useDebouncedValue-DHjoudTq.js → useDebouncedValue-s0BC8Yyp.js} +1 -1
  164. package/dist/client/assets/{useFloatingRootContext-D5EZmrCa.js → useFloatingRootContext-CLCaQEJk.js} +1 -1
  165. package/dist/client/assets/{useHandleNewThread-DX2FtXcP.js → useHandleNewThread-Bw460iXT.js} +1 -1
  166. package/dist/client/assets/{useLabelableId-DnQJ7amm.js → useLabelableId-CB_9OReR.js} +1 -1
  167. package/dist/client/assets/{useLocation-CDeYzWW6.js → useLocation-DGJMt6gP.js} +1 -1
  168. package/dist/client/assets/{useOpenInteractionType-CjtpACKR.js → useOpenInteractionType-BSSI2GzS.js} +1 -1
  169. package/dist/client/assets/{usePhoneThreadActions-BEa3VzGG.js → usePhoneThreadActions-BIDUSWSI.js} +1 -1
  170. package/dist/client/assets/{usePopupViewport-BuhsNdVy.js → usePopupViewport-8F-J1h5f.js} +1 -1
  171. package/dist/client/assets/{useScrollLock-D3tMGsRk.js → useScrollLock-CBz-5_MX.js} +1 -1
  172. package/dist/client/assets/{useStatistics-CtunoTE-.js → useStatistics-B91973jb.js} +2 -2
  173. package/dist/client/assets/{useSwipeDismiss-CbgDJvw1.js → useSwipeDismiss-D22_vuiH.js} +1 -1
  174. package/dist/client/assets/{useTheme-DiC-5xCb.js → useTheme-By1kfyiU.js} +1 -1
  175. package/dist/client/assets/{useThreadActions-fN-Al13y.js → useThreadActions-BCH01d6u.js} +1 -1
  176. package/dist/client/assets/{useTriggerFocusGuards-CrugmkhX.js → useTriggerFocusGuards-f7afwACm.js} +1 -1
  177. package/dist/client/assets/{useValueChanged-MQtIzPIU.js → useValueChanged-EkWF0C3k.js} +1 -1
  178. package/dist/client/assets/{utils-BofFIn5Y.js → utils-CV2fJJxC.js} +1 -1
  179. package/dist/client/index.html +1 -1
  180. package/dist/{collectUint8StreamText-Bb52hlpd.cjs → collectUint8StreamText-Dsbmrw73.cjs} +48 -10
  181. package/dist/{collectUint8StreamText-EDg4F0TU.mjs → collectUint8StreamText-oFvWyN3_.mjs} +37 -11
  182. package/dist/{makeManagedServerProvider-itynW7xv.cjs → makeManagedServerProvider-CANTNAsz.cjs} +9 -2
  183. package/dist/{makeManagedServerProvider-Cf8bNWwc.mjs → makeManagedServerProvider-PLtJj7EV.mjs} +10 -3
  184. package/package.json +1 -1
  185. package/dist/client/assets/AppearanceSettings-CYbSApl4.js +0 -1
  186. package/dist/client/assets/ChatRightPanel-BIS1DPGa.js +0 -27
  187. package/dist/client/assets/CommandPaletteDialog-C5xAo65V.js +0 -1
  188. package/dist/client/assets/DialogRoot-BpIvUdm7.js +0 -1
  189. package/dist/client/assets/GlassSurface-C3IIWMu9.js +0 -1
  190. package/dist/client/assets/HostedHubRoot-Cc8GYcK6.js +0 -1
  191. package/dist/client/assets/KeybindingsSettings-D2bNQPI-.js +0 -7
  192. package/dist/client/assets/PhoneHome-BtPE7bQn.js +0 -1
  193. package/dist/client/assets/PhoneSettingsSurface-tcFCccEL.js +0 -1
  194. package/dist/client/assets/ProvidersSettingsPanel-B3aBKY--.js +0 -1
  195. package/dist/client/assets/RootAppShell-C-0ChFVJ.js +0 -6
  196. package/dist/client/assets/SettingsDialog-Bbuoh793.js +0 -1
  197. package/dist/client/assets/SourceControlSettings-CkiYR4lR.js +0 -1
  198. package/dist/client/assets/ThreadStatusIndicators-ZImeLExQ.js +0 -0
  199. package/dist/client/assets/appearancePreferences-COvj0WMT.js +0 -1
  200. package/dist/client/assets/authorization-mIJKV2yp.js +0 -1
  201. package/dist/client/assets/composerDraftStore-CdJJZe42.js +0 -11
  202. package/dist/client/assets/device-B_qvyvtW.js +0 -168
  203. package/dist/client/assets/editorPreferences-DHIJntKF.js +0 -1
  204. package/dist/client/assets/main-BKS5Nf2_.js +0 -9
  205. package/dist/client/assets/main-DaYHZt-J.css +0 -2
  206. package/dist/client/assets/panel-right-BodNpkM9.js +0 -1
  207. package/dist/client/assets/primary-BzLEg2w1.js +0 -2
  208. package/dist/client/assets/projectPaths-BAd6NFcE.js +0 -1
  209. package/dist/client/assets/providerInstances-BJcfB_9E.js +0 -1
  210. package/dist/client/assets/providerModels-BJcfB_9E.js +0 -1
  211. package/dist/client/assets/runtime-CXut_g4p.js +0 -1
  212. package/dist/client/assets/session-logic-GZix7S2I.js +0 -4
  213. package/dist/client/assets/sidebarProjectFolders-cnmz3B_-.js +0 -4
  214. package/dist/client/assets/storeSelectors-DYekgeHu.js +0 -1
  215. package/dist/client/assets/types-DYekgeHu.js +0 -1
  216. package/dist/client/assets/useAppearancePreference-BlLlxQl7.js +0 -1
  217. package/dist/client/assets/useAtlassian-9-hy2f8z.js +0 -0
package/dist/bin.cjs CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
4
4
  const require_rolldown_runtime = require("./rolldown-runtime-LGfotAqq.cjs");
5
- const require_collectUint8StreamText = require("./collectUint8StreamText-Bb52hlpd.cjs");
5
+ const require_collectUint8StreamText = require("./collectUint8StreamText-Dsbmrw73.cjs");
6
6
  const require_Metrics = require("./Metrics-DIjMQ5pa.cjs");
7
- const require_SourceControlProviderDiscoveryCatalog = require("./SourceControlProviderDiscoveryCatalog-DJWDCoup.cjs");
7
+ const require_SourceControlProviderDiscoveryCatalog = require("./SourceControlProviderDiscoveryCatalog-CPO3a9_U.cjs");
8
8
  const require_sourceControl = require("./sourceControl-B0D1Op29.cjs");
9
9
  let _effect_platform_node_NodeRuntime = require("@effect/platform-node/NodeRuntime");
10
10
  _effect_platform_node_NodeRuntime = require_rolldown_runtime.__toESM(_effect_platform_node_NodeRuntime, 1);
@@ -75,7 +75,6 @@ let node_http = require("node:http");
75
75
  let effect_unstable_sql_SqlSchema = require("effect/unstable/sql/SqlSchema");
76
76
  effect_unstable_sql_SqlSchema = require_rolldown_runtime.__toESM(effect_unstable_sql_SqlSchema, 1);
77
77
  let effect_Number = require("effect/Number");
78
- let node_url = require("node:url");
79
78
  let _pierre_diffs = require("@pierre/diffs");
80
79
  let effect_unstable_http_HttpServerRequest = require("effect/unstable/http/HttpServerRequest");
81
80
  effect_unstable_http_HttpServerRequest = require_rolldown_runtime.__toESM(effect_unstable_http_HttpServerRequest, 1);
@@ -1539,6 +1538,7 @@ function attachmentRelativePath(attachment) {
1539
1538
  });
1540
1539
  return `${attachment.id}${extension}`;
1541
1540
  }
1541
+ case "file": return `${attachment.id}.bin`;
1542
1542
  }
1543
1543
  }
1544
1544
  function resolveAttachmentPath(input) {
@@ -1547,6 +1547,64 @@ function resolveAttachmentPath(input) {
1547
1547
  relativePath: attachmentRelativePath(input.attachment)
1548
1548
  });
1549
1549
  }
1550
+ function attachmentByteLimit(attachment) {
1551
+ return attachment.type === "image" ? require_collectUint8StreamText.PROVIDER_SEND_TURN_MAX_IMAGE_BYTES : require_collectUint8StreamText.PROVIDER_SEND_TURN_MAX_FILE_BYTES;
1552
+ }
1553
+ /**
1554
+ * Opens and reads a persisted attachment through one descriptor. Comparing
1555
+ * the path's lstat identity with the opened descriptor prevents a path or
1556
+ * symlink swap between validation and read, including on platforms without a
1557
+ * useful O_NOFOLLOW flag.
1558
+ */
1559
+ function readPersistedAttachment(input) {
1560
+ const attachmentPath = resolveAttachmentPath(input);
1561
+ if (!attachmentPath) return {
1562
+ ok: false,
1563
+ reason: `Invalid attachment id '${input.attachment.id}'.`
1564
+ };
1565
+ let descriptor;
1566
+ try {
1567
+ const pathInfo = (0, node_fs.lstatSync)(attachmentPath);
1568
+ if (!pathInfo.isFile()) return {
1569
+ ok: false,
1570
+ reason: `Attachment '${input.attachment.name}' is not a regular file.`
1571
+ };
1572
+ const noFollow = typeof node_fs.constants.O_NOFOLLOW === "number" ? node_fs.constants.O_NOFOLLOW : 0;
1573
+ descriptor = (0, node_fs.openSync)(attachmentPath, node_fs.constants.O_RDONLY | noFollow);
1574
+ const openedInfo = (0, node_fs.fstatSync)(descriptor);
1575
+ if (!openedInfo.isFile() || openedInfo.dev !== pathInfo.dev || openedInfo.ino !== pathInfo.ino) return {
1576
+ ok: false,
1577
+ reason: `Attachment '${input.attachment.name}' changed while it was being opened. Attach it again and retry.`
1578
+ };
1579
+ const limit = attachmentByteLimit(input.attachment);
1580
+ if (openedInfo.size <= 0 || openedInfo.size > limit) return {
1581
+ ok: false,
1582
+ reason: `Attachment '${input.attachment.name}' is ${openedInfo.size} bytes; limit is ${limit} bytes.`
1583
+ };
1584
+ if (openedInfo.size !== input.attachment.sizeBytes) return {
1585
+ ok: false,
1586
+ reason: `Attachment '${input.attachment.name}' changed after upload; expected ${input.attachment.sizeBytes} bytes but found ${openedInfo.size}.`
1587
+ };
1588
+ const bytes = (0, node_fs.readFileSync)(descriptor);
1589
+ const completedInfo = (0, node_fs.fstatSync)(descriptor);
1590
+ if (completedInfo.dev !== openedInfo.dev || completedInfo.ino !== openedInfo.ino || completedInfo.size !== openedInfo.size || bytes.byteLength !== openedInfo.size) return {
1591
+ ok: false,
1592
+ reason: `Attachment '${input.attachment.name}' changed while it was being read. Attach it again and retry.`
1593
+ };
1594
+ return {
1595
+ ok: true,
1596
+ bytes,
1597
+ sizeBytes: bytes.byteLength
1598
+ };
1599
+ } catch {
1600
+ return {
1601
+ ok: false,
1602
+ reason: `Attachment '${input.attachment.name}' is missing, unreadable, or not a safe regular file.`
1603
+ };
1604
+ } finally {
1605
+ if (descriptor !== void 0) (0, node_fs.closeSync)(descriptor);
1606
+ }
1607
+ }
1550
1608
  function resolveAttachmentPathById(input) {
1551
1609
  const normalizedId = normalizeAttachmentRelativePath(input.attachmentId);
1552
1610
  if (!normalizedId || normalizedId.includes("/") || normalizedId.includes(".")) return null;
@@ -1996,7 +2054,7 @@ const authClientsRevokeOthersRouteLayer = effect_unstable_http.HttpRouter.add("P
1996
2054
  var ServerEnvironment = class extends effect.Context.Service()("ryco/environment/Services/ServerEnvironment") {};
1997
2055
  //#endregion
1998
2056
  //#region src/http.ts
1999
- const PROJECT_FAVICON_CACHE_CONTROL = "public, max-age=3600";
2057
+ const PROJECT_FAVICON_CACHE_CONTROL = "private, max-age=3600";
2000
2058
  const PROJECT_AVATAR_MAX_BYTES = 2097152;
2001
2059
  const PROJECT_AVATAR_CACHE_CONTROL = "private, max-age=0, must-revalidate";
2002
2060
  const STATIC_INDEX_CACHE_CONTROL = "no-cache";
@@ -2010,6 +2068,19 @@ const LOOPBACK_HOSTNAMES = /* @__PURE__ */ new Set([
2010
2068
  "::1",
2011
2069
  "localhost"
2012
2070
  ]);
2071
+ const SVG_CONTENT_SECURITY_POLICY = "default-src 'none'; style-src 'unsafe-inline'; sandbox";
2072
+ const DOWNLOAD_CONTENT_SECURITY_POLICY = "default-src 'none'; sandbox";
2073
+ const INLINE_ATTACHMENT_EXTENSIONS = /* @__PURE__ */ new Set([
2074
+ ".avif",
2075
+ ".bmp",
2076
+ ".gif",
2077
+ ".ico",
2078
+ ".jpeg",
2079
+ ".jpg",
2080
+ ".png",
2081
+ ".svg",
2082
+ ".webp"
2083
+ ]);
2013
2084
  const STATIC_CONTENT_TYPES = {
2014
2085
  ".css": "text/css; charset=utf-8",
2015
2086
  ".html": "text/html; charset=utf-8",
@@ -2054,6 +2125,33 @@ function resolveStaticCacheControl(staticRelativePath) {
2054
2125
  const basename = normalized.split("/").at(-1) ?? normalized;
2055
2126
  return /(?:^|[-.])[a-zA-Z0-9_-]{8,}\.[a-zA-Z0-9]+$/u.test(basename) ? STATIC_IMMUTABLE_CACHE_CONTROL : STATIC_INDEX_CACHE_CONTROL;
2056
2127
  }
2128
+ /** Build a download disposition with a safe ASCII fallback and UTF-8 filename. */
2129
+ function downloadContentDisposition(fileName) {
2130
+ if (fileName === void 0) return "attachment";
2131
+ const sanitized = fileName.toWellFormed().replace(/[\u0000-\u001f"\\]/g, "_");
2132
+ const asciiFallback = sanitized.replace(/[^\u0020-\u007e]/g, "_");
2133
+ const extendedName = encodeURIComponent(sanitized).replace(/['()*]/g, (character) => `%${character.charCodeAt(0).toString(16).toUpperCase()}`);
2134
+ return `attachment; filename="${asciiFallback}"${asciiFallback === sanitized ? "" : `; filename*=UTF-8''${extendedName}`}`;
2135
+ }
2136
+ function userAssetResponseHeaders(filePath, path) {
2137
+ const extension = path.extname(filePath).toLowerCase();
2138
+ return {
2139
+ "Cache-Control": "private, max-age=3600",
2140
+ "X-Content-Type-Options": "nosniff",
2141
+ ...!INLINE_ATTACHMENT_EXTENSIONS.has(extension) ? {
2142
+ "Content-Disposition": downloadContentDisposition(path.basename(filePath)),
2143
+ "Content-Security-Policy": DOWNLOAD_CONTENT_SECURITY_POLICY,
2144
+ "Content-Type": "application/octet-stream"
2145
+ } : extension === ".svg" ? { "Content-Security-Policy": SVG_CONTENT_SECURITY_POLICY } : {}
2146
+ };
2147
+ }
2148
+ function inlineImageResponseHeaders(filePath) {
2149
+ return {
2150
+ "Cache-Control": PROJECT_FAVICON_CACHE_CONTROL,
2151
+ "X-Content-Type-Options": "nosniff",
2152
+ ...filePath.toLowerCase().endsWith(".svg") ? { "Content-Security-Policy": SVG_CONTENT_SECURITY_POLICY } : {}
2153
+ };
2154
+ }
2057
2155
  function resolveStaticContentType(filePath, path) {
2058
2156
  return STATIC_CONTENT_TYPES[path.extname(filePath).toLowerCase()] ?? "application/octet-stream";
2059
2157
  }
@@ -2116,11 +2214,13 @@ const attachmentsRouteLayer = effect_unstable_http.HttpRouter.add("GET", `${ATTA
2116
2214
  relativePath: normalizedRelativePath
2117
2215
  });
2118
2216
  if (!filePath) return effect_unstable_http.HttpServerResponse.text(isIdLookup ? "Not Found" : "Invalid attachment path", { status: isIdLookup ? 404 : 400 });
2119
- const fileInfo = yield* (yield* effect.FileSystem.FileSystem).stat(filePath).pipe(effect.Effect.catch(() => effect.Effect.succeed(null)));
2217
+ const fileSystem = yield* effect.FileSystem.FileSystem;
2218
+ const path = yield* effect.Path.Path;
2219
+ const fileInfo = yield* fileSystem.stat(filePath).pipe(effect.Effect.catch(() => effect.Effect.succeed(null)));
2120
2220
  if (!fileInfo || fileInfo.type !== "File") return effect_unstable_http.HttpServerResponse.text("Not Found", { status: 404 });
2121
2221
  return yield* effect_unstable_http.HttpServerResponse.file(filePath, {
2122
2222
  status: 200,
2123
- headers: { "Cache-Control": "public, max-age=31536000, immutable" }
2223
+ headers: userAssetResponseHeaders(filePath, path)
2124
2224
  }).pipe(effect.Effect.catch(() => effect.Effect.succeed(effect_unstable_http.HttpServerResponse.text("Internal Server Error", { status: 500 }))));
2125
2225
  }).pipe(effect.Effect.catchTag("AuthError", respondToAuthError)));
2126
2226
  const projectFaviconRouteLayer = effect_unstable_http.HttpRouter.add("GET", "/api/project-favicon", effect.Effect.gen(function* () {
@@ -2134,11 +2234,11 @@ const projectFaviconRouteLayer = effect_unstable_http.HttpRouter.add("GET", "/ap
2134
2234
  if (!faviconFilePath) return effect_unstable_http.HttpServerResponse.text(FALLBACK_PROJECT_FAVICON_SVG, {
2135
2235
  status: 200,
2136
2236
  contentType: "image/svg+xml",
2137
- headers: { "Cache-Control": PROJECT_FAVICON_CACHE_CONTROL }
2237
+ headers: inlineImageResponseHeaders("fallback.svg")
2138
2238
  });
2139
2239
  return yield* effect_unstable_http.HttpServerResponse.file(faviconFilePath, {
2140
2240
  status: 200,
2141
- headers: { "Cache-Control": PROJECT_FAVICON_CACHE_CONTROL }
2241
+ headers: inlineImageResponseHeaders(faviconFilePath)
2142
2242
  }).pipe(effect.Effect.catch(() => effect.Effect.succeed(effect_unstable_http.HttpServerResponse.text("Internal Server Error", { status: 500 }))));
2143
2243
  }).pipe(effect.Effect.catchTag("AuthError", respondToAuthError)));
2144
2244
  const AvatarFormSchema = effect_Schema.Struct({ avatar: effect_unstable_http.Multipart.SingleFileSchema });
@@ -5893,6 +5993,7 @@ const makeRuntimeSqliteLayer = effect.Effect.fn("makeRuntimeSqliteLayer")(functi
5893
5993
  const setup = effect.Layer.effectDiscard(effect.Effect.gen(function* () {
5894
5994
  const startedAt = Date.now();
5895
5995
  const sql = yield* effect_unstable_sql_SqlClient.SqlClient;
5996
+ yield* sql`PRAGMA busy_timeout = 5000;`;
5896
5997
  yield* sql`PRAGMA journal_mode = WAL;`;
5897
5998
  yield* sql`PRAGMA foreign_keys = ON;`;
5898
5999
  yield* runMigrations();
@@ -7901,6 +8002,31 @@ const makeGitVcsDriverCore = effect.Effect.fn("makeGitVcsDriverCore")(function*
7901
8002
  }
7902
8003
  const currentUpstream = yield* resolveCurrentUpstream(cwd).pipe(effect.Effect.catch(() => effect.Effect.succeed(null)));
7903
8004
  if (currentUpstream) {
8005
+ if (!(branch === currentUpstream.branchName || branch.endsWith(`/${currentUpstream.branchName}`) && currentUpstream.upstreamRef.endsWith(`/${branch}`))) {
8006
+ const remoteName = (yield* resolvePushRemoteName(cwd, branch).pipe(effect.Effect.catch(() => effect.Effect.succeed(null)))) ?? currentUpstream.remoteName;
8007
+ const publishBranch = yield* resolvePublishBranchName(cwd, branch);
8008
+ if ((yield* runGitStdout("GitVcsDriver.pushCurrentBranch.readMergeBase", cwd, [
8009
+ "config",
8010
+ "--get",
8011
+ `branch.${branch}.gh-merge-base`
8012
+ ], true).pipe(effect.Effect.map((stdout) => stdout.trim()))).length === 0) yield* runGit("GitVcsDriver.pushCurrentBranch.recordMergeBase", cwd, [
8013
+ "config",
8014
+ `branch.${branch}.gh-merge-base`,
8015
+ currentUpstream.branchName
8016
+ ]);
8017
+ yield* runGit("GitVcsDriver.pushCurrentBranch.pushOwnBranch", cwd, [
8018
+ "push",
8019
+ "-u",
8020
+ remoteName,
8021
+ `HEAD:refs/heads/${publishBranch}`
8022
+ ]);
8023
+ return {
8024
+ status: "pushed",
8025
+ branch,
8026
+ upstreamBranch: `${remoteName}/${publishBranch}`,
8027
+ setUpstream: true
8028
+ };
8029
+ }
7904
8030
  yield* runGit("GitVcsDriver.pushCurrentBranch.pushUpstream", cwd, [
7905
8031
  "push",
7906
8032
  currentUpstream.remoteName,
@@ -8129,6 +8255,25 @@ const makeGitVcsDriverCore = effect.Effect.fn("makeGitVcsDriverCore")(function*
8129
8255
  input.refName
8130
8256
  ];
8131
8257
  yield* executeGit("GitVcsDriver.createWorktree", input.cwd, args, { fallbackErrorMessage: "git worktree add failed" });
8258
+ const gitmodulesPath = path.join(worktreePath, ".gitmodules");
8259
+ if (yield* fileSystem.exists(gitmodulesPath).pipe(effect.Effect.mapError((cause) => new require_collectUint8StreamText.GitCommandError({
8260
+ operation: "GitVcsDriver.createWorktree.inspectSubmodules",
8261
+ command: "inspect .gitmodules",
8262
+ cwd: worktreePath,
8263
+ detail: `Failed to inspect ${gitmodulesPath} after creating the worktree.`,
8264
+ cause
8265
+ })))) {
8266
+ const submoduleArgs = [
8267
+ "submodule",
8268
+ "update",
8269
+ "--init",
8270
+ "--recursive"
8271
+ ];
8272
+ yield* executeGit("GitVcsDriver.createWorktree.initializeSubmodules", worktreePath, submoduleArgs, {
8273
+ timeoutMs: 12e4,
8274
+ fallbackErrorMessage: "git submodule initialization failed"
8275
+ }).pipe(effect.Effect.mapError((error) => createGitCommandError("GitVcsDriver.createWorktree.initializeSubmodules", worktreePath, submoduleArgs, `The worktree was created, but its submodules could not be initialized: ${error.detail}`, error)));
8276
+ }
8132
8277
  if (input.dependencyHydration === "copyInstallDirs") yield* copyWorktreeDependencyInstallDirs({
8133
8278
  cwd: input.cwd,
8134
8279
  worktreePath
@@ -8193,6 +8338,15 @@ const makeGitVcsDriverCore = effect.Effect.fn("makeGitVcsDriverCore")(function*
8193
8338
  fallbackErrorMessage: "git worktree remove failed"
8194
8339
  }).pipe(effect.Effect.mapError((error) => createGitCommandError("GitVcsDriver.removeWorktree", input.cwd, args, `${commandLabel$1(args)} failed (cwd: ${input.cwd}): ${error.message}`, error)));
8195
8340
  });
8341
+ const pruneWorktrees = (cwd) => executeGit("GitVcsDriver.pruneWorktrees", cwd, [
8342
+ "worktree",
8343
+ "prune",
8344
+ "--expire",
8345
+ "now"
8346
+ ], {
8347
+ timeoutMs: 1e4,
8348
+ fallbackErrorMessage: "git worktree prune failed"
8349
+ }).pipe(effect.Effect.asVoid);
8196
8350
  const renameBranch = effect.Effect.fn("renameBranch")(function* (input) {
8197
8351
  if (input.oldBranch === input.newBranch) return { branch: input.newBranch };
8198
8352
  const targetBranch = yield* resolveAvailableBranchName(input.cwd, input.newBranch);
@@ -8319,6 +8473,7 @@ const makeGitVcsDriverCore = effect.Effect.fn("makeGitVcsDriverCore")(function*
8319
8473
  fetchRemoteTrackingBranch,
8320
8474
  setBranchUpstream,
8321
8475
  removeWorktree,
8476
+ pruneWorktrees,
8322
8477
  renameBranch,
8323
8478
  createRef,
8324
8479
  deleteBranch,
@@ -12697,26 +12852,26 @@ const make$12 = effect.Effect.fn("makeSourceControlProviderRegistry")(function*
12697
12852
  const azureDevOpsCli = yield* AzureDevOpsCli;
12698
12853
  const fileSystem = yield* effect.FileSystem.FileSystem;
12699
12854
  const github = yield* makeLazyProvider("github", effect.Effect.tryPromise({
12700
- try: () => Promise.resolve().then(() => require("./GitHubSourceControlProvider-DfFR9O2o.cjs")),
12855
+ try: () => Promise.resolve().then(() => require("./GitHubSourceControlProvider-CrYNFu8S.cjs")),
12701
12856
  catch: (cause) => providerLoadError("github", cause)
12702
12857
  }).pipe(effect.Effect.flatMap((module) => module.make()), effect.Effect.provideService(GitHubCli, githubCli), effect.Effect.provideService(effect.FileSystem.FileSystem, fileSystem)));
12703
12858
  const gitlab = yield* makeLazyProvider("gitlab", effect.Effect.tryPromise({
12704
- try: () => Promise.resolve().then(() => require("./GitLabSourceControlProvider-DGoelNmL.cjs")),
12859
+ try: () => Promise.resolve().then(() => require("./GitLabSourceControlProvider-jbX5M34A.cjs")),
12705
12860
  catch: (cause) => providerLoadError("gitlab", cause)
12706
12861
  }).pipe(effect.Effect.flatMap((module) => module.make()), effect.Effect.provideService(GitLabCli, gitlabCli)));
12707
12862
  const bitbucket = yield* makeLazyProvider("bitbucket", effect.Effect.tryPromise({
12708
- try: () => Promise.resolve().then(() => require("./BitbucketSourceControlProvider-CEZEd4PX.cjs")),
12863
+ try: () => Promise.resolve().then(() => require("./BitbucketSourceControlProvider-3VHGKSl1.cjs")),
12709
12864
  catch: (cause) => providerLoadError("bitbucket", cause)
12710
12865
  }).pipe(effect.Effect.flatMap((module) => module.make()), effect.Effect.provideService(BitbucketApi, bitbucketApi)), {
12711
12866
  searchRepositories: true,
12712
12867
  cloneAuthentication: true
12713
12868
  });
12714
12869
  const forgejo = yield* makeLazyProvider("forgejo", effect.Effect.tryPromise({
12715
- try: () => Promise.resolve().then(() => require("./ForgejoSourceControlProvider-CzmmcAZO.cjs")),
12870
+ try: () => Promise.resolve().then(() => require("./ForgejoSourceControlProvider-CJLksvL_.cjs")),
12716
12871
  catch: (cause) => providerLoadError("forgejo", cause)
12717
12872
  }).pipe(effect.Effect.flatMap((module) => module.make()), effect.Effect.provideService(ForgejoApi, forgejoApi)));
12718
12873
  const azureDevOps = yield* makeLazyProvider("azure-devops", effect.Effect.tryPromise({
12719
- try: () => Promise.resolve().then(() => require("./AzureDevOpsSourceControlProvider-CVj-F-pW.cjs")),
12874
+ try: () => Promise.resolve().then(() => require("./AzureDevOpsSourceControlProvider-Dyu8KQ_S.cjs")),
12720
12875
  catch: (cause) => providerLoadError("azure-devops", cause)
12721
12876
  }).pipe(effect.Effect.flatMap((module) => module.make()), effect.Effect.provideService(AzureDevOpsCli, azureDevOpsCli)));
12722
12877
  const bitbucketDiscovery = require_SourceControlProviderDiscoveryCatalog.makeBitbucketDiscovery(bitbucketApi);
@@ -12955,6 +13110,11 @@ const DEFAULT_KEYBINDINGS = [
12955
13110
  command: "thread.find",
12956
13111
  when: "!terminalFocus"
12957
13112
  },
13113
+ {
13114
+ key: "mod+alt+p",
13115
+ command: "thread.pinToggle",
13116
+ when: "!terminalFocus"
13117
+ },
12958
13118
  {
12959
13119
  key: "mod+shift+[",
12960
13120
  command: "thread.previous"
@@ -14541,7 +14701,8 @@ const ServerNotification__SpendControlLimitSnapshot = effect_Schema.Struct({
14541
14701
  const ServerNotification__SubAgentActivityKind = effect_Schema.Literals([
14542
14702
  "started",
14543
14703
  "interacted",
14544
- "interrupted"
14704
+ "interrupted",
14705
+ "completed"
14545
14706
  ]);
14546
14707
  const ServerNotification__TerminalInteractionNotification = effect_Schema.Struct({
14547
14708
  itemId: effect_Schema.String,
@@ -15428,7 +15589,8 @@ const V2ItemCompletedNotification__ReasoningEffort = effect_Schema.String.annota
15428
15589
  const V2ItemCompletedNotification__SubAgentActivityKind = effect_Schema.Literals([
15429
15590
  "started",
15430
15591
  "interacted",
15431
- "interrupted"
15592
+ "interrupted",
15593
+ "completed"
15432
15594
  ]);
15433
15595
  const V2ItemCompletedNotification__TextElement = effect_Schema.Struct({
15434
15596
  byteRange: effect_Schema.Struct({
@@ -15612,7 +15774,8 @@ const V2ItemStartedNotification__ReasoningEffort = effect_Schema.String.annotate
15612
15774
  const V2ItemStartedNotification__SubAgentActivityKind = effect_Schema.Literals([
15613
15775
  "started",
15614
15776
  "interacted",
15615
- "interrupted"
15777
+ "interrupted",
15778
+ "completed"
15616
15779
  ]);
15617
15780
  const V2ItemStartedNotification__TextElement = effect_Schema.Struct({
15618
15781
  byteRange: effect_Schema.Struct({
@@ -16107,7 +16270,8 @@ const V2ReviewStartResponse__ReasoningEffort = effect_Schema.String.annotate({ d
16107
16270
  const V2ReviewStartResponse__SubAgentActivityKind = effect_Schema.Literals([
16108
16271
  "started",
16109
16272
  "interacted",
16110
- "interrupted"
16273
+ "interrupted",
16274
+ "completed"
16111
16275
  ]);
16112
16276
  const V2ReviewStartResponse__TextElement = effect_Schema.Struct({
16113
16277
  byteRange: effect_Schema.Struct({
@@ -16292,7 +16456,8 @@ const V2ThreadForkResponse__ReasoningEffort = effect_Schema.String.annotate({ de
16292
16456
  const V2ThreadForkResponse__SubAgentActivityKind = effect_Schema.Literals([
16293
16457
  "started",
16294
16458
  "interacted",
16295
- "interrupted"
16459
+ "interrupted",
16460
+ "completed"
16296
16461
  ]);
16297
16462
  const V2ThreadForkResponse__TextElement = effect_Schema.Struct({
16298
16463
  byteRange: effect_Schema.Struct({
@@ -16474,7 +16639,8 @@ const V2ThreadListResponse__ReasoningEffort = effect_Schema.String.annotate({ de
16474
16639
  const V2ThreadListResponse__SubAgentActivityKind = effect_Schema.Literals([
16475
16640
  "started",
16476
16641
  "interacted",
16477
- "interrupted"
16642
+ "interrupted",
16643
+ "completed"
16478
16644
  ]);
16479
16645
  const V2ThreadListResponse__TextElement = effect_Schema.Struct({
16480
16646
  byteRange: effect_Schema.Struct({
@@ -16610,7 +16776,8 @@ const V2ThreadMetadataUpdateResponse__ReasoningEffort = effect_Schema.String.ann
16610
16776
  const V2ThreadMetadataUpdateResponse__SubAgentActivityKind = effect_Schema.Literals([
16611
16777
  "started",
16612
16778
  "interacted",
16613
- "interrupted"
16779
+ "interrupted",
16780
+ "completed"
16614
16781
  ]);
16615
16782
  const V2ThreadMetadataUpdateResponse__TextElement = effect_Schema.Struct({
16616
16783
  byteRange: effect_Schema.Struct({
@@ -16741,7 +16908,8 @@ const V2ThreadReadResponse__ReasoningEffort = effect_Schema.String.annotate({ de
16741
16908
  const V2ThreadReadResponse__SubAgentActivityKind = effect_Schema.Literals([
16742
16909
  "started",
16743
16910
  "interacted",
16744
- "interrupted"
16911
+ "interrupted",
16912
+ "completed"
16745
16913
  ]);
16746
16914
  const V2ThreadReadResponse__TextElement = effect_Schema.Struct({
16747
16915
  byteRange: effect_Schema.Struct({
@@ -16983,7 +17151,8 @@ const V2ThreadResumeResponse__ReasoningEffort = effect_Schema.String.annotate({
16983
17151
  const V2ThreadResumeResponse__SubAgentActivityKind = effect_Schema.Literals([
16984
17152
  "started",
16985
17153
  "interacted",
16986
- "interrupted"
17154
+ "interrupted",
17155
+ "completed"
16987
17156
  ]);
16988
17157
  const V2ThreadResumeResponse__TextElement = effect_Schema.Struct({
16989
17158
  byteRange: effect_Schema.Struct({
@@ -17114,7 +17283,8 @@ const V2ThreadRollbackResponse__ReasoningEffort = effect_Schema.String.annotate(
17114
17283
  const V2ThreadRollbackResponse__SubAgentActivityKind = effect_Schema.Literals([
17115
17284
  "started",
17116
17285
  "interacted",
17117
- "interrupted"
17286
+ "interrupted",
17287
+ "completed"
17118
17288
  ]);
17119
17289
  const V2ThreadRollbackResponse__TextElement = effect_Schema.Struct({
17120
17290
  byteRange: effect_Schema.Struct({
@@ -17278,7 +17448,8 @@ const V2ThreadStartedNotification__ReasoningEffort = effect_Schema.String.annota
17278
17448
  const V2ThreadStartedNotification__SubAgentActivityKind = effect_Schema.Literals([
17279
17449
  "started",
17280
17450
  "interacted",
17281
- "interrupted"
17451
+ "interrupted",
17452
+ "completed"
17282
17453
  ]);
17283
17454
  const V2ThreadStartedNotification__TextElement = effect_Schema.Struct({
17284
17455
  byteRange: effect_Schema.Struct({
@@ -17456,7 +17627,8 @@ const V2ThreadStartResponse__ReasoningEffort = effect_Schema.String.annotate({ d
17456
17627
  const V2ThreadStartResponse__SubAgentActivityKind = effect_Schema.Literals([
17457
17628
  "started",
17458
17629
  "interacted",
17459
- "interrupted"
17630
+ "interrupted",
17631
+ "completed"
17460
17632
  ]);
17461
17633
  const V2ThreadStartResponse__TextElement = effect_Schema.Struct({
17462
17634
  byteRange: effect_Schema.Struct({
@@ -17599,7 +17771,8 @@ const V2ThreadUnarchiveResponse__ReasoningEffort = effect_Schema.String.annotate
17599
17771
  const V2ThreadUnarchiveResponse__SubAgentActivityKind = effect_Schema.Literals([
17600
17772
  "started",
17601
17773
  "interacted",
17602
- "interrupted"
17774
+ "interrupted",
17775
+ "completed"
17603
17776
  ]);
17604
17777
  const V2ThreadUnarchiveResponse__TextElement = effect_Schema.Struct({
17605
17778
  byteRange: effect_Schema.Struct({
@@ -17729,7 +17902,8 @@ const V2TurnCompletedNotification__ReasoningEffort = effect_Schema.String.annota
17729
17902
  const V2TurnCompletedNotification__SubAgentActivityKind = effect_Schema.Literals([
17730
17903
  "started",
17731
17904
  "interacted",
17732
- "interrupted"
17905
+ "interrupted",
17906
+ "completed"
17733
17907
  ]);
17734
17908
  const V2TurnCompletedNotification__TextElement = effect_Schema.Struct({
17735
17909
  byteRange: effect_Schema.Struct({
@@ -17856,7 +18030,8 @@ const V2TurnStartedNotification__ReasoningEffort = effect_Schema.String.annotate
17856
18030
  const V2TurnStartedNotification__SubAgentActivityKind = effect_Schema.Literals([
17857
18031
  "started",
17858
18032
  "interacted",
17859
- "interrupted"
18033
+ "interrupted",
18034
+ "completed"
17860
18035
  ]);
17861
18036
  const V2TurnStartedNotification__TextElement = effect_Schema.Struct({
17862
18037
  byteRange: effect_Schema.Struct({
@@ -18022,7 +18197,8 @@ const V2TurnStartResponse__ReasoningEffort = effect_Schema.String.annotate({ des
18022
18197
  const V2TurnStartResponse__SubAgentActivityKind = effect_Schema.Literals([
18023
18198
  "started",
18024
18199
  "interacted",
18025
- "interrupted"
18200
+ "interrupted",
18201
+ "completed"
18026
18202
  ]);
18027
18203
  const V2TurnStartResponse__TextElement = effect_Schema.Struct({
18028
18204
  byteRange: effect_Schema.Struct({
@@ -21933,14 +22109,19 @@ const ServerNotification__ThreadItem = effect_Schema.Union([
21933
22109
  status: effect_Schema.Literals([
21934
22110
  "inProgress",
21935
22111
  "completed",
21936
- "failed"
22112
+ "failed",
22113
+ "interrupted"
21937
22114
  ]).annotate({ description: "Current status of the collab tool call." }),
21938
22115
  tool: effect_Schema.Literals([
21939
22116
  "spawnAgent",
21940
22117
  "sendInput",
21941
22118
  "resumeAgent",
21942
22119
  "wait",
21943
- "closeAgent"
22120
+ "closeAgent",
22121
+ "sendMessage",
22122
+ "followupTask",
22123
+ "interruptAgent",
22124
+ "listAgents"
21944
22125
  ]).annotate({ description: "Name of the collab tool that was invoked." }),
21945
22126
  type: effect_Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType" })
21946
22127
  }).annotate({ title: "CollabAgentToolCallThreadItem" }),
@@ -22338,14 +22519,19 @@ const V2ItemCompletedNotification__ThreadItem = effect_Schema.Union([
22338
22519
  status: effect_Schema.Literals([
22339
22520
  "inProgress",
22340
22521
  "completed",
22341
- "failed"
22522
+ "failed",
22523
+ "interrupted"
22342
22524
  ]).annotate({ description: "Current status of the collab tool call." }),
22343
22525
  tool: effect_Schema.Literals([
22344
22526
  "spawnAgent",
22345
22527
  "sendInput",
22346
22528
  "resumeAgent",
22347
22529
  "wait",
22348
- "closeAgent"
22530
+ "closeAgent",
22531
+ "sendMessage",
22532
+ "followupTask",
22533
+ "interruptAgent",
22534
+ "listAgents"
22349
22535
  ]).annotate({ description: "Name of the collab tool that was invoked." }),
22350
22536
  type: effect_Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType" })
22351
22537
  }).annotate({ title: "CollabAgentToolCallThreadItem" }),
@@ -22532,14 +22718,19 @@ const V2ItemStartedNotification__ThreadItem = effect_Schema.Union([
22532
22718
  status: effect_Schema.Literals([
22533
22719
  "inProgress",
22534
22720
  "completed",
22535
- "failed"
22721
+ "failed",
22722
+ "interrupted"
22536
22723
  ]).annotate({ description: "Current status of the collab tool call." }),
22537
22724
  tool: effect_Schema.Literals([
22538
22725
  "spawnAgent",
22539
22726
  "sendInput",
22540
22727
  "resumeAgent",
22541
22728
  "wait",
22542
- "closeAgent"
22729
+ "closeAgent",
22730
+ "sendMessage",
22731
+ "followupTask",
22732
+ "interruptAgent",
22733
+ "listAgents"
22543
22734
  ]).annotate({ description: "Name of the collab tool that was invoked." }),
22544
22735
  type: effect_Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType" })
22545
22736
  }).annotate({ title: "CollabAgentToolCallThreadItem" }),
@@ -22775,14 +22966,19 @@ const V2ReviewStartResponse__ThreadItem = effect_Schema.Union([
22775
22966
  status: effect_Schema.Literals([
22776
22967
  "inProgress",
22777
22968
  "completed",
22778
- "failed"
22969
+ "failed",
22970
+ "interrupted"
22779
22971
  ]).annotate({ description: "Current status of the collab tool call." }),
22780
22972
  tool: effect_Schema.Literals([
22781
22973
  "spawnAgent",
22782
22974
  "sendInput",
22783
22975
  "resumeAgent",
22784
22976
  "wait",
22785
- "closeAgent"
22977
+ "closeAgent",
22978
+ "sendMessage",
22979
+ "followupTask",
22980
+ "interruptAgent",
22981
+ "listAgents"
22786
22982
  ]).annotate({ description: "Name of the collab tool that was invoked." }),
22787
22983
  type: effect_Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType" })
22788
22984
  }).annotate({ title: "CollabAgentToolCallThreadItem" }),
@@ -22956,14 +23152,19 @@ const V2ThreadForkResponse__ThreadItem = effect_Schema.Union([
22956
23152
  status: effect_Schema.Literals([
22957
23153
  "inProgress",
22958
23154
  "completed",
22959
- "failed"
23155
+ "failed",
23156
+ "interrupted"
22960
23157
  ]).annotate({ description: "Current status of the collab tool call." }),
22961
23158
  tool: effect_Schema.Literals([
22962
23159
  "spawnAgent",
22963
23160
  "sendInput",
22964
23161
  "resumeAgent",
22965
23162
  "wait",
22966
- "closeAgent"
23163
+ "closeAgent",
23164
+ "sendMessage",
23165
+ "followupTask",
23166
+ "interruptAgent",
23167
+ "listAgents"
22967
23168
  ]).annotate({ description: "Name of the collab tool that was invoked." }),
22968
23169
  type: effect_Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType" })
22969
23170
  }).annotate({ title: "CollabAgentToolCallThreadItem" }),
@@ -23127,14 +23328,19 @@ const V2ThreadListResponse__ThreadItem = effect_Schema.Union([
23127
23328
  status: effect_Schema.Literals([
23128
23329
  "inProgress",
23129
23330
  "completed",
23130
- "failed"
23331
+ "failed",
23332
+ "interrupted"
23131
23333
  ]).annotate({ description: "Current status of the collab tool call." }),
23132
23334
  tool: effect_Schema.Literals([
23133
23335
  "spawnAgent",
23134
23336
  "sendInput",
23135
23337
  "resumeAgent",
23136
23338
  "wait",
23137
- "closeAgent"
23339
+ "closeAgent",
23340
+ "sendMessage",
23341
+ "followupTask",
23342
+ "interruptAgent",
23343
+ "listAgents"
23138
23344
  ]).annotate({ description: "Name of the collab tool that was invoked." }),
23139
23345
  type: effect_Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType" })
23140
23346
  }).annotate({ title: "CollabAgentToolCallThreadItem" }),
@@ -23298,14 +23504,19 @@ const V2ThreadMetadataUpdateResponse__ThreadItem = effect_Schema.Union([
23298
23504
  status: effect_Schema.Literals([
23299
23505
  "inProgress",
23300
23506
  "completed",
23301
- "failed"
23507
+ "failed",
23508
+ "interrupted"
23302
23509
  ]).annotate({ description: "Current status of the collab tool call." }),
23303
23510
  tool: effect_Schema.Literals([
23304
23511
  "spawnAgent",
23305
23512
  "sendInput",
23306
23513
  "resumeAgent",
23307
23514
  "wait",
23308
- "closeAgent"
23515
+ "closeAgent",
23516
+ "sendMessage",
23517
+ "followupTask",
23518
+ "interruptAgent",
23519
+ "listAgents"
23309
23520
  ]).annotate({ description: "Name of the collab tool that was invoked." }),
23310
23521
  type: effect_Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType" })
23311
23522
  }).annotate({ title: "CollabAgentToolCallThreadItem" }),
@@ -23469,14 +23680,19 @@ const V2ThreadReadResponse__ThreadItem = effect_Schema.Union([
23469
23680
  status: effect_Schema.Literals([
23470
23681
  "inProgress",
23471
23682
  "completed",
23472
- "failed"
23683
+ "failed",
23684
+ "interrupted"
23473
23685
  ]).annotate({ description: "Current status of the collab tool call." }),
23474
23686
  tool: effect_Schema.Literals([
23475
23687
  "spawnAgent",
23476
23688
  "sendInput",
23477
23689
  "resumeAgent",
23478
23690
  "wait",
23479
- "closeAgent"
23691
+ "closeAgent",
23692
+ "sendMessage",
23693
+ "followupTask",
23694
+ "interruptAgent",
23695
+ "listAgents"
23480
23696
  ]).annotate({ description: "Name of the collab tool that was invoked." }),
23481
23697
  type: effect_Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType" })
23482
23698
  }).annotate({ title: "CollabAgentToolCallThreadItem" }),
@@ -23641,14 +23857,19 @@ const V2ThreadResumeResponse__ThreadItem = effect_Schema.Union([
23641
23857
  status: effect_Schema.Literals([
23642
23858
  "inProgress",
23643
23859
  "completed",
23644
- "failed"
23860
+ "failed",
23861
+ "interrupted"
23645
23862
  ]).annotate({ description: "Current status of the collab tool call." }),
23646
23863
  tool: effect_Schema.Literals([
23647
23864
  "spawnAgent",
23648
23865
  "sendInput",
23649
23866
  "resumeAgent",
23650
23867
  "wait",
23651
- "closeAgent"
23868
+ "closeAgent",
23869
+ "sendMessage",
23870
+ "followupTask",
23871
+ "interruptAgent",
23872
+ "listAgents"
23652
23873
  ]).annotate({ description: "Name of the collab tool that was invoked." }),
23653
23874
  type: effect_Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType" })
23654
23875
  }).annotate({ title: "CollabAgentToolCallThreadItem" }),
@@ -23812,14 +24033,19 @@ const V2ThreadRollbackResponse__ThreadItem = effect_Schema.Union([
23812
24033
  status: effect_Schema.Literals([
23813
24034
  "inProgress",
23814
24035
  "completed",
23815
- "failed"
24036
+ "failed",
24037
+ "interrupted"
23816
24038
  ]).annotate({ description: "Current status of the collab tool call." }),
23817
24039
  tool: effect_Schema.Literals([
23818
24040
  "spawnAgent",
23819
24041
  "sendInput",
23820
24042
  "resumeAgent",
23821
24043
  "wait",
23822
- "closeAgent"
24044
+ "closeAgent",
24045
+ "sendMessage",
24046
+ "followupTask",
24047
+ "interruptAgent",
24048
+ "listAgents"
23823
24049
  ]).annotate({ description: "Name of the collab tool that was invoked." }),
23824
24050
  type: effect_Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType" })
23825
24051
  }).annotate({ title: "CollabAgentToolCallThreadItem" }),
@@ -23987,14 +24213,19 @@ const V2ThreadStartedNotification__ThreadItem = effect_Schema.Union([
23987
24213
  status: effect_Schema.Literals([
23988
24214
  "inProgress",
23989
24215
  "completed",
23990
- "failed"
24216
+ "failed",
24217
+ "interrupted"
23991
24218
  ]).annotate({ description: "Current status of the collab tool call." }),
23992
24219
  tool: effect_Schema.Literals([
23993
24220
  "spawnAgent",
23994
24221
  "sendInput",
23995
24222
  "resumeAgent",
23996
24223
  "wait",
23997
- "closeAgent"
24224
+ "closeAgent",
24225
+ "sendMessage",
24226
+ "followupTask",
24227
+ "interruptAgent",
24228
+ "listAgents"
23998
24229
  ]).annotate({ description: "Name of the collab tool that was invoked." }),
23999
24230
  type: effect_Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType" })
24000
24231
  }).annotate({ title: "CollabAgentToolCallThreadItem" }),
@@ -24158,14 +24389,19 @@ const V2ThreadStartResponse__ThreadItem = effect_Schema.Union([
24158
24389
  status: effect_Schema.Literals([
24159
24390
  "inProgress",
24160
24391
  "completed",
24161
- "failed"
24392
+ "failed",
24393
+ "interrupted"
24162
24394
  ]).annotate({ description: "Current status of the collab tool call." }),
24163
24395
  tool: effect_Schema.Literals([
24164
24396
  "spawnAgent",
24165
24397
  "sendInput",
24166
24398
  "resumeAgent",
24167
24399
  "wait",
24168
- "closeAgent"
24400
+ "closeAgent",
24401
+ "sendMessage",
24402
+ "followupTask",
24403
+ "interruptAgent",
24404
+ "listAgents"
24169
24405
  ]).annotate({ description: "Name of the collab tool that was invoked." }),
24170
24406
  type: effect_Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType" })
24171
24407
  }).annotate({ title: "CollabAgentToolCallThreadItem" }),
@@ -24329,14 +24565,19 @@ const V2ThreadUnarchiveResponse__ThreadItem = effect_Schema.Union([
24329
24565
  status: effect_Schema.Literals([
24330
24566
  "inProgress",
24331
24567
  "completed",
24332
- "failed"
24568
+ "failed",
24569
+ "interrupted"
24333
24570
  ]).annotate({ description: "Current status of the collab tool call." }),
24334
24571
  tool: effect_Schema.Literals([
24335
24572
  "spawnAgent",
24336
24573
  "sendInput",
24337
24574
  "resumeAgent",
24338
24575
  "wait",
24339
- "closeAgent"
24576
+ "closeAgent",
24577
+ "sendMessage",
24578
+ "followupTask",
24579
+ "interruptAgent",
24580
+ "listAgents"
24340
24581
  ]).annotate({ description: "Name of the collab tool that was invoked." }),
24341
24582
  type: effect_Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType" })
24342
24583
  }).annotate({ title: "CollabAgentToolCallThreadItem" }),
@@ -24500,14 +24741,19 @@ const V2TurnCompletedNotification__ThreadItem = effect_Schema.Union([
24500
24741
  status: effect_Schema.Literals([
24501
24742
  "inProgress",
24502
24743
  "completed",
24503
- "failed"
24744
+ "failed",
24745
+ "interrupted"
24504
24746
  ]).annotate({ description: "Current status of the collab tool call." }),
24505
24747
  tool: effect_Schema.Literals([
24506
24748
  "spawnAgent",
24507
24749
  "sendInput",
24508
24750
  "resumeAgent",
24509
24751
  "wait",
24510
- "closeAgent"
24752
+ "closeAgent",
24753
+ "sendMessage",
24754
+ "followupTask",
24755
+ "interruptAgent",
24756
+ "listAgents"
24511
24757
  ]).annotate({ description: "Name of the collab tool that was invoked." }),
24512
24758
  type: effect_Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType" })
24513
24759
  }).annotate({ title: "CollabAgentToolCallThreadItem" }),
@@ -24671,14 +24917,19 @@ const V2TurnStartedNotification__ThreadItem = effect_Schema.Union([
24671
24917
  status: effect_Schema.Literals([
24672
24918
  "inProgress",
24673
24919
  "completed",
24674
- "failed"
24920
+ "failed",
24921
+ "interrupted"
24675
24922
  ]).annotate({ description: "Current status of the collab tool call." }),
24676
24923
  tool: effect_Schema.Literals([
24677
24924
  "spawnAgent",
24678
24925
  "sendInput",
24679
24926
  "resumeAgent",
24680
24927
  "wait",
24681
- "closeAgent"
24928
+ "closeAgent",
24929
+ "sendMessage",
24930
+ "followupTask",
24931
+ "interruptAgent",
24932
+ "listAgents"
24682
24933
  ]).annotate({ description: "Name of the collab tool that was invoked." }),
24683
24934
  type: effect_Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType" })
24684
24935
  }).annotate({ title: "CollabAgentToolCallThreadItem" }),
@@ -24842,14 +25093,19 @@ const V2TurnStartResponse__ThreadItem = effect_Schema.Union([
24842
25093
  status: effect_Schema.Literals([
24843
25094
  "inProgress",
24844
25095
  "completed",
24845
- "failed"
25096
+ "failed",
25097
+ "interrupted"
24846
25098
  ]).annotate({ description: "Current status of the collab tool call." }),
24847
25099
  tool: effect_Schema.Literals([
24848
25100
  "spawnAgent",
24849
25101
  "sendInput",
24850
25102
  "resumeAgent",
24851
25103
  "wait",
24852
- "closeAgent"
25104
+ "closeAgent",
25105
+ "sendMessage",
25106
+ "followupTask",
25107
+ "interruptAgent",
25108
+ "listAgents"
24853
25109
  ]).annotate({ description: "Name of the collab tool that was invoked." }),
24854
25110
  type: effect_Schema.Literal("collabAgentToolCall").annotate({ title: "CollabAgentToolCallThreadItemType" })
24855
25111
  }).annotate({ title: "CollabAgentToolCallThreadItem" }),
@@ -28107,12 +28363,17 @@ effect_Schema.Literals([
28107
28363
  "sendInput",
28108
28364
  "resumeAgent",
28109
28365
  "wait",
28110
- "closeAgent"
28366
+ "closeAgent",
28367
+ "sendMessage",
28368
+ "followupTask",
28369
+ "interruptAgent",
28370
+ "listAgents"
28111
28371
  ]);
28112
28372
  effect_Schema.Literals([
28113
28373
  "inProgress",
28114
28374
  "completed",
28115
- "failed"
28375
+ "failed",
28376
+ "interrupted"
28116
28377
  ]);
28117
28378
  effect_Schema.Literals(["stdout", "stderr"]).annotate({ description: "Stream label for `command/exec/outputDelta` notifications." });
28118
28379
  effect_Schema.Literals([
@@ -28836,12 +29097,17 @@ effect_Schema.Literals([
28836
29097
  "sendInput",
28837
29098
  "resumeAgent",
28838
29099
  "wait",
28839
- "closeAgent"
29100
+ "closeAgent",
29101
+ "sendMessage",
29102
+ "followupTask",
29103
+ "interruptAgent",
29104
+ "listAgents"
28840
29105
  ]);
28841
29106
  effect_Schema.Literals([
28842
29107
  "inProgress",
28843
29108
  "completed",
28844
- "failed"
29109
+ "failed",
29110
+ "interrupted"
28845
29111
  ]);
28846
29112
  effect_Schema.Literals([
28847
29113
  "agent",
@@ -28902,12 +29168,17 @@ effect_Schema.Literals([
28902
29168
  "sendInput",
28903
29169
  "resumeAgent",
28904
29170
  "wait",
28905
- "closeAgent"
29171
+ "closeAgent",
29172
+ "sendMessage",
29173
+ "followupTask",
29174
+ "interruptAgent",
29175
+ "listAgents"
28906
29176
  ]);
28907
29177
  effect_Schema.Literals([
28908
29178
  "inProgress",
28909
29179
  "completed",
28910
- "failed"
29180
+ "failed",
29181
+ "interrupted"
28911
29182
  ]);
28912
29183
  effect_Schema.Literals([
28913
29184
  "agent",
@@ -29264,12 +29535,17 @@ effect_Schema.Literals([
29264
29535
  "sendInput",
29265
29536
  "resumeAgent",
29266
29537
  "wait",
29267
- "closeAgent"
29538
+ "closeAgent",
29539
+ "sendMessage",
29540
+ "followupTask",
29541
+ "interruptAgent",
29542
+ "listAgents"
29268
29543
  ]);
29269
29544
  effect_Schema.Literals([
29270
29545
  "inProgress",
29271
29546
  "completed",
29272
- "failed"
29547
+ "failed",
29548
+ "interrupted"
29273
29549
  ]);
29274
29550
  effect_Schema.Literals([
29275
29551
  "agent",
@@ -29400,12 +29676,17 @@ effect_Schema.Literals([
29400
29676
  "sendInput",
29401
29677
  "resumeAgent",
29402
29678
  "wait",
29403
- "closeAgent"
29679
+ "closeAgent",
29680
+ "sendMessage",
29681
+ "followupTask",
29682
+ "interruptAgent",
29683
+ "listAgents"
29404
29684
  ]);
29405
29685
  effect_Schema.Literals([
29406
29686
  "inProgress",
29407
29687
  "completed",
29408
- "failed"
29688
+ "failed",
29689
+ "interrupted"
29409
29690
  ]);
29410
29691
  effect_Schema.Literals([
29411
29692
  "agent",
@@ -29511,12 +29792,17 @@ effect_Schema.Literals([
29511
29792
  "sendInput",
29512
29793
  "resumeAgent",
29513
29794
  "wait",
29514
- "closeAgent"
29795
+ "closeAgent",
29796
+ "sendMessage",
29797
+ "followupTask",
29798
+ "interruptAgent",
29799
+ "listAgents"
29515
29800
  ]);
29516
29801
  effect_Schema.Literals([
29517
29802
  "inProgress",
29518
29803
  "completed",
29519
- "failed"
29804
+ "failed",
29805
+ "interrupted"
29520
29806
  ]);
29521
29807
  effect_Schema.Literals([
29522
29808
  "agent",
@@ -29576,12 +29862,17 @@ effect_Schema.Literals([
29576
29862
  "sendInput",
29577
29863
  "resumeAgent",
29578
29864
  "wait",
29579
- "closeAgent"
29865
+ "closeAgent",
29866
+ "sendMessage",
29867
+ "followupTask",
29868
+ "interruptAgent",
29869
+ "listAgents"
29580
29870
  ]);
29581
29871
  effect_Schema.Literals([
29582
29872
  "inProgress",
29583
29873
  "completed",
29584
- "failed"
29874
+ "failed",
29875
+ "interrupted"
29585
29876
  ]);
29586
29877
  effect_Schema.Literals([
29587
29878
  "agent",
@@ -29634,12 +29925,17 @@ effect_Schema.Literals([
29634
29925
  "sendInput",
29635
29926
  "resumeAgent",
29636
29927
  "wait",
29637
- "closeAgent"
29928
+ "closeAgent",
29929
+ "sendMessage",
29930
+ "followupTask",
29931
+ "interruptAgent",
29932
+ "listAgents"
29638
29933
  ]);
29639
29934
  effect_Schema.Literals([
29640
29935
  "inProgress",
29641
29936
  "completed",
29642
- "failed"
29937
+ "failed",
29938
+ "interrupted"
29643
29939
  ]);
29644
29940
  effect_Schema.Literals([
29645
29941
  "agent",
@@ -29928,12 +30224,17 @@ effect_Schema.Literals([
29928
30224
  "sendInput",
29929
30225
  "resumeAgent",
29930
30226
  "wait",
29931
- "closeAgent"
30227
+ "closeAgent",
30228
+ "sendMessage",
30229
+ "followupTask",
30230
+ "interruptAgent",
30231
+ "listAgents"
29932
30232
  ]);
29933
30233
  effect_Schema.Literals([
29934
30234
  "inProgress",
29935
30235
  "completed",
29936
- "failed"
30236
+ "failed",
30237
+ "interrupted"
29937
30238
  ]);
29938
30239
  effect_Schema.Literals([
29939
30240
  "agent",
@@ -30062,12 +30363,17 @@ effect_Schema.Literals([
30062
30363
  "sendInput",
30063
30364
  "resumeAgent",
30064
30365
  "wait",
30065
- "closeAgent"
30366
+ "closeAgent",
30367
+ "sendMessage",
30368
+ "followupTask",
30369
+ "interruptAgent",
30370
+ "listAgents"
30066
30371
  ]);
30067
30372
  effect_Schema.Literals([
30068
30373
  "inProgress",
30069
30374
  "completed",
30070
- "failed"
30375
+ "failed",
30376
+ "interrupted"
30071
30377
  ]);
30072
30378
  effect_Schema.Literals([
30073
30379
  "agent",
@@ -30178,12 +30484,17 @@ effect_Schema.Literals([
30178
30484
  "sendInput",
30179
30485
  "resumeAgent",
30180
30486
  "wait",
30181
- "closeAgent"
30487
+ "closeAgent",
30488
+ "sendMessage",
30489
+ "followupTask",
30490
+ "interruptAgent",
30491
+ "listAgents"
30182
30492
  ]);
30183
30493
  effect_Schema.Literals([
30184
30494
  "inProgress",
30185
30495
  "completed",
30186
- "failed"
30496
+ "failed",
30497
+ "interrupted"
30187
30498
  ]);
30188
30499
  effect_Schema.Literals([
30189
30500
  "agent",
@@ -30328,12 +30639,17 @@ effect_Schema.Literals([
30328
30639
  "sendInput",
30329
30640
  "resumeAgent",
30330
30641
  "wait",
30331
- "closeAgent"
30642
+ "closeAgent",
30643
+ "sendMessage",
30644
+ "followupTask",
30645
+ "interruptAgent",
30646
+ "listAgents"
30332
30647
  ]);
30333
30648
  effect_Schema.Literals([
30334
30649
  "inProgress",
30335
30650
  "completed",
30336
- "failed"
30651
+ "failed",
30652
+ "interrupted"
30337
30653
  ]);
30338
30654
  effect_Schema.Literals([
30339
30655
  "agent",
@@ -30409,12 +30725,17 @@ effect_Schema.Literals([
30409
30725
  "sendInput",
30410
30726
  "resumeAgent",
30411
30727
  "wait",
30412
- "closeAgent"
30728
+ "closeAgent",
30729
+ "sendMessage",
30730
+ "followupTask",
30731
+ "interruptAgent",
30732
+ "listAgents"
30413
30733
  ]);
30414
30734
  effect_Schema.Literals([
30415
30735
  "inProgress",
30416
30736
  "completed",
30417
- "failed"
30737
+ "failed",
30738
+ "interrupted"
30418
30739
  ]);
30419
30740
  effect_Schema.Literals([
30420
30741
  "agent",
@@ -30464,12 +30785,17 @@ effect_Schema.Literals([
30464
30785
  "sendInput",
30465
30786
  "resumeAgent",
30466
30787
  "wait",
30467
- "closeAgent"
30788
+ "closeAgent",
30789
+ "sendMessage",
30790
+ "followupTask",
30791
+ "interruptAgent",
30792
+ "listAgents"
30468
30793
  ]);
30469
30794
  effect_Schema.Literals([
30470
30795
  "inProgress",
30471
30796
  "completed",
30472
- "failed"
30797
+ "failed",
30798
+ "interrupted"
30473
30799
  ]);
30474
30800
  effect_Schema.Literals([
30475
30801
  "agent",
@@ -30519,12 +30845,17 @@ effect_Schema.Literals([
30519
30845
  "sendInput",
30520
30846
  "resumeAgent",
30521
30847
  "wait",
30522
- "closeAgent"
30848
+ "closeAgent",
30849
+ "sendMessage",
30850
+ "followupTask",
30851
+ "interruptAgent",
30852
+ "listAgents"
30523
30853
  ]);
30524
30854
  effect_Schema.Literals([
30525
30855
  "inProgress",
30526
30856
  "completed",
30527
- "failed"
30857
+ "failed",
30858
+ "interrupted"
30528
30859
  ]);
30529
30860
  effect_Schema.Literals([
30530
30861
  "agent",
@@ -30581,12 +30912,17 @@ effect_Schema.Literals([
30581
30912
  "sendInput",
30582
30913
  "resumeAgent",
30583
30914
  "wait",
30584
- "closeAgent"
30915
+ "closeAgent",
30916
+ "sendMessage",
30917
+ "followupTask",
30918
+ "interruptAgent",
30919
+ "listAgents"
30585
30920
  ]);
30586
30921
  effect_Schema.Literals([
30587
30922
  "inProgress",
30588
30923
  "completed",
30589
- "failed"
30924
+ "failed",
30925
+ "interrupted"
30590
30926
  ]);
30591
30927
  effect_Schema.Literals([
30592
30928
  "agent",
@@ -31190,7 +31526,10 @@ const makeCodexAppServerPatchedProtocol = effect_Effect.fn("makeCodexAppServerPa
31190
31526
  const incomingRequests = yield* options.onRequest ? effect_Queue.sliding(PROTOCOL_QUEUE_CAPACITY) : effect_Queue.bounded(PROTOCOL_QUEUE_CAPACITY);
31191
31527
  const pending = yield* effect_Ref.make(/* @__PURE__ */ new Map());
31192
31528
  const nextRequestId = yield* effect_Ref.make(1);
31193
- const remainder = yield* effect_Ref.make("");
31529
+ const remainder = {
31530
+ fragments: [],
31531
+ byteLength: 0
31532
+ };
31194
31533
  const terminationHandled = yield* effect_Ref.make(false);
31195
31534
  const logProtocol = (event) => {
31196
31535
  if (event.direction === "incoming" && !options.logIncoming) return effect_Effect.void;
@@ -31289,19 +31628,39 @@ const makeCodexAppServerPatchedProtocol = effect_Effect.fn("makeCodexAppServerPa
31289
31628
  }
31290
31629
  })), effect_Effect.flatMap(routeMessage));
31291
31630
  };
31292
- yield* options.stdio.stdin.pipe(effect_Stream.decodeText(), effect_Stream.runForEach((chunk) => effect_Ref.modify(remainder, (current) => {
31293
- const lines = (current + chunk).split("\n");
31294
- const nextRemainder = lines.pop() ?? "";
31295
- return [{
31296
- lines: lines.map((line) => line.replace(/\r$/, "")),
31297
- remainderBytes: new TextEncoder().encode(nextRemainder).byteLength
31298
- }, nextRemainder];
31299
- }).pipe(effect_Effect.flatMap(({ lines, remainderBytes }) => remainderBytes > PROTOCOL_MAX_FRAME_BYTES ? effect_Effect.fail(new CodexAppServerProtocolOverloadedError({
31300
- queue: "incoming-frame-bytes",
31301
- capacity: PROTOCOL_MAX_FRAME_BYTES
31302
- })) : effect_Effect.forEach(lines, handleLine, { discard: true })))), effect_Effect.matchEffect({
31631
+ yield* options.stdio.stdin.pipe(effect_Stream.decodeText(), effect_Stream.runForEach((chunk) => effect_Effect.gen(function* () {
31632
+ const lines = [];
31633
+ let start = 0;
31634
+ for (let newline = chunk.indexOf("\n"); newline !== -1; newline = chunk.indexOf("\n", start)) {
31635
+ const fragment = chunk.slice(start, newline);
31636
+ if (remainder.byteLength + new TextEncoder().encode(fragment).byteLength > PROTOCOL_MAX_FRAME_BYTES) return yield* effect_Effect.fail(new CodexAppServerProtocolOverloadedError({
31637
+ queue: "incoming-frame-bytes",
31638
+ capacity: PROTOCOL_MAX_FRAME_BYTES
31639
+ }));
31640
+ remainder.fragments.push(fragment);
31641
+ lines.push(remainder.fragments.join("").replace(/\r$/, ""));
31642
+ remainder.fragments.length = 0;
31643
+ remainder.byteLength = 0;
31644
+ start = newline + 1;
31645
+ }
31646
+ if (start < chunk.length) {
31647
+ const fragment = chunk.slice(start);
31648
+ remainder.byteLength += new TextEncoder().encode(fragment).byteLength;
31649
+ if (remainder.byteLength > PROTOCOL_MAX_FRAME_BYTES) return yield* effect_Effect.fail(new CodexAppServerProtocolOverloadedError({
31650
+ queue: "incoming-frame-bytes",
31651
+ capacity: PROTOCOL_MAX_FRAME_BYTES
31652
+ }));
31653
+ remainder.fragments.push(fragment);
31654
+ }
31655
+ yield* effect_Effect.forEach(lines, handleLine, { discard: true });
31656
+ })), effect_Effect.matchEffect({
31303
31657
  onFailure: (error) => handleTermination(() => effect_Effect.succeed(normalizeProtocolError(error, "Codex App Server input stream failed"))),
31304
- onSuccess: () => effect_Ref.get(remainder).pipe(effect_Effect.flatMap((line) => line.trim().length === 0 ? effect_Effect.void : handleLine(line)), effect_Effect.matchEffect({
31658
+ onSuccess: () => effect_Effect.sync(() => {
31659
+ const line = remainder.fragments.join("");
31660
+ remainder.fragments.length = 0;
31661
+ remainder.byteLength = 0;
31662
+ return line;
31663
+ }).pipe(effect_Effect.flatMap((line) => line.trim().length === 0 ? effect_Effect.void : handleLine(line)), effect_Effect.matchEffect({
31305
31664
  onFailure: (error) => handleTermination(() => effect_Effect.succeed(error)),
31306
31665
  onSuccess: () => handleTermination(() => options.terminationError ?? effect_Effect.succeed(new CodexAppServerTransportError({
31307
31666
  detail: "Codex App Server input stream ended",
@@ -32409,7 +32768,7 @@ const DEVICE_TOOL_DEFINITIONS = [
32409
32768
  }
32410
32769
  }
32411
32770
  ];
32412
- function asRecord$5(value) {
32771
+ function asRecord$6(value) {
32413
32772
  if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("Tool arguments must be a JSON object.");
32414
32773
  return value;
32415
32774
  }
@@ -32632,7 +32991,7 @@ async function startDeviceToolGateway(manager) {
32632
32991
  if (typeof method !== "string") return json(response, 400, mcpError$1(id, -32600, "Missing method."));
32633
32992
  if (method === "notifications/initialized" || method === "notifications/cancelled") return empty(response, 202);
32634
32993
  if (method === "initialize") {
32635
- const requested = asRecord$5(message.params ?? {}).protocolVersion;
32994
+ const requested = asRecord$6(message.params ?? {}).protocolVersion;
32636
32995
  return json(response, 200, mcpSuccess(id, {
32637
32996
  protocolVersion: typeof requested === "string" ? requested : "2025-06-18",
32638
32997
  capabilities: { tools: { listChanged: false } },
@@ -32652,7 +33011,7 @@ async function startDeviceToolGateway(manager) {
32652
33011
  text: "Device tools are only available during an active Ryco turn."
32653
33012
  }]
32654
33013
  }));
32655
- const params = asRecord$5(message.params ?? {});
33014
+ const params = asRecord$6(message.params ?? {});
32656
33015
  const name = params.name;
32657
33016
  if (typeof name !== "string" || !DEVICE_TOOL_NAMES.includes(name)) return json(response, 200, mcpError$1(id, -32602, "Unknown device tool."));
32658
33017
  if (agentControlBlocksLegacyTool(binding.threadId, name)) return json(response, 200, mcpSuccess(id, {
@@ -32667,7 +33026,7 @@ async function startDeviceToolGateway(manager) {
32667
33026
  manager,
32668
33027
  threadId: binding.threadId,
32669
33028
  name,
32670
- args: asRecord$5(params.arguments ?? {})
33029
+ args: asRecord$6(params.arguments ?? {})
32671
33030
  });
32672
33031
  return json(response, 200, mcpSuccess(id, { content: value && typeof value === "object" && "_mcpContent" in value ? value._mcpContent : [{
32673
33032
  type: "text",
@@ -32966,7 +33325,7 @@ const BUILT_IN_DRIVERS = [
32966
33325
  configSchema: require_collectUint8StreamText.CodexSettings,
32967
33326
  defaultConfig: () => effect.Schema.decodeSync(require_collectUint8StreamText.CodexSettings)({}),
32968
33327
  create: (input) => effect.Effect.tryPromise({
32969
- try: () => Promise.resolve().then(() => require("./CodexDriver-CZCIJSLV.cjs")),
33328
+ try: () => Promise.resolve().then(() => require("./CodexDriver-3TZPgrGk.cjs")),
32970
33329
  catch: (cause) => driverImportError(codexDriverKind, input, cause)
32971
33330
  }).pipe(effect.Effect.flatMap(({ CodexDriver }) => CodexDriver.create(input)))
32972
33331
  },
@@ -32980,7 +33339,7 @@ const BUILT_IN_DRIVERS = [
32980
33339
  configSchema: require_collectUint8StreamText.ClaudeSettings,
32981
33340
  defaultConfig: () => effect.Schema.decodeSync(require_collectUint8StreamText.ClaudeSettings)({}),
32982
33341
  create: (input) => effect.Effect.tryPromise({
32983
- try: () => Promise.resolve().then(() => require("./ClaudeDriver-lBU7EyUX.cjs")),
33342
+ try: () => Promise.resolve().then(() => require("./ClaudeDriver-CBCy0_WX.cjs")),
32984
33343
  catch: (cause) => driverImportError(claudeDriverKind, input, cause)
32985
33344
  }).pipe(effect.Effect.flatMap(({ ClaudeDriver }) => ClaudeDriver.create(input)))
32986
33345
  },
@@ -32994,7 +33353,7 @@ const BUILT_IN_DRIVERS = [
32994
33353
  configSchema: require_collectUint8StreamText.CopilotSettings,
32995
33354
  defaultConfig: () => effect.Schema.decodeSync(require_collectUint8StreamText.CopilotSettings)({}),
32996
33355
  create: (input) => effect.Effect.tryPromise({
32997
- try: () => Promise.resolve().then(() => require("./CopilotDriver-CX5zhEdZ.cjs")),
33356
+ try: () => Promise.resolve().then(() => require("./CopilotDriver-C7a8IhyK.cjs")),
32998
33357
  catch: (cause) => driverImportError(copilotDriverKind, input, cause)
32999
33358
  }).pipe(effect.Effect.flatMap(({ CopilotDriver }) => CopilotDriver.create(input)))
33000
33359
  },
@@ -33008,7 +33367,7 @@ const BUILT_IN_DRIVERS = [
33008
33367
  configSchema: require_collectUint8StreamText.CursorSettings,
33009
33368
  defaultConfig: () => effect.Schema.decodeSync(require_collectUint8StreamText.CursorSettings)({}),
33010
33369
  create: (input) => effect.Effect.tryPromise({
33011
- try: () => Promise.resolve().then(() => require("./CursorDriver-CPBVeesr.cjs")),
33370
+ try: () => Promise.resolve().then(() => require("./CursorDriver-uNsDetA3.cjs")),
33012
33371
  catch: (cause) => driverImportError(cursorDriverKind, input, cause)
33013
33372
  }).pipe(effect.Effect.flatMap(({ CursorDriver }) => CursorDriver.create(input)))
33014
33373
  },
@@ -33022,7 +33381,7 @@ const BUILT_IN_DRIVERS = [
33022
33381
  configSchema: require_collectUint8StreamText.GrokSettings,
33023
33382
  defaultConfig: () => effect.Schema.decodeSync(require_collectUint8StreamText.GrokSettings)({}),
33024
33383
  create: (input) => effect.Effect.tryPromise({
33025
- try: () => Promise.resolve().then(() => require("./GrokDriver-CIXj_4ry.cjs")),
33384
+ try: () => Promise.resolve().then(() => require("./GrokDriver-BJ00ZiYg.cjs")),
33026
33385
  catch: (cause) => driverImportError(grokDriverKind, input, cause)
33027
33386
  }).pipe(effect.Effect.flatMap(({ GrokDriver }) => GrokDriver.create(input)))
33028
33387
  },
@@ -33036,7 +33395,7 @@ const BUILT_IN_DRIVERS = [
33036
33395
  configSchema: require_collectUint8StreamText.OpenCodeSettings,
33037
33396
  defaultConfig: () => effect.Schema.decodeSync(require_collectUint8StreamText.OpenCodeSettings)({}),
33038
33397
  create: (input) => effect.Effect.tryPromise({
33039
- try: () => Promise.resolve().then(() => require("./OpenCodeDriver-DDEuwtXl.cjs")),
33398
+ try: () => Promise.resolve().then(() => require("./OpenCodeDriver-BTxd2Q3Q.cjs")),
33040
33399
  catch: (cause) => driverImportError(openCodeDriverKind, input, cause)
33041
33400
  }).pipe(effect.Effect.flatMap(({ OpenCodeDriver }) => OpenCodeDriver.create(input)))
33042
33401
  }
@@ -33751,7 +34110,7 @@ const scopedSafeTeardown = (label) => (effect$28) => effect.Effect.gen(function*
33751
34110
  });
33752
34111
  //#endregion
33753
34112
  //#region package.json
33754
- var version$1 = "0.1.13";
34113
+ var version$1 = "0.1.15";
33755
34114
  //#endregion
33756
34115
  //#region src/provider/Layers/CodexProvider.ts
33757
34116
  const PROVIDER_PROBE_TIMEOUT_MS = 8e3;
@@ -34236,7 +34595,7 @@ function sortProviderSupport(left, right) {
34236
34595
  };
34237
34596
  return statusRank[left.status] - statusRank[right.status] || Number(right.enabled) - Number(left.enabled) || left.driver.localeCompare(right.driver) || left.instanceId.localeCompare(right.instanceId);
34238
34597
  }
34239
- function asRecord$4(value) {
34598
+ function asRecord$5(value) {
34240
34599
  if (value === null || typeof value !== "object" || Array.isArray(value)) return;
34241
34600
  return value;
34242
34601
  }
@@ -34244,7 +34603,7 @@ function asStringArray(value) {
34244
34603
  return Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : [];
34245
34604
  }
34246
34605
  function asStringRecord(value) {
34247
- const record = asRecord$4(value);
34606
+ const record = asRecord$5(value);
34248
34607
  if (!record) return {};
34249
34608
  const entries = Object.entries(record).filter((entry) => {
34250
34609
  const [, entryValue] = entry;
@@ -34269,7 +34628,7 @@ function asOptionalNumber(value) {
34269
34628
  return typeof value === "number" && Number.isFinite(value) ? value : void 0;
34270
34629
  }
34271
34630
  function sourceFromOrigin(origin) {
34272
- const type = asRecord$4(asRecord$4(origin)?.name)?.type;
34631
+ const type = asRecord$5(asRecord$5(origin)?.name)?.type;
34273
34632
  if (type === "user" || type === "project" || type === "system") return type;
34274
34633
  if (type === "mdm") return "managed";
34275
34634
  return "unknown";
@@ -34289,13 +34648,13 @@ function collectLayerServers(layers) {
34289
34648
  if (!layers) return [];
34290
34649
  const layerServers = [];
34291
34650
  for (const layer of layers) {
34292
- const servers = asRecord$4(asRecord$4(layer.config)?.mcp_servers);
34651
+ const servers = asRecord$5(asRecord$5(layer.config)?.mcp_servers);
34293
34652
  if (servers) layerServers.push(servers);
34294
34653
  }
34295
34654
  return layerServers;
34296
34655
  }
34297
34656
  function decodeServerConfig(raw) {
34298
- const record = asRecord$4(raw);
34657
+ const record = asRecord$5(raw);
34299
34658
  if (!record) return effect.Schema.decodeSync(require_collectUint8StreamText.McpServerConfig)({ transport: "unknown" });
34300
34659
  const input = {
34301
34660
  transport: typeof record.url === "string" ? "http" : typeof record.command === "string" ? "stdio" : "unknown",
@@ -34412,15 +34771,15 @@ function toStartupStatus(config, status) {
34412
34771
  }
34413
34772
  function extractConfigPath(layers) {
34414
34773
  const userLayer = layers?.find((layer) => {
34415
- const name = asRecord$4(layer.name);
34774
+ const name = asRecord$5(layer.name);
34416
34775
  return name?.type === "user" && typeof name.file === "string";
34417
34776
  });
34418
- const file = asRecord$4(userLayer?.name)?.file;
34777
+ const file = asRecord$5(userLayer?.name)?.file;
34419
34778
  return typeof file === "string" ? file : void 0;
34420
34779
  }
34421
34780
  function buildServers(input) {
34422
34781
  const configRecord = input.configResponse.config;
34423
- const configuredServers = asRecord$4(configRecord.mcp_servers) ?? {};
34782
+ const configuredServers = asRecord$5(configRecord.mcp_servers) ?? {};
34424
34783
  const statusByName = new Map(input.statuses.map((status) => [status.name, status]));
34425
34784
  const names = [.../* @__PURE__ */ new Set([...Object.keys(configuredServers), ...statusByName.keys()])].toSorted((left, right) => left.localeCompare(right));
34426
34785
  const layerServers = collectLayerServers(input.configResponse.layers);
@@ -34645,7 +35004,7 @@ const makeCodexMcpService = effect.Effect.gen(function* () {
34645
35004
  cwd: serverConfig.cwd,
34646
35005
  includeLayers: false
34647
35006
  })).config;
34648
- const config = mergeServerSecrets((asRecord$4(configRecord.mcp_servers) ?? {})[input.name], input);
35007
+ const config = mergeServerSecrets((asRecord$5(configRecord.mcp_servers) ?? {})[input.name], input);
34649
35008
  return yield* client.request("config/batchWrite", {
34650
35009
  edits: [{
34651
35010
  keyPath: `mcp_servers.${input.name}`,
@@ -37158,6 +37517,20 @@ const OpenLive = effect.Layer.effect(Open, make$10);
37158
37517
  */
37159
37518
  var OrchestrationEngineService = class extends effect.Context.Service()("ryco/orchestration/Services/OrchestrationEngine/OrchestrationEngineService") {};
37160
37519
  //#endregion
37520
+ //#region src/orchestration/Services/ThreadDeletionReactor.ts
37521
+ /**
37522
+ * ThreadDeletionReactor - Thread deletion cleanup reactor service interface.
37523
+ *
37524
+ * Owns background workers that react to thread deletion domain events and
37525
+ * perform best-effort runtime cleanup for provider sessions and terminals.
37526
+ *
37527
+ * @module ThreadDeletionReactor
37528
+ */
37529
+ /**
37530
+ * ThreadDeletionReactor - Service tag for thread deletion cleanup workers.
37531
+ */
37532
+ var ThreadDeletionReactor = class extends effect.Context.Service()("ryco/orchestration/Services/ThreadDeletionReactor") {};
37533
+ //#endregion
37161
37534
  //#region src/orchestration/Services/ContextHandoffInspection.ts
37162
37535
  var ContextHandoffInspection = class extends effect.Context.Service()("ryco/orchestration/Services/ContextHandoffInspection") {};
37163
37536
  //#endregion
@@ -38703,6 +39076,9 @@ var WorkspaceAccessPolicy = class extends effect.Context.Service()("ryco/workspa
38703
39076
  //#region src/provider/Services/ProviderSessionReaper.ts
38704
39077
  var ProviderSessionReaper = class extends effect.Context.Service()("ryco/provider/Services/ProviderSessionReaper") {};
38705
39078
  //#endregion
39079
+ //#region src/provider/Services/ProviderSessionDirectory.ts
39080
+ var ProviderSessionDirectory = class extends effect.Context.Service()("ryco/provider/Services/ProviderSessionDirectory") {};
39081
+ //#endregion
38706
39082
  //#region ../../packages/shared/src/qrCode.ts
38707
39083
  var QrCode = class QrCode {
38708
39084
  static Ecc;
@@ -39917,6 +40293,86 @@ const validateRestrictedWorkspaceSnapshot = (snapshot) => effect.Effect.gen(func
39917
40293
  operation: "persisted worktree startup validation"
39918
40294
  }), { discard: true });
39919
40295
  }).pipe(effect.Effect.mapError(incompatibleWorkspaceStateError));
40296
+ const ORPHANED_PROVIDER_SESSION_ERROR = "Provider session did not survive a server restart. Send a new message to continue.";
40297
+ function clearRuntimePayloadActiveTurn(runtimePayload) {
40298
+ if (typeof runtimePayload === "object" && runtimePayload !== null && !Array.isArray(runtimePayload)) return {
40299
+ ...runtimePayload,
40300
+ activeTurnId: null
40301
+ };
40302
+ return { activeTurnId: null };
40303
+ }
40304
+ /**
40305
+ * Settle projected provider sessions whose native process did not survive this
40306
+ * server process. This runs after the provider/orchestration roots subscribe,
40307
+ * but before the startup command gate opens, so repaired state is authoritative
40308
+ * before clients can mutate it.
40309
+ */
40310
+ const reconcileOrphanedProviderSessions = effect.Effect.gen(function* () {
40311
+ const directory = yield* ProviderSessionDirectory;
40312
+ const orchestrationEngine = yield* OrchestrationEngineService;
40313
+ const providerService = yield* ProviderService;
40314
+ const projectionSnapshotQuery = yield* ProjectionSnapshotQuery;
40315
+ const liveSessionsExit = yield* effect.Effect.exit(providerService.listSessions());
40316
+ if (effect.Exit.isFailure(liveSessionsExit)) {
40317
+ if (effect.Cause.hasInterrupts(liveSessionsExit.cause)) return yield* effect.Effect.failCause(liveSessionsExit.cause);
40318
+ yield* effect.Effect.logWarning("provider session startup inventory failed", { cause: effect.Cause.pretty(liveSessionsExit.cause) });
40319
+ return;
40320
+ }
40321
+ const liveThreadIds = new Set(liveSessionsExit.value.map((session) => session.threadId));
40322
+ const orphanedThreads = (yield* projectionSnapshotQuery.getCommandReadModel()).threads.filter((thread) => thread.session !== null && (thread.session.status === "starting" || thread.session.status === "running" || thread.session.activeTurnId !== null) && !liveThreadIds.has(thread.id));
40323
+ for (const thread of orphanedThreads) {
40324
+ const session = thread.session;
40325
+ if (session === null) continue;
40326
+ yield* effect.Effect.gen(function* () {
40327
+ const binding = yield* directory.getBinding(thread.id);
40328
+ if (effect.Option.isNone(binding)) return;
40329
+ yield* providerService.stopSessionBinding(binding.value).pipe(effect.Effect.catchCause((cause) => effect.Cause.hasInterrupts(cause) ? effect.Effect.failCause(cause) : effect.Effect.logWarning("failed to stop orphaned provider runtime binding", {
40330
+ threadId: thread.id,
40331
+ cause: effect.Cause.pretty(cause)
40332
+ })));
40333
+ yield* directory.upsert({
40334
+ ...binding.value,
40335
+ status: "stopped",
40336
+ runtimePayload: clearRuntimePayloadActiveTurn(binding.value.runtimePayload)
40337
+ });
40338
+ }).pipe(effect.Effect.catchCause((cause) => effect.Cause.hasInterrupts(cause) ? effect.Effect.failCause(cause) : effect.Effect.logWarning("failed to reconcile orphaned provider session binding", {
40339
+ threadId: thread.id,
40340
+ cause: effect.Cause.pretty(cause)
40341
+ })));
40342
+ const reconciledAt = (/* @__PURE__ */ new Date()).toISOString();
40343
+ if (session.activeTurnId !== null) {
40344
+ const interruptCommand = {
40345
+ type: "thread.turn.interrupt",
40346
+ commandId: require_collectUint8StreamText.CommandId.make(`provider:startup-reconciliation:turn-interrupt:${crypto.randomUUID()}`),
40347
+ threadId: thread.id,
40348
+ turnId: session.activeTurnId,
40349
+ createdAt: reconciledAt
40350
+ };
40351
+ yield* effect.Effect.suspend(() => orchestrationEngine.dispatch(interruptCommand)).pipe(effect.Effect.retry(effect.Schedule.recurs(1)), effect.Effect.catchCause((cause) => effect.Cause.hasInterrupts(cause) ? effect.Effect.failCause(cause) : effect.Effect.logWarning("failed to settle orphaned provider turn projection", {
40352
+ threadId: thread.id,
40353
+ turnId: session.activeTurnId,
40354
+ cause: effect.Cause.pretty(cause)
40355
+ })));
40356
+ }
40357
+ const sessionCommand = {
40358
+ type: "thread.session.set",
40359
+ commandId: require_collectUint8StreamText.CommandId.make(`server:startup-reconciliation:${crypto.randomUUID()}`),
40360
+ threadId: thread.id,
40361
+ session: {
40362
+ ...session,
40363
+ status: "error",
40364
+ activeTurnId: null,
40365
+ lastError: ORPHANED_PROVIDER_SESSION_ERROR,
40366
+ updatedAt: reconciledAt
40367
+ },
40368
+ createdAt: reconciledAt
40369
+ };
40370
+ yield* effect.Effect.suspend(() => orchestrationEngine.dispatch(sessionCommand)).pipe(effect.Effect.retry(effect.Schedule.recurs(1)), effect.Effect.catchCause((cause) => effect.Cause.hasInterrupts(cause) ? effect.Effect.failCause(cause) : effect.Effect.logWarning("failed to settle orphaned provider session projection", {
40371
+ threadId: thread.id,
40372
+ cause: effect.Cause.pretty(cause)
40373
+ })));
40374
+ }
40375
+ }).pipe(effect.Effect.catchCause((cause) => effect.Cause.hasInterrupts(cause) ? effect.Effect.failCause(cause) : effect.Effect.logWarning("provider session startup reconciliation failed", { cause: effect.Cause.pretty(cause) })));
39920
40376
  const makeServerRuntimeStartup = effect.Effect.gen(function* () {
39921
40377
  const runtimeStartedAt = Date.now();
39922
40378
  const serverConfig = yield* require_Metrics.ServerConfig;
@@ -39951,6 +40407,8 @@ const makeServerRuntimeStartup = effect.Effect.gen(function* () {
39951
40407
  concurrency: "unbounded",
39952
40408
  discard: true
39953
40409
  }));
40410
+ yield* effect.Effect.logDebug("startup phase: reconciling orphaned provider sessions");
40411
+ yield* runStartupPhase("provider-sessions.reconcile", reconcileOrphanedProviderSessions);
39954
40412
  const welcomeBase = yield* resolveWelcomeBase;
39955
40413
  const environment = yield* serverEnvironment.getDescriptor;
39956
40414
  yield* effect.Effect.logDebug("startup phase: preparing welcome payload");
@@ -41035,17 +41493,40 @@ const makeGitManager = effect.Effect.fn("makeGitManager")(function* () {
41035
41493
  timeToLive: (exit) => effect.Exit.isSuccess(exit) ? STATUS_RESULT_CACHE_TTL : effect.Duration.zero
41036
41494
  });
41037
41495
  const invalidateLocalStatusResultCache = (cwd) => normalizeStatusCacheKey(cwd).pipe(effect.Effect.flatMap((cacheKey) => effect.Cache.invalidate(localStatusResultCache, cacheKey)));
41496
+ const probeBranchPublished = effect.Effect.fn("probeBranchPublished")(function* (cwd, branch, upstreamRef) {
41497
+ if (upstreamRef !== null) return true;
41498
+ return yield* effect.Effect.gen(function* () {
41499
+ const remotes = (yield* gitCore.execute({
41500
+ operation: "GitManager.probeBranchPublished.remotes",
41501
+ cwd,
41502
+ args: ["remote"]
41503
+ })).stdout.split("\n").map((remote) => remote.trim()).filter((remote) => remote.length > 0);
41504
+ if (remotes.length === 0) return null;
41505
+ const refsResult = yield* gitCore.execute({
41506
+ operation: "GitManager.probeBranchPublished.remoteRefs",
41507
+ cwd,
41508
+ args: [
41509
+ "for-each-ref",
41510
+ "--format=%(refname:short)",
41511
+ "refs/remotes"
41512
+ ]
41513
+ });
41514
+ const remoteRefs = new Set(refsResult.stdout.split("\n").map((ref) => ref.trim()).filter((ref) => ref.length > 0));
41515
+ return remotes.some((remote) => remoteRefs.has(`${remote}/${branch}`));
41516
+ }).pipe(effect.Effect.catch(() => effect.Effect.succeed(null)));
41517
+ });
41038
41518
  const readRemoteStatus = effect.Effect.fn("readRemoteStatus")(function* (cwd) {
41039
41519
  const details = yield* gitCore.statusDetails(cwd).pipe(effect.Effect.catchIf(isNotGitRepositoryError, () => effect.Effect.succeed(null)));
41040
41520
  if (details === null || !details.isRepo) return null;
41041
- const pr = details.branch !== null ? yield* findLatestPr(cwd, {
41521
+ const shouldQueryPullRequests = details.branch === null ? false : (yield* probeBranchPublished(cwd, details.branch, details.upstreamRef)) ?? true;
41522
+ const pr = details.branch !== null && shouldQueryPullRequests ? yield* findLatestPr(cwd, {
41042
41523
  branch: details.branch,
41043
41524
  upstreamRef: details.upstreamRef
41044
41525
  }).pipe(effect.Effect.map((latest) => {
41045
41526
  if (!latest) return null;
41046
41527
  if (details.isDefaultBranch && latest.state !== "open") return null;
41047
41528
  return toStatusPr(latest);
41048
- }), effect.Effect.catch(() => effect.Effect.succeed(null))) : null;
41529
+ })) : null;
41049
41530
  return {
41050
41531
  hasUpstream: details.hasUpstream,
41051
41532
  aheadCount: details.aheadCount,
@@ -41707,6 +42188,7 @@ const make$9 = effect.Effect.fn("makeGitWorkflowService")(function* () {
41707
42188
  listRefs: (input) => detectGitRepositoryForCommand("GitWorkflowService.listRefs", input.cwd).pipe(effect.Effect.flatMap((isGitRepository) => isGitRepository ? git.listRefs(input).pipe(effect.Effect.catch(recoverMissingCwd(input.cwd, nonRepositoryListRefs()))) : effect.Effect.succeed(nonRepositoryListRefs()))),
41708
42189
  createWorktree: (input) => ensureGitCommand("GitWorkflowService.createWorktree", input.cwd).pipe(effect.Effect.andThen(git.createWorktree(input))),
41709
42190
  removeWorktree: (input) => ensureGitCommand("GitWorkflowService.removeWorktree", input.cwd).pipe(effect.Effect.andThen(git.removeWorktree(input))),
42191
+ pruneWorktrees: (cwd) => ensureGitCommand("GitWorkflowService.pruneWorktrees", cwd).pipe(effect.Effect.andThen(git.pruneWorktrees(cwd))),
41710
42192
  listWorktreePaths: (cwd) => {
41711
42193
  const empty = [];
41712
42194
  return detectGitRepositoryForCommand("GitWorkflowService.listWorktreePaths", cwd).pipe(effect.Effect.flatMap((isGitRepository) => isGitRepository ? git.listWorktreePaths(cwd).pipe(effect.Effect.catch(recoverMissingCwd(cwd, empty))) : effect.Effect.succeed(empty)));
@@ -44882,6 +45364,7 @@ const makeWsRpcContext = (principal) => effect.Effect.gen(function* () {
44882
45364
  const usageServiceOption = yield* effect.Effect.serviceOption(UsageService);
44883
45365
  const usageService = effect.Option.getOrElse(usageServiceOption, () => UsageServiceTest);
44884
45366
  const orchestrationEngine = yield* OrchestrationEngineService;
45367
+ const threadDeletionReactor = yield* ThreadDeletionReactor;
44885
45368
  const contextHandoffInspection = yield* effect.Effect.serviceOption(ContextHandoffInspection);
44886
45369
  const threadPriorityCoordinator = yield* effect.Effect.serviceOption(ThreadPriorityCoordinator);
44887
45370
  const agentControlProposals = yield* effect.Effect.serviceOption(AgentControlProposalService);
@@ -45099,7 +45582,7 @@ const makeWsRpcContext = (principal) => effect.Effect.gen(function* () {
45099
45582
  })() : effect.Effect.void;
45100
45583
  return yield* effect.Effect.gen(function* () {
45101
45584
  if (bootstrap?.createThread) {
45102
- yield* orchestrationEngine.dispatch({
45585
+ const created = yield* orchestrationEngine.dispatch({
45103
45586
  type: "thread.create",
45104
45587
  commandId: serverCommandId("bootstrap-thread-create"),
45105
45588
  threadId: command.threadId,
@@ -45112,6 +45595,7 @@ const makeWsRpcContext = (principal) => effect.Effect.gen(function* () {
45112
45595
  worktreePath: bootstrap.createThread.worktreePath,
45113
45596
  createdAt: bootstrap.createThread.createdAt
45114
45597
  });
45598
+ yield* threadDeletionReactor.drainThrough(created.sequence);
45115
45599
  createdThread = true;
45116
45600
  }
45117
45601
  if (bootstrap?.prepareWorktree) {
@@ -45148,7 +45632,7 @@ const makeWsRpcContext = (principal) => effect.Effect.gen(function* () {
45148
45632
  }));
45149
45633
  });
45150
45634
  const dispatchNormalizedCommand = (normalizedCommand) => {
45151
- const dispatchEffect = normalizedCommand.type === "thread.turn.start" && normalizedCommand.bootstrap ? dispatchBootstrapTurnStart(normalizedCommand) : orchestrationEngine.dispatch(normalizedCommand).pipe(effect.Effect.mapError((cause) => toDispatchCommandError(cause, "Failed to dispatch orchestration command")));
45635
+ const dispatchEffect = normalizedCommand.type === "thread.turn.start" && normalizedCommand.bootstrap ? dispatchBootstrapTurnStart(normalizedCommand) : orchestrationEngine.dispatch(normalizedCommand).pipe(effect.Effect.tap(({ sequence }) => normalizedCommand.type === "thread.create" ? threadDeletionReactor.drainThrough(sequence) : effect.Effect.void), effect.Effect.mapError((cause) => toDispatchCommandError(cause, "Failed to dispatch orchestration command")));
45152
45636
  return startup.enqueueCommand(dispatchEffect).pipe(effect.Effect.mapError((cause) => toDispatchCommandError(cause, "Failed to dispatch orchestration command")));
45153
45637
  };
45154
45638
  const loadDiagnosticsMetrics = localDiagnosticsMetrics.snapshot;
@@ -45536,18 +46020,24 @@ const normalizeDispatchCommand = (command) => effect.Effect.gen(function* () {
45536
46020
  ...command.projectMetadataDir !== void 0 ? { projectMetadataDir: yield* normalizeProjectMetadataDir(command.projectMetadataDir) } : {}
45537
46021
  };
45538
46022
  if (command.type !== "thread.turn.start" && command.type !== "thread.turn.steer") return command;
45539
- const normalizedAttachments = yield* effect.Effect.forEach(command.message.attachments, (attachment) => effect.Effect.gen(function* () {
46023
+ const preparedAttachments = yield* effect.Effect.forEach(command.message.attachments, (attachment) => effect.Effect.gen(function* () {
45540
46024
  const parsed = parseBase64DataUrl(attachment.dataUrl);
45541
- if (!parsed || !parsed.mimeType.startsWith("image/")) return yield* new require_collectUint8StreamText.OrchestrationDispatchCommandError({ message: `Invalid image attachment payload for '${attachment.name}'.` });
45542
- const bytes = Buffer.from(parsed.base64, "base64");
45543
- if (bytes.byteLength === 0 || bytes.byteLength > 10485760) return yield* new require_collectUint8StreamText.OrchestrationDispatchCommandError({ message: `Image attachment '${attachment.name}' is empty or too large.` });
46025
+ if (!parsed) return yield* new require_collectUint8StreamText.OrchestrationDispatchCommandError({ message: `Attachment '${attachment.name}' must use a valid base64 data URL.` });
46026
+ const normalizedMimeType = parsed.mimeType.toLowerCase();
46027
+ if (normalizedMimeType !== attachment.mimeType.toLowerCase()) return yield* new require_collectUint8StreamText.OrchestrationDispatchCommandError({ message: `Attachment '${attachment.name}' declares '${attachment.mimeType}' but its payload is '${parsed.mimeType}'.` });
46028
+ if (attachment.type === "image" && !normalizedMimeType.startsWith("image/")) return yield* new require_collectUint8StreamText.OrchestrationDispatchCommandError({ message: `Image attachment '${attachment.name}' must use an image MIME type.` });
46029
+ const normalizedBase64 = parsed.base64.replace(/\s+/g, "");
46030
+ const bytes = Buffer.from(normalizedBase64, "base64");
46031
+ if (bytes.byteLength === 0 || bytes.toString("base64") !== normalizedBase64 || bytes.byteLength !== attachment.sizeBytes) return yield* new require_collectUint8StreamText.OrchestrationDispatchCommandError({ message: `Attachment '${attachment.name}' has invalid base64 data or mismatched size metadata.` });
46032
+ const attachmentLimit = attachment.type === "image" ? require_collectUint8StreamText.PROVIDER_SEND_TURN_MAX_IMAGE_BYTES : require_collectUint8StreamText.PROVIDER_SEND_TURN_MAX_FILE_BYTES;
46033
+ if (bytes.byteLength > attachmentLimit) return yield* new require_collectUint8StreamText.OrchestrationDispatchCommandError({ message: `Attachment '${attachment.name}' is ${bytes.byteLength} bytes; limit is ${attachmentLimit} bytes.` });
45544
46034
  const attachmentId = createAttachmentId(command.threadId);
45545
46035
  if (!attachmentId) return yield* new require_collectUint8StreamText.OrchestrationDispatchCommandError({ message: "Failed to create a safe attachment id." });
45546
46036
  const persistedAttachment = {
45547
- type: "image",
46037
+ type: attachment.type,
45548
46038
  id: attachmentId,
45549
46039
  name: attachment.name,
45550
- mimeType: parsed.mimeType.toLowerCase(),
46040
+ mimeType: normalizedMimeType,
45551
46041
  sizeBytes: bytes.byteLength
45552
46042
  };
45553
46043
  const attachmentPath = resolveAttachmentPath({
@@ -45555,10 +46045,22 @@ const normalizeDispatchCommand = (command) => effect.Effect.gen(function* () {
45555
46045
  attachment: persistedAttachment
45556
46046
  });
45557
46047
  if (!attachmentPath) return yield* new require_collectUint8StreamText.OrchestrationDispatchCommandError({ message: `Failed to resolve persisted path for '${attachment.name}'.` });
45558
- yield* fileSystem.makeDirectory(path.dirname(attachmentPath), { recursive: true }).pipe(effect.Effect.mapError(() => new require_collectUint8StreamText.OrchestrationDispatchCommandError({ message: `Failed to create attachment directory for '${attachment.name}'.` })));
45559
- yield* fileSystem.writeFile(attachmentPath, bytes).pipe(effect.Effect.mapError(() => new require_collectUint8StreamText.OrchestrationDispatchCommandError({ message: `Failed to persist attachment '${attachment.name}'.` })));
45560
- return persistedAttachment;
46048
+ return {
46049
+ attachment: persistedAttachment,
46050
+ attachmentPath,
46051
+ bytes
46052
+ };
45561
46053
  }), { concurrency: 1 });
46054
+ const totalAttachmentBytes = preparedAttachments.reduce((total, prepared) => total + prepared.bytes.byteLength, 0);
46055
+ if (totalAttachmentBytes > 52428800) return yield* new require_collectUint8StreamText.OrchestrationDispatchCommandError({ message: `Attachments total ${totalAttachmentBytes} bytes; limit is ${require_collectUint8StreamText.PROVIDER_SEND_TURN_MAX_ATTACHMENT_TOTAL_BYTES} bytes.` });
46056
+ yield* effect.Effect.forEach(preparedAttachments, ({ attachment, attachmentPath, bytes }) => fileSystem.makeDirectory(path.dirname(attachmentPath), { recursive: true }).pipe(effect.Effect.mapError(() => new require_collectUint8StreamText.OrchestrationDispatchCommandError({ message: `Failed to create attachment directory for '${attachment.name}'.` })), effect.Effect.andThen(fileSystem.writeFile(attachmentPath, bytes).pipe(effect.Effect.mapError(() => new require_collectUint8StreamText.OrchestrationDispatchCommandError({ message: `Failed to persist attachment '${attachment.name}'.` }))))), {
46057
+ concurrency: 1,
46058
+ discard: true
46059
+ }).pipe(effect.Effect.onError(() => effect.Effect.forEach(preparedAttachments, ({ attachmentPath }) => fileSystem.remove(attachmentPath).pipe(effect.Effect.ignore), {
46060
+ concurrency: 1,
46061
+ discard: true
46062
+ })));
46063
+ const normalizedAttachments = preparedAttachments.map(({ attachment }) => attachment);
45562
46064
  return {
45563
46065
  ...command,
45564
46066
  message: {
@@ -47776,10 +48278,10 @@ const ContextHandoffDocument = effect.Schema.Struct({
47776
48278
  subagents: effect.Schema.Array(ContextHandoffSubagentEntry),
47777
48279
  priorHandoffs: effect.Schema.Array(ContextHandoffBoundaryEntry)
47778
48280
  });
47779
- function asRecord$3(value) {
48281
+ function asRecord$4(value) {
47780
48282
  return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
47781
48283
  }
47782
- function asTrimmedString$1(value) {
48284
+ function asTrimmedString$2(value) {
47783
48285
  if (typeof value !== "string") return;
47784
48286
  const trimmed = value.trim();
47785
48287
  return trimmed.length > 0 ? trimmed : void 0;
@@ -47798,7 +48300,7 @@ function truncateUnicodeSafe(value, maxChars) {
47798
48300
  return value.slice(0, end);
47799
48301
  }
47800
48302
  function boundedString(value, maxChars) {
47801
- const normalized = asTrimmedString$1(value);
48303
+ const normalized = asTrimmedString$2(value);
47802
48304
  if (!normalized) return { truncated: false };
47803
48305
  const bounded = truncateUnicodeSafe(normalized, maxChars);
47804
48306
  return {
@@ -47850,7 +48352,7 @@ function boundedEndpoint(endpoint) {
47850
48352
  };
47851
48353
  }
47852
48354
  function activityPayload(activity) {
47853
- return asRecord$3(activity.payload);
48355
+ return asRecord$4(activity.payload);
47854
48356
  }
47855
48357
  function decodeHandoffPayload(activity) {
47856
48358
  if (activity.kind !== "context-handoff") return;
@@ -47937,7 +48439,7 @@ function collectRuntimePlan(activities) {
47937
48439
  if (!Array.isArray(payload?.plan)) continue;
47938
48440
  let truncated = payload.plan.length > MAX_PLAN_STEPS;
47939
48441
  const steps = payload.plan.slice(0, MAX_PLAN_STEPS).flatMap((entry) => {
47940
- const record = asRecord$3(entry);
48442
+ const record = asRecord$4(entry);
47941
48443
  const step = boundedString(record?.step, DETAIL_MAX_CHARS);
47942
48444
  if (!step.value) return [];
47943
48445
  truncated ||= step.truncated;
@@ -47964,21 +48466,21 @@ function collectRuntimePlan(activities) {
47964
48466
  return latest ? [latest] : [];
47965
48467
  }
47966
48468
  function normalizeCommand(value) {
47967
- const direct = asTrimmedString$1(value);
48469
+ const direct = asTrimmedString$2(value);
47968
48470
  if (direct) return direct;
47969
48471
  if (!Array.isArray(value)) return;
47970
48472
  const parts = value.flatMap((entry) => {
47971
- const part = asTrimmedString$1(entry);
48473
+ const part = asTrimmedString$2(entry);
47972
48474
  return part ? [part] : [];
47973
48475
  });
47974
48476
  return parts.length > 0 ? parts.join(" ") : void 0;
47975
48477
  }
47976
48478
  function extractCommand(payload) {
47977
- const data = asRecord$3(payload.data);
47978
- const item = asRecord$3(data?.item);
47979
- const input = asRecord$3(item?.input);
47980
- const result = asRecord$3(item?.result);
47981
- const rawInput = asRecord$3(data?.rawInput);
48479
+ const data = asRecord$4(payload.data);
48480
+ const item = asRecord$4(data?.item);
48481
+ const input = asRecord$4(item?.input);
48482
+ const result = asRecord$4(item?.result);
48483
+ const rawInput = asRecord$4(data?.rawInput);
47982
48484
  for (const candidate of [
47983
48485
  item?.command,
47984
48486
  input?.command,
@@ -47989,7 +48491,7 @@ function extractCommand(payload) {
47989
48491
  const command = normalizeCommand(candidate);
47990
48492
  if (command) return command;
47991
48493
  }
47992
- const executable = asTrimmedString$1(rawInput?.executable);
48494
+ const executable = asTrimmedString$2(rawInput?.executable);
47993
48495
  const args = normalizeCommand(rawInput?.args);
47994
48496
  return executable ? args ? `${executable} ${args}` : executable : void 0;
47995
48497
  }
@@ -47997,36 +48499,36 @@ function textFromContentArray(value) {
47997
48499
  if (!Array.isArray(value)) return;
47998
48500
  const chunks = [];
47999
48501
  for (const entry of value) {
48000
- const record = asRecord$3(entry);
48001
- const direct = asTrimmedString$1(record?.text);
48002
- const nested = asTrimmedString$1(asRecord$3(record?.content)?.text);
48502
+ const record = asRecord$4(entry);
48503
+ const direct = asTrimmedString$2(record?.text);
48504
+ const nested = asTrimmedString$2(asRecord$4(record?.content)?.text);
48003
48505
  if (direct) chunks.push(direct);
48004
48506
  else if (nested) chunks.push(nested);
48005
48507
  }
48006
48508
  return chunks.length > 0 ? chunks.join("\n") : void 0;
48007
48509
  }
48008
48510
  function extractOutput(payload) {
48009
- const data = asRecord$3(payload.data);
48010
- const item = asRecord$3(data?.item);
48011
- if (item?.type === "commandExecution") return asTrimmedString$1(item.aggregatedOutput);
48511
+ const data = asRecord$4(payload.data);
48512
+ const item = asRecord$4(data?.item);
48513
+ if (item?.type === "commandExecution") return asTrimmedString$2(item.aggregatedOutput);
48012
48514
  if (item?.type === "mcpToolCall") {
48013
- const error = asTrimmedString$1(asRecord$3(item.error)?.message);
48515
+ const error = asTrimmedString$2(asRecord$4(item.error)?.message);
48014
48516
  if (error) return error;
48015
- const content = textFromContentArray(asRecord$3(item.result)?.content);
48517
+ const content = textFromContentArray(asRecord$4(item.result)?.content);
48016
48518
  if (content) return content;
48017
48519
  }
48018
48520
  if (item?.type === "dynamicToolCall") {
48019
48521
  const content = textFromContentArray(item.contentItems);
48020
48522
  if (content) return content;
48021
48523
  }
48022
- const rawOutput = asRecord$3(data?.rawOutput);
48023
- return asTrimmedString$1(rawOutput?.stdout) ?? asTrimmedString$1(rawOutput?.stderr) ?? asTrimmedString$1(rawOutput?.content) ?? textFromContentArray(data?.content);
48524
+ const rawOutput = asRecord$4(data?.rawOutput);
48525
+ return asTrimmedString$2(rawOutput?.stdout) ?? asTrimmedString$2(rawOutput?.stderr) ?? asTrimmedString$2(rawOutput?.content) ?? textFromContentArray(data?.content);
48024
48526
  }
48025
48527
  function extractExitCode(payload) {
48026
- const data = asRecord$3(payload.data);
48027
- const item = asRecord$3(data?.item);
48028
- const itemResult = asRecord$3(item?.result);
48029
- const rawOutput = asRecord$3(data?.rawOutput);
48528
+ const data = asRecord$4(payload.data);
48529
+ const item = asRecord$4(data?.item);
48530
+ const itemResult = asRecord$4(item?.result);
48531
+ const rawOutput = asRecord$4(data?.rawOutput);
48030
48532
  for (const candidate of [
48031
48533
  item?.exitCode,
48032
48534
  itemResult?.exitCode,
@@ -48035,7 +48537,7 @@ function extractExitCode(payload) {
48035
48537
  const exitCode = asInteger(candidate);
48036
48538
  if (exitCode !== void 0) return exitCode;
48037
48539
  }
48038
- const detail = asTrimmedString$1(payload.detail);
48540
+ const detail = asTrimmedString$2(payload.detail);
48039
48541
  const match = detail ? /<exited with exit code (?<code>-?\d+)>\s*$/iu.exec(detail) : null;
48040
48542
  const parsed = Number.parseInt(match?.groups?.code ?? "", 10);
48041
48543
  return Number.isInteger(parsed) ? parsed : void 0;
@@ -48049,7 +48551,7 @@ function pathFromRecord(record) {
48049
48551
  "newPath",
48050
48552
  "oldPath"
48051
48553
  ]) {
48052
- const path = asTrimmedString$1(record[key]);
48554
+ const path = asTrimmedString$2(record[key]);
48053
48555
  if (path) return truncateUnicodeSafe(path, PATH_MAX_CHARS);
48054
48556
  }
48055
48557
  }
@@ -48070,7 +48572,7 @@ function collectPathsAndChanges(value) {
48070
48572
  for (const entry of current) visit(entry, depth + 1);
48071
48573
  return;
48072
48574
  }
48073
- const record = asRecord$3(current);
48575
+ const record = asRecord$4(current);
48074
48576
  if (!record || seenObjects.has(record)) return;
48075
48577
  seenObjects.add(record);
48076
48578
  const path = pathFromRecord(record);
@@ -48124,10 +48626,10 @@ function extractTool(activity) {
48124
48626
  const lifecycle = toolLifecycle(activity.kind);
48125
48627
  const payload = activityPayload(activity);
48126
48628
  if (!lifecycle || !payload || !effect.Schema.is(require_collectUint8StreamText.ToolLifecycleItemType)(payload.itemType)) return;
48127
- const data = asRecord$3(payload.data);
48128
- const providerRefs = asRecord$3(payload.providerRefs);
48129
- const providerItemId = asTrimmedString$1(payload.providerItemId) ?? asTrimmedString$1(providerRefs?.providerItemId);
48130
- const toolCallId = asTrimmedString$1(data?.toolCallId);
48629
+ const data = asRecord$4(payload.data);
48630
+ const providerRefs = asRecord$4(payload.providerRefs);
48631
+ const providerItemId = asTrimmedString$2(payload.providerItemId) ?? asTrimmedString$2(providerRefs?.providerItemId);
48632
+ const toolCallId = asTrimmedString$2(data?.toolCallId);
48131
48633
  const command = boundedString(extractCommand(payload), TOOL_COMMAND_MAX_CHARS);
48132
48634
  const output = boundedString(extractOutput(payload), TOOL_OUTPUT_MAX_CHARS);
48133
48635
  const detail = boundedString(payload.detail, DETAIL_MAX_CHARS);
@@ -48219,7 +48721,7 @@ function parseQuestions(payload) {
48219
48721
  let truncated = payload.questions.length > MAX_QUESTIONS_PER_REQUEST;
48220
48722
  return {
48221
48723
  questions: payload.questions.slice(0, MAX_QUESTIONS_PER_REQUEST).flatMap((value) => {
48222
- const record = asRecord$3(value);
48724
+ const record = asRecord$4(value);
48223
48725
  const id = boundedString(record?.id, LABEL_MAX_CHARS);
48224
48726
  const header = boundedString(record?.header, LABEL_MAX_CHARS);
48225
48727
  const question = boundedString(record?.question, QUESTION_MAX_CHARS);
@@ -48228,7 +48730,7 @@ function parseQuestions(payload) {
48228
48730
  const rawOptions = Array.isArray(record?.options) ? record.options : [];
48229
48731
  truncated ||= rawOptions.length > MAX_OPTIONS_PER_QUESTION;
48230
48732
  const options = rawOptions.slice(0, MAX_OPTIONS_PER_QUESTION).flatMap((option) => {
48231
- const label = boundedString(asRecord$3(option)?.label, LABEL_MAX_CHARS);
48733
+ const label = boundedString(asRecord$4(option)?.label, LABEL_MAX_CHARS);
48232
48734
  truncated ||= label.truncated;
48233
48735
  return label.value ? [label.value] : [];
48234
48736
  });
@@ -48269,7 +48771,7 @@ function collectNotices(activities) {
48269
48771
  const failure = failureFromActivity(activity);
48270
48772
  if (failure) failures.push(failure);
48271
48773
  const payload = activityPayload(activity);
48272
- const requestId = asTrimmedString$1(payload?.requestId);
48774
+ const requestId = asTrimmedString$2(payload?.requestId);
48273
48775
  if (!requestId) continue;
48274
48776
  if (activity.kind === "user-input.resolved") {
48275
48777
  pendingQuestions.delete(requestId);
@@ -48296,7 +48798,7 @@ function collectSubagents(activities) {
48296
48798
  for (const activity of activities.toSorted(compareOrdered)) {
48297
48799
  if (activity.kind !== "subagent.completed") continue;
48298
48800
  const payload = activityPayload(activity);
48299
- const subagent = asRecord$3(payload?.subagent);
48801
+ const subagent = asRecord$4(payload?.subagent);
48300
48802
  const subagentId = boundedString(subagent?.subagentId, LABEL_MAX_CHARS);
48301
48803
  const status = payload?.status;
48302
48804
  if (!subagentId.value || !effect.Schema.is(require_collectUint8StreamText.RuntimeSubagentStatus)(status)) continue;
@@ -50315,10 +50817,10 @@ const DEVICE_CAPABILITY_IDS = [
50315
50817
  "accessibility",
50316
50818
  "encoder"
50317
50819
  ];
50318
- const asRecord$2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
50820
+ const asRecord$3 = (value) => typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
50319
50821
  const asNonEmptyString = (value) => typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
50320
50822
  const parseToolchain = (value) => {
50321
- const record = asRecord$2(value);
50823
+ const record = asRecord$3(value);
50322
50824
  if (!record) return void 0;
50323
50825
  const toolchain = {
50324
50826
  xcodeVersion: asNonEmptyString(record["xcodeVersion"]),
@@ -50340,7 +50842,7 @@ const parseCapability = (id, raw) => {
50340
50842
  id,
50341
50843
  ok: true
50342
50844
  };
50343
- const record = asRecord$2(raw);
50845
+ const record = asRecord$3(raw);
50344
50846
  if (!record) return {
50345
50847
  id,
50346
50848
  ok: false,
@@ -50373,7 +50875,7 @@ const parseHelperProbe = (stdout) => {
50373
50875
  error: "The device helper preflight returned unreadable output."
50374
50876
  };
50375
50877
  }
50376
- const record = asRecord$2(parsed);
50878
+ const record = asRecord$3(parsed);
50377
50879
  if (!record) return {
50378
50880
  ok: false,
50379
50881
  capabilities: DEVICE_CAPABILITY_IDS.map((id) => ({
@@ -50384,7 +50886,7 @@ const parseHelperProbe = (stdout) => {
50384
50886
  toolchain: void 0,
50385
50887
  error: "The device helper preflight returned unreadable output."
50386
50888
  };
50387
- const capabilitiesRecord = asRecord$2(record["capabilities"]);
50889
+ const capabilitiesRecord = asRecord$3(record["capabilities"]);
50388
50890
  const error = asNonEmptyString(record["error"]);
50389
50891
  if (!capabilitiesRecord) {
50390
50892
  const ok = record["ok"] === true;
@@ -50637,7 +51139,7 @@ var DeviceHelperError = class extends Error {
50637
51139
  this.code = code;
50638
51140
  }
50639
51141
  };
50640
- function asRecord$1(value) {
51142
+ function asRecord$2(value) {
50641
51143
  return typeof value === "object" && value !== null ? value : {};
50642
51144
  }
50643
51145
  /**
@@ -50773,8 +51275,8 @@ var HelperClient = class {
50773
51275
  async attach(udid, options = {}) {
50774
51276
  if (!options.force && this.attachment?.udid === udid) return this.attachment;
50775
51277
  this.attachment = null;
50776
- const result = asRecord$1(await this.request(HELPER_METHODS.attach, { udid }));
50777
- const capabilities = asRecord$1(result.capabilities);
51278
+ const result = asRecord$2(await this.request(HELPER_METHODS.attach, { udid }));
51279
+ const capabilities = asRecord$2(result.capabilities);
50778
51280
  const pixelWidth = readNumber(result, "pixelWidth", 0);
50779
51281
  const pixelHeight = readNumber(result, "pixelHeight", 0);
50780
51282
  const scale = readNumber(result, "scale", 3);
@@ -50928,14 +51430,14 @@ var HelperClient = class {
50928
51430
  } catch {
50929
51431
  return;
50930
51432
  }
50931
- const record = asRecord$1(message);
51433
+ const record = asRecord$2(message);
50932
51434
  if (typeof record.id !== "number") return;
50933
51435
  const request = this.pending.get(record.id);
50934
51436
  if (!request) return;
50935
51437
  this.pending.delete(record.id);
50936
51438
  clearTimeout(request.timer);
50937
51439
  if (record.error !== void 0 && record.error !== null) {
50938
- const error = asRecord$1(record.error);
51440
+ const error = asRecord$2(record.error);
50939
51441
  request.reject(new DeviceHelperError(typeof error.code === "number" ? `helper_${error.code}` : "helper_error", typeof error.message === "string" ? error.message : "Device helper reported an error"));
50940
51442
  return;
50941
51443
  }
@@ -75007,9 +75509,6 @@ effect.Schema.Struct({ threadId: require_collectUint8StreamText.ThreadId });
75007
75509
  */
75008
75510
  var ProviderSessionRuntimeRepository = class extends effect.Context.Service()("ryco/persistence/Services/ProviderSessionRuntime/ProviderSessionRuntimeRepository") {};
75009
75511
  //#endregion
75010
- //#region src/provider/Services/ProviderSessionDirectory.ts
75011
- var ProviderSessionDirectory = class extends effect.Context.Service()("ryco/provider/Services/ProviderSessionDirectory") {};
75012
- //#endregion
75013
75512
  //#region src/provider/Layers/ProviderSessionDirectory.ts
75014
75513
  function toPersistenceError(operation) {
75015
75514
  return (cause) => new ProviderSessionDirectoryPersistenceError({
@@ -75694,6 +76193,12 @@ const ProviderEventLoggersLive = effect.Layer.effect(ProviderEventLoggers, effec
75694
76193
  };
75695
76194
  }));
75696
76195
  //#endregion
76196
+ //#region ../../packages/shared/src/providerCapabilities.ts
76197
+ /** Drivers whose native turn API accepts arbitrary file bytes, not only images. */
76198
+ function providerSupportsGeneralFileAttachments(provider) {
76199
+ return provider === "copilot" || provider === "opencode";
76200
+ }
76201
+ //#endregion
75697
76202
  //#region src/provider/Layers/ProviderService.ts
75698
76203
  /**
75699
76204
  * ProviderServiceLive - Cross-provider orchestration layer.
@@ -76240,6 +76745,8 @@ const makeProviderService = effect.Effect.fn("makeProviderService")(function* (o
76240
76745
  });
76241
76746
  metricProvider = routed.adapter.provider;
76242
76747
  metricModel = input.modelSelection?.model;
76748
+ const unsupportedFile = input.attachments.find((attachment) => attachment.type === "file");
76749
+ if (unsupportedFile && !providerSupportsGeneralFileAttachments(routed.adapter.provider)) return yield* toValidationError("ProviderService.sendTurn", `Provider '${routed.adapter.provider}' does not accept general file attachments. Add '${unsupportedFile.name}' to the workspace and reference its path instead.`);
76243
76750
  yield* effect.Effect.annotateCurrentSpan({
76244
76751
  "provider.kind": routed.adapter.provider,
76245
76752
  ...input.modelSelection?.model ? { "provider.model": input.modelSelection.model } : {}
@@ -76314,6 +76821,8 @@ const makeProviderService = effect.Effect.fn("makeProviderService")(function* (o
76314
76821
  allowRecovery: false
76315
76822
  });
76316
76823
  if (!routed.isActive || routed.session === void 0) return yield* new ProviderSessionNotFoundError({ threadId: input.threadId });
76824
+ const unsupportedFile = input.attachments.find((attachment) => attachment.type === "file");
76825
+ if (unsupportedFile && !providerSupportsGeneralFileAttachments(routed.adapter.provider)) return yield* toValidationError("ProviderService.steerTurn", `Provider '${routed.adapter.provider}' does not accept general file attachments. Add '${unsupportedFile.name}' to the workspace and reference its path instead.`);
76317
76826
  if (routed.session.activeTurnId !== input.expectedTurnId) return yield* toValidationError("ProviderService.steerTurn", `Expected active turn '${input.expectedTurnId}', found '${routed.session.activeTurnId ?? "none"}'.`);
76318
76827
  const steer = routed.adapter.steerTurn;
76319
76828
  if (routed.adapter.capabilities.turnSteering !== "native" || steer === void 0) return yield* toValidationError("ProviderService.steerTurn", `Provider '${routed.adapter.provider}' does not support active-turn steering.`);
@@ -76692,6 +77201,7 @@ const ProviderSessionReaperLive = makeProviderSessionReaperLive();
76692
77201
  const OPENCODE_SERVER_READY_PREFIX = "opencode server listening";
76693
77202
  const DEFAULT_OPENCODE_SERVER_TIMEOUT_MS = 5e3;
76694
77203
  const DEFAULT_HOSTNAME = "127.0.0.1";
77204
+ const MINIMUM_OPENCODE_VERSION = "1.14.19";
76695
77205
  const OPENCODE_RUNTIME_ERROR_TAG = "OpenCodeRuntimeError";
76696
77206
  var OpenCodeRuntimeError = class extends effect.Data.TaggedError(OPENCODE_RUNTIME_ERROR_TAG) {
76697
77207
  static is = (u) => effect.Predicate.isTagged(u, OPENCODE_RUNTIME_ERROR_TAG);
@@ -76717,6 +77227,22 @@ const runOpenCodeSdk = (operation, fn) => effect.Effect.tryPromise({
76717
77227
  cause
76718
77228
  })
76719
77229
  }).pipe(effect.Effect.withSpan(`opencode.${operation}`));
77230
+ const verifyOpenCodeServerVersion = (client) => runOpenCodeSdk("global.health", (signal) => client.global.health({ signal })).pipe(effect.Effect.timeoutOption("5 seconds"), effect.Effect.flatMap((result) => {
77231
+ if (effect.Option.isNone(result)) return effect.Effect.fail(new OpenCodeRuntimeError({
77232
+ operation: "global.health",
77233
+ detail: "Timed out while checking the OpenCode server version."
77234
+ }));
77235
+ const health = result.value.data;
77236
+ if (!health?.healthy || typeof health.version !== "string" || health.version.length === 0) return effect.Effect.fail(new OpenCodeRuntimeError({
77237
+ operation: "global.health",
77238
+ detail: "OpenCode server health check returned an invalid response."
77239
+ }));
77240
+ if (compareCliVersions(health.version, "1.14.19") < 0) return effect.Effect.fail(new OpenCodeRuntimeError({
77241
+ operation: "global.health",
77242
+ detail: `OpenCode v${health.version} is too old. Upgrade to v${MINIMUM_OPENCODE_VERSION} or newer.`
77243
+ }));
77244
+ return effect.Effect.succeed(health.version);
77245
+ }));
76720
77246
  let openCodeSdkModulePromise;
76721
77247
  const loadOpenCodeSdkModule = () => effect.Effect.tryPromise({
76722
77248
  try: async () => {
@@ -76734,6 +77260,11 @@ const loadOpenCodeSdkModule = () => effect.Effect.tryPromise({
76734
77260
  cause
76735
77261
  })
76736
77262
  }).pipe(effect.Effect.withSpan("opencode.sdk.load"));
77263
+ function resolveOpenCodeServerPassword(input) {
77264
+ if (input.configuredPassword !== void 0) return input.configuredPassword;
77265
+ if (input.external) return;
77266
+ return input.environment === void 0 ? process.env.OPENCODE_SERVER_PASSWORD : input.environment.OPENCODE_SERVER_PASSWORD;
77267
+ }
76737
77268
  function parseServerUrlFromOutput(output) {
76738
77269
  for (const line of output.split("\n")) {
76739
77270
  if (!line.startsWith(OPENCODE_SERVER_READY_PREFIX)) continue;
@@ -76758,13 +77289,13 @@ function openCodeQuestionId(index, question) {
76758
77289
  function toOpenCodeFileParts(input) {
76759
77290
  const parts = [];
76760
77291
  for (const attachment of input.attachments ?? []) {
76761
- const attachmentPath = input.resolveAttachmentPath(attachment);
76762
- if (!attachmentPath) continue;
77292
+ const attachmentUrl = input.resolveAttachmentUrl(attachment);
77293
+ if (!attachmentUrl) continue;
76763
77294
  parts.push({
76764
77295
  type: "file",
76765
77296
  mime: attachment.mimeType,
76766
77297
  filename: attachment.name,
76767
- url: (0, node_url.pathToFileURL)(attachmentPath).href
77298
+ url: attachmentUrl
76768
77299
  });
76769
77300
  }
76770
77301
  return parts;
@@ -76883,11 +77414,17 @@ const makeOpenCodeRuntime = effect.Effect.gen(function* () {
76883
77414
  `--hostname=${hostname}`,
76884
77415
  `--port=${port}`
76885
77416
  ];
77417
+ const serverPassword = resolveOpenCodeServerPassword({
77418
+ external: false,
77419
+ ...input.serverPassword !== void 0 ? { configuredPassword: input.serverPassword } : {},
77420
+ ...input.environment !== void 0 ? { environment: input.environment } : {}
77421
+ });
76886
77422
  const child = yield* spawner.spawn(effect_unstable_process.ChildProcess.make(input.binaryPath, args, {
76887
77423
  detached: process.platform !== "win32",
76888
77424
  shell: process.platform === "win32",
76889
77425
  env: {
76890
77426
  ...input.environment ?? process.env,
77427
+ ...serverPassword !== void 0 ? { OPENCODE_SERVER_PASSWORD: serverPassword } : {},
76891
77428
  OPENCODE_CONFIG_CONTENT: JSON.stringify({})
76892
77429
  }
76893
77430
  })).pipe(effect.Effect.provideService(effect.Scope.Scope, runtimeScope), effect.Effect.mapError((cause) => new OpenCodeRuntimeError({
@@ -76950,24 +77487,34 @@ const makeOpenCodeRuntime = effect.Effect.gen(function* () {
76950
77487
  }
76951
77488
  return {
76952
77489
  url: readyOption.value,
77490
+ ...serverPassword !== void 0 ? { serverPassword } : {},
76953
77491
  exitCode: child.exitCode.pipe(effect.Effect.map(Number), effect.Effect.orElseSucceed(() => 0))
76954
77492
  };
76955
77493
  });
76956
77494
  const connectToOpenCodeServer = (input) => {
76957
77495
  const serverUrl = input.serverUrl?.trim();
76958
- if (serverUrl) return effect.Effect.succeed({
76959
- url: serverUrl,
76960
- exitCode: null,
76961
- external: true
76962
- });
77496
+ if (serverUrl) {
77497
+ const serverPassword = resolveOpenCodeServerPassword({
77498
+ external: true,
77499
+ ...input.serverPassword !== void 0 ? { configuredPassword: input.serverPassword } : {}
77500
+ });
77501
+ return effect.Effect.succeed({
77502
+ url: serverUrl,
77503
+ ...serverPassword !== void 0 ? { serverPassword } : {},
77504
+ exitCode: null,
77505
+ external: true
77506
+ });
77507
+ }
76963
77508
  return startOpenCodeServerProcess({
76964
77509
  binaryPath: input.binaryPath,
77510
+ ...input.serverPassword !== void 0 ? { serverPassword: input.serverPassword } : {},
76965
77511
  ...input.environment !== void 0 ? { environment: input.environment } : {},
76966
77512
  ...input.port !== void 0 ? { port: input.port } : {},
76967
77513
  ...input.hostname !== void 0 ? { hostname: input.hostname } : {},
76968
77514
  ...input.timeoutMs !== void 0 ? { timeoutMs: input.timeoutMs } : {}
76969
77515
  }).pipe(effect.Effect.map((server) => ({
76970
77516
  url: server.url,
77517
+ ...server.serverPassword !== void 0 ? { serverPassword: server.serverPassword } : {},
76971
77518
  exitCode: server.exitCode,
76972
77519
  external: false
76973
77520
  })));
@@ -76978,11 +77525,11 @@ const makeOpenCodeRuntime = effect.Effect.gen(function* () {
76978
77525
  ...input.serverPassword ? { headers: { Authorization: `Basic ${Buffer.from(`opencode:${input.serverPassword}`, "utf8").toString("base64")}` } } : {},
76979
77526
  throwOnError: true
76980
77527
  })));
76981
- const loadProviders = (client) => runOpenCodeSdk("provider.list", () => client.provider.list()).pipe(effect.Effect.filterMapOrFail((list) => list.data ? effect.Result.succeed(list.data) : effect.Result.fail(new OpenCodeRuntimeError({
77528
+ const loadProviders = (client) => runOpenCodeSdk("provider.list", (signal) => client.provider.list({}, { signal })).pipe(effect.Effect.filterMapOrFail((list) => list.data ? effect.Result.succeed(list.data) : effect.Result.fail(new OpenCodeRuntimeError({
76982
77529
  operation: "provider.list",
76983
77530
  detail: "OpenCode provider list was empty."
76984
77531
  })), (result) => result));
76985
- const loadAgents = (client) => runOpenCodeSdk("app.agents", () => client.app.agents()).pipe(effect.Effect.map((result) => result.data ?? []));
77532
+ const loadAgents = (client) => runOpenCodeSdk("app.agents", (signal) => client.app.agents({}, { signal })).pipe(effect.Effect.map((result) => result.data ?? []));
76986
77533
  const loadOpenCodeInventory = (client) => effect.Effect.all([loadProviders(client), loadAgents(client)], { concurrency: "unbounded" }).pipe(effect.Effect.map(([providerList, agents]) => ({
76987
77534
  providerList,
76988
77535
  agents
@@ -77571,12 +78118,10 @@ const TERMINAL_ENV_BLOCKLIST = /* @__PURE__ */ new Set([
77571
78118
  var TerminalSubprocessCheckError = class extends effect.Schema.TaggedError()("TerminalSubprocessCheckError", {
77572
78119
  message: effect.Schema.String,
77573
78120
  cause: effect.Schema.optional(effect.Schema.Defect()),
77574
- terminalPid: effect.Schema.Number,
77575
- command: effect.Schema.Literals([
77576
- "powershell",
77577
- "pgrep",
77578
- "ps"
77579
- ])
78121
+ command: effect.Schema.Literals(["powershell", "ps"]),
78122
+ exitCode: effect.Schema.optional(effect.Schema.NullOr(effect.Schema.Number)),
78123
+ timedOut: effect.Schema.optional(effect.Schema.Boolean),
78124
+ stdoutTruncated: effect.Schema.optional(effect.Schema.Boolean)
77580
78125
  }) {};
77581
78126
  var TerminalProcessSignalError = class extends effect.Schema.TaggedError()("TerminalProcessSignalError", {
77582
78127
  message: effect.Schema.String,
@@ -77796,81 +78341,90 @@ function isRetryableShellSpawnError(error) {
77796
78341
  const message = messages.join(" ").toLowerCase();
77797
78342
  return message.includes("posix_spawnp failed") || message.includes("enoent") || message.includes("not found") || message.includes("file not found") || message.includes("no such file");
77798
78343
  }
77799
- function checkWindowsSubprocessActivity(terminalPid) {
77800
- const command = [
77801
- `$children = Get-CimInstance Win32_Process -Filter "ParentProcessId = ${terminalPid}" -ErrorAction SilentlyContinue`,
77802
- "if ($children) { exit 0 }",
77803
- "exit 1"
77804
- ].join("; ");
77805
- return effect.Effect.tryPromise({
77806
- try: () => runProcess("powershell.exe", [
77807
- "-NoProfile",
77808
- "-NonInteractive",
77809
- "-Command",
77810
- command
77811
- ], {
77812
- timeoutMs: 1500,
77813
- allowNonZeroExit: true,
77814
- maxBufferBytes: 32768,
77815
- outputMode: "truncate"
77816
- }),
77817
- catch: (cause) => new TerminalSubprocessCheckError({
77818
- message: "Failed to check Windows terminal subprocess activity.",
77819
- cause,
77820
- terminalPid,
77821
- command: "powershell"
77822
- })
77823
- }).pipe(effect.Effect.map((result) => result.code === 0));
78344
+ function parsePosixProcessTable(stdout) {
78345
+ const childrenByParent = /* @__PURE__ */ new Map();
78346
+ for (const line of stdout.split(/\r?\n/g)) {
78347
+ const match = /^\s*(\d+)\s+(\d+)(?:\s|$)/.exec(line);
78348
+ if (!match) continue;
78349
+ const pid = Number(match[1]);
78350
+ const parentPid = Number(match[2]);
78351
+ if (!Number.isInteger(pid) || !Number.isInteger(parentPid)) continue;
78352
+ const children = childrenByParent.get(parentPid) ?? [];
78353
+ children.push(pid);
78354
+ childrenByParent.set(parentPid, children);
78355
+ }
78356
+ return { childrenByParent };
78357
+ }
78358
+ function parseWindowsProcessTable(stdout) {
78359
+ const childrenByParent = /* @__PURE__ */ new Map();
78360
+ for (const line of stdout.split(/\r?\n/g)) {
78361
+ const [pidRaw, parentPidRaw] = line.trim().split("|", 2);
78362
+ const pid = Number(pidRaw);
78363
+ const parentPid = Number(parentPidRaw);
78364
+ if (!Number.isInteger(pid) || !Number.isInteger(parentPid)) continue;
78365
+ const children = childrenByParent.get(parentPid) ?? [];
78366
+ children.push(pid);
78367
+ childrenByParent.set(parentPid, children);
78368
+ }
78369
+ return { childrenByParent };
77824
78370
  }
77825
- const checkPosixSubprocessActivity = effect.Effect.fn("terminal.checkPosixSubprocessActivity")(function* (terminalPid) {
77826
- const runPgrep = effect.Effect.tryPromise({
77827
- try: () => runProcess("pgrep", ["-P", String(terminalPid)], {
78371
+ const POSIX_PS_ABSOLUTE_PATHS = ["/bin/ps", "/usr/bin/ps"];
78372
+ const resolvePosixPsCommand = effect.Effect.fn("terminal.resolvePosixPsCommand")(function* () {
78373
+ const fileSystem = yield* effect.FileSystem.FileSystem;
78374
+ for (const candidate of POSIX_PS_ABSOLUTE_PATHS) if (yield* fileSystem.exists(candidate).pipe(effect.Effect.orElseSucceed(() => false))) return candidate;
78375
+ return "ps";
78376
+ });
78377
+ const snapshotPosixProcessTable = effect.Effect.fn("terminal.snapshotPosixProcessTable")(function* (psCommand) {
78378
+ const result = yield* effect.Effect.tryPromise({
78379
+ try: () => runProcess(psCommand, ["-eo", "pid=,ppid="], {
77828
78380
  timeoutMs: 1e3,
77829
78381
  allowNonZeroExit: true,
77830
- maxBufferBytes: 32768,
78382
+ maxBufferBytes: 524288,
77831
78383
  outputMode: "truncate"
77832
78384
  }),
77833
78385
  catch: (cause) => new TerminalSubprocessCheckError({
77834
- message: "Failed to inspect terminal subprocesses with pgrep.",
78386
+ message: "Failed to snapshot POSIX processes.",
77835
78387
  cause,
77836
- terminalPid,
77837
- command: "pgrep"
78388
+ command: "ps"
77838
78389
  })
77839
78390
  });
77840
- const runPs = effect.Effect.tryPromise({
77841
- try: () => runProcess("ps", ["-eo", "pid=,ppid="], {
77842
- timeoutMs: 1e3,
78391
+ if (result.code !== 0 || result.timedOut || result.stdoutTruncated) return yield* new TerminalSubprocessCheckError({
78392
+ message: "POSIX process snapshot was incomplete.",
78393
+ command: "ps",
78394
+ exitCode: result.code,
78395
+ timedOut: result.timedOut,
78396
+ stdoutTruncated: result.stdoutTruncated
78397
+ });
78398
+ return parsePosixProcessTable(result.stdout);
78399
+ });
78400
+ const snapshotWindowsProcessTable = effect.Effect.fn("terminal.snapshotWindowsProcessTable")(function* () {
78401
+ const command = ["$processes = Get-CimInstance Win32_Process -ErrorAction Stop", "foreach ($process in $processes) { Write-Output \"$($process.ProcessId)|$($process.ParentProcessId)\" }"].join("; ");
78402
+ const result = yield* effect.Effect.tryPromise({
78403
+ try: () => runProcess("powershell.exe", [
78404
+ "-NoProfile",
78405
+ "-NonInteractive",
78406
+ "-Command",
78407
+ command
78408
+ ], {
78409
+ timeoutMs: 1500,
77843
78410
  allowNonZeroExit: true,
77844
- maxBufferBytes: 262144,
78411
+ maxBufferBytes: 524288,
77845
78412
  outputMode: "truncate"
77846
78413
  }),
77847
78414
  catch: (cause) => new TerminalSubprocessCheckError({
77848
- message: "Failed to inspect terminal subprocesses with ps.",
78415
+ message: "Failed to snapshot Windows processes.",
77849
78416
  cause,
77850
- terminalPid,
77851
- command: "ps"
78417
+ command: "powershell"
77852
78418
  })
77853
78419
  });
77854
- const pgrepResult = yield* effect.Effect.exit(runPgrep);
77855
- if (pgrepResult._tag === "Success") {
77856
- if (pgrepResult.value.code === 0) return pgrepResult.value.stdout.trim().length > 0;
77857
- if (pgrepResult.value.code === 1) return false;
77858
- }
77859
- const psResult = yield* effect.Effect.exit(runPs);
77860
- if (psResult._tag === "Failure" || psResult.value.code !== 0) return false;
77861
- for (const line of psResult.value.stdout.split(/\r?\n/g)) {
77862
- const [pidRaw, ppidRaw] = line.trim().split(/\s+/g);
77863
- const pid = Number(pidRaw);
77864
- const ppid = Number(ppidRaw);
77865
- if (!Number.isInteger(pid) || !Number.isInteger(ppid)) continue;
77866
- if (ppid === terminalPid) return true;
77867
- }
77868
- return false;
77869
- });
77870
- const defaultSubprocessChecker = effect.Effect.fn("terminal.defaultSubprocessChecker")(function* (terminalPid) {
77871
- if (!Number.isInteger(terminalPid) || terminalPid <= 0) return false;
77872
- if (process.platform === "win32") return yield* checkWindowsSubprocessActivity(terminalPid);
77873
- return yield* checkPosixSubprocessActivity(terminalPid);
78420
+ if (result.code !== 0 || result.timedOut || result.stdoutTruncated) return yield* new TerminalSubprocessCheckError({
78421
+ message: "Windows process snapshot was incomplete.",
78422
+ command: "powershell",
78423
+ exitCode: result.code,
78424
+ timedOut: result.timedOut,
78425
+ stdoutTruncated: result.stdoutTruncated
78426
+ });
78427
+ return parseWindowsProcessTable(result.stdout);
77874
78428
  });
77875
78429
  function capHistory(history, maxLines) {
77876
78430
  if (history.length === 0) return history;
@@ -78062,7 +78616,8 @@ const makeTerminalManagerWithOptions = effect.Effect.fn("makeTerminalManagerWith
78062
78616
  const platform = options.platform ?? process.platform;
78063
78617
  const baseEnv = options.env ?? process.env;
78064
78618
  const shellResolver = options.shellResolver ?? (() => defaultShellResolver(platform, baseEnv));
78065
- const subprocessChecker = options.subprocessChecker ?? defaultSubprocessChecker;
78619
+ const posixPsCommand = options.processTableSnapshotter === void 0 && platform !== "win32" ? yield* resolvePosixPsCommand() : null;
78620
+ const processTableSnapshotter = options.processTableSnapshotter ?? (platform === "win32" ? snapshotWindowsProcessTable : () => snapshotPosixProcessTable(posixPsCommand ?? "ps"));
78066
78621
  const subprocessPollIntervalMs = options.subprocessPollIntervalMs ?? DEFAULT_SUBPROCESS_POLL_INTERVAL_MS;
78067
78622
  const processKillGraceMs = options.processKillGraceMs ?? DEFAULT_PROCESS_KILL_GRACE_MS;
78068
78623
  const maxRetainedInactiveSessions = options.maxRetainedInactiveSessions ?? DEFAULT_MAX_RETAINED_INACTIVE_SESSIONS;
@@ -78553,26 +79108,22 @@ const makeTerminalManagerWithOptions = effect.Effect.fn("makeTerminalManagerWith
78553
79108
  const pollSubprocessActivity = effect.Effect.fn("terminal.pollSubprocessActivity")(function* () {
78554
79109
  const runningSessions = [...(yield* readManagerState).sessions.values()].filter((session) => session.status === "running" && Number.isInteger(session.pid));
78555
79110
  if (runningSessions.length === 0) return;
79111
+ const processTable = yield* processTableSnapshotter().pipe(effect.Effect.map(effect.Option.some), effect.Effect.catch((reason) => effect.Effect.logWarning("failed to snapshot processes for terminal subprocess polling", { reason }).pipe(effect.Effect.as(effect.Option.none()))));
79112
+ if (effect.Option.isNone(processTable)) return;
78556
79113
  const checkSubprocessActivity = effect.Effect.fn("terminal.checkSubprocessActivity")(function* (session) {
78557
79114
  const terminalPid = session.pid;
78558
- const hasRunningSubprocess = yield* subprocessChecker(terminalPid).pipe(effect.Effect.map(effect.Option.some), effect.Effect.catch((reason) => effect.Effect.logWarning("failed to check terminal subprocess activity", {
78559
- threadId: session.threadId,
78560
- terminalId: session.terminalId,
78561
- terminalPid,
78562
- reason
78563
- }).pipe(effect.Effect.as(effect.Option.none()))));
78564
- if (effect.Option.isNone(hasRunningSubprocess)) return;
79115
+ const hasRunningSubprocess = (processTable.value.childrenByParent.get(terminalPid)?.length ?? 0) > 0;
78565
79116
  const event = yield* modifyManagerState((state) => {
78566
79117
  const liveSession = effect.Option.fromNullishOr(state.sessions.get(toSessionKey(session.threadId, session.terminalId)));
78567
- if (effect.Option.isNone(liveSession) || liveSession.value.status !== "running" || liveSession.value.pid !== terminalPid || liveSession.value.hasRunningSubprocess === hasRunningSubprocess.value) return [effect.Option.none(), state];
78568
- liveSession.value.hasRunningSubprocess = hasRunningSubprocess.value;
79118
+ if (effect.Option.isNone(liveSession) || liveSession.value.status !== "running" || liveSession.value.pid !== terminalPid || liveSession.value.hasRunningSubprocess === hasRunningSubprocess) return [effect.Option.none(), state];
79119
+ liveSession.value.hasRunningSubprocess = hasRunningSubprocess;
78569
79120
  liveSession.value.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
78570
79121
  return [effect.Option.some({
78571
79122
  type: "activity",
78572
79123
  threadId: liveSession.value.threadId,
78573
79124
  terminalId: liveSession.value.terminalId,
78574
79125
  createdAt: (/* @__PURE__ */ new Date()).toISOString(),
78575
- hasRunningSubprocess: hasRunningSubprocess.value
79126
+ hasRunningSubprocess
78576
79127
  }), state];
78577
79128
  });
78578
79129
  if (effect.Option.isSome(event)) yield* publishEvent(event.value);
@@ -78880,20 +79431,6 @@ var ProviderCommandReactor = class extends effect.Context.Service()("ryco/orches
78880
79431
  */
78881
79432
  var ProviderRuntimeIngestionService = class extends effect.Context.Service()("ryco/orchestration/Services/ProviderRuntimeIngestion/ProviderRuntimeIngestionService") {};
78882
79433
  //#endregion
78883
- //#region src/orchestration/Services/ThreadDeletionReactor.ts
78884
- /**
78885
- * ThreadDeletionReactor - Thread deletion cleanup reactor service interface.
78886
- *
78887
- * Owns background workers that react to thread deletion domain events and
78888
- * perform best-effort runtime cleanup for provider sessions and terminals.
78889
- *
78890
- * @module ThreadDeletionReactor
78891
- */
78892
- /**
78893
- * ThreadDeletionReactor - Service tag for thread deletion cleanup workers.
78894
- */
78895
- var ThreadDeletionReactor = class extends effect.Context.Service()("ryco/orchestration/Services/ThreadDeletionReactor") {};
78896
- //#endregion
78897
79434
  //#region src/orchestration/Layers/OrchestrationReactor.ts
78898
79435
  const makeOrchestrationReactor = effect.Effect.gen(function* () {
78899
79436
  const providerRuntimeIngestion = yield* ProviderRuntimeIngestionService;
@@ -79469,6 +80006,227 @@ function make$4() {
79469
80006
  }
79470
80007
  const layer = effect.Layer.effect(ThreadBackgroundLivenessService, effect.Effect.sync(make$4));
79471
80008
  //#endregion
80009
+ //#region src/orchestration/ActivityPayloadProjection.ts
80010
+ function asRecord$1(value) {
80011
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
80012
+ }
80013
+ function asTrimmedString$1(value) {
80014
+ if (typeof value !== "string") return null;
80015
+ const trimmed = value.trim();
80016
+ return trimmed.length > 0 ? trimmed : null;
80017
+ }
80018
+ function summarizeToolTextOutput(value) {
80019
+ const lines = [];
80020
+ for (const rawLine of value.split(/\r?\n/u)) {
80021
+ const line = rawLine.replace(/\s+/g, " ").trim();
80022
+ if (line.length > 0) lines.push(line);
80023
+ }
80024
+ const firstLine = lines.find((line) => line !== "```");
80025
+ if (firstLine) return firstLine.length <= 84 ? firstLine : `${firstLine.slice(0, 83).trimEnd()}…`;
80026
+ if (lines.length > 1) return `${lines.length.toLocaleString()} lines`;
80027
+ return null;
80028
+ }
80029
+ function pushChangedFile(target, seen, value) {
80030
+ const normalized = asTrimmedString$1(value);
80031
+ if (!normalized || seen.has(normalized)) return;
80032
+ seen.add(normalized);
80033
+ target.push(normalized);
80034
+ }
80035
+ function collectChangedFiles(value, target, seen, depth) {
80036
+ if (depth > 4 || target.length >= 12) return;
80037
+ if (Array.isArray(value)) {
80038
+ for (const entry of value) {
80039
+ collectChangedFiles(entry, target, seen, depth + 1);
80040
+ if (target.length >= 12) return;
80041
+ }
80042
+ return;
80043
+ }
80044
+ const record = asRecord$1(value);
80045
+ if (!record) return;
80046
+ pushChangedFile(target, seen, record.path);
80047
+ pushChangedFile(target, seen, record.filePath);
80048
+ pushChangedFile(target, seen, record.relativePath);
80049
+ pushChangedFile(target, seen, record.filename);
80050
+ pushChangedFile(target, seen, record.newPath);
80051
+ pushChangedFile(target, seen, record.oldPath);
80052
+ for (const nestedKey of [
80053
+ "item",
80054
+ "result",
80055
+ "input",
80056
+ "data",
80057
+ "changes",
80058
+ "files",
80059
+ "edits",
80060
+ "patch",
80061
+ "patches",
80062
+ "operations"
80063
+ ]) {
80064
+ if (!(nestedKey in record)) continue;
80065
+ collectChangedFiles(record[nestedKey], target, seen, depth + 1);
80066
+ if (target.length >= 12) return;
80067
+ }
80068
+ }
80069
+ function projectCommandData(data) {
80070
+ const item = asRecord$1(data.item);
80071
+ if (!item) return;
80072
+ const projectedItem = {};
80073
+ if ("command" in item) projectedItem.command = item.command;
80074
+ const aggregatedOutput = asTrimmedString$1(item.aggregatedOutput);
80075
+ if (aggregatedOutput) {
80076
+ const summary = summarizeToolTextOutput(aggregatedOutput);
80077
+ if (summary) projectedItem.aggregatedOutput = summary;
80078
+ }
80079
+ const input = asRecord$1(item.input);
80080
+ if (input && "command" in input) projectedItem.input = { command: input.command };
80081
+ const result = asRecord$1(item.result);
80082
+ if (result) {
80083
+ const projectedResult = {};
80084
+ if ("command" in result) projectedResult.command = result.command;
80085
+ const content = asTrimmedString$1(result.content);
80086
+ if (content) {
80087
+ const summary = summarizeToolTextOutput(content);
80088
+ if (summary) projectedResult.content = summary;
80089
+ }
80090
+ if (Object.keys(projectedResult).length > 0) projectedItem.result = projectedResult;
80091
+ }
80092
+ return Object.keys(projectedItem).length > 0 ? projectedItem : void 0;
80093
+ }
80094
+ function projectCommandValue(data) {
80095
+ if (data.command !== void 0) return data.command;
80096
+ const input = asRecord$1(data.input);
80097
+ if (input?.command !== void 0) return input.command;
80098
+ const stateInput = asRecord$1(asRecord$1(data.state)?.input);
80099
+ if (stateInput?.command !== void 0) return stateInput.command;
80100
+ }
80101
+ const MCP_ITEM_KEPT_FIELDS = [
80102
+ "type",
80103
+ "id",
80104
+ "tool",
80105
+ "server",
80106
+ "status",
80107
+ "arguments",
80108
+ "appContext",
80109
+ "error",
80110
+ "durationMs"
80111
+ ];
80112
+ function extractMcpResultText(result) {
80113
+ const record = asRecord$1(result);
80114
+ if (!record) return typeof result === "string" ? result : null;
80115
+ if (typeof record.content === "string") return record.content;
80116
+ if (Array.isArray(record.content)) {
80117
+ const texts = [];
80118
+ for (const entry of record.content) {
80119
+ const text = asRecord$1(entry)?.text;
80120
+ if (typeof text === "string" && text.trim().length > 0) texts.push(text);
80121
+ }
80122
+ if (texts.length > 0) return texts.join("\n");
80123
+ }
80124
+ return null;
80125
+ }
80126
+ function summarizeMcpResult(result) {
80127
+ if (result === void 0 || result === null) return;
80128
+ const text = extractMcpResultText(result);
80129
+ const summary = text ? summarizeToolTextOutput(text) : null;
80130
+ return summary ? { content: summary } : void 0;
80131
+ }
80132
+ function projectMcpToolCallData(data) {
80133
+ const projectedData = {};
80134
+ const item = asRecord$1(data.item);
80135
+ if (item) {
80136
+ const projectedItem = {};
80137
+ for (const key of MCP_ITEM_KEPT_FIELDS) if (key in item) projectedItem[key] = item[key];
80138
+ const result = summarizeMcpResult(item.result);
80139
+ if (result) projectedItem.result = result;
80140
+ projectedData.item = projectedItem;
80141
+ }
80142
+ if ("toolName" in data) projectedData.toolName = data.toolName;
80143
+ if ("input" in data) projectedData.input = data.input;
80144
+ if (!item) {
80145
+ const result = summarizeMcpResult(data.result);
80146
+ if (result) projectedData.result = result;
80147
+ }
80148
+ if ("toolCallId" in data) projectedData.toolCallId = data.toolCallId;
80149
+ if ("kind" in data) projectedData.kind = data.kind;
80150
+ const changedFiles = [];
80151
+ collectChangedFiles(data, changedFiles, /* @__PURE__ */ new Set(), 0);
80152
+ if (changedFiles.length > 0) projectedData.files = changedFiles.map((path) => ({ path }));
80153
+ return projectedData;
80154
+ }
80155
+ function projectRawOutput(value) {
80156
+ const direct = asTrimmedString$1(value);
80157
+ if (direct) {
80158
+ const summary = summarizeToolTextOutput(direct);
80159
+ return summary ? { content: summary } : void 0;
80160
+ }
80161
+ const rawOutput = asRecord$1(value);
80162
+ if (!rawOutput) return;
80163
+ if (typeof rawOutput.totalFiles === "number" && Number.isFinite(rawOutput.totalFiles)) return {
80164
+ totalFiles: rawOutput.totalFiles,
80165
+ ...rawOutput.truncated === true ? { truncated: true } : {}
80166
+ };
80167
+ for (const key of [
80168
+ "content",
80169
+ "stdout",
80170
+ "stderr"
80171
+ ]) {
80172
+ const output = asTrimmedString$1(rawOutput[key]);
80173
+ if (!output) continue;
80174
+ const summary = summarizeToolTextOutput(output);
80175
+ return summary ? { content: summary } : void 0;
80176
+ }
80177
+ }
80178
+ function projectAcpContent(value) {
80179
+ if (!Array.isArray(value)) return;
80180
+ const summary = summarizeToolTextOutput(value.map((entryValue) => {
80181
+ const entry = asRecord$1(entryValue);
80182
+ const content = asRecord$1(entry?.content);
80183
+ return entry?.type === "content" && content?.type === "text" ? asTrimmedString$1(content.text) : null;
80184
+ }).filter((entry) => entry !== null).join("\n"));
80185
+ return summary ? { content: summary } : void 0;
80186
+ }
80187
+ /**
80188
+ * Projects provider-specific tool data to the fields shared clients consume.
80189
+ * The result is safe to persist for cumulative streaming updates: unbounded
80190
+ * tool output is reduced to a one-line summary while identity, command, and
80191
+ * changed-file metadata remain available to every client.
80192
+ */
80193
+ function projectActivityPayload(activity) {
80194
+ const payload = asRecord$1(activity.payload);
80195
+ const data = asRecord$1(payload?.data);
80196
+ if (!payload || !data) return activity;
80197
+ const itemStatus = asRecord$1(data.item)?.status;
80198
+ const projectedPayload = payload.status === "completed" && (itemStatus === "failed" || itemStatus === "declined") ? {
80199
+ ...payload,
80200
+ status: itemStatus
80201
+ } : payload;
80202
+ if (payload.itemType === "mcp_tool_call") return {
80203
+ ...activity,
80204
+ payload: {
80205
+ ...projectedPayload,
80206
+ data: projectMcpToolCallData(data)
80207
+ }
80208
+ };
80209
+ const projectedData = {};
80210
+ const item = projectCommandData(data);
80211
+ if (item) projectedData.item = item;
80212
+ const command = projectCommandValue(data);
80213
+ if (command !== void 0) projectedData.command = command;
80214
+ const changedFiles = [];
80215
+ collectChangedFiles(data, changedFiles, /* @__PURE__ */ new Set(), 0);
80216
+ if (changedFiles.length > 0) projectedData.files = changedFiles.map((path) => ({ path }));
80217
+ if ("toolCallId" in data) projectedData.toolCallId = data.toolCallId;
80218
+ if ("kind" in data) projectedData.kind = data.kind;
80219
+ const rawOutput = projectRawOutput(data.rawOutput) ?? projectAcpContent(data.content);
80220
+ if (rawOutput) projectedData.rawOutput = rawOutput;
80221
+ return {
80222
+ ...activity,
80223
+ payload: {
80224
+ ...projectedPayload,
80225
+ data: projectedData
80226
+ }
80227
+ };
80228
+ }
80229
+ //#endregion
79472
80230
  //#region src/orchestration/Layers/ProviderRuntimeIngestion.ts
79473
80231
  const providerTurnKey = (threadId, turnId) => `${threadId}:${turnId}`;
79474
80232
  const providerTaskKey = (threadId, taskId) => `${threadId}:${taskId}`;
@@ -79986,7 +80744,7 @@ function runtimeEventToActivities(event, taskTitle) {
79986
80744
  }
79987
80745
  case "item.updated":
79988
80746
  if (!require_collectUint8StreamText.isToolLifecycleItemType(event.payload.itemType)) return [];
79989
- return [{
80747
+ return [projectActivityPayload({
79990
80748
  id: event.eventId,
79991
80749
  createdAt: event.createdAt,
79992
80750
  tone: "tool",
@@ -80004,7 +80762,7 @@ function runtimeEventToActivities(event, taskTitle) {
80004
80762
  },
80005
80763
  turnId: toTurnId$1(event.turnId) ?? null,
80006
80764
  ...maybeSequence
80007
- }];
80765
+ })];
80008
80766
  case "item.completed":
80009
80767
  if (!require_collectUint8StreamText.isToolLifecycleItemType(event.payload.itemType)) return [];
80010
80768
  return [{
@@ -80980,6 +81738,15 @@ const HANDLED_TURN_START_KEY_TTL = effect.Duration.minutes(30);
80980
81738
  const DEFAULT_RUNTIME_MODE = "full-access";
80981
81739
  const DEFAULT_TOKEN_MODE = require_collectUint8StreamText.DEFAULT_AGENT_TOKEN_MODE;
80982
81740
  const DEFAULT_THREAD_TITLE = "New thread";
81741
+ function pathEntryExists(targetPath) {
81742
+ try {
81743
+ (0, node_fs.lstatSync)(targetPath);
81744
+ return true;
81745
+ } catch (error) {
81746
+ if (error.code === "ENOENT") return false;
81747
+ throw error;
81748
+ }
81749
+ }
80983
81750
  function providerErrorLabel(value) {
80984
81751
  const normalized = value?.trim();
80985
81752
  return normalized && normalized.length > 0 ? normalized : "unknown";
@@ -81001,10 +81768,10 @@ function isUnknownPendingApprovalRequestError(cause) {
81001
81768
  const error = findProviderAdapterRequestError(cause);
81002
81769
  if (error) {
81003
81770
  const detail = error.detail.toLowerCase();
81004
- return detail.includes("unknown pending approval request") || detail.includes("unknown pending permission request");
81771
+ return detail.includes("unknown pending approval request") || detail.includes("unknown pending permission request") || detail.includes("unknown pending codex approval request");
81005
81772
  }
81006
- const message = effect.Cause.pretty(cause);
81007
- return message.includes("unknown pending approval request") || message.includes("unknown pending permission request");
81773
+ const message = effect.Cause.pretty(cause).toLowerCase();
81774
+ return message.includes("unknown pending approval request") || message.includes("unknown pending permission request") || message.includes("unknown pending codex approval request");
81008
81775
  }
81009
81776
  function isUnknownPendingUserInputRequestError(cause) {
81010
81777
  const error = findProviderAdapterRequestError(cause);
@@ -81088,9 +81855,64 @@ const make$2 = effect.Effect.gen(function* () {
81088
81855
  const resolveThread = effect.Effect.fnUntraced(function* (threadId) {
81089
81856
  return yield* projectionSnapshotQuery.getThreadDetailById(threadId).pipe(effect.Effect.map(effect.Option.getOrUndefined));
81090
81857
  });
81858
+ const ensureRecordedWorktreeAvailable = effect.Effect.fn("ensureRecordedWorktreeAvailable")(function* (thread, project) {
81859
+ if (thread.worktreePath === null) return;
81860
+ if (!project) return yield* new ProviderAdapterRequestError({
81861
+ provider: providerErrorLabel(String(thread.modelSelection.instanceId)),
81862
+ method: "thread.turn.start",
81863
+ detail: `Cannot verify worktree '${thread.worktreePath}' because project '${thread.projectId}' is unavailable.`
81864
+ });
81865
+ const repositoryRoot = node_path.default.resolve(project.workspaceRoot);
81866
+ const worktreePath = node_path.default.resolve(thread.worktreePath);
81867
+ if (worktreePath === repositoryRoot) return;
81868
+ const registeredWorktreePaths = () => gitWorkflow.listWorktreePaths(repositoryRoot).pipe(effect.Effect.map((paths) => paths.map((entry) => node_path.default.resolve(entry))));
81869
+ const failRecovery = (detail) => new ProviderAdapterRequestError({
81870
+ provider: providerErrorLabel(String(thread.modelSelection.instanceId)),
81871
+ method: "thread.turn.start",
81872
+ detail
81873
+ });
81874
+ if (pathEntryExists(worktreePath)) {
81875
+ if (!(yield* registeredWorktreePaths()).includes(worktreePath)) return yield* failRecovery(`Refusing to use '${worktreePath}' because it exists but is not a registered worktree for '${repositoryRoot}'.`);
81876
+ return;
81877
+ }
81878
+ const branch = thread.branch;
81879
+ if (branch === null) return yield* failRecovery(`Cannot recreate missing worktree '${worktreePath}' because the thread has no recorded branch.`);
81880
+ if (!(yield* gitWorkflow.listLocalBranchNames(repositoryRoot)).includes(branch)) return yield* failRecovery(`Cannot recreate missing worktree '${worktreePath}' because branch '${branch}' no longer exists.`);
81881
+ yield* gitWorkflow.pruneWorktrees(repositoryRoot);
81882
+ if (pathEntryExists(worktreePath)) {
81883
+ if ((yield* registeredWorktreePaths()).includes(worktreePath)) return;
81884
+ return yield* failRecovery(`Refusing to recreate worktree '${worktreePath}' because another filesystem entry now occupies that path.`);
81885
+ }
81886
+ const recreated = yield* gitWorkflow.createWorktree({
81887
+ cwd: repositoryRoot,
81888
+ path: worktreePath,
81889
+ refName: branch,
81890
+ dependencyHydration: "none"
81891
+ });
81892
+ if (node_path.default.resolve(recreated.worktree.path) !== worktreePath || recreated.worktree.refName !== branch) return yield* failRecovery(`Worktree recovery returned unexpected metadata for '${worktreePath}' and branch '${branch}'.`);
81893
+ const changedAt = (/* @__PURE__ */ new Date()).toISOString();
81894
+ yield* orchestrationEngine.dispatch({
81895
+ type: "thread.meta.update",
81896
+ commandId: serverCommandId$2("worktree-recovered"),
81897
+ threadId: thread.id,
81898
+ branch,
81899
+ worktreePath
81900
+ });
81901
+ if (thread.worktreeId !== void 0 && thread.worktreeId !== null) yield* orchestrationEngine.dispatch({
81902
+ type: "worktree.meta.update",
81903
+ commandId: serverCommandId$2("worktree-recovered-meta"),
81904
+ worktreeId: thread.worktreeId,
81905
+ branch,
81906
+ changedAt
81907
+ });
81908
+ yield* gitWorkflow.invalidateStatus(worktreePath);
81909
+ yield* vcsStatusBroadcaster.refreshStatus(worktreePath).pipe(effect.Effect.ignoreCause({ log: true }));
81910
+ });
81091
81911
  const ensureSessionForThread = effect.Effect.fn("ensureSessionForThread")(function* (threadId, createdAt, options) {
81092
81912
  const thread = yield* resolveThread(threadId);
81093
81913
  if (!thread) return yield* effect.Effect.die(/* @__PURE__ */ new Error(`Thread '${threadId}' was not found in read model.`));
81914
+ const project = yield* resolveProject(thread.projectId);
81915
+ yield* ensureRecordedWorktreeAvailable(thread, project);
81094
81916
  const desiredRuntimeMode = thread.runtimeMode;
81095
81917
  const desiredTokenMode = thread.tokenMode ?? DEFAULT_TOKEN_MODE;
81096
81918
  const requestedModelSelection = options?.modelSelection;
@@ -81138,7 +81960,6 @@ const make$2 = effect.Effect.gen(function* () {
81138
81960
  detail: `Thread '${threadId}' cannot switch from instance '${currentInstanceId}' to '${desiredInstanceId}' because their provider resume state is incompatible.`
81139
81961
  });
81140
81962
  }
81141
- const project = yield* resolveProject(thread.projectId);
81142
81963
  const effectiveCwd = resolveThreadWorkspaceCwd({
81143
81964
  thread,
81144
81965
  projects: project ? [project] : []
@@ -81326,7 +82147,10 @@ const make$2 = effect.Effect.gen(function* () {
81326
82147
  message: input.messageText,
81327
82148
  ...attachments.length > 0 ? { attachments } : {},
81328
82149
  modelSelection
81329
- });
82150
+ }).pipe(effect.Effect.retry({
82151
+ times: 2,
82152
+ schedule: effect.Schedule.exponential("2 seconds")
82153
+ }));
81330
82154
  if (!generated) return;
81331
82155
  const thread = yield* resolveThread(input.threadId);
81332
82156
  if (!thread) return;
@@ -81371,34 +82195,7 @@ const make$2 = effect.Effect.gen(function* () {
81371
82195
  });
81372
82196
  return;
81373
82197
  }
81374
- if (event.payload.contextHandoff !== void 0) {
81375
- yield* contextHandoffCoordinator.processTurnStart(event);
81376
- return;
81377
- }
81378
- if (thread.messages.filter((entry) => entry.role === "user").length === 1) {
81379
- const project = yield* resolveProject(thread.projectId);
81380
- const generationCwd = resolveThreadWorkspaceCwd({
81381
- thread,
81382
- projects: project ? [project] : []
81383
- }) ?? process.cwd();
81384
- const generationInput = {
81385
- messageText: message.text,
81386
- ...message.attachments !== void 0 ? { attachments: message.attachments } : {},
81387
- ...event.payload.titleSeed !== void 0 ? { titleSeed: event.payload.titleSeed } : {}
81388
- };
81389
- yield* maybeGenerateAndRenameWorktreeBranchForFirstTurn({
81390
- threadId: event.payload.threadId,
81391
- branch: thread.branch,
81392
- worktreePath: thread.worktreePath,
81393
- worktreeId: thread.worktreeId ?? null,
81394
- ...generationInput
81395
- }).pipe(effect.Effect.forkScoped);
81396
- if (canReplaceThreadTitle(thread.title, event.payload.titleSeed)) yield* maybeGenerateThreadTitleForFirstTurn({
81397
- threadId: event.payload.threadId,
81398
- cwd: generationCwd,
81399
- ...generationInput
81400
- }).pipe(effect.Effect.forkScoped);
81401
- }
82198
+ const isFirstUserMessageTurn = thread.messages.filter((entry) => entry.role === "user").length === 1;
81402
82199
  const handleTurnStartFailure = (cause) => {
81403
82200
  if (effect.Cause.hasInterruptsOnly(cause)) return effect.Effect.void;
81404
82201
  const detail = formatFailureDetail(cause);
@@ -81421,6 +82218,12 @@ const make$2 = effect.Effect.gen(function* () {
81421
82218
  cause: effect.Cause.pretty(recoveryCause),
81422
82219
  originalCause: effect.Cause.pretty(cause)
81423
82220
  })));
82221
+ if (event.payload.contextHandoff !== void 0) {
82222
+ const project = yield* resolveProject(thread.projectId);
82223
+ if (!(yield* ensureRecordedWorktreeAvailable(thread, project).pipe(effect.Effect.as(true), effect.Effect.catchCause((cause) => handleTurnStartFailure(cause).pipe(effect.Effect.as(false)))))) return;
82224
+ yield* contextHandoffCoordinator.processTurnStart(event);
82225
+ return;
82226
+ }
81424
82227
  const sendTurnRequest = yield* buildSendTurnRequestForThread({
81425
82228
  threadId: event.payload.threadId,
81426
82229
  messageText: message.text,
@@ -81431,6 +82234,30 @@ const make$2 = effect.Effect.gen(function* () {
81431
82234
  createdAt: event.payload.createdAt
81432
82235
  }).pipe(effect.Effect.map(effect.Option.some), effect.Effect.catchCause((cause) => handleTurnStartFailure(cause).pipe(effect.Effect.as(effect.Option.none()))));
81433
82236
  if (effect.Option.isNone(sendTurnRequest)) return;
82237
+ if (isFirstUserMessageTurn) {
82238
+ const project = yield* resolveProject(thread.projectId);
82239
+ const generationCwd = resolveThreadWorkspaceCwd({
82240
+ thread,
82241
+ projects: project ? [project] : []
82242
+ }) ?? process.cwd();
82243
+ const generationInput = {
82244
+ messageText: message.text,
82245
+ ...message.attachments !== void 0 ? { attachments: message.attachments } : {},
82246
+ ...event.payload.titleSeed !== void 0 ? { titleSeed: event.payload.titleSeed } : {}
82247
+ };
82248
+ yield* maybeGenerateAndRenameWorktreeBranchForFirstTurn({
82249
+ threadId: event.payload.threadId,
82250
+ branch: thread.branch,
82251
+ worktreePath: thread.worktreePath,
82252
+ worktreeId: thread.worktreeId ?? null,
82253
+ ...generationInput
82254
+ }).pipe(effect.Effect.forkScoped);
82255
+ if (canReplaceThreadTitle(thread.title, event.payload.titleSeed)) yield* maybeGenerateThreadTitleForFirstTurn({
82256
+ threadId: event.payload.threadId,
82257
+ cwd: generationCwd,
82258
+ ...generationInput
82259
+ }).pipe(effect.Effect.forkScoped);
82260
+ }
81434
82261
  const commitAcceptedModelSelection = event.payload.modelSelection !== void 0 && !effect.Equal.equals(thread.modelSelection, event.payload.modelSelection) ? orchestrationEngine.dispatch({
81435
82262
  type: "thread.meta.update",
81436
82263
  commandId: serverCommandId$2("accepted-model-selection"),
@@ -81443,7 +82270,8 @@ const make$2 = effect.Effect.gen(function* () {
81443
82270
  if (isProviderOriginatedCommandId(event.commandId)) return;
81444
82271
  const thread = yield* resolveThread(event.payload.threadId);
81445
82272
  if (!thread) return;
81446
- if (!(thread.session && thread.session.status !== "stopped")) return yield* appendProviderFailureActivity({
82273
+ const session = thread.session;
82274
+ if (!session || session.status === "stopped") return yield* appendProviderFailureActivity({
81447
82275
  threadId: event.payload.threadId,
81448
82276
  kind: "provider.turn.interrupt.failed",
81449
82277
  summary: "Provider turn interrupt failed",
@@ -81451,7 +82279,41 @@ const make$2 = effect.Effect.gen(function* () {
81451
82279
  turnId: event.payload.turnId ?? null,
81452
82280
  createdAt: event.payload.createdAt
81453
82281
  });
81454
- yield* providerService.interruptTurn({ threadId: event.payload.threadId });
82282
+ const recoverInterruptFailure = (cause) => {
82283
+ if (effect.Cause.hasInterruptsOnly(cause)) return effect.Effect.interrupt;
82284
+ const detail = formatFailureDetail(cause);
82285
+ return effect.Effect.gen(function* () {
82286
+ const latestSession = (yield* resolveThread(event.payload.threadId))?.session;
82287
+ if (!latestSession || latestSession.status === "stopped" || latestSession.status === "ready" || latestSession.activeTurnId === null || event.payload.turnId !== void 0 && latestSession.activeTurnId !== event.payload.turnId) return;
82288
+ yield* providerService.stopSession({ threadId: event.payload.threadId }).pipe(effect.Effect.catchCause((stopCause) => effect.Cause.hasInterruptsOnly(stopCause) ? effect.Effect.interrupt : effect.Effect.logWarning("provider command reactor failed to stop session after interrupt failure", {
82289
+ threadId: event.payload.threadId,
82290
+ cause: effect.Cause.pretty(stopCause),
82291
+ originalCause: effect.Cause.pretty(cause)
82292
+ })));
82293
+ const stoppedSession = (yield* resolveThread(event.payload.threadId))?.session;
82294
+ if (!stoppedSession || stoppedSession.status === "stopped" || stoppedSession.status === "ready" || stoppedSession.activeTurnId === null || event.payload.turnId !== void 0 && stoppedSession.activeTurnId !== event.payload.turnId) return;
82295
+ yield* setThreadSession({
82296
+ threadId: event.payload.threadId,
82297
+ session: {
82298
+ ...stoppedSession,
82299
+ status: "stopped",
82300
+ activeTurnId: null,
82301
+ lastError: detail,
82302
+ updatedAt: event.payload.createdAt
82303
+ },
82304
+ createdAt: event.payload.createdAt
82305
+ });
82306
+ yield* appendProviderFailureActivity({
82307
+ threadId: event.payload.threadId,
82308
+ kind: "provider.turn.interrupt.failed",
82309
+ summary: "Provider turn interrupt failed",
82310
+ detail,
82311
+ turnId: event.payload.turnId ?? null,
82312
+ createdAt: event.payload.createdAt
82313
+ });
82314
+ });
82315
+ };
82316
+ yield* providerService.interruptTurn({ threadId: event.payload.threadId }).pipe(effect.Effect.catchCause(recoverInterruptFailure));
81455
82317
  });
81456
82318
  const processGoalUpdated = effect.Effect.fn("processGoalUpdated")(function* (event) {
81457
82319
  if (event.payload.origin !== "client") return;
@@ -83243,14 +84105,17 @@ const make = effect.Effect.gen(function* () {
83243
84105
  }),
83244
84106
  process: processThreadDeletedSafely
83245
84107
  });
84108
+ const seenSequence = yield* effect.SubscriptionRef.make(0);
84109
+ const noteSeen = (sequence) => effect.SubscriptionRef.update(seenSequence, (seen) => Math.max(seen, sequence));
83246
84110
  return {
83247
84111
  start: effect.Effect.fn("start")(function* () {
83248
- yield* effect.Effect.forkScoped(effect.Stream.runForEach(orchestrationEngine.streamDomainEvents, (event) => {
83249
- if (event.type !== "thread.deleted") return effect.Effect.void;
83250
- return worker.enqueue(event);
83251
- }));
84112
+ const subscription = yield* orchestrationEngine.subscribeDomainEvents;
84113
+ yield* effect.Effect.forkScoped(effect.Stream.runForEach(effect.Stream.fromSubscription(subscription), (event) => (event.type === "thread.deleted" ? worker.enqueue(event) : effect.Effect.void).pipe(effect.Effect.andThen(noteSeen(event.sequence)))));
83252
84114
  }),
83253
- drain: worker.drain
84115
+ drainThrough: effect.Effect.fn("ThreadDeletionReactor.drainThrough")(function* (targetSequence) {
84116
+ yield* effect.SubscriptionRef.changes(seenSequence).pipe(effect.Stream.filter((seen) => seen >= targetSequence), effect.Stream.runHead);
84117
+ yield* worker.drain;
84118
+ })
83254
84119
  };
83255
84120
  });
83256
84121
  const ThreadDeletionReactorLive = effect.Layer.effect(ThreadDeletionReactor, make);
@@ -97568,10 +98433,21 @@ const OrchestrationEventPersistedRowSchema = effect.Schema.Struct({
97568
98433
  payload: UnknownFromJsonString,
97569
98434
  metadata: EventMetadataFromJsonString
97570
98435
  });
98436
+ const HasEventAfterRequestSchema = effect.Schema.Struct({
98437
+ aggregateKind: require_collectUint8StreamText.OrchestrationAggregateKind,
98438
+ aggregateId: effect.Schema.String,
98439
+ type: require_collectUint8StreamText.OrchestrationEventType,
98440
+ sequenceExclusive: require_collectUint8StreamText.NonNegativeInt
98441
+ });
97571
98442
  const ReadFromSequenceRequestSchema = effect.Schema.Struct({
97572
98443
  sequenceExclusive: require_collectUint8StreamText.NonNegativeInt,
97573
98444
  limit: effect.Schema.Number
97574
98445
  });
98446
+ const ReadThroughSequenceRequestSchema = effect.Schema.Struct({
98447
+ sequenceExclusive: require_collectUint8StreamText.NonNegativeInt,
98448
+ sequenceInclusive: require_collectUint8StreamText.NonNegativeInt,
98449
+ limit: effect.Schema.Number
98450
+ });
97575
98451
  const DEFAULT_READ_FROM_SEQUENCE_LIMIT = 1e3;
97576
98452
  const READ_PAGE_SIZE = 500;
97577
98453
  function inferActorKind(event) {
@@ -97664,6 +98540,34 @@ const makeEventStore = effect.Effect.gen(function* () {
97664
98540
  LIMIT ${request.limit}
97665
98541
  `
97666
98542
  });
98543
+ const readEventRowsThroughSequence = effect_unstable_sql_SqlSchema.findAll({
98544
+ Request: ReadThroughSequenceRequestSchema,
98545
+ Result: OrchestrationEventPersistedRowSchema,
98546
+ execute: (request) => sql`
98547
+ SELECT
98548
+ sequence,
98549
+ event_id AS "eventId",
98550
+ event_type AS "type",
98551
+ aggregate_kind AS "aggregateKind",
98552
+ stream_id AS "aggregateId",
98553
+ occurred_at AS "occurredAt",
98554
+ command_id AS "commandId",
98555
+ causation_event_id AS "causationEventId",
98556
+ correlation_id AS "correlationId",
98557
+ payload_json AS "payload",
98558
+ metadata_json AS "metadata"
98559
+ FROM orchestration_events
98560
+ WHERE sequence > ${request.sequenceExclusive}
98561
+ AND sequence <= ${request.sequenceInclusive}
98562
+ ORDER BY sequence ASC
98563
+ LIMIT ${request.limit}
98564
+ `
98565
+ });
98566
+ const readLatestSequence = effect_unstable_sql_SqlSchema.findOne({
98567
+ Request: effect.Schema.Void,
98568
+ Result: effect.Schema.Struct({ sequence: effect.Schema.NullOr(require_collectUint8StreamText.NonNegativeInt) }),
98569
+ execute: () => sql`SELECT MAX(sequence) AS "sequence" FROM orchestration_events`
98570
+ });
97667
98571
  const readRecentEventRows = effect_unstable_sql_SqlSchema.findAll({
97668
98572
  Request: effect.Schema.Struct({
97669
98573
  since: require_collectUint8StreamText.IsoDateTime,
@@ -97681,6 +98585,20 @@ const makeEventStore = effect.Effect.gen(function* () {
97681
98585
  ORDER BY sequence DESC
97682
98586
  LIMIT ${limit}
97683
98587
  `
98588
+ });
98589
+ const findEventAfter = effect_unstable_sql_SqlSchema.findOneOption({
98590
+ Request: HasEventAfterRequestSchema,
98591
+ Result: effect.Schema.Struct({ sequence: require_collectUint8StreamText.NonNegativeInt }),
98592
+ execute: (request) => sql`
98593
+ SELECT sequence
98594
+ FROM orchestration_events
98595
+ WHERE aggregate_kind = ${request.aggregateKind}
98596
+ AND stream_id = ${request.aggregateId}
98597
+ AND event_type = ${request.type}
98598
+ AND sequence > ${request.sequenceExclusive}
98599
+ ORDER BY sequence ASC
98600
+ LIMIT 1
98601
+ `
97684
98602
  });
97685
98603
  const append = (event) => appendEventRow({
97686
98604
  eventId: event.eventId,
@@ -97709,6 +98627,22 @@ const makeEventStore = effect.Effect.gen(function* () {
97709
98627
  }));
97710
98628
  return readPage(sequenceExclusive, normalizedLimit);
97711
98629
  };
98630
+ const readThroughSequence = (sequenceExclusive, sequenceInclusive) => {
98631
+ const normalizedStart = Math.max(0, Math.floor(sequenceExclusive));
98632
+ const normalizedEnd = Math.max(0, Math.floor(sequenceInclusive));
98633
+ if (normalizedEnd <= normalizedStart) return effect.Stream.empty;
98634
+ const readPage = (cursor) => effect.Stream.fromEffect(readEventRowsThroughSequence({
98635
+ sequenceExclusive: cursor,
98636
+ sequenceInclusive: normalizedEnd,
98637
+ limit: READ_PAGE_SIZE
98638
+ }).pipe(effect.Effect.mapError(toPersistenceSqlOrDecodeError$2("OrchestrationEventStore.readThroughSequence:query", "OrchestrationEventStore.readThroughSequence:decodeRows")), effect.Effect.flatMap((rows) => effect.Effect.forEach(rows, (row) => decodeEvent(row).pipe(effect.Effect.mapError(toPersistenceDecodeError("OrchestrationEventStore.readThroughSequence:rowToEvent"))))))).pipe(effect.Stream.flatMap((events) => {
98639
+ if (events.length === 0) return effect.Stream.empty;
98640
+ const nextCursor = events[events.length - 1].sequence;
98641
+ return effect.Stream.concat(effect.Stream.fromIterable(events), nextCursor < normalizedEnd ? readPage(nextCursor) : effect.Stream.empty);
98642
+ }));
98643
+ return readPage(normalizedStart);
98644
+ };
98645
+ const latestSequence = readLatestSequence(void 0).pipe(effect.Effect.map((row) => row.sequence ?? 0), effect.Effect.mapError(toPersistenceSqlOrDecodeError$2("OrchestrationEventStore.latestSequence:query", "OrchestrationEventStore.latestSequence:decodeRow")));
97712
98646
  const readPage = (sequenceExclusive, limit) => {
97713
98647
  const normalizedLimit = Math.max(0, Math.floor(limit));
97714
98648
  const normalizedSequenceExclusive = Math.max(0, Math.floor(sequenceExclusive));
@@ -97730,12 +98664,16 @@ const makeEventStore = effect.Effect.gen(function* () {
97730
98664
  since: input.since,
97731
98665
  limit: Math.min(Math.max(1, Math.floor(input.limit)), 500)
97732
98666
  }).pipe(effect.Effect.mapError(toPersistenceSqlOrDecodeError$2("OrchestrationEventStore.readRecent:query", "OrchestrationEventStore.readRecent:decodeRows")), effect.Effect.flatMap((rows) => effect.Effect.forEach(rows, (row) => decodeEvent(row).pipe(effect.Effect.mapError(toPersistenceDecodeError("OrchestrationEventStore.readRecent:rowToEvent"))))));
98667
+ const hasEventAfter = (input) => findEventAfter(input).pipe(effect.Effect.map(effect.Option.isSome), effect.Effect.mapError(toPersistenceSqlOrDecodeError$2("OrchestrationEventStore.hasEventAfter:query", "OrchestrationEventStore.hasEventAfter:decodeRow")));
97733
98668
  return {
97734
98669
  append,
97735
98670
  readPage,
97736
98671
  readRecent,
97737
98672
  readFromSequence,
97738
- readAll: () => readFromSequence(0, Number.MAX_SAFE_INTEGER)
98673
+ readThroughSequence,
98674
+ latestSequence,
98675
+ readAll: () => readFromSequence(0, Number.MAX_SAFE_INTEGER),
98676
+ hasEventAfter
97739
98677
  };
97740
98678
  });
97741
98679
  const OrchestrationEventStoreLive = effect.Layer.effect(OrchestrationEventStore, makeEventStore);
@@ -98053,7 +98991,8 @@ function requireThreadHasUserMessage(input) {
98053
98991
  return requireThread(input).pipe(effect.Effect.flatMap((thread) => thread.messages.some((message) => message.role === "user") ? effect.Effect.succeed(thread) : effect.Effect.fail(invariantError(input.command.type, `Thread '${input.threadId}' cannot be archived before a message has been sent.`))));
98054
98992
  }
98055
98993
  function requireThreadAbsent(input) {
98056
- if (!findThreadById(input.readModel, input.threadId)) return effect.Effect.void;
98994
+ const existing = findThreadById(input.readModel, input.threadId);
98995
+ if (existing === void 0 || existing.deletedAt !== null) return effect.Effect.void;
98057
98996
  return effect.Effect.fail(invariantError(input.command.type, `Thread '${input.threadId}' already exists and cannot be created twice.`));
98058
98997
  }
98059
98998
  //#endregion
@@ -100466,17 +101405,26 @@ const makeProjectionPendingApprovalRepository = effect.Effect.gen(function* () {
100466
101405
  execute: ({ requestId }) => sql`
100467
101406
  DELETE FROM projection_pending_approvals
100468
101407
  WHERE request_id = ${requestId}
101408
+ `
101409
+ });
101410
+ const deleteProjectionPendingApprovalRowsByThread = effect_unstable_sql_SqlSchema.void({
101411
+ Request: ListProjectionPendingApprovalsInput,
101412
+ execute: ({ threadId }) => sql`
101413
+ DELETE FROM projection_pending_approvals
101414
+ WHERE thread_id = ${threadId}
100469
101415
  `
100470
101416
  });
100471
101417
  const upsert = (row) => upsertProjectionPendingApprovalRow(row).pipe(effect.Effect.mapError(toPersistenceSqlError("ProjectionPendingApprovalRepository.upsert:query")));
100472
101418
  const listByThreadId = (input) => listProjectionPendingApprovalRows(input).pipe(effect.Effect.mapError(toPersistenceSqlError("ProjectionPendingApprovalRepository.listByThreadId:query")));
100473
101419
  const getByRequestId = (input) => getProjectionPendingApprovalRow(input).pipe(effect.Effect.mapError(toPersistenceSqlError("ProjectionPendingApprovalRepository.getByRequestId:query")));
100474
101420
  const deleteByRequestId = (input) => deleteProjectionPendingApprovalRow(input).pipe(effect.Effect.mapError(toPersistenceSqlError("ProjectionPendingApprovalRepository.deleteByRequestId:query")));
101421
+ const deleteByThreadId = (input) => deleteProjectionPendingApprovalRowsByThread(input).pipe(effect.Effect.mapError(toPersistenceSqlError("ProjectionPendingApprovalRepository.deleteByThreadId:query")));
100475
101422
  return {
100476
101423
  upsert,
100477
101424
  listByThreadId,
100478
101425
  getByRequestId,
100479
- deleteByRequestId
101426
+ deleteByRequestId,
101427
+ deleteByThreadId
100480
101428
  };
100481
101429
  });
100482
101430
  const ProjectionPendingApprovalRepositoryLive = effect.Layer.effect(ProjectionPendingApprovalRepository, makeProjectionPendingApprovalRepository);
@@ -101424,7 +102372,15 @@ const ORCHESTRATION_EVENT_PROJECTORS = {
101424
102372
  "project.meta-updated": [ORCHESTRATION_PROJECTOR_NAMES.projects],
101425
102373
  "project.avatar-set": [ORCHESTRATION_PROJECTOR_NAMES.projects],
101426
102374
  "project.deleted": [ORCHESTRATION_PROJECTOR_NAMES.projects],
101427
- "thread.created": [ORCHESTRATION_PROJECTOR_NAMES.threads],
102375
+ "thread.created": [
102376
+ ORCHESTRATION_PROJECTOR_NAMES.threadMessages,
102377
+ ORCHESTRATION_PROJECTOR_NAMES.threadProposedPlans,
102378
+ ORCHESTRATION_PROJECTOR_NAMES.threadActivities,
102379
+ ORCHESTRATION_PROJECTOR_NAMES.threadSessions,
102380
+ ORCHESTRATION_PROJECTOR_NAMES.threadTurns,
102381
+ ORCHESTRATION_PROJECTOR_NAMES.pendingApprovals,
102382
+ ORCHESTRATION_PROJECTOR_NAMES.threads
102383
+ ],
101428
102384
  "thread.deleted": [ORCHESTRATION_PROJECTOR_NAMES.threads],
101429
102385
  "thread.archived": [ORCHESTRATION_PROJECTOR_NAMES.threads],
101430
102386
  "thread.unarchived": [ORCHESTRATION_PROJECTOR_NAMES.threads],
@@ -101489,7 +102445,7 @@ function extractActivityRequestId(payload) {
101489
102445
  }
101490
102446
  function isStalePendingApprovalFailureDetail(detail) {
101491
102447
  if (detail === null) return false;
101492
- return detail.includes("stale pending approval request") || detail.includes("unknown pending approval request") || detail.includes("unknown pending permission request");
102448
+ return detail.includes("stale pending approval request") || detail.includes("unknown pending approval request") || detail.includes("unknown pending permission request") || detail.includes("unknown pending codex approval request");
101493
102449
  }
101494
102450
  function derivePendingUserInputStatesFromActivities(activities) {
101495
102451
  const states = /* @__PURE__ */ new Map();
@@ -101574,7 +102530,6 @@ function collectThreadAttachmentRelativePaths(threadId, messages) {
101574
102530
  if (!threadSegment) return /* @__PURE__ */ new Set();
101575
102531
  const relativePaths = /* @__PURE__ */ new Set();
101576
102532
  for (const message of messages) for (const attachment of message.attachments ?? []) {
101577
- if (attachment.type !== "image") continue;
101578
102533
  const attachmentThreadSegment = parseThreadSegmentFromAttachmentId(attachment.id);
101579
102534
  if (!attachmentThreadSegment || attachmentThreadSegment !== threadSegment) continue;
101580
102535
  relativePaths.add(attachmentRelativePath(attachment));
@@ -101876,7 +102831,12 @@ const makeOrchestrationProjectionPipeline = effect.Effect.fn("makeOrchestrationP
101876
102831
  return;
101877
102832
  }
101878
102833
  case "thread.deleted": {
101879
- attachmentSideEffects.deletedThreadIds.add(event.payload.threadId);
102834
+ if (!(yield* eventStore.hasEventAfter({
102835
+ aggregateKind: "thread",
102836
+ aggregateId: event.payload.threadId,
102837
+ type: "thread.created",
102838
+ sequenceExclusive: event.sequence
102839
+ }))) attachmentSideEffects.deletedThreadIds.add(event.payload.threadId);
101880
102840
  const existingRow = yield* projectionThreadRepository.getById({ threadId: event.payload.threadId });
101881
102841
  if (effect.Option.isNone(existingRow)) return;
101882
102842
  yield* projectionThreadRepository.upsert({
@@ -102111,6 +103071,9 @@ const makeOrchestrationProjectionPipeline = effect.Effect.fn("makeOrchestrationP
102111
103071
  });
102112
103072
  const applyThreadMessagesProjection = effect.Effect.fn("applyThreadMessagesProjection")(function* (event, attachmentSideEffects) {
102113
103073
  switch (event.type) {
103074
+ case "thread.created":
103075
+ yield* projectionThreadMessageRepository.deleteByThreadId({ threadId: event.payload.threadId });
103076
+ return;
102114
103077
  case "thread.message-sent": {
102115
103078
  const existingMessage = yield* projectionThreadMessageRepository.getByMessageId({ messageId: event.payload.messageId });
102116
103079
  const previousMessage = effect.Option.getOrUndefined(existingMessage);
@@ -102152,6 +103115,9 @@ const makeOrchestrationProjectionPipeline = effect.Effect.fn("makeOrchestrationP
102152
103115
  });
102153
103116
  const applyThreadProposedPlansProjection = effect.Effect.fn("applyThreadProposedPlansProjection")(function* (event, _attachmentSideEffects) {
102154
103117
  switch (event.type) {
103118
+ case "thread.created":
103119
+ yield* projectionThreadProposedPlanRepository.deleteByThreadId({ threadId: event.payload.threadId });
103120
+ return;
102155
103121
  case "thread.proposed-plan-upserted":
102156
103122
  yield* projectionThreadProposedPlanRepository.upsert({
102157
103123
  planId: event.payload.proposedPlan.id,
@@ -102178,6 +103144,10 @@ const makeOrchestrationProjectionPipeline = effect.Effect.fn("makeOrchestrationP
102178
103144
  });
102179
103145
  const applyThreadActivitiesProjection = effect.Effect.fn("applyThreadActivitiesProjection")(function* (event, attachmentSideEffects) {
102180
103146
  switch (event.type) {
103147
+ case "thread.created":
103148
+ yield* projectionThreadActivityRepository.deleteByThreadId({ threadId: event.payload.threadId });
103149
+ yield* projectionThreadUserInputRequestRepository.deleteByThreadId({ threadId: event.payload.threadId });
103150
+ return;
102181
103151
  case "thread.activity-appended": {
102182
103152
  const requestId = extractActivityRequestId(event.payload.activity.payload);
102183
103153
  const activityPayload = typeof event.payload.activity.payload === "object" && event.payload.activity.payload !== null ? event.payload.activity.payload : null;
@@ -102233,6 +103203,10 @@ const makeOrchestrationProjectionPipeline = effect.Effect.fn("makeOrchestrationP
102233
103203
  }
102234
103204
  });
102235
103205
  const applyThreadSessionsProjection = effect.Effect.fn("applyThreadSessionsProjection")(function* (event, _attachmentSideEffects) {
103206
+ if (event.type === "thread.created") {
103207
+ yield* projectionThreadSessionRepository.deleteByThreadId({ threadId: event.payload.threadId });
103208
+ return;
103209
+ }
102236
103210
  if (event.type !== "thread.session-set") return;
102237
103211
  yield* projectionThreadSessionRepository.upsert({
102238
103212
  threadId: event.payload.threadId,
@@ -102249,6 +103223,9 @@ const makeOrchestrationProjectionPipeline = effect.Effect.fn("makeOrchestrationP
102249
103223
  });
102250
103224
  const applyThreadTurnsProjection = effect.Effect.fn("applyThreadTurnsProjection")(function* (event, _attachmentSideEffects) {
102251
103225
  switch (event.type) {
103226
+ case "thread.created":
103227
+ yield* projectionTurnRepository.deleteByThreadId({ threadId: event.payload.threadId });
103228
+ return;
102252
103229
  case "thread.turn-start-requested":
102253
103230
  yield* projectionTurnRepository.replacePendingTurnStart({
102254
103231
  threadId: event.payload.threadId,
@@ -102424,6 +103401,9 @@ const makeOrchestrationProjectionPipeline = effect.Effect.fn("makeOrchestrationP
102424
103401
  const applyCheckpointsProjection = () => effect.Effect.void;
102425
103402
  const applyPendingApprovalsProjection = effect.Effect.fn("applyPendingApprovalsProjection")(function* (event, attachmentSideEffects) {
102426
103403
  switch (event.type) {
103404
+ case "thread.created":
103405
+ yield* projectionPendingApprovalRepository.deleteByThreadId({ threadId: event.payload.threadId });
103406
+ return;
102427
103407
  case "thread.activity-appended": {
102428
103408
  const requestId = extractActivityRequestId(event.payload.activity.payload) ?? event.metadata.requestId ?? null;
102429
103409
  if (requestId === null) return;
@@ -102581,7 +103561,8 @@ const makeOrchestrationProjectionPipeline = effect.Effect.fn("makeOrchestrationP
102581
103561
  const lastAppliedByProjector = new Map(projectors.map((projector) => [projector.name, 0]));
102582
103562
  for (const row of stateRows) if (lastAppliedByProjector.has(row.projector)) lastAppliedByProjector.set(row.projector, row.lastAppliedSequence);
102583
103563
  const replayFromSequence = Math.min(...lastAppliedByProjector.values());
102584
- yield* effect.Stream.runForEach(eventStore.readFromSequence(replayFromSequence), (event) => effect.Effect.gen(function* () {
103564
+ const replayThroughSequence = yield* eventStore.latestSequence;
103565
+ yield* effect.Stream.runForEach(eventStore.readThroughSequence(replayFromSequence, replayThroughSequence), (event) => effect.Effect.gen(function* () {
102585
103566
  const projectorsToAdvance = projectors.filter((projector) => event.sequence > (lastAppliedByProjector.get(projector.name) ?? 0));
102586
103567
  if (projectorsToAdvance.length === 0) return;
102587
103568
  const postCommit = yield* sql.withTransaction(applyProjectorsForEvent(event, projectorsToAdvance));
@@ -106516,6 +107497,7 @@ exports.GITHUB_PULL_REQUEST_LIST_JSON_FIELDS = GITHUB_PULL_REQUEST_LIST_JSON_FIE
106516
107497
  exports.GitHubCli = GitHubCli;
106517
107498
  exports.GitHubCliError = GitHubCliError;
106518
107499
  exports.GitLabCli = GitLabCli;
107500
+ exports.MINIMUM_OPENCODE_VERSION = MINIMUM_OPENCODE_VERSION;
106519
107501
  exports.OpenCodeRuntime = OpenCodeRuntime;
106520
107502
  exports.OpenCodeRuntimeError = OpenCodeRuntimeError;
106521
107503
  exports.ProviderAdapterProcessError = ProviderAdapterProcessError;
@@ -106637,6 +107619,7 @@ exports.openCodeRuntimeErrorDetail = openCodeRuntimeErrorDetail;
106637
107619
  exports.parseGenericCliVersion = parseGenericCliVersion;
106638
107620
  exports.parseOpenCodeModelSlug = parseOpenCodeModelSlug;
106639
107621
  exports.providerModelsFromSettings = providerModelsFromSettings;
107622
+ exports.readPersistedAttachment = readPersistedAttachment;
106640
107623
  exports.redactAgentControlSecrets = redactAgentControlSecrets;
106641
107624
  exports.resolveAttachmentPath = resolveAttachmentPath;
106642
107625
  exports.resolveClaudeHomePath = resolveClaudeHomePath$1;
@@ -106654,4 +107637,5 @@ exports.toOpenCodeFileParts = toOpenCodeFileParts;
106654
107637
  exports.toOpenCodePermissionReply = toOpenCodePermissionReply;
106655
107638
  exports.toOpenCodeQuestionAnswers = toOpenCodeQuestionAnswers;
106656
107639
  exports.validateRankInboxThreadsResult = validateRankInboxThreadsResult;
107640
+ exports.verifyOpenCodeServerVersion = verifyOpenCodeServerVersion;
106657
107641
  exports.withoutStatusCheckRollupJsonField = withoutStatusCheckRollupJsonField;