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
@@ -1,19 +1,80 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  const require_rolldown_runtime = require("./rolldown-runtime-LGfotAqq.cjs");
4
- const require_collectUint8StreamText = require("./collectUint8StreamText-Bb52hlpd.cjs");
4
+ const require_collectUint8StreamText = require("./collectUint8StreamText-Dsbmrw73.cjs");
5
5
  const require_Metrics = require("./Metrics-DIjMQ5pa.cjs");
6
6
  const require_bin = require("./bin.cjs");
7
7
  const require_sourceControlContextFormatter = require("./sourceControlContextFormatter-BDZqn-4T.cjs");
8
- const require_makeManagedServerProvider = require("./makeManagedServerProvider-itynW7xv.cjs");
8
+ const require_makeManagedServerProvider = require("./makeManagedServerProvider-CANTNAsz.cjs");
9
9
  const require_ProviderDriver = require("./ProviderDriver--rNeAi3B.cjs");
10
10
  let effect = require("effect");
11
11
  let effect_unstable_http = require("effect/unstable/http");
12
12
  require("effect/unstable/process");
13
13
  let effect_Semaphore = require("effect/Semaphore");
14
14
  effect_Semaphore = require_rolldown_runtime.__toESM(effect_Semaphore, 1);
15
+ //#region src/provider/OpenCodeServerOwner.ts
16
+ const OPENCODE_MANAGED_SERVER_IDLE_TTL = "30 seconds";
17
+ const makeOpenCodeServerOwner = effect.Effect.fn("makeOpenCodeServerOwner")(function* (settings, environment = process.env) {
18
+ const runtime = yield* require_bin.OpenCodeRuntime;
19
+ const ownerScope = yield* effect.Effect.scope;
20
+ const mutex = yield* effect_Semaphore.make(1);
21
+ let owned = null;
22
+ const closeOwned = (record) => effect.Effect.gen(function* () {
23
+ if (owned === record) owned = null;
24
+ const idleFiber = record.idleCloseFiber;
25
+ record.idleCloseFiber = null;
26
+ if (idleFiber !== null) yield* effect.Fiber.interrupt(idleFiber).pipe(effect.Effect.ignore);
27
+ yield* effect.Scope.close(record.scope, effect.Exit.void).pipe(effect.Effect.ignore);
28
+ });
29
+ const cancelIdleClose = (record) => effect.Effect.gen(function* () {
30
+ const fiber = record.idleCloseFiber;
31
+ record.idleCloseFiber = null;
32
+ if (fiber !== null) yield* effect.Fiber.interrupt(fiber).pipe(effect.Effect.ignore);
33
+ });
34
+ const acquireProcess = mutex.withPermit(effect.Effect.gen(function* () {
35
+ if (owned !== null) {
36
+ yield* cancelIdleClose(owned);
37
+ owned.leases += 1;
38
+ return owned.process;
39
+ }
40
+ return yield* effect.Effect.uninterruptibleMask((restore) => effect.Effect.gen(function* () {
41
+ const processScope = yield* effect.Scope.make();
42
+ const started = yield* effect.Effect.exit(restore(runtime.startOpenCodeServerProcess({
43
+ binaryPath: settings.binaryPath,
44
+ ...settings.serverPassword ? { serverPassword: settings.serverPassword } : {},
45
+ environment
46
+ }).pipe(effect.Effect.provideService(effect.Scope.Scope, processScope))));
47
+ if (effect.Exit.isFailure(started)) {
48
+ yield* effect.Scope.close(processScope, effect.Exit.void).pipe(effect.Effect.ignore);
49
+ return yield* effect.Effect.failCause(started.cause);
50
+ }
51
+ owned = {
52
+ process: started.value,
53
+ scope: processScope,
54
+ leases: 1,
55
+ idleCloseFiber: null
56
+ };
57
+ return started.value;
58
+ }));
59
+ }));
60
+ const releaseProcess = (process) => mutex.withPermit(effect.Effect.gen(function* () {
61
+ const record = owned;
62
+ if (record === null || record.process !== process) return;
63
+ record.leases = Math.max(0, record.leases - 1);
64
+ if (record.leases > 0 || record.idleCloseFiber !== null) return;
65
+ record.idleCloseFiber = yield* effect.Effect.sleep(OPENCODE_MANAGED_SERVER_IDLE_TTL).pipe(effect.Effect.andThen(mutex.withPermit(effect.Effect.gen(function* () {
66
+ if (owned !== record || record.leases > 0) return;
67
+ record.idleCloseFiber = null;
68
+ yield* closeOwned(record);
69
+ }))), effect.Effect.forkIn(ownerScope));
70
+ }));
71
+ yield* effect.Effect.addFinalizer(() => mutex.withPermit(effect.Effect.gen(function* () {
72
+ if (owned !== null) yield* closeOwned(owned);
73
+ })));
74
+ return { acquire: effect.Effect.acquireRelease(acquireProcess, releaseProcess) };
75
+ });
76
+ //#endregion
15
77
  //#region src/textGeneration/OpenCodeTextGeneration.ts
16
- const OPENCODE_TEXT_GENERATION_IDLE_TTL = "30 seconds";
17
78
  function getOpenCodePromptErrorMessage(error) {
18
79
  if (!error || typeof error !== "object") return null;
19
80
  const message = "data" in error && error.data && typeof error.data === "object" && "message" in error.data && typeof error.data.message === "string" ? error.data.message.trim() : "";
@@ -32,105 +93,58 @@ function getOpenCodeTextResponse(parts) {
32
93
  return [part.text];
33
94
  }).join("").trim();
34
95
  }
35
- const makeOpenCodeTextGeneration = effect.Effect.fn("makeOpenCodeTextGeneration")(function* (openCodeSettings, environment = process.env) {
96
+ const makeOpenCodeTextGeneration = effect.Effect.fn("makeOpenCodeTextGeneration")(function* (openCodeSettings, environment = process.env, options) {
36
97
  const serverConfig = yield* require_Metrics.ServerConfig;
37
98
  const openCodeRuntime = yield* require_bin.OpenCodeRuntime;
38
- const idleFiberScope = yield* effect.Effect.acquireRelease(effect.Scope.make(), (scope) => effect.Scope.close(scope, effect.Exit.void));
39
- const sharedServerMutex = yield* effect_Semaphore.make(1);
40
- const sharedServerState = {
41
- server: null,
42
- serverScope: null,
43
- binaryPath: null,
44
- activeRequests: 0,
45
- idleCloseFiber: null
46
- };
47
- const closeSharedServer = effect.Effect.fn("closeSharedServer")(function* () {
48
- const scope = sharedServerState.serverScope;
49
- sharedServerState.server = null;
50
- sharedServerState.serverScope = null;
51
- sharedServerState.binaryPath = null;
52
- if (scope !== null) yield* effect.Scope.close(scope, effect.Exit.void).pipe(effect.Effect.ignore);
53
- });
54
- const cancelIdleCloseFiber = effect.Effect.fn("cancelIdleCloseFiber")(function* () {
55
- const idleCloseFiber = sharedServerState.idleCloseFiber;
56
- sharedServerState.idleCloseFiber = null;
57
- if (idleCloseFiber !== null) yield* effect.Fiber.interrupt(idleCloseFiber).pipe(effect.Effect.ignore);
58
- });
59
- const scheduleIdleClose = effect.Effect.fn("scheduleIdleClose")(function* (server) {
60
- yield* cancelIdleCloseFiber();
61
- const fiber = yield* effect.Effect.sleep(OPENCODE_TEXT_GENERATION_IDLE_TTL).pipe(effect.Effect.andThen(sharedServerMutex.withPermit(effect.Effect.gen(function* () {
62
- if (sharedServerState.server !== server || sharedServerState.activeRequests > 0) return;
63
- sharedServerState.idleCloseFiber = null;
64
- yield* closeSharedServer();
65
- }))), effect.Effect.forkIn(idleFiberScope));
66
- sharedServerState.idleCloseFiber = fiber;
67
- });
68
- const acquireSharedServer = (input) => sharedServerMutex.withPermit(effect.Effect.gen(function* () {
69
- yield* cancelIdleCloseFiber();
70
- const existingServer = sharedServerState.server;
71
- if (existingServer !== null) {
72
- if (sharedServerState.binaryPath !== input.binaryPath && sharedServerState.activeRequests === 0) yield* closeSharedServer();
73
- else {
74
- if (sharedServerState.binaryPath !== input.binaryPath) yield* effect.Effect.logWarning("OpenCode shared server binary path mismatch: requested " + input.binaryPath + " but active server uses " + sharedServerState.binaryPath + "; reusing existing server because there are active requests");
75
- sharedServerState.activeRequests += 1;
76
- return existingServer;
77
- }
78
- }
79
- return yield* effect.Effect.uninterruptibleMask((restore) => effect.Effect.gen(function* () {
80
- const serverScope = yield* effect.Scope.make();
81
- const startedExit = yield* effect.Effect.exit(restore(openCodeRuntime.startOpenCodeServerProcess({
82
- binaryPath: input.binaryPath,
83
- environment
84
- }).pipe(effect.Effect.provideService(effect.Scope.Scope, serverScope), effect.Effect.mapError((cause) => new require_collectUint8StreamText.TextGenerationError({
85
- operation: input.operation,
86
- detail: require_bin.openCodeRuntimeErrorDetail(cause),
87
- cause
88
- })))));
89
- if (startedExit._tag === "Failure") {
90
- yield* effect.Scope.close(serverScope, effect.Exit.void).pipe(effect.Effect.ignore);
91
- return yield* effect.Effect.failCause(startedExit.cause);
92
- }
93
- const server = startedExit.value;
94
- sharedServerState.server = server;
95
- sharedServerState.serverScope = serverScope;
96
- sharedServerState.binaryPath = input.binaryPath;
97
- sharedServerState.activeRequests = 1;
98
- return server;
99
- }));
100
- }));
101
- const releaseSharedServer = (server) => sharedServerMutex.withPermit(effect.Effect.gen(function* () {
102
- if (sharedServerState.server !== server) return;
103
- sharedServerState.activeRequests = Math.max(0, sharedServerState.activeRequests - 1);
104
- if (sharedServerState.activeRequests === 0) yield* scheduleIdleClose(server);
105
- }));
106
- yield* effect.Effect.addFinalizer(() => sharedServerMutex.withPermit(effect.Effect.gen(function* () {
107
- yield* cancelIdleCloseFiber();
108
- sharedServerState.activeRequests = 0;
109
- yield* closeSharedServer();
110
- })));
99
+ const serverOwner = options?.serverOwner ?? (openCodeSettings.serverUrl.trim().length === 0 ? yield* makeOpenCodeServerOwner(openCodeSettings, environment) : void 0);
111
100
  const runOpenCodeJson = effect.Effect.fn("runOpenCodeJson")(function* (input) {
112
101
  const parsedModel = require_bin.parseOpenCodeModelSlug(input.modelSelection.model);
113
102
  if (!parsedModel) return yield* new require_collectUint8StreamText.TextGenerationError({
114
103
  operation: input.operation,
115
104
  detail: "OpenCode model selection must use the 'provider/model' format."
116
105
  });
117
- const fileParts = require_bin.toOpenCodeFileParts({
118
- attachments: input.attachments,
119
- resolveAttachmentPath: (attachment) => require_bin.resolveAttachmentPath({
106
+ const declaredAttachmentBytes = (input.attachments ?? []).reduce((total, attachment) => total + attachment.sizeBytes, 0);
107
+ if (declaredAttachmentBytes > 52428800) return yield* new require_collectUint8StreamText.TextGenerationError({
108
+ operation: input.operation,
109
+ detail: `Attachments total ${declaredAttachmentBytes} bytes; limit is ${require_collectUint8StreamText.PROVIDER_SEND_TURN_MAX_ATTACHMENT_TOTAL_BYTES} bytes.`
110
+ });
111
+ const attachmentUrlById = /* @__PURE__ */ new Map();
112
+ let attachmentTotalBytes = 0;
113
+ for (const attachment of input.attachments ?? []) {
114
+ const persisted = require_bin.readPersistedAttachment({
120
115
  attachmentsDir: serverConfig.attachmentsDir,
121
116
  attachment
122
- })
117
+ });
118
+ if (!persisted.ok) return yield* new require_collectUint8StreamText.TextGenerationError({
119
+ operation: input.operation,
120
+ detail: persisted.reason
121
+ });
122
+ attachmentTotalBytes += persisted.sizeBytes;
123
+ if (attachmentTotalBytes > 52428800) return yield* new require_collectUint8StreamText.TextGenerationError({
124
+ operation: input.operation,
125
+ detail: `Attachments total ${attachmentTotalBytes} bytes; limit is ${require_collectUint8StreamText.PROVIDER_SEND_TURN_MAX_ATTACHMENT_TOTAL_BYTES} bytes.`
126
+ });
127
+ attachmentUrlById.set(attachment.id, `data:${attachment.mimeType};base64,${persisted.bytes.toString("base64")}`);
128
+ }
129
+ const fileParts = require_bin.toOpenCodeFileParts({
130
+ attachments: input.attachments,
131
+ resolveAttachmentUrl: (attachment) => attachmentUrlById.get(attachment.id) ?? null
123
132
  });
124
133
  const runAgainstServer = (server) => effect.Effect.gen(function* () {
125
134
  const client = yield* openCodeRuntime.createOpenCodeSdkClient({
126
135
  baseUrl: server.url,
127
136
  directory: input.cwd,
128
- ...openCodeSettings.serverUrl.length > 0 && openCodeSettings.serverPassword ? { serverPassword: openCodeSettings.serverPassword } : {}
137
+ ...server.serverPassword ? { serverPassword: server.serverPassword } : {}
129
138
  }).pipe(effect.Effect.mapError((cause) => new require_collectUint8StreamText.TextGenerationError({
130
139
  operation: input.operation,
131
140
  detail: require_bin.openCodeRuntimeErrorDetail(cause),
132
141
  cause
133
142
  })));
143
+ yield* require_bin.verifyOpenCodeServerVersion(client).pipe(effect.Effect.mapError((cause) => new require_collectUint8StreamText.TextGenerationError({
144
+ operation: input.operation,
145
+ detail: require_bin.openCodeRuntimeErrorDetail(cause),
146
+ cause
147
+ })));
134
148
  return yield* effect.Effect.tryPromise({
135
149
  try: async () => {
136
150
  const session = await client.session.create({
@@ -168,10 +182,14 @@ const makeOpenCodeTextGeneration = effect.Effect.fn("makeOpenCodeTextGeneration"
168
182
  })
169
183
  });
170
184
  });
171
- const rawOutput = openCodeSettings.serverUrl.length > 0 ? yield* runAgainstServer({ url: openCodeSettings.serverUrl }) : yield* effect.Effect.acquireUseRelease(acquireSharedServer({
172
- binaryPath: openCodeSettings.binaryPath,
173
- operation: input.operation
174
- }), runAgainstServer, releaseSharedServer);
185
+ const rawOutput = openCodeSettings.serverUrl.length > 0 ? yield* runAgainstServer({
186
+ url: openCodeSettings.serverUrl,
187
+ ...openCodeSettings.serverPassword ? { serverPassword: openCodeSettings.serverPassword } : {}
188
+ }) : yield* effect.Effect.scoped(serverOwner.acquire.pipe(effect.Effect.mapError((cause) => new require_collectUint8StreamText.TextGenerationError({
189
+ operation: input.operation,
190
+ detail: require_bin.openCodeRuntimeErrorDetail(cause),
191
+ cause
192
+ })), effect.Effect.flatMap(runAgainstServer)));
175
193
  return yield* effect.Schema.decodeEffect(effect.Schema.fromJsonString(input.outputSchemaJson))(require_bin.extractJsonObject(rawOutput)).pipe(effect.Effect.catchTag("SchemaError", (cause) => effect.Effect.fail(new require_collectUint8StreamText.TextGenerationError({
176
194
  operation: input.operation,
177
195
  detail: "OpenCode returned invalid structured output.",
@@ -294,6 +312,7 @@ const makeOpenCodeTextGeneration = effect.Effect.fn("makeOpenCodeTextGeneration"
294
312
  //#endregion
295
313
  //#region src/provider/Layers/OpenCodeAdapter.ts
296
314
  const PROVIDER$1 = require_collectUint8StreamText.ProviderDriverKind.make("opencode");
315
+ const OPENCODE_RESUME_VERSION = 1;
297
316
  function nowIso() {
298
317
  return (/* @__PURE__ */ new Date()).toISOString();
299
318
  }
@@ -301,6 +320,15 @@ function nonEmptyString(value) {
301
320
  const trimmed = value?.trim();
302
321
  return trimmed && trimmed.length > 0 ? trimmed : void 0;
303
322
  }
323
+ function parseOpenCodeResume(value) {
324
+ if (!value || typeof value !== "object") return;
325
+ const cursor = value;
326
+ return cursor.schemaVersion === OPENCODE_RESUME_VERSION && typeof cursor.sessionId === "string" && cursor.sessionId.trim().length > 0 ? { sessionId: cursor.sessionId } : void 0;
327
+ }
328
+ function isOpenCodeNotFound(error) {
329
+ const cause = error.cause;
330
+ return typeof cause === "object" && cause !== null && "response" in cause && cause.response?.status === 404;
331
+ }
304
332
  function scopedOpenCodeId(sessionId, id) {
305
333
  return `${sessionId}:${id}`;
306
334
  }
@@ -313,6 +341,9 @@ function subagentKey(subagentId) {
313
341
  function statusFromOpenCodeSubagentState(status) {
314
342
  return status;
315
343
  }
344
+ function isOpenCodeRequestEvent(event) {
345
+ return event.type === "permission.asked" || event.type === "permission.replied" || event.type === "question.asked" || event.type === "question.replied" || event.type === "question.rejected";
346
+ }
316
347
  function subagentCompletionStatus(status) {
317
348
  return status;
318
349
  }
@@ -322,6 +353,7 @@ function metadataWithEntries(entries) {
322
353
  }
323
354
  function makeSubtaskSubagentRef(part) {
324
355
  const description = nonEmptyString(part.description) ?? nonEmptyString(part.prompt);
356
+ const model = part.model ? `${part.model.providerID}/${part.model.modelID}` : void 0;
325
357
  const label = nonEmptyString(part.agent) ?? nonEmptyString(part.command) ?? (description ? "OpenCode subtask" : void 0);
326
358
  return {
327
359
  subagentId: openCodeSubagentId("subtask", part.id),
@@ -329,6 +361,7 @@ function makeSubtaskSubagentRef(part) {
329
361
  capability: "summary",
330
362
  ...label ? { label } : {},
331
363
  ...description ? { description } : {},
364
+ ...model ? { model } : {},
332
365
  parentProviderItemId: require_collectUint8StreamText.ProviderItemId.make(part.id),
333
366
  metadata: metadataWithEntries([
334
367
  ["source", "opencode.subtask"],
@@ -347,6 +380,8 @@ function mergeOpenCodeChildSessionRef(existing, session, parentSessionId) {
347
380
  capability: "transcript",
348
381
  label,
349
382
  ...existing?.description ? { description: existing.description } : {},
383
+ ...existing?.model ? { model: existing.model } : {},
384
+ ...existing?.effort ? { effort: existing.effort } : {},
350
385
  providerSessionId: session.id,
351
386
  providerThreadId: session.id,
352
387
  ...existing?.parentProviderItemId && { parentProviderItemId: existing.parentProviderItemId },
@@ -383,6 +418,13 @@ const toProcessError = (threadId, cause) => new require_bin.ProviderAdapterProce
383
418
  detail: require_bin.OpenCodeRuntimeError.is(cause) ? cause.detail : require_bin.openCodeRuntimeErrorDetail(cause),
384
419
  cause
385
420
  });
421
+ const abortOpenCodeSession = (context, sessionID) => require_bin.runOpenCodeSdk("session.abort", (signal) => context.client.session.abort({ sessionID }, { signal })).pipe(effect.Effect.timeoutOrElse({
422
+ duration: "2 seconds",
423
+ orElse: () => effect.Effect.fail(new require_bin.OpenCodeRuntimeError({
424
+ operation: "session.abort",
425
+ detail: `Timed out aborting OpenCode session '${sessionID}'.`
426
+ }))
427
+ }));
386
428
  const buildEventBase = (input) => effect.Effect.sync(() => crypto.randomUUID()).pipe(effect.Effect.map((uuid) => ({
387
429
  eventId: require_collectUint8StreamText.EventId.make(uuid),
388
430
  provider: PROVIDER$1,
@@ -542,7 +584,12 @@ function updateProviderSession(context, patch, options) {
542
584
  }
543
585
  const stopOpenCodeContext = effect.Effect.fn("stopOpenCodeContext")(function* (context) {
544
586
  if (yield* effect.Ref.getAndSet(context.stopped, true)) return false;
545
- yield* require_bin.runOpenCodeSdk("session.abort", () => context.client.session.abort({ sessionID: context.openCodeSessionId })).pipe(effect.Effect.ignore({ log: true }));
587
+ const pendingPrompt = context.pendingPrompt;
588
+ if (pendingPrompt) {
589
+ context.pendingPrompt = void 0;
590
+ yield* effect.Fiber.interrupt(pendingPrompt.fiber).pipe(effect.Effect.ignore);
591
+ }
592
+ yield* effect.Effect.forEach([context.openCodeSessionId, ...context.childSessionIds], (sessionID) => abortOpenCodeSession(context, sessionID).pipe(effect.Effect.ignore({ log: true })), { discard: true });
546
593
  yield* effect.Scope.close(context.sessionScope, effect.Exit.void);
547
594
  return true;
548
595
  });
@@ -629,6 +676,13 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
629
676
  }
630
677
  });
631
678
  });
679
+ const emitStoppedOpenCodeChildren = effect.Effect.fn("emitStoppedOpenCodeChildren")(function* (context, raw) {
680
+ for (const subagent of context.subagentBySessionId.values()) yield* emitOpenCodeSubagentCompleted(context, {
681
+ subagent,
682
+ status: subagentCompletionStatus("stopped"),
683
+ raw
684
+ });
685
+ });
632
686
  const bindOpenCodeSubtaskPart = effect.Effect.fn("bindOpenCodeSubtaskPart")(function* (context, part, raw) {
633
687
  const partKey = scopedOpenCodeId(part.sessionID, part.id);
634
688
  const existing = context.subagentBySubtaskPartId.get(partKey);
@@ -650,8 +704,8 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
650
704
  return context.subagentBySubtaskPartId.get(partKey);
651
705
  };
652
706
  const registerOpenCodeChildSession = effect.Effect.fn("registerOpenCodeChildSession")(function* (context, session, raw) {
653
- if (session.parentID !== context.openCodeSessionId) return;
654
- const subagent = mergeOpenCodeChildSessionRef(context.subagentBySessionId.get(session.id) ?? takeUnboundOpenCodeSubtask(context), session, context.openCodeSessionId);
707
+ if (session.parentID !== context.openCodeSessionId && (session.parentID === void 0 || !context.childSessionIds.has(session.parentID))) return;
708
+ const subagent = mergeOpenCodeChildSessionRef(context.subagentBySessionId.get(session.id) ?? takeUnboundOpenCodeSubtask(context), session, session.parentID ?? context.openCodeSessionId);
655
709
  const known = context.childSessionIds.has(session.id);
656
710
  context.childSessionIds.add(session.id);
657
711
  context.subagentBySessionId.set(session.id, subagent);
@@ -695,6 +749,89 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
695
749
  child
696
750
  });
697
751
  });
752
+ const isRelatedOpenCodeSession = effect.Effect.fn("isRelatedOpenCodeSession")(function* (context, candidateSessionId) {
753
+ if (candidateSessionId === context.openCodeSessionId || context.childSessionIds.has(candidateSessionId)) return true;
754
+ const seen = /* @__PURE__ */ new Set();
755
+ let sessionId = candidateSessionId;
756
+ for (let depth = 0; sessionId !== void 0 && depth < 32; depth += 1) {
757
+ if (sessionId === context.openCodeSessionId || context.childSessionIds.has(sessionId)) {
758
+ for (const relatedId of seen) context.childSessionIds.add(relatedId);
759
+ return true;
760
+ }
761
+ if (seen.has(sessionId)) return false;
762
+ seen.add(sessionId);
763
+ const currentSessionId = sessionId;
764
+ const response = yield* require_bin.runOpenCodeSdk("session.get", () => context.client.session.get({ sessionID: currentSessionId })).pipe(effect.Effect.catchIf(isOpenCodeNotFound, () => effect.Effect.succeed(void 0)));
765
+ if (!response?.data) return false;
766
+ sessionId = response.data.parentID;
767
+ }
768
+ return false;
769
+ });
770
+ const recoverPendingOpenCodeRequests = effect.Effect.fn("recoverPendingOpenCodeRequests")(function* (context) {
771
+ for (let attempt = 0; attempt < 5; attempt += 1) {
772
+ if (yield* effect.Ref.get(context.stopped)) return;
773
+ const result = yield* effect.Effect.all({
774
+ permissions: require_bin.runOpenCodeSdk("permission.list", () => context.client.permission.list()),
775
+ questions: require_bin.runOpenCodeSdk("question.list", () => context.client.question.list())
776
+ }).pipe(effect.Effect.exit);
777
+ if (effect.Exit.isFailure(result)) {
778
+ if (attempt === 4) {
779
+ yield* emitForContext(context, {
780
+ ...yield* buildEventBase({ threadId: context.session.threadId }),
781
+ type: "runtime.warning",
782
+ payload: {
783
+ message: "OpenCode pending request recovery failed.",
784
+ detail: require_bin.openCodeRuntimeErrorDetail(effect.Cause.squash(result.cause))
785
+ }
786
+ });
787
+ return;
788
+ }
789
+ yield* effect.Effect.sleep(`${250 * 2 ** attempt} millis`);
790
+ continue;
791
+ }
792
+ for (const request of result.value.permissions.data ?? []) {
793
+ if (context.resolvedRequestIds.has(request.id) || context.pendingPermissions.has(request.id) || !(yield* isRelatedOpenCodeSession(context, request.sessionID))) continue;
794
+ context.pendingPermissions.set(request.id, request);
795
+ yield* emitForContext(context, {
796
+ ...yield* buildEventBase({
797
+ threadId: context.session.threadId,
798
+ turnId: context.activeTurnId,
799
+ requestId: request.id,
800
+ raw: {
801
+ type: "permission.asked",
802
+ properties: request,
803
+ recovered: true
804
+ }
805
+ }),
806
+ type: "request.opened",
807
+ payload: {
808
+ requestType: mapPermissionToRequestType(request.permission),
809
+ detail: request.patterns.length > 0 ? request.patterns.join("\n") : request.permission,
810
+ args: request.metadata
811
+ }
812
+ });
813
+ }
814
+ for (const request of result.value.questions.data ?? []) {
815
+ if (context.resolvedRequestIds.has(request.id) || context.pendingQuestions.has(request.id) || !(yield* isRelatedOpenCodeSession(context, request.sessionID))) continue;
816
+ context.pendingQuestions.set(request.id, request);
817
+ yield* emitForContext(context, {
818
+ ...yield* buildEventBase({
819
+ threadId: context.session.threadId,
820
+ turnId: context.activeTurnId,
821
+ requestId: request.id,
822
+ raw: {
823
+ type: "question.asked",
824
+ properties: request,
825
+ recovered: true
826
+ }
827
+ }),
828
+ type: "user-input.requested",
829
+ payload: { questions: normalizeQuestionRequest(request) }
830
+ });
831
+ }
832
+ return;
833
+ }
834
+ });
698
835
  const emitUnexpectedExit = effect.Effect.fn("emitUnexpectedExit")(function* (context, message) {
699
836
  if (yield* effect.Ref.getAndSet(context.stopped, true)) return;
700
837
  const turnId = context.activeTurnId;
@@ -722,7 +859,7 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
722
859
  }
723
860
  }).pipe(effect.Effect.ignore);
724
861
  sessions.delete(context.session.threadId);
725
- yield* require_bin.runOpenCodeSdk("session.abort", () => context.client.session.abort({ sessionID: context.openCodeSessionId })).pipe(effect.Effect.ignore({ log: true }));
862
+ yield* effect.Effect.forEach([context.openCodeSessionId, ...context.childSessionIds], (sessionID) => require_bin.runOpenCodeSdk("session.abort", () => context.client.session.abort({ sessionID })).pipe(effect.Effect.ignore({ log: true })), { discard: true });
726
863
  yield* effect.Scope.close(context.sessionScope, effect.Exit.void);
727
864
  });
728
865
  /** Emit content.delta and item.completed events for an assistant text part. */
@@ -797,8 +934,9 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
797
934
  const eventSessionId = typeof payloadSessionId === "string" ? payloadSessionId : void 0;
798
935
  const isRootSessionEvent = eventSessionId === context.openCodeSessionId;
799
936
  const isKnownChildSessionEvent = eventSessionId !== void 0 && context.childSessionIds.has(eventSessionId);
800
- const isChildSessionCreatedEvent = event.type === "session.created" && event.properties.info.parentID === context.openCodeSessionId;
801
- if (!isRootSessionEvent && !isKnownChildSessionEvent && !isChildSessionCreatedEvent) return;
937
+ const isChildSessionCreatedEvent = event.type === "session.created" && (event.properties.info.parentID === context.openCodeSessionId || event.properties.info.parentID !== void 0 && context.childSessionIds.has(event.properties.info.parentID));
938
+ const isRelatedRequestEvent = eventSessionId !== void 0 && isOpenCodeRequestEvent(event) && (yield* isRelatedOpenCodeSession(context, eventSessionId).pipe(effect.Effect.orElseSucceed(() => false)));
939
+ if (!isRootSessionEvent && !isKnownChildSessionEvent && !isChildSessionCreatedEvent && !isRelatedRequestEvent) return;
802
940
  const turnId = context.activeTurnId;
803
941
  yield* writeNativeEventBestEffort(context.session.threadId, {
804
942
  observedAt: nowIso(),
@@ -921,6 +1059,7 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
921
1059
  break;
922
1060
  }
923
1061
  case "permission.asked":
1062
+ if (context.resolvedRequestIds.has(event.properties.id) || context.pendingPermissions.has(event.properties.id)) break;
924
1063
  context.pendingPermissions.set(event.properties.id, event.properties);
925
1064
  yield* emitForContext(context, {
926
1065
  ...yield* buildEventBase({
@@ -938,6 +1077,7 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
938
1077
  });
939
1078
  break;
940
1079
  case "permission.replied":
1080
+ context.resolvedRequestIds.add(event.properties.requestID);
941
1081
  context.pendingPermissions.delete(event.properties.requestID);
942
1082
  yield* emitForContext(context, {
943
1083
  ...yield* buildEventBase({
@@ -954,6 +1094,7 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
954
1094
  });
955
1095
  break;
956
1096
  case "question.asked":
1097
+ if (context.resolvedRequestIds.has(event.properties.id) || context.pendingQuestions.has(event.properties.id)) break;
957
1098
  context.pendingQuestions.set(event.properties.id, event.properties);
958
1099
  yield* emitForContext(context, {
959
1100
  ...yield* buildEventBase({
@@ -967,6 +1108,7 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
967
1108
  });
968
1109
  break;
969
1110
  case "question.replied": {
1111
+ context.resolvedRequestIds.add(event.properties.requestID);
970
1112
  const request = context.pendingQuestions.get(event.properties.requestID);
971
1113
  context.pendingQuestions.delete(event.properties.requestID);
972
1114
  const answers = Object.fromEntries((request?.questions ?? []).map((question, index) => [require_bin.openCodeQuestionId(index, question), event.properties.answers[index]?.join(", ") ?? ""]));
@@ -983,6 +1125,7 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
983
1125
  break;
984
1126
  }
985
1127
  case "question.rejected":
1128
+ context.resolvedRequestIds.add(event.properties.requestID);
986
1129
  context.pendingQuestions.delete(event.properties.requestID);
987
1130
  yield* emitForContext(context, {
988
1131
  ...yield* buildEventBase({
@@ -1034,7 +1177,13 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
1034
1177
  break;
1035
1178
  }
1036
1179
  if (event.properties.status.type === "idle" && turnId) {
1180
+ if (context.pendingPrompt?.turnId === turnId) {
1181
+ context.pendingPrompt.idleEvent = event;
1182
+ break;
1183
+ }
1037
1184
  context.activeTurnId = void 0;
1185
+ context.activeAgent = void 0;
1186
+ context.activeVariant = void 0;
1038
1187
  updateProviderSession(context, { status: "ready" }, { clearActiveTurnId: true });
1039
1188
  yield* emitForContext(context, {
1040
1189
  ...yield* buildEventBase({
@@ -1070,7 +1219,14 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
1070
1219
  break;
1071
1220
  }
1072
1221
  const activeTurnId = context.activeTurnId;
1222
+ const pendingPrompt = context.pendingPrompt;
1223
+ if (pendingPrompt && pendingPrompt.turnId === activeTurnId) {
1224
+ context.pendingPrompt = void 0;
1225
+ yield* effect.Fiber.interrupt(pendingPrompt.fiber).pipe(effect.Effect.ignore);
1226
+ }
1073
1227
  context.activeTurnId = void 0;
1228
+ context.activeAgent = void 0;
1229
+ context.activeVariant = void 0;
1074
1230
  updateProviderSession(context, {
1075
1231
  status: "error",
1076
1232
  lastError: message
@@ -1135,6 +1291,7 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
1135
1291
  const serverUrl = openCodeSettings.serverUrl;
1136
1292
  const serverPassword = openCodeSettings.serverPassword;
1137
1293
  const directory = input.cwd ?? serverConfig.cwd;
1294
+ const resumeSessionId = input.resumePolicy === "fresh" ? void 0 : parseOpenCodeResume(input.resumeCursor)?.sessionId;
1138
1295
  const existing = sessions.get(input.threadId);
1139
1296
  if (existing) {
1140
1297
  if (existing.session.runtimeSessionId === runtimeSessionId) return existing.session;
@@ -1153,16 +1310,23 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
1153
1310
  const sessionScope = yield* effect.Scope.make();
1154
1311
  if (deviceToolBinding) yield* effect.Scope.addFinalizer(sessionScope, effect.Effect.sync(() => deviceToolBinding.dispose()));
1155
1312
  const startedExit = yield* effect.Effect.exit(effect.Effect.gen(function* () {
1156
- const server = yield* openCodeRuntime.connectToOpenCodeServer({
1313
+ const server = options?.serverOwner ? yield* options.serverOwner.acquire.pipe(effect.Effect.map((process) => ({
1314
+ url: process.url,
1315
+ ...process.serverPassword ? { serverPassword: process.serverPassword } : {},
1316
+ exitCode: process.exitCode,
1317
+ external: false
1318
+ }))) : yield* openCodeRuntime.connectToOpenCodeServer({
1157
1319
  binaryPath,
1158
1320
  serverUrl,
1321
+ ...serverPassword ? { serverPassword } : {},
1159
1322
  ...options?.environment ? { environment: options.environment } : {}
1160
1323
  });
1161
1324
  const client = yield* openCodeRuntime.createOpenCodeSdkClient({
1162
1325
  baseUrl: server.url,
1163
1326
  directory,
1164
- ...server.external && serverPassword ? { serverPassword } : {}
1327
+ ...server.serverPassword ? { serverPassword: server.serverPassword } : {}
1165
1328
  });
1329
+ yield* require_bin.verifyOpenCodeServerVersion(client);
1166
1330
  if (deviceToolBinding) yield* require_bin.runOpenCodeSdk("mcp.add", () => client.mcp.add({
1167
1331
  directory,
1168
1332
  name: `ryco_device_${runtimeSessionId}`,
@@ -1174,13 +1338,18 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
1174
1338
  enabled: true
1175
1339
  }
1176
1340
  }));
1177
- const openCodeSession = yield* require_bin.runOpenCodeSdk("session.create", () => client.session.create({
1341
+ const adoptedSession = resumeSessionId ? yield* require_bin.runOpenCodeSdk("session.get", () => client.session.get({ sessionID: resumeSessionId })).pipe(effect.Effect.map((response) => response.data), effect.Effect.catchIf(isOpenCodeNotFound, () => effect.Effect.succeed(void 0))) : void 0;
1342
+ if (adoptedSession) yield* require_bin.runOpenCodeSdk("session.update", () => client.session.update({
1343
+ sessionID: adoptedSession.id,
1344
+ permission: require_bin.buildOpenCodePermissionRules(input.runtimeMode)
1345
+ }));
1346
+ const openCodeSession = adoptedSession ? { data: adoptedSession } : yield* require_bin.runOpenCodeSdk("session.create", () => client.session.create({
1178
1347
  title: `Ryco ${input.threadId}`,
1179
1348
  permission: require_bin.buildOpenCodePermissionRules(input.runtimeMode)
1180
1349
  }));
1181
1350
  if (!openCodeSession.data) return yield* new require_bin.OpenCodeRuntimeError({
1182
- operation: "session.create",
1183
- detail: "OpenCode session.create returned no session payload."
1351
+ operation: adoptedSession ? "session.get" : "session.create",
1352
+ detail: adoptedSession ? "OpenCode session.get returned no session payload." : "OpenCode session.create returned no session payload."
1184
1353
  });
1185
1354
  return {
1186
1355
  sessionScope,
@@ -1213,6 +1382,10 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
1213
1382
  cwd: directory,
1214
1383
  ...input.modelSelection ? { model: input.modelSelection.model } : {},
1215
1384
  threadId: input.threadId,
1385
+ resumeCursor: {
1386
+ schemaVersion: OPENCODE_RESUME_VERSION,
1387
+ sessionId: started.openCodeSession.id
1388
+ },
1216
1389
  createdAt,
1217
1390
  updatedAt: createdAt
1218
1391
  };
@@ -1224,6 +1397,7 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
1224
1397
  openCodeSessionId: started.openCodeSession.id,
1225
1398
  pendingPermissions: /* @__PURE__ */ new Map(),
1226
1399
  pendingQuestions: /* @__PURE__ */ new Map(),
1400
+ resolvedRequestIds: /* @__PURE__ */ new Set(),
1227
1401
  partById: /* @__PURE__ */ new Map(),
1228
1402
  emittedTextByPartId: /* @__PURE__ */ new Map(),
1229
1403
  messageRoleById: /* @__PURE__ */ new Map(),
@@ -1238,6 +1412,9 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
1238
1412
  activeTurnId: void 0,
1239
1413
  activeAgent: void 0,
1240
1414
  activeVariant: void 0,
1415
+ promptSemaphore: yield* effect.Semaphore.make(1),
1416
+ pendingPrompt: void 0,
1417
+ promptGeneration: 0,
1241
1418
  agentControlHostContextDelivered: false,
1242
1419
  stopped: yield* effect.Ref.make(false),
1243
1420
  sessionScope: started.sessionScope
@@ -1255,120 +1432,206 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
1255
1432
  payload: { providerThreadId: started.openCodeSession.id }
1256
1433
  });
1257
1434
  yield* startEventPump(context);
1258
- yield* hydrateOpenCodeChildSessions(context).pipe(effect.Effect.forkIn(context.sessionScope));
1435
+ yield* effect.Effect.gen(function* () {
1436
+ yield* hydrateOpenCodeChildSessions(context);
1437
+ yield* recoverPendingOpenCodeRequests(context);
1438
+ }).pipe(effect.Effect.forkIn(context.sessionScope));
1259
1439
  return session;
1260
1440
  });
1261
1441
  const sendTurn = effect.Effect.fn("sendTurn")(function* (input) {
1262
1442
  const context = ensureSessionContext(sessions, input.threadId);
1263
- const turnId = require_collectUint8StreamText.TurnId.make(`opencode-turn-${yield* effect.Effect.sync(() => crypto.randomUUID())}`);
1264
- const modelSelection = input.modelSelection ?? (context.session.model ? {
1265
- instanceId: boundInstanceId,
1266
- model: context.session.model
1267
- } : void 0);
1268
- if (modelSelection !== void 0 && modelSelection.instanceId !== boundInstanceId) return yield* new require_bin.ProviderAdapterValidationError({
1269
- provider: PROVIDER$1,
1270
- operation: "sendTurn",
1271
- issue: `OpenCode model selection is bound to instance '${modelSelection?.instanceId}', expected '${boundInstanceId}'.`
1272
- });
1273
- const parsedModel = require_bin.parseOpenCodeModelSlug(modelSelection?.model);
1274
- if (!parsedModel) return yield* new require_bin.ProviderAdapterValidationError({
1275
- provider: PROVIDER$1,
1276
- operation: "sendTurn",
1277
- issue: "OpenCode model selection must use the 'provider/model' format."
1278
- });
1279
- const formatted = require_sourceControlContextFormatter.formatSourceControlContextsForAgent(input.sourceControlContexts ?? []);
1280
- let text = formatted ? formatted + "\n\n" + (input.input?.trim() ?? "") : input.input?.trim();
1281
- const fileParts = require_bin.toOpenCodeFileParts({
1282
- attachments: input.attachments,
1283
- resolveAttachmentPath: (attachment) => require_bin.resolveAttachmentPath({
1284
- attachmentsDir: serverConfig.attachmentsDir,
1285
- attachment
1286
- })
1287
- });
1288
- if ((!text || text.length === 0) && fileParts.length === 0) return yield* new require_bin.ProviderAdapterValidationError({
1289
- provider: PROVIDER$1,
1290
- operation: "sendTurn",
1291
- issue: "OpenCode turns require text input or at least one attachment."
1292
- });
1293
- if (!context.agentControlHostContextDelivered) {
1294
- text = `<ryco_host_context>${require_bin.agentControlHostContext(false)}</ryco_host_context>${text ? `\n\n${text}` : ""}`;
1295
- context.agentControlHostContextDelivered = true;
1296
- }
1297
- const agent = require_bin.getModelSelectionStringOptionValue(modelSelection, "agent");
1298
- const variant = require_bin.getModelSelectionStringOptionValue(modelSelection, "variant");
1299
- context.activeTurnId = turnId;
1300
- context.activeAgent = agent ?? (input.interactionMode === "plan" || input.interactionMode === "ask" ? "plan" : void 0);
1301
- context.activeVariant = variant;
1302
- updateProviderSession(context, {
1303
- status: "running",
1304
- activeTurnId: turnId,
1305
- model: modelSelection?.model ?? context.session.model
1306
- }, { clearLastError: true });
1307
- yield* emitForContext(context, {
1308
- ...yield* buildEventBase({
1309
- threadId: input.threadId,
1310
- turnId
1311
- }),
1312
- type: "turn.started",
1313
- payload: {
1314
- model: modelSelection?.model ?? context.session.model,
1315
- ...variant ? { effort: variant } : {}
1443
+ return yield* context.promptSemaphore.withPermits(1)(effect.Effect.gen(function* () {
1444
+ if (sessions.get(input.threadId) !== context || (yield* effect.Ref.get(context.stopped))) return yield* new require_bin.ProviderAdapterSessionClosedError({
1445
+ provider: PROVIDER$1,
1446
+ threadId: input.threadId
1447
+ });
1448
+ const turnId = require_collectUint8StreamText.TurnId.make(`opencode-turn-${yield* effect.Effect.sync(() => crypto.randomUUID())}`);
1449
+ const modelSelection = input.modelSelection ?? (context.session.model ? {
1450
+ instanceId: boundInstanceId,
1451
+ model: context.session.model
1452
+ } : void 0);
1453
+ if (modelSelection !== void 0 && modelSelection.instanceId !== boundInstanceId) return yield* new require_bin.ProviderAdapterValidationError({
1454
+ provider: PROVIDER$1,
1455
+ operation: "sendTurn",
1456
+ issue: `OpenCode model selection is bound to instance '${modelSelection?.instanceId}', expected '${boundInstanceId}'.`
1457
+ });
1458
+ const parsedModel = require_bin.parseOpenCodeModelSlug(modelSelection?.model);
1459
+ if (!parsedModel) return yield* new require_bin.ProviderAdapterValidationError({
1460
+ provider: PROVIDER$1,
1461
+ operation: "sendTurn",
1462
+ issue: "OpenCode model selection must use the 'provider/model' format."
1463
+ });
1464
+ const formatted = require_sourceControlContextFormatter.formatSourceControlContextsForAgent(input.sourceControlContexts ?? []);
1465
+ let text = formatted ? formatted + "\n\n" + (input.input?.trim() ?? "") : input.input?.trim();
1466
+ const attachmentUrlById = /* @__PURE__ */ new Map();
1467
+ const declaredAttachmentBytes = (input.attachments ?? []).reduce((total, attachment) => total + attachment.sizeBytes, 0);
1468
+ if (declaredAttachmentBytes > 52428800) return yield* new require_bin.ProviderAdapterRequestError({
1469
+ provider: PROVIDER$1,
1470
+ method: "session.prompt",
1471
+ detail: `Attachments total ${declaredAttachmentBytes} bytes; limit is ${require_collectUint8StreamText.PROVIDER_SEND_TURN_MAX_ATTACHMENT_TOTAL_BYTES} bytes.`
1472
+ });
1473
+ let attachmentTotalBytes = 0;
1474
+ for (const attachment of input.attachments ?? []) {
1475
+ const persisted = require_bin.readPersistedAttachment({
1476
+ attachmentsDir: serverConfig.attachmentsDir,
1477
+ attachment
1478
+ });
1479
+ if (!persisted.ok) return yield* new require_bin.ProviderAdapterRequestError({
1480
+ provider: PROVIDER$1,
1481
+ method: "session.prompt",
1482
+ detail: persisted.reason
1483
+ });
1484
+ attachmentUrlById.set(attachment.id, `data:${attachment.mimeType};base64,${persisted.bytes.toString("base64")}`);
1485
+ attachmentTotalBytes += persisted.sizeBytes;
1486
+ if (attachmentTotalBytes > 52428800) return yield* new require_bin.ProviderAdapterRequestError({
1487
+ provider: PROVIDER$1,
1488
+ method: "session.prompt",
1489
+ detail: `Attachments total ${attachmentTotalBytes} bytes; limit is ${require_collectUint8StreamText.PROVIDER_SEND_TURN_MAX_ATTACHMENT_TOTAL_BYTES} bytes.`
1490
+ });
1316
1491
  }
1317
- });
1318
- yield* require_bin.runOpenCodeSdk("session.promptAsync", () => context.client.session.promptAsync({
1319
- sessionID: context.openCodeSessionId,
1320
- model: parsedModel,
1321
- ...context.activeAgent ? { agent: context.activeAgent } : {},
1322
- ...context.activeVariant ? { variant: context.activeVariant } : {},
1323
- parts: [...text ? [{
1324
- type: "text",
1325
- text
1326
- }] : [], ...fileParts]
1327
- })).pipe(effect.Effect.mapError(toRequestError), effect.Effect.tapError((requestError) => effect.Effect.gen(function* () {
1328
- context.activeTurnId = void 0;
1329
- context.activeAgent = void 0;
1330
- context.activeVariant = void 0;
1492
+ const fileParts = require_bin.toOpenCodeFileParts({
1493
+ attachments: input.attachments,
1494
+ resolveAttachmentUrl: (attachment) => attachmentUrlById.get(attachment.id) ?? null
1495
+ });
1496
+ if ((!text || text.length === 0) && fileParts.length === 0) return yield* new require_bin.ProviderAdapterValidationError({
1497
+ provider: PROVIDER$1,
1498
+ operation: "sendTurn",
1499
+ issue: "OpenCode turns require text input or at least one attachment."
1500
+ });
1501
+ if (!context.agentControlHostContextDelivered) {
1502
+ text = `<ryco_host_context>${require_bin.agentControlHostContext(false)}</ryco_host_context>${text ? `\n\n${text}` : ""}`;
1503
+ context.agentControlHostContextDelivered = true;
1504
+ }
1505
+ const agent = require_bin.getModelSelectionStringOptionValue(modelSelection, "agent");
1506
+ const variant = require_bin.getModelSelectionStringOptionValue(modelSelection, "variant");
1507
+ context.activeTurnId = turnId;
1508
+ context.activeAgent = agent ?? (input.interactionMode === "plan" || input.interactionMode === "ask" ? "plan" : void 0);
1509
+ context.activeVariant = variant;
1331
1510
  updateProviderSession(context, {
1332
- status: "ready",
1333
- model: modelSelection?.model ?? context.session.model,
1334
- lastError: requestError.detail
1335
- }, { clearActiveTurnId: true });
1511
+ status: "running",
1512
+ activeTurnId: turnId,
1513
+ model: modelSelection?.model ?? context.session.model
1514
+ }, { clearLastError: true });
1336
1515
  yield* emitForContext(context, {
1337
1516
  ...yield* buildEventBase({
1338
1517
  threadId: input.threadId,
1339
1518
  turnId
1340
1519
  }),
1341
- type: "turn.aborted",
1342
- payload: { reason: requestError.detail }
1520
+ type: "turn.started",
1521
+ payload: {
1522
+ model: modelSelection?.model ?? context.session.model,
1523
+ ...variant ? { effort: variant } : {}
1524
+ }
1343
1525
  });
1344
- })));
1345
- return {
1346
- threadId: input.threadId,
1347
- turnId
1348
- };
1526
+ context.promptGeneration += 1;
1527
+ const generation = context.promptGeneration;
1528
+ const promptFiber = yield* require_bin.runOpenCodeSdk("session.promptAsync", (signal) => context.client.session.promptAsync({
1529
+ sessionID: context.openCodeSessionId,
1530
+ model: parsedModel,
1531
+ ...context.activeAgent ? { agent: context.activeAgent } : {},
1532
+ ...context.activeVariant ? { variant: context.activeVariant } : {},
1533
+ parts: [...text ? [{
1534
+ type: "text",
1535
+ text
1536
+ }] : [], ...fileParts]
1537
+ }, { signal })).pipe(effect.Effect.mapError(toRequestError), effect.Effect.tapError((requestError) => context.activeTurnId === turnId && context.promptGeneration === generation ? effect.Effect.gen(function* () {
1538
+ context.activeTurnId = void 0;
1539
+ context.activeAgent = void 0;
1540
+ context.activeVariant = void 0;
1541
+ updateProviderSession(context, {
1542
+ status: "ready",
1543
+ model: modelSelection?.model ?? context.session.model,
1544
+ lastError: requestError.detail
1545
+ }, { clearActiveTurnId: true });
1546
+ yield* emitForContext(context, {
1547
+ ...yield* buildEventBase({
1548
+ threadId: input.threadId,
1549
+ turnId
1550
+ }),
1551
+ type: "turn.aborted",
1552
+ payload: { reason: requestError.detail }
1553
+ });
1554
+ }) : effect.Effect.void)).pipe(effect.Effect.forkIn(context.sessionScope));
1555
+ const pendingPrompt = {
1556
+ turnId,
1557
+ fiber: promptFiber
1558
+ };
1559
+ context.pendingPrompt = pendingPrompt;
1560
+ yield* effect.Fiber.join(promptFiber).pipe(effect.Effect.ensuring(effect.Effect.sync(() => {
1561
+ if (context.pendingPrompt?.fiber === promptFiber) context.pendingPrompt = void 0;
1562
+ })));
1563
+ const completedDuringAdmission = pendingPrompt.idleEvent !== void 0;
1564
+ if (completedDuringAdmission && context.activeTurnId === turnId) {
1565
+ context.activeTurnId = void 0;
1566
+ context.activeAgent = void 0;
1567
+ context.activeVariant = void 0;
1568
+ updateProviderSession(context, { status: "ready" }, { clearActiveTurnId: true });
1569
+ yield* emitForContext(context, {
1570
+ ...yield* buildEventBase({
1571
+ threadId: context.session.threadId,
1572
+ turnId,
1573
+ raw: pendingPrompt.idleEvent
1574
+ }),
1575
+ type: "turn.completed",
1576
+ payload: { state: "completed" }
1577
+ });
1578
+ }
1579
+ if (sessions.get(input.threadId) !== context || (yield* effect.Ref.get(context.stopped)) || !completedDuringAdmission && context.activeTurnId !== turnId || context.promptGeneration !== generation) return yield* effect.Effect.interrupt;
1580
+ return {
1581
+ threadId: input.threadId,
1582
+ turnId,
1583
+ resumeCursor: context.session.resumeCursor
1584
+ };
1585
+ }));
1349
1586
  });
1350
1587
  const interruptTurn = effect.Effect.fn("interruptTurn")(function* (threadId, turnId) {
1351
1588
  const context = ensureSessionContext(sessions, threadId);
1352
- yield* require_bin.runOpenCodeSdk("session.abort", () => context.client.session.abort({ sessionID: context.openCodeSessionId })).pipe(effect.Effect.mapError(toRequestError));
1353
- if (turnId ?? context.activeTurnId) yield* emitForContext(context, {
1354
- ...yield* buildEventBase({
1355
- threadId,
1356
- turnId: turnId ?? context.activeTurnId
1357
- }),
1358
- type: "turn.aborted",
1359
- payload: { reason: "Interrupted by user." }
1589
+ const interruptedTurnId = turnId ?? context.activeTurnId;
1590
+ if (turnId !== void 0 && context.activeTurnId !== void 0 && turnId !== context.activeTurnId) return;
1591
+ const pendingPrompt = context.pendingPrompt;
1592
+ if (pendingPrompt && pendingPrompt.turnId === interruptedTurnId) {
1593
+ context.pendingPrompt = void 0;
1594
+ yield* effect.Fiber.interrupt(pendingPrompt.fiber).pipe(effect.Effect.ignore);
1595
+ }
1596
+ const rootAbortExit = yield* abortOpenCodeSession(context, context.openCodeSessionId).pipe(effect.Effect.mapError(toRequestError), effect.Effect.exit);
1597
+ yield* effect.Effect.forEach(context.childSessionIds, (sessionID) => abortOpenCodeSession(context, sessionID).pipe(effect.Effect.ignore({ log: true })), { discard: true });
1598
+ yield* emitStoppedOpenCodeChildren(context, {
1599
+ method: "session.abort",
1600
+ reason: "turn-interrupted"
1360
1601
  });
1602
+ if (effect.Exit.isFailure(rootAbortExit)) return yield* effect.Effect.failCause(rootAbortExit.cause);
1603
+ if (interruptedTurnId) {
1604
+ if (context.activeTurnId === interruptedTurnId) {
1605
+ context.activeTurnId = void 0;
1606
+ context.activeAgent = void 0;
1607
+ context.activeVariant = void 0;
1608
+ updateProviderSession(context, { status: "ready" }, {
1609
+ clearActiveTurnId: true,
1610
+ clearLastError: true
1611
+ });
1612
+ }
1613
+ yield* emitForContext(context, {
1614
+ ...yield* buildEventBase({
1615
+ threadId,
1616
+ turnId: interruptedTurnId
1617
+ }),
1618
+ type: "turn.aborted",
1619
+ payload: { reason: "Interrupted by user." }
1620
+ });
1621
+ }
1361
1622
  });
1362
1623
  const respondToRequest = effect.Effect.fn("respondToRequest")(function* (threadId, requestId, decision) {
1363
1624
  const context = ensureSessionContext(sessions, threadId);
1364
- if (!context.pendingPermissions.has(requestId)) return yield* new require_bin.ProviderAdapterRequestError({
1625
+ const request = context.pendingPermissions.get(requestId);
1626
+ if (!request) return yield* new require_bin.ProviderAdapterRequestError({
1365
1627
  provider: PROVIDER$1,
1366
- method: "permission.reply",
1628
+ method: "permission.respond",
1367
1629
  detail: `Unknown pending permission request: ${requestId}`
1368
1630
  });
1369
- yield* require_bin.runOpenCodeSdk("permission.reply", () => context.client.permission.reply({
1370
- requestID: requestId,
1371
- reply: require_bin.toOpenCodePermissionReply(decision)
1631
+ yield* require_bin.runOpenCodeSdk("permission.respond", () => context.client.permission.respond({
1632
+ sessionID: request.sessionID,
1633
+ permissionID: requestId,
1634
+ response: require_bin.toOpenCodePermissionReply(decision)
1372
1635
  })).pipe(effect.Effect.mapError(toRequestError));
1373
1636
  });
1374
1637
  const respondToUserInput = effect.Effect.fn("respondToUserInput")(function* (threadId, requestId, answers) {
@@ -1391,6 +1654,10 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
1391
1654
  threadId
1392
1655
  });
1393
1656
  if (!(yield* stopOpenCodeContext(context))) return;
1657
+ yield* emitStoppedOpenCodeChildren(context, {
1658
+ method: "session.abort",
1659
+ reason: "session-stopped"
1660
+ });
1394
1661
  yield* emitForContext(context, {
1395
1662
  ...yield* buildEventBase({ threadId }),
1396
1663
  type: "session.exited",
@@ -1460,7 +1727,6 @@ const OPENCODE_PRESENTATION = {
1460
1727
  displayName: "OpenCode",
1461
1728
  showInteractionModeToggle: false
1462
1729
  };
1463
- const MINIMUM_OPENCODE_VERSION = "1.14.19";
1464
1730
  var OpenCodeProbeError = class extends effect.Data.TaggedError("OpenCodeProbeError") {};
1465
1731
  function normalizeProbeMessage(message) {
1466
1732
  const trimmed = message.trim();
@@ -1520,7 +1786,7 @@ function inferDefaultAgent(agents) {
1520
1786
  }
1521
1787
  const DEFAULT_OPENCODE_MODEL_CAPABILITIES = require_bin.createModelCapabilities({ optionDescriptors: [] });
1522
1788
  function openCodeCapabilitiesForModel(input) {
1523
- const variantValues = Object.keys(input.model.variants ?? {});
1789
+ const variantValues = Object.entries(input.model.variants ?? {}).filter(([, configuration]) => configuration.disabled !== true).map(([variant]) => variant).toSorted((left, right) => left.localeCompare(right));
1524
1790
  const defaultVariant = inferDefaultVariant(input.providerID, variantValues);
1525
1791
  const variantOptions = variantValues.map((value) => defaultVariant === value ? {
1526
1792
  id: value,
@@ -1530,7 +1796,7 @@ function openCodeCapabilitiesForModel(input) {
1530
1796
  id: value,
1531
1797
  label: titleCaseSlug(value)
1532
1798
  });
1533
- const primaryAgents = input.agents.filter((agent) => !agent.hidden && (agent.mode === "primary" || agent.mode === "all"));
1799
+ const primaryAgents = [...new Map(input.agents.filter((agent) => !agent.hidden && (agent.mode === "primary" || agent.mode === "all")).map((agent) => [agent.name, agent])).values()].toSorted((left, right) => left.name.localeCompare(right.name));
1534
1800
  const defaultAgent = inferDefaultAgent(primaryAgents);
1535
1801
  const agentOptions = primaryAgents.map((agent) => defaultAgent === agent.name ? {
1536
1802
  id: agent.name,
@@ -1556,16 +1822,19 @@ function openCodeCapabilitiesForModel(input) {
1556
1822
  }
1557
1823
  function flattenOpenCodeModels(input) {
1558
1824
  const connected = new Set(input.providerList.connected);
1559
- const models = [];
1825
+ const models = /* @__PURE__ */ new Map();
1560
1826
  for (const provider of input.providerList.all) {
1561
1827
  if (!connected.has(provider.id)) continue;
1562
1828
  for (const model of Object.values(provider.models)) {
1829
+ const modelId = require_bin.nonEmptyTrimmed(model.id);
1563
1830
  const name = require_bin.nonEmptyTrimmed(model.name);
1564
- if (!name) continue;
1831
+ if (!modelId || !name) continue;
1565
1832
  const subProvider = require_bin.nonEmptyTrimmed(provider.name);
1566
1833
  const shortName = subProvider ? deriveShortNameByStrippingPrefix(name, subProvider) : void 0;
1567
- models.push({
1568
- slug: `${provider.id}/${model.id}`,
1834
+ const slug = `${provider.id}/${modelId}`;
1835
+ if (models.has(slug)) continue;
1836
+ models.set(slug, {
1837
+ slug,
1569
1838
  name,
1570
1839
  ...subProvider ? { subProvider } : {},
1571
1840
  ...shortName ? { shortName } : {},
@@ -1578,7 +1847,7 @@ function flattenOpenCodeModels(input) {
1578
1847
  });
1579
1848
  }
1580
1849
  }
1581
- return models.toSorted((left, right) => left.name.localeCompare(right.name));
1850
+ return [...models.values()].toSorted((left, right) => left.name.localeCompare(right.name) || left.slug.localeCompare(right.slug));
1582
1851
  }
1583
1852
  /**
1584
1853
  * Strip a leading provider prefix from `name` so the chat-box trigger doesn't
@@ -1672,8 +1941,8 @@ const checkOpenCodeProviderStatus = effect.Effect.fn("checkOpenCodeProviderStatu
1672
1941
  }))));
1673
1942
  if (versionExit._tag === "Failure") return fallback(effect.Cause.squash(versionExit.cause));
1674
1943
  version = require_bin.parseGenericCliVersion(versionExit.value.stdout) ?? null;
1675
- if (!version) return fallback(/* @__PURE__ */ new Error(`Unable to determine OpenCode version from \`opencode --version\` output. Ryco requires OpenCode v${MINIMUM_OPENCODE_VERSION} or newer.`), null);
1676
- if (require_bin.compareCliVersions(version, MINIMUM_OPENCODE_VERSION) < 0) return require_bin.buildServerProvider({
1944
+ if (!version) return fallback(/* @__PURE__ */ new Error(`Unable to determine OpenCode version from \`opencode --version\` output. Ryco requires OpenCode v${require_bin.MINIMUM_OPENCODE_VERSION} or newer.`), null);
1945
+ if (require_bin.compareCliVersions(version, "1.14.19") < 0) return require_bin.buildServerProvider({
1677
1946
  presentation: OPENCODE_PRESENTATION,
1678
1947
  enabled: openCodeSettings.enabled,
1679
1948
  checkedAt,
@@ -1683,7 +1952,7 @@ const checkOpenCodeProviderStatus = effect.Effect.fn("checkOpenCodeProviderStatu
1683
1952
  version,
1684
1953
  status: "error",
1685
1954
  auth: { status: "unknown" },
1686
- message: `OpenCode v${version} is too old. Upgrade to v${MINIMUM_OPENCODE_VERSION} or newer.`
1955
+ message: `OpenCode v${version} is too old. Upgrade to v${require_bin.MINIMUM_OPENCODE_VERSION} or newer.`
1687
1956
  }
1688
1957
  });
1689
1958
  }
@@ -1691,6 +1960,7 @@ const checkOpenCodeProviderStatus = effect.Effect.fn("checkOpenCodeProviderStatu
1691
1960
  const server = yield* openCodeRuntime.connectToOpenCodeServer({
1692
1961
  binaryPath: openCodeSettings.binaryPath,
1693
1962
  serverUrl: openCodeSettings.serverUrl,
1963
+ ...openCodeSettings.serverPassword ? { serverPassword: openCodeSettings.serverPassword } : {},
1694
1964
  environment
1695
1965
  }).pipe(effect.Effect.mapError((cause) => new OpenCodeProbeError({
1696
1966
  cause,
@@ -1699,19 +1969,27 @@ const checkOpenCodeProviderStatus = effect.Effect.fn("checkOpenCodeProviderStatu
1699
1969
  const client = yield* openCodeRuntime.createOpenCodeSdkClient({
1700
1970
  baseUrl: server.url,
1701
1971
  directory: cwd,
1702
- ...isExternalServer && openCodeSettings.serverPassword ? { serverPassword: openCodeSettings.serverPassword } : {}
1972
+ ...server.serverPassword ? { serverPassword: server.serverPassword } : {}
1703
1973
  }).pipe(effect.Effect.mapError((cause) => new OpenCodeProbeError({
1704
1974
  cause,
1705
1975
  detail: require_bin.openCodeRuntimeErrorDetail(cause)
1706
1976
  })));
1707
- return yield* openCodeRuntime.loadOpenCodeInventory(client).pipe(effect.Effect.mapError((cause) => new OpenCodeProbeError({
1977
+ const serverVersion = yield* require_bin.verifyOpenCodeServerVersion(client).pipe(effect.Effect.mapError((cause) => new OpenCodeProbeError({
1708
1978
  cause,
1709
1979
  detail: require_bin.openCodeRuntimeErrorDetail(cause)
1710
1980
  })));
1981
+ return {
1982
+ inventory: yield* openCodeRuntime.loadOpenCodeInventory(client).pipe(effect.Effect.mapError((cause) => new OpenCodeProbeError({
1983
+ cause,
1984
+ detail: require_bin.openCodeRuntimeErrorDetail(cause)
1985
+ }))),
1986
+ serverVersion
1987
+ };
1711
1988
  })));
1712
1989
  if (inventoryExit._tag === "Failure") return fallback(effect.Cause.squash(inventoryExit.cause), version);
1713
- const models = require_bin.providerModelsFromSettings(flattenOpenCodeModels(inventoryExit.value), PROVIDER, customModels, DEFAULT_OPENCODE_MODEL_CAPABILITIES);
1714
- const connectedCount = inventoryExit.value.providerList.connected.length;
1990
+ version = inventoryExit.value.serverVersion;
1991
+ const models = require_bin.providerModelsFromSettings(flattenOpenCodeModels(inventoryExit.value.inventory), PROVIDER, customModels, DEFAULT_OPENCODE_MODEL_CAPABILITIES);
1992
+ const connectedCount = new Set(inventoryExit.value.inventory.providerList.connected).size;
1715
1993
  return require_bin.buildServerProvider({
1716
1994
  presentation: OPENCODE_PRESENTATION,
1717
1995
  enabled: true,
@@ -1740,8 +2018,7 @@ const checkOpenCodeProviderStatus = effect.Effect.fn("checkOpenCodeProviderStatu
1740
2018
  *
1741
2019
  * Two instances with different `serverUrl`s therefore talk to independent
1742
2020
  * OpenCode servers; when no `serverUrl` is set, the adapter + text-generation
1743
- * shares spin up their own scoped child processes, and those child
1744
- * processes are released when the registry scope closes.
2021
+ * shares reuse one scoped child process owned by the provider instance.
1745
2022
  *
1746
2023
  * @module provider/Drivers/OpenCodeDriver
1747
2024
  */
@@ -1802,12 +2079,14 @@ const OpenCodeDriver = {
1802
2079
  binaryPath: effectiveConfig.binaryPath,
1803
2080
  env: processEnv
1804
2081
  });
2082
+ const serverOwner = effectiveConfig.serverUrl.trim().length === 0 ? yield* makeOpenCodeServerOwner(effectiveConfig, processEnv) : void 0;
1805
2083
  const adapter = yield* makeOpenCodeAdapter(effectiveConfig, {
1806
2084
  instanceId,
1807
2085
  environment: processEnv,
2086
+ ...serverOwner ? { serverOwner } : {},
1808
2087
  ...eventLoggers.native ? { nativeEventLogger: eventLoggers.native } : {}
1809
2088
  });
1810
- const textGeneration = yield* makeOpenCodeTextGeneration(effectiveConfig, processEnv);
2089
+ const textGeneration = yield* makeOpenCodeTextGeneration(effectiveConfig, processEnv, serverOwner ? { serverOwner } : void 0);
1811
2090
  const checkProvider = checkOpenCodeProviderStatus(effectiveConfig, serverConfig.cwd, processEnv).pipe(effect.Effect.map(stampIdentity), effect.Effect.provideService(require_bin.OpenCodeRuntime, openCodeRuntime));
1812
2091
  const snapshot = yield* require_makeManagedServerProvider.makeManagedServerProvider({
1813
2092
  maintenanceCapabilities,
@@ -1817,6 +2096,7 @@ const OpenCodeDriver = {
1817
2096
  initialSnapshot: (settings) => stampIdentity(makePendingOpenCodeProvider(settings)),
1818
2097
  checkProvider,
1819
2098
  enrichSnapshot: ({ snapshot, publishSnapshot }) => require_bin.enrichProviderSnapshotWithVersionAdvisory(snapshot, maintenanceCapabilities).pipe(effect.Effect.provideService(effect_unstable_http.HttpClient.HttpClient, httpClient), effect.Effect.provideService(require_bin.ServerSettingsService, serverSettings), effect.Effect.flatMap((enrichedSnapshot) => publishSnapshot(enrichedSnapshot))),
2099
+ retainInventoryOnError: true,
1820
2100
  refreshInterval: null
1821
2101
  }).pipe(effect.Effect.mapError((cause) => new require_bin.ProviderDriverError({
1822
2102
  driver: DRIVER_KIND,