ryco-cli 0.1.14 → 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 (189) hide show
  1. package/dist/{AcpNativeLogging-vLtnq5f1.cjs → AcpNativeLogging-OhEq3XNp.cjs} +1 -1
  2. package/dist/{AcpNativeLogging-D3fe64a6.mjs → AcpNativeLogging-qZgtIa5K.mjs} +2 -2
  3. package/dist/{AzureDevOpsSourceControlProvider-WNUDtsur.mjs → AzureDevOpsSourceControlProvider-B0YsaJyI.mjs} +3 -3
  4. package/dist/{AzureDevOpsSourceControlProvider-BtezW57t.cjs → AzureDevOpsSourceControlProvider-Dyu8KQ_S.cjs} +2 -2
  5. package/dist/{BitbucketSourceControlProvider-BWzNM0jW.cjs → BitbucketSourceControlProvider-3VHGKSl1.cjs} +2 -2
  6. package/dist/{BitbucketSourceControlProvider-tbbUFKz3.mjs → BitbucketSourceControlProvider-B8IPx2Ad.mjs} +3 -3
  7. package/dist/{ClaudeDriver-BTvdJvam.cjs → ClaudeDriver-CBCy0_WX.cjs} +8 -6
  8. package/dist/{ClaudeDriver-CG5ngU5z.mjs → ClaudeDriver-DsW8yDj9.mjs} +9 -7
  9. package/dist/{CodexDriver-CFxwJNXx.cjs → CodexDriver-3TZPgrGk.cjs} +3 -3
  10. package/dist/{CodexDriver-49o7TA-C.mjs → CodexDriver-DLwPz5sk.mjs} +4 -4
  11. package/dist/{CodexTextGeneration-C0t4xcPO.mjs → CodexTextGeneration-D1vV8grr.mjs} +2 -2
  12. package/dist/{CodexTextGeneration-CedcXf9a.cjs → CodexTextGeneration-DLHSW4Mz.cjs} +1 -1
  13. package/dist/{CopilotDriver-B8J_ovCX.cjs → CopilotDriver-C7a8IhyK.cjs} +3 -3
  14. package/dist/{CopilotDriver-Cu1B1skB.mjs → CopilotDriver-DXvGBv-s.mjs} +4 -4
  15. package/dist/{CursorDriver-P_A8uQki.mjs → CursorDriver-CeB_vMKJ.mjs} +4 -4
  16. package/dist/{CursorDriver-zlKHPy1_.cjs → CursorDriver-uNsDetA3.cjs} +3 -3
  17. package/dist/{ForgejoSourceControlProvider-szJ-dvsD.cjs → ForgejoSourceControlProvider-CJLksvL_.cjs} +2 -2
  18. package/dist/{ForgejoSourceControlProvider-DLhJZtq9.mjs → ForgejoSourceControlProvider-Ds0rU_PN.mjs} +3 -3
  19. package/dist/{GitHubSourceControlProvider-D5MQQPCJ.mjs → GitHubSourceControlProvider-C7CJAslU.mjs} +3 -3
  20. package/dist/{GitHubSourceControlProvider-3ofb6HsF.cjs → GitHubSourceControlProvider-CrYNFu8S.cjs} +2 -2
  21. package/dist/{GitLabSourceControlProvider-DkupZH5G.cjs → GitLabSourceControlProvider-jbX5M34A.cjs} +2 -2
  22. package/dist/{GitLabSourceControlProvider-DLkxeob5.mjs → GitLabSourceControlProvider-u-Y-e8PV.mjs} +3 -3
  23. package/dist/{GrokDriver-CTUNclwp.cjs → GrokDriver-BJ00ZiYg.cjs} +3 -3
  24. package/dist/{GrokDriver-D8KoMY76.mjs → GrokDriver-CFgjwnvE.mjs} +4 -4
  25. package/dist/{OpenCodeDriver-pXM8bSct.cjs → OpenCodeDriver-BTxd2Q3Q.cjs} +424 -209
  26. package/dist/{OpenCodeDriver-B7htxutj.mjs → OpenCodeDriver-DNApoGdu.mjs} +424 -209
  27. package/dist/{SourceControlProviderDiscoveryCatalog-Bj_sZfmB.cjs → SourceControlProviderDiscoveryCatalog-CPO3a9_U.cjs} +1 -1
  28. package/dist/{SourceControlProviderDiscoveryCatalog-C6Fn7rZE.mjs → SourceControlProviderDiscoveryCatalog-hXWNwRMn.mjs} +1 -1
  29. package/dist/bin.cjs +226 -43
  30. package/dist/bin.mjs +225 -44
  31. package/dist/client/assets/{AccountSettings-CinnQaX-.js → AccountSettings-Cey-16wq.js} +1 -1
  32. package/dist/client/assets/{AiFocusSettings-UbXOywZg.js → AiFocusSettings-CaHQXDaQ.js} +1 -1
  33. package/dist/client/assets/{AnimatedHeight-DCad8EQ2.js → AnimatedHeight-BC-qaTJY.js} +1 -1
  34. package/dist/client/assets/{AppearanceSettings-CTh8Z8nz.js → AppearanceSettings-B6UaU-_a.js} +1 -1
  35. package/dist/client/assets/{BranchToolbar.logic-37EnknDD.js → BranchToolbar.logic-DILAA3Cz.js} +1 -1
  36. package/dist/client/assets/{ChatRightPanel-DUwLYKbp.js → ChatRightPanel-D-AL07IU.js} +6 -6
  37. package/dist/client/assets/{ChatThreadRouteView-C43W0PEz.js → ChatThreadRouteView-tEo-zoCf.js} +1 -1
  38. package/dist/client/assets/{CommandPaletteDialog-IHOe0hOG.js → CommandPaletteDialog-s7yf5Y2S.js} +1 -1
  39. package/dist/client/assets/{CompositeItem-ClLCuzeJ.js → CompositeItem-97y1QiiT.js} +1 -1
  40. package/dist/client/assets/{CompositeRoot-Bdsr9eHn.js → CompositeRoot-C7Mz4Y_2.js} +1 -1
  41. package/dist/client/assets/{ConnectionsSettings-tmBjGOPj.js → ConnectionsSettings-B0-Hkwof.js} +1 -1
  42. package/dist/client/assets/{DiagnosticsSettings-CbCEgaau.js → DiagnosticsSettings-DX5LH9Bt.js} +1 -1
  43. package/dist/client/assets/{DialogHandle-CitVLvYq.js → DialogHandle-Cl9dQBJp.js} +1 -1
  44. package/dist/client/assets/{DialogPopup-CfaEr9jv.js → DialogPopup-a1M74u16.js} +1 -1
  45. package/dist/client/assets/DialogRoot-C_DO1gtO.js +1 -0
  46. package/dist/client/assets/{DialogTitle-BUkU0qXf.js → DialogTitle-Bk-w3xLJ.js} +1 -1
  47. package/dist/client/assets/{DialogTrigger-CEjWue7M.js → DialogTrigger-D9nkMFu2.js} +1 -1
  48. package/dist/client/assets/{DialogViewport-Cyc_ye5w.js → DialogViewport-tgJz2Lwn.js} +1 -1
  49. package/dist/client/assets/{DraftChatThreadRouteView-BSA67nKa.js → DraftChatThreadRouteView-BU2IGTR6.js} +1 -1
  50. package/dist/client/assets/{ExternalIdentityWeb.logic-BqdBjAua.js → ExternalIdentityWeb.logic-Bn1HigS9.js} +1 -1
  51. package/dist/client/assets/{GlassSurface-B3cq28tB.js → GlassSurface-CDok2tTN.js} +1 -1
  52. package/dist/client/assets/{HostedConnectionControls-S2Wr9fiZ.js → HostedConnectionControls-Cux_sRCM.js} +1 -1
  53. package/dist/client/assets/{HostedHubRoot-DK9zP4tJ.js → HostedHubRoot-CyySCdJV.js} +1 -1
  54. package/dist/client/assets/{HostedNativeAuthorizationRoute-CKnLbCOH.js → HostedNativeAuthorizationRoute-490iDXmk.js} +1 -1
  55. package/dist/client/assets/{HostedRelayTrustNotice-CbF_SOpf.js → HostedRelayTrustNotice-CcDOAwgS.js} +1 -1
  56. package/dist/client/assets/{Icons-DZpTOLIb.js → Icons-BEtED8P8.js} +1 -1
  57. package/dist/client/assets/{IntegrationsSettingsPanel-BdBEGIyL.js → IntegrationsSettingsPanel-BFTAvxtn.js} +1 -1
  58. package/dist/client/assets/{KeybindingsSettings-Bye1H9Sx.js → KeybindingsSettings-VYgbhiZF.js} +1 -1
  59. package/dist/client/assets/{McpServersSettings-D0U0g2q7.js → McpServersSettings-DSDCjoTn.js} +1 -1
  60. package/dist/client/assets/{MobileSheet-BPvuTPR6.js → MobileSheet-BDvnUC5W.js} +1 -1
  61. package/dist/client/assets/{NewWorktreeDialog-C_xJCZWF.js → NewWorktreeDialog-C65Aifeb.js} +1 -1
  62. package/dist/client/assets/{NoActiveThreadState-Cfn_Wwnf.js → NoActiveThreadState-DehHNgAp.js} +1 -1
  63. package/dist/client/assets/{NodeSecuritySettings-DUQNZJqJ.js → NodeSecuritySettings-DW9GJ-kU.js} +1 -1
  64. package/dist/client/assets/{OpinionatedPluginsSettings-D44efcv7.js → OpinionatedPluginsSettings-DbxPOokL.js} +1 -1
  65. package/dist/client/assets/{PhoneGetAppInterstitial-CzduFI4-.js → PhoneGetAppInterstitial-CbyVrtDn.js} +1 -1
  66. package/dist/client/assets/{PhoneGetAppInterstitialBackdrop-CJ44QRCp.js → PhoneGetAppInterstitialBackdrop-BA4R225F.js} +1 -1
  67. package/dist/client/assets/{PhoneHome-BLEJm5TG.js → PhoneHome-c0j_TBEC.js} +1 -1
  68. package/dist/client/assets/{PhoneSettingsSurface-CqetLTIm.js → PhoneSettingsSurface-5LFRIx_5.js} +1 -1
  69. package/dist/client/assets/{ProjectFavicon-DrBXI2cH.js → ProjectFavicon-CeVJCQCy.js} +1 -1
  70. package/dist/client/assets/{ProviderModelPicker-CyID3P1C.js → ProviderModelPicker-MFRYAv_3.js} +1 -1
  71. package/dist/client/assets/{ProviderUpdateLaunchNotification.logic-C6VoLD-w.js → ProviderUpdateLaunchNotification.logic-CywRitn3.js} +1 -1
  72. package/dist/client/assets/{ProvidersSettingsPanel-BHmpXUIM.js → ProvidersSettingsPanel-FYBEqSr_.js} +1 -1
  73. package/dist/client/assets/{RedactedSensitiveText-CZwFEoNn.js → RedactedSensitiveText-BuWSWty8.js} +1 -1
  74. package/dist/client/assets/{RootAppShell-BVXRShhe.js → RootAppShell-5HrP6N8H.js} +2 -2
  75. package/dist/client/assets/{RycoLetterMark-C-fvI9UB.js → RycoLetterMark-CZYntY8t.js} +1 -1
  76. package/dist/client/assets/{SettingsDialog-CnETTu23.js → SettingsDialog-CpwoqGS8.js} +1 -1
  77. package/dist/client/assets/{SettingsPanels-C3HDrmQq.js → SettingsPanels-COWRB29-.js} +1 -1
  78. package/dist/client/assets/{SettingsPanels.editor-DI8Z5rsl.js → SettingsPanels.editor-lbLEbllb.js} +1 -1
  79. package/dist/client/assets/{SourceControlSettings-BG4tsvql.js → SourceControlSettings-DvBNelcO.js} +1 -1
  80. package/dist/client/assets/{StatisticsPage-dy_aYqvS.js → StatisticsPage-DxAKqvVX.js} +1 -1
  81. package/dist/client/assets/{StatisticsPanel-CeRJBu65.js → StatisticsPanel-C0xGLlMA.js} +1 -1
  82. package/dist/client/assets/{StatisticsSettingsLink-ChlwCDG0.js → StatisticsSettingsLink-B7SZerf3.js} +1 -1
  83. package/dist/client/assets/{ThreadStatusIndicators-D-ioX09X.js → ThreadStatusIndicators-CIOM98q2.js} +0 -0
  84. package/dist/client/assets/{ThreadTerminalDrawer-BvGaRxBP.js → ThreadTerminalDrawer-DRelLlEP.js} +1 -1
  85. package/dist/client/assets/{ThreadWorkspacePanel-BAWm7mGl.js → ThreadWorkspacePanel-CktVSliZ.js} +2 -2
  86. package/dist/client/assets/{ToolbarRootContext-k-_m5nCN.js → ToolbarRootContext-B1g8IP6k.js} +1 -1
  87. package/dist/client/assets/{WorkItemsTab-Q2V2EuvK.js → WorkItemsTab-CahU_t_S.js} +1 -1
  88. package/dist/client/assets/{alert-BymbRVPf.js → alert-DomE7dAt.js} +1 -1
  89. package/dist/client/assets/{alert-dialog-Gym8_p4Q.js → alert-dialog-9Jyh0e8u.js} +1 -1
  90. package/dist/client/assets/{authorization-BwQZHweJ.js → authorization-D8lJzXTE.js} +1 -1
  91. package/dist/client/assets/{badge-BQI7J3Sg.js → badge-w43sx8eF.js} +1 -1
  92. package/dist/client/assets/{branding-DqHDcyzW.js → branding-B7DcCXjn.js} +1 -1
  93. package/dist/client/assets/{button-Wf_1nfeu.js → button-DG8WqjNn.js} +1 -1
  94. package/dist/client/assets/{capabilities-BrllgEYz.js → capabilities-B1FHGoov.js} +1 -1
  95. package/dist/client/assets/{chatThreadActions-BGkJmj6T.js → chatThreadActions-BZvyhfKr.js} +1 -1
  96. package/dist/client/assets/{collapsible-GOpRckDq.js → collapsible-EhAEe5S9.js} +1 -1
  97. package/dist/client/assets/{command-Dx5YM54H.js → command-Cyn6yIEa.js} +1 -1
  98. package/dist/client/assets/{composerDraftStore-DC2r8dcu.js → composerDraftStore-TYv9j3vY.js} +2 -2
  99. package/dist/client/assets/{data-list-BSiCZBKn.js → data-list-DTdqWMGN.js} +1 -1
  100. package/dist/client/assets/{desktopUpdateAtoms-DkmoIGr0.js → desktopUpdateAtoms-CPlZiFRm.js} +1 -1
  101. package/dist/client/assets/{desktopWorkspace-Ddm531g5.js → desktopWorkspace-DEZ30LlY.js} +1 -1
  102. package/dist/client/assets/device-CHdXzvhB.js +168 -0
  103. package/dist/client/assets/{dialog-CUxw5AxI.js → dialog-BNmFD6Nh.js} +1 -1
  104. package/dist/client/assets/{draft-input-CpfrGQ1h.js → draft-input-dP7F8odz.js} +1 -1
  105. package/dist/client/assets/{editorPreferences-SOMXdQpi.js → editorPreferences-B4GvqMiF.js} +1 -1
  106. package/dist/client/assets/{empty-D420OZA9.js → empty-Ccxhyvdf.js} +1 -1
  107. package/dist/client/assets/{env-Bf33qXdb.js → env-Bcq9YR3B.js} +1 -1
  108. package/dist/client/assets/{getPseudoElementBounds-nDGTWECG.js → getPseudoElementBounds-CO5HJT7x.js} +1 -1
  109. package/dist/client/assets/{group-Cq4Llttm.js → group-CzdKmc45.js} +1 -1
  110. package/dist/client/assets/{index-BL8_ra0g.js → index-Gre6bNC8.js} +2 -2
  111. package/dist/client/assets/{input-Dl4N9ZfE.js → input-BZz4eLRl.js} +1 -1
  112. package/dist/client/assets/{kbd-CqoZVQfv.js → kbd-DbvN3zTb.js} +1 -1
  113. package/dist/client/assets/{keybindings-DQzcPjMv.js → keybindings-BPE3eEAM.js} +1 -1
  114. package/dist/client/assets/{label-x5DgpBI_.js → label-DZf4lbNF.js} +1 -1
  115. package/dist/client/assets/{lib-BXIqHSZx.js → lib-DgOYoged.js} +1 -1
  116. package/dist/client/assets/{logging-CZlHfeu2.js → logging-81iP6Hps.js} +1 -1
  117. package/dist/client/assets/main-DlGNPwsH.css +2 -0
  118. package/dist/client/assets/{main-J4YlUJad.js → main-Dz0zookE.js} +2 -2
  119. package/dist/client/assets/{menu-BuDpxm_Q.js → menu-B6UEFcn0.js} +1 -1
  120. package/dist/client/assets/{popover-DuprDUaB.js → popover-BuYzXGwl.js} +1 -1
  121. package/dist/client/assets/{primary-CJx2nSkc.js → primary-CiDY2oUi.js} +1 -1
  122. package/dist/client/assets/{projectPaths-DrelgodZ.js → projectPaths-D6fHIU1b.js} +1 -1
  123. package/dist/client/assets/{providerDriverMeta-D27Koh7Q.js → providerDriverMeta-sBwZhQoN.js} +1 -1
  124. package/dist/client/assets/{providerIconUtils-CtOHwjWL.js → providerIconUtils-DiDJeNtT.js} +1 -1
  125. package/dist/client/assets/providerInstances-vd2eZtHx.js +1 -0
  126. package/dist/client/assets/providerModels-vd2eZtHx.js +1 -0
  127. package/dist/client/assets/{qr-code-BVfzPOP3.js → qr-code-Ie92aZvE.js} +1 -1
  128. package/dist/client/assets/{radio-group-rgmJqPI7.js → radio-group-BuuTEtdC.js} +1 -1
  129. package/dist/client/assets/{resolveAriaLabelledBy-l4SuqStl.js → resolveAriaLabelledBy-0FA0k4xp.js} +1 -1
  130. package/dist/client/assets/{rightPanelRouteSearch-DmpObL1z.js → rightPanelRouteSearch-BS8CkNS6.js} +1 -1
  131. package/dist/client/assets/{runtime-DYzjhL5M.js → runtime-CPM0EUhb.js} +1 -1
  132. package/dist/client/assets/{scroll-area-DMs8l4bb.js → scroll-area-C0yF015F.js} +1 -1
  133. package/dist/client/assets/{scrollEdges-DWTOweRb.js → scrollEdges-DI5Y3mtR.js} +1 -1
  134. package/dist/client/assets/{select-Djwp8HDm.js → select-CZukJlTn.js} +1 -1
  135. package/dist/client/assets/{separator-rjtf5Q3V.js → separator-D4ckGtPe.js} +1 -1
  136. package/dist/client/assets/session-logic-BalPN1Sc.js +4 -0
  137. package/dist/client/assets/{settingsDialogStore-Dbykwvfs.js → settingsDialogStore-LxRFC5hh.js} +1 -1
  138. package/dist/client/assets/{settingsLayout-C7bl9Xi4.js → settingsLayout-CHJT5wtl.js} +1 -1
  139. package/dist/client/assets/{sheet-CQIQYfOM.js → sheet-BNfImQ-7.js} +1 -1
  140. package/dist/client/assets/{sidebar-BdDOvXe8.js → sidebar-CFGg5Tkr.js} +1 -1
  141. package/dist/client/assets/{sidebarProjectFolders-D_Me0oJ8.js → sidebarProjectFolders-bhNsO9Z_.js} +1 -1
  142. package/dist/client/assets/{sidebarStatusText-BF6odB03.js → sidebarStatusText-C8QBhZhZ.js} +1 -1
  143. package/dist/client/assets/{skeleton-Mgh4Gx9x.js → skeleton-DOgQaVXv.js} +1 -1
  144. package/dist/client/assets/{spinner-CzzUdFeE.js → spinner-ClQu8SdC.js} +1 -1
  145. package/dist/client/assets/{src-Ca7Gag3m.js → src-DmPIm3ie.js} +1 -1
  146. package/dist/client/assets/storeSelectors-Cf2WDMfx.js +1 -0
  147. package/dist/client/assets/{switch-CntUxI1A.js → switch-BZjA7VT9.js} +1 -1
  148. package/dist/client/assets/{terminal-links-CUFISn8U.js → terminal-links-CzJomeox.js} +1 -1
  149. package/dist/client/assets/{textarea-C8QxddDb.js → textarea-DHdmRD1r.js} +1 -1
  150. package/dist/client/assets/{threadPinning-BIV4KXZU.js → threadPinning-BLqwZebi.js} +1 -1
  151. package/dist/client/assets/{threadPriorityRefreshRuntime-B-pVYK_y.js → threadPriorityRefreshRuntime-BoNAlBXK.js} +1 -1
  152. package/dist/client/assets/{toast-Cw7bXJzg.js → toast-C-0Ft2jD.js} +1 -1
  153. package/dist/client/assets/{toggle-Bi9uP4Hb.js → toggle-DsnOFDbJ.js} +1 -1
  154. package/dist/client/assets/{toggle-group-LcgyMgj5.js → toggle-group-Chxh9G6t.js} +1 -1
  155. package/dist/client/assets/{tooltip-t3Nrleyq.js → tooltip-C_-9XEfA.js} +1 -1
  156. package/dist/client/assets/types-Cf2WDMfx.js +1 -0
  157. package/dist/client/assets/{uiStateStore-BW2WnK4k.js → uiStateStore-DzUrk2GS.js} +1 -1
  158. package/dist/client/assets/{useAtlassian-a-MaAd0k.js → useAtlassian-CoHKzu-e.js} +0 -0
  159. package/dist/client/assets/{useButton-DUuWgIMw.js → useButton-BmvYhoMC.js} +1 -1
  160. package/dist/client/assets/{useCompositeListItem-CL5mJqCb.js → useCompositeListItem-D0PvH4nv.js} +1 -1
  161. package/dist/client/assets/{useDebouncedValue-jDDWNjgt.js → useDebouncedValue-s0BC8Yyp.js} +1 -1
  162. package/dist/client/assets/{useFloatingRootContext-C4I8IxtL.js → useFloatingRootContext-CLCaQEJk.js} +1 -1
  163. package/dist/client/assets/{useHandleNewThread-820pBJCC.js → useHandleNewThread-Bw460iXT.js} +1 -1
  164. package/dist/client/assets/{useLabelableId-KX33mhBC.js → useLabelableId-CB_9OReR.js} +1 -1
  165. package/dist/client/assets/{useLocation-B4QlXdMt.js → useLocation-DGJMt6gP.js} +1 -1
  166. package/dist/client/assets/{useOpenInteractionType-DjM9MBY7.js → useOpenInteractionType-BSSI2GzS.js} +1 -1
  167. package/dist/client/assets/{usePhoneThreadActions-DxxWMYgC.js → usePhoneThreadActions-BIDUSWSI.js} +1 -1
  168. package/dist/client/assets/{usePopupViewport-CAMlnyaP.js → usePopupViewport-8F-J1h5f.js} +1 -1
  169. package/dist/client/assets/{useScrollLock-CAPfesBT.js → useScrollLock-CBz-5_MX.js} +1 -1
  170. package/dist/client/assets/{useStatistics-CWasDzsV.js → useStatistics-B91973jb.js} +1 -1
  171. package/dist/client/assets/{useSwipeDismiss-BZsYSBgq.js → useSwipeDismiss-D22_vuiH.js} +1 -1
  172. package/dist/client/assets/{useThreadActions-MOjDrEnS.js → useThreadActions-BCH01d6u.js} +1 -1
  173. package/dist/client/assets/{useTriggerFocusGuards-D5z439rn.js → useTriggerFocusGuards-f7afwACm.js} +1 -1
  174. package/dist/client/assets/{useValueChanged-D0CHQQwP.js → useValueChanged-EkWF0C3k.js} +1 -1
  175. package/dist/client/assets/{utils-B76_2Yk7.js → utils-CV2fJJxC.js} +1 -1
  176. package/dist/client/index.html +1 -1
  177. package/dist/{collectUint8StreamText-B9B7bGv9.cjs → collectUint8StreamText-Dsbmrw73.cjs} +2 -0
  178. package/dist/{collectUint8StreamText-RzKEq2NY.mjs → collectUint8StreamText-oFvWyN3_.mjs} +2 -0
  179. package/dist/{makeManagedServerProvider-BF1eBatf.cjs → makeManagedServerProvider-CANTNAsz.cjs} +9 -2
  180. package/dist/{makeManagedServerProvider-BuG2fLP8.mjs → makeManagedServerProvider-PLtJj7EV.mjs} +10 -3
  181. package/package.json +1 -1
  182. package/dist/client/assets/DialogRoot-CyEOjgGH.js +0 -1
  183. package/dist/client/assets/device-B0aqBYM1.js +0 -168
  184. package/dist/client/assets/main-B7T7on1T.css +0 -2
  185. package/dist/client/assets/providerInstances-BPwEwwpF.js +0 -1
  186. package/dist/client/assets/providerModels-BPwEwwpF.js +0 -1
  187. package/dist/client/assets/session-logic-DLEAZb3K.js +0 -4
  188. package/dist/client/assets/storeSelectors-D7HbqO4E.js +0 -1
  189. package/dist/client/assets/types-D7HbqO4E.js +0 -1
@@ -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-B9B7bGv9.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-BF1eBatf.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,82 +93,10 @@ 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({
@@ -145,12 +134,17 @@ const makeOpenCodeTextGeneration = effect.Effect.fn("makeOpenCodeTextGeneration"
145
134
  const client = yield* openCodeRuntime.createOpenCodeSdkClient({
146
135
  baseUrl: server.url,
147
136
  directory: input.cwd,
148
- ...openCodeSettings.serverUrl.length > 0 && openCodeSettings.serverPassword ? { serverPassword: openCodeSettings.serverPassword } : {}
137
+ ...server.serverPassword ? { serverPassword: server.serverPassword } : {}
149
138
  }).pipe(effect.Effect.mapError((cause) => new require_collectUint8StreamText.TextGenerationError({
150
139
  operation: input.operation,
151
140
  detail: require_bin.openCodeRuntimeErrorDetail(cause),
152
141
  cause
153
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
+ })));
154
148
  return yield* effect.Effect.tryPromise({
155
149
  try: async () => {
156
150
  const session = await client.session.create({
@@ -188,10 +182,14 @@ const makeOpenCodeTextGeneration = effect.Effect.fn("makeOpenCodeTextGeneration"
188
182
  })
189
183
  });
190
184
  });
191
- const rawOutput = openCodeSettings.serverUrl.length > 0 ? yield* runAgainstServer({ url: openCodeSettings.serverUrl }) : yield* effect.Effect.acquireUseRelease(acquireSharedServer({
192
- binaryPath: openCodeSettings.binaryPath,
193
- operation: input.operation
194
- }), 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)));
195
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({
196
194
  operation: input.operation,
197
195
  detail: "OpenCode returned invalid structured output.",
@@ -314,6 +312,7 @@ const makeOpenCodeTextGeneration = effect.Effect.fn("makeOpenCodeTextGeneration"
314
312
  //#endregion
315
313
  //#region src/provider/Layers/OpenCodeAdapter.ts
316
314
  const PROVIDER$1 = require_collectUint8StreamText.ProviderDriverKind.make("opencode");
315
+ const OPENCODE_RESUME_VERSION = 1;
317
316
  function nowIso() {
318
317
  return (/* @__PURE__ */ new Date()).toISOString();
319
318
  }
@@ -321,6 +320,15 @@ function nonEmptyString(value) {
321
320
  const trimmed = value?.trim();
322
321
  return trimmed && trimmed.length > 0 ? trimmed : void 0;
323
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
+ }
324
332
  function scopedOpenCodeId(sessionId, id) {
325
333
  return `${sessionId}:${id}`;
326
334
  }
@@ -333,6 +341,9 @@ function subagentKey(subagentId) {
333
341
  function statusFromOpenCodeSubagentState(status) {
334
342
  return status;
335
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
+ }
336
347
  function subagentCompletionStatus(status) {
337
348
  return status;
338
349
  }
@@ -342,6 +353,7 @@ function metadataWithEntries(entries) {
342
353
  }
343
354
  function makeSubtaskSubagentRef(part) {
344
355
  const description = nonEmptyString(part.description) ?? nonEmptyString(part.prompt);
356
+ const model = part.model ? `${part.model.providerID}/${part.model.modelID}` : void 0;
345
357
  const label = nonEmptyString(part.agent) ?? nonEmptyString(part.command) ?? (description ? "OpenCode subtask" : void 0);
346
358
  return {
347
359
  subagentId: openCodeSubagentId("subtask", part.id),
@@ -349,6 +361,7 @@ function makeSubtaskSubagentRef(part) {
349
361
  capability: "summary",
350
362
  ...label ? { label } : {},
351
363
  ...description ? { description } : {},
364
+ ...model ? { model } : {},
352
365
  parentProviderItemId: require_collectUint8StreamText.ProviderItemId.make(part.id),
353
366
  metadata: metadataWithEntries([
354
367
  ["source", "opencode.subtask"],
@@ -367,6 +380,8 @@ function mergeOpenCodeChildSessionRef(existing, session, parentSessionId) {
367
380
  capability: "transcript",
368
381
  label,
369
382
  ...existing?.description ? { description: existing.description } : {},
383
+ ...existing?.model ? { model: existing.model } : {},
384
+ ...existing?.effort ? { effort: existing.effort } : {},
370
385
  providerSessionId: session.id,
371
386
  providerThreadId: session.id,
372
387
  ...existing?.parentProviderItemId && { parentProviderItemId: existing.parentProviderItemId },
@@ -403,6 +418,13 @@ const toProcessError = (threadId, cause) => new require_bin.ProviderAdapterProce
403
418
  detail: require_bin.OpenCodeRuntimeError.is(cause) ? cause.detail : require_bin.openCodeRuntimeErrorDetail(cause),
404
419
  cause
405
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
+ }));
406
428
  const buildEventBase = (input) => effect.Effect.sync(() => crypto.randomUUID()).pipe(effect.Effect.map((uuid) => ({
407
429
  eventId: require_collectUint8StreamText.EventId.make(uuid),
408
430
  provider: PROVIDER$1,
@@ -562,7 +584,12 @@ function updateProviderSession(context, patch, options) {
562
584
  }
563
585
  const stopOpenCodeContext = effect.Effect.fn("stopOpenCodeContext")(function* (context) {
564
586
  if (yield* effect.Ref.getAndSet(context.stopped, true)) return false;
565
- 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 });
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 });
566
593
  yield* effect.Scope.close(context.sessionScope, effect.Exit.void);
567
594
  return true;
568
595
  });
@@ -677,8 +704,8 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
677
704
  return context.subagentBySubtaskPartId.get(partKey);
678
705
  };
679
706
  const registerOpenCodeChildSession = effect.Effect.fn("registerOpenCodeChildSession")(function* (context, session, raw) {
680
- if (session.parentID !== context.openCodeSessionId) return;
681
- 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);
682
709
  const known = context.childSessionIds.has(session.id);
683
710
  context.childSessionIds.add(session.id);
684
711
  context.subagentBySessionId.set(session.id, subagent);
@@ -722,6 +749,89 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
722
749
  child
723
750
  });
724
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
+ });
725
835
  const emitUnexpectedExit = effect.Effect.fn("emitUnexpectedExit")(function* (context, message) {
726
836
  if (yield* effect.Ref.getAndSet(context.stopped, true)) return;
727
837
  const turnId = context.activeTurnId;
@@ -824,8 +934,9 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
824
934
  const eventSessionId = typeof payloadSessionId === "string" ? payloadSessionId : void 0;
825
935
  const isRootSessionEvent = eventSessionId === context.openCodeSessionId;
826
936
  const isKnownChildSessionEvent = eventSessionId !== void 0 && context.childSessionIds.has(eventSessionId);
827
- const isChildSessionCreatedEvent = event.type === "session.created" && event.properties.info.parentID === context.openCodeSessionId;
828
- 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;
829
940
  const turnId = context.activeTurnId;
830
941
  yield* writeNativeEventBestEffort(context.session.threadId, {
831
942
  observedAt: nowIso(),
@@ -948,6 +1059,7 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
948
1059
  break;
949
1060
  }
950
1061
  case "permission.asked":
1062
+ if (context.resolvedRequestIds.has(event.properties.id) || context.pendingPermissions.has(event.properties.id)) break;
951
1063
  context.pendingPermissions.set(event.properties.id, event.properties);
952
1064
  yield* emitForContext(context, {
953
1065
  ...yield* buildEventBase({
@@ -965,6 +1077,7 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
965
1077
  });
966
1078
  break;
967
1079
  case "permission.replied":
1080
+ context.resolvedRequestIds.add(event.properties.requestID);
968
1081
  context.pendingPermissions.delete(event.properties.requestID);
969
1082
  yield* emitForContext(context, {
970
1083
  ...yield* buildEventBase({
@@ -981,6 +1094,7 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
981
1094
  });
982
1095
  break;
983
1096
  case "question.asked":
1097
+ if (context.resolvedRequestIds.has(event.properties.id) || context.pendingQuestions.has(event.properties.id)) break;
984
1098
  context.pendingQuestions.set(event.properties.id, event.properties);
985
1099
  yield* emitForContext(context, {
986
1100
  ...yield* buildEventBase({
@@ -994,6 +1108,7 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
994
1108
  });
995
1109
  break;
996
1110
  case "question.replied": {
1111
+ context.resolvedRequestIds.add(event.properties.requestID);
997
1112
  const request = context.pendingQuestions.get(event.properties.requestID);
998
1113
  context.pendingQuestions.delete(event.properties.requestID);
999
1114
  const answers = Object.fromEntries((request?.questions ?? []).map((question, index) => [require_bin.openCodeQuestionId(index, question), event.properties.answers[index]?.join(", ") ?? ""]));
@@ -1010,6 +1125,7 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
1010
1125
  break;
1011
1126
  }
1012
1127
  case "question.rejected":
1128
+ context.resolvedRequestIds.add(event.properties.requestID);
1013
1129
  context.pendingQuestions.delete(event.properties.requestID);
1014
1130
  yield* emitForContext(context, {
1015
1131
  ...yield* buildEventBase({
@@ -1061,7 +1177,13 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
1061
1177
  break;
1062
1178
  }
1063
1179
  if (event.properties.status.type === "idle" && turnId) {
1180
+ if (context.pendingPrompt?.turnId === turnId) {
1181
+ context.pendingPrompt.idleEvent = event;
1182
+ break;
1183
+ }
1064
1184
  context.activeTurnId = void 0;
1185
+ context.activeAgent = void 0;
1186
+ context.activeVariant = void 0;
1065
1187
  updateProviderSession(context, { status: "ready" }, { clearActiveTurnId: true });
1066
1188
  yield* emitForContext(context, {
1067
1189
  ...yield* buildEventBase({
@@ -1097,7 +1219,14 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
1097
1219
  break;
1098
1220
  }
1099
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
+ }
1100
1227
  context.activeTurnId = void 0;
1228
+ context.activeAgent = void 0;
1229
+ context.activeVariant = void 0;
1101
1230
  updateProviderSession(context, {
1102
1231
  status: "error",
1103
1232
  lastError: message
@@ -1162,6 +1291,7 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
1162
1291
  const serverUrl = openCodeSettings.serverUrl;
1163
1292
  const serverPassword = openCodeSettings.serverPassword;
1164
1293
  const directory = input.cwd ?? serverConfig.cwd;
1294
+ const resumeSessionId = input.resumePolicy === "fresh" ? void 0 : parseOpenCodeResume(input.resumeCursor)?.sessionId;
1165
1295
  const existing = sessions.get(input.threadId);
1166
1296
  if (existing) {
1167
1297
  if (existing.session.runtimeSessionId === runtimeSessionId) return existing.session;
@@ -1180,16 +1310,23 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
1180
1310
  const sessionScope = yield* effect.Scope.make();
1181
1311
  if (deviceToolBinding) yield* effect.Scope.addFinalizer(sessionScope, effect.Effect.sync(() => deviceToolBinding.dispose()));
1182
1312
  const startedExit = yield* effect.Effect.exit(effect.Effect.gen(function* () {
1183
- 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({
1184
1319
  binaryPath,
1185
1320
  serverUrl,
1321
+ ...serverPassword ? { serverPassword } : {},
1186
1322
  ...options?.environment ? { environment: options.environment } : {}
1187
1323
  });
1188
1324
  const client = yield* openCodeRuntime.createOpenCodeSdkClient({
1189
1325
  baseUrl: server.url,
1190
1326
  directory,
1191
- ...server.external && serverPassword ? { serverPassword } : {}
1327
+ ...server.serverPassword ? { serverPassword: server.serverPassword } : {}
1192
1328
  });
1329
+ yield* require_bin.verifyOpenCodeServerVersion(client);
1193
1330
  if (deviceToolBinding) yield* require_bin.runOpenCodeSdk("mcp.add", () => client.mcp.add({
1194
1331
  directory,
1195
1332
  name: `ryco_device_${runtimeSessionId}`,
@@ -1201,13 +1338,18 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
1201
1338
  enabled: true
1202
1339
  }
1203
1340
  }));
1204
- 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({
1205
1347
  title: `Ryco ${input.threadId}`,
1206
1348
  permission: require_bin.buildOpenCodePermissionRules(input.runtimeMode)
1207
1349
  }));
1208
1350
  if (!openCodeSession.data) return yield* new require_bin.OpenCodeRuntimeError({
1209
- operation: "session.create",
1210
- 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."
1211
1353
  });
1212
1354
  return {
1213
1355
  sessionScope,
@@ -1240,6 +1382,10 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
1240
1382
  cwd: directory,
1241
1383
  ...input.modelSelection ? { model: input.modelSelection.model } : {},
1242
1384
  threadId: input.threadId,
1385
+ resumeCursor: {
1386
+ schemaVersion: OPENCODE_RESUME_VERSION,
1387
+ sessionId: started.openCodeSession.id
1388
+ },
1243
1389
  createdAt,
1244
1390
  updatedAt: createdAt
1245
1391
  };
@@ -1251,6 +1397,7 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
1251
1397
  openCodeSessionId: started.openCodeSession.id,
1252
1398
  pendingPermissions: /* @__PURE__ */ new Map(),
1253
1399
  pendingQuestions: /* @__PURE__ */ new Map(),
1400
+ resolvedRequestIds: /* @__PURE__ */ new Set(),
1254
1401
  partById: /* @__PURE__ */ new Map(),
1255
1402
  emittedTextByPartId: /* @__PURE__ */ new Map(),
1256
1403
  messageRoleById: /* @__PURE__ */ new Map(),
@@ -1265,6 +1412,9 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
1265
1412
  activeTurnId: void 0,
1266
1413
  activeAgent: void 0,
1267
1414
  activeVariant: void 0,
1415
+ promptSemaphore: yield* effect.Semaphore.make(1),
1416
+ pendingPrompt: void 0,
1417
+ promptGeneration: 0,
1268
1418
  agentControlHostContextDelivered: false,
1269
1419
  stopped: yield* effect.Ref.make(false),
1270
1420
  sessionScope: started.sessionScope
@@ -1282,138 +1432,193 @@ function makeOpenCodeAdapter(openCodeSettings, options) {
1282
1432
  payload: { providerThreadId: started.openCodeSession.id }
1283
1433
  });
1284
1434
  yield* startEventPump(context);
1285
- 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));
1286
1439
  return session;
1287
1440
  });
1288
1441
  const sendTurn = effect.Effect.fn("sendTurn")(function* (input) {
1289
1442
  const context = ensureSessionContext(sessions, input.threadId);
1290
- const turnId = require_collectUint8StreamText.TurnId.make(`opencode-turn-${yield* effect.Effect.sync(() => crypto.randomUUID())}`);
1291
- const modelSelection = input.modelSelection ?? (context.session.model ? {
1292
- instanceId: boundInstanceId,
1293
- model: context.session.model
1294
- } : void 0);
1295
- if (modelSelection !== void 0 && modelSelection.instanceId !== boundInstanceId) return yield* new require_bin.ProviderAdapterValidationError({
1296
- provider: PROVIDER$1,
1297
- operation: "sendTurn",
1298
- issue: `OpenCode model selection is bound to instance '${modelSelection?.instanceId}', expected '${boundInstanceId}'.`
1299
- });
1300
- const parsedModel = require_bin.parseOpenCodeModelSlug(modelSelection?.model);
1301
- if (!parsedModel) return yield* new require_bin.ProviderAdapterValidationError({
1302
- provider: PROVIDER$1,
1303
- operation: "sendTurn",
1304
- issue: "OpenCode model selection must use the 'provider/model' format."
1305
- });
1306
- const formatted = require_sourceControlContextFormatter.formatSourceControlContextsForAgent(input.sourceControlContexts ?? []);
1307
- let text = formatted ? formatted + "\n\n" + (input.input?.trim() ?? "") : input.input?.trim();
1308
- const attachmentUrlById = /* @__PURE__ */ new Map();
1309
- const declaredAttachmentBytes = (input.attachments ?? []).reduce((total, attachment) => total + attachment.sizeBytes, 0);
1310
- if (declaredAttachmentBytes > 52428800) return yield* new require_bin.ProviderAdapterRequestError({
1311
- provider: PROVIDER$1,
1312
- method: "session.prompt",
1313
- detail: `Attachments total ${declaredAttachmentBytes} bytes; limit is ${require_collectUint8StreamText.PROVIDER_SEND_TURN_MAX_ATTACHMENT_TOTAL_BYTES} bytes.`
1314
- });
1315
- let attachmentTotalBytes = 0;
1316
- for (const attachment of input.attachments ?? []) {
1317
- const persisted = require_bin.readPersistedAttachment({
1318
- attachmentsDir: serverConfig.attachmentsDir,
1319
- attachment
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
1320
1447
  });
1321
- if (!persisted.ok) return yield* new require_bin.ProviderAdapterRequestError({
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({
1322
1454
  provider: PROVIDER$1,
1323
- method: "session.prompt",
1324
- detail: persisted.reason
1455
+ operation: "sendTurn",
1456
+ issue: `OpenCode model selection is bound to instance '${modelSelection?.instanceId}', expected '${boundInstanceId}'.`
1325
1457
  });
1326
- attachmentUrlById.set(attachment.id, `data:${attachment.mimeType};base64,${persisted.bytes.toString("base64")}`);
1327
- attachmentTotalBytes += persisted.sizeBytes;
1328
- if (attachmentTotalBytes > 52428800) return yield* new require_bin.ProviderAdapterRequestError({
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({
1329
1469
  provider: PROVIDER$1,
1330
1470
  method: "session.prompt",
1331
- detail: `Attachments total ${attachmentTotalBytes} bytes; limit is ${require_collectUint8StreamText.PROVIDER_SEND_TURN_MAX_ATTACHMENT_TOTAL_BYTES} bytes.`
1471
+ detail: `Attachments total ${declaredAttachmentBytes} bytes; limit is ${require_collectUint8StreamText.PROVIDER_SEND_TURN_MAX_ATTACHMENT_TOTAL_BYTES} bytes.`
1332
1472
  });
1333
- }
1334
- const fileParts = require_bin.toOpenCodeFileParts({
1335
- attachments: input.attachments,
1336
- resolveAttachmentUrl: (attachment) => attachmentUrlById.get(attachment.id) ?? null
1337
- });
1338
- if ((!text || text.length === 0) && fileParts.length === 0) return yield* new require_bin.ProviderAdapterValidationError({
1339
- provider: PROVIDER$1,
1340
- operation: "sendTurn",
1341
- issue: "OpenCode turns require text input or at least one attachment."
1342
- });
1343
- if (!context.agentControlHostContextDelivered) {
1344
- text = `<ryco_host_context>${require_bin.agentControlHostContext(false)}</ryco_host_context>${text ? `\n\n${text}` : ""}`;
1345
- context.agentControlHostContextDelivered = true;
1346
- }
1347
- const agent = require_bin.getModelSelectionStringOptionValue(modelSelection, "agent");
1348
- const variant = require_bin.getModelSelectionStringOptionValue(modelSelection, "variant");
1349
- context.activeTurnId = turnId;
1350
- context.activeAgent = agent ?? (input.interactionMode === "plan" || input.interactionMode === "ask" ? "plan" : void 0);
1351
- context.activeVariant = variant;
1352
- updateProviderSession(context, {
1353
- status: "running",
1354
- activeTurnId: turnId,
1355
- model: modelSelection?.model ?? context.session.model
1356
- }, { clearLastError: true });
1357
- yield* emitForContext(context, {
1358
- ...yield* buildEventBase({
1359
- threadId: input.threadId,
1360
- turnId
1361
- }),
1362
- type: "turn.started",
1363
- payload: {
1364
- model: modelSelection?.model ?? context.session.model,
1365
- ...variant ? { effort: variant } : {}
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
+ });
1366
1491
  }
1367
- });
1368
- yield* require_bin.runOpenCodeSdk("session.promptAsync", () => context.client.session.promptAsync({
1369
- sessionID: context.openCodeSessionId,
1370
- model: parsedModel,
1371
- ...context.activeAgent ? { agent: context.activeAgent } : {},
1372
- ...context.activeVariant ? { variant: context.activeVariant } : {},
1373
- parts: [...text ? [{
1374
- type: "text",
1375
- text
1376
- }] : [], ...fileParts]
1377
- })).pipe(effect.Effect.mapError(toRequestError), effect.Effect.tapError((requestError) => effect.Effect.gen(function* () {
1378
- context.activeTurnId = void 0;
1379
- context.activeAgent = void 0;
1380
- 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;
1381
1510
  updateProviderSession(context, {
1382
- status: "ready",
1383
- model: modelSelection?.model ?? context.session.model,
1384
- lastError: requestError.detail
1385
- }, { clearActiveTurnId: true });
1511
+ status: "running",
1512
+ activeTurnId: turnId,
1513
+ model: modelSelection?.model ?? context.session.model
1514
+ }, { clearLastError: true });
1386
1515
  yield* emitForContext(context, {
1387
1516
  ...yield* buildEventBase({
1388
1517
  threadId: input.threadId,
1389
1518
  turnId
1390
1519
  }),
1391
- type: "turn.aborted",
1392
- payload: { reason: requestError.detail }
1520
+ type: "turn.started",
1521
+ payload: {
1522
+ model: modelSelection?.model ?? context.session.model,
1523
+ ...variant ? { effort: variant } : {}
1524
+ }
1393
1525
  });
1394
- })));
1395
- return {
1396
- threadId: input.threadId,
1397
- turnId
1398
- };
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
+ }));
1399
1586
  });
1400
1587
  const interruptTurn = effect.Effect.fn("interruptTurn")(function* (threadId, turnId) {
1401
1588
  const context = ensureSessionContext(sessions, threadId);
1402
- const rootAbortExit = yield* require_bin.runOpenCodeSdk("session.abort", () => context.client.session.abort({ sessionID: context.openCodeSessionId })).pipe(effect.Effect.mapError(toRequestError), effect.Effect.exit);
1403
- yield* effect.Effect.forEach(context.childSessionIds, (sessionID) => require_bin.runOpenCodeSdk("session.abort", () => context.client.session.abort({ sessionID })).pipe(effect.Effect.ignore({ log: true })), { discard: true });
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 });
1404
1598
  yield* emitStoppedOpenCodeChildren(context, {
1405
1599
  method: "session.abort",
1406
1600
  reason: "turn-interrupted"
1407
1601
  });
1408
1602
  if (effect.Exit.isFailure(rootAbortExit)) return yield* effect.Effect.failCause(rootAbortExit.cause);
1409
- if (turnId ?? context.activeTurnId) yield* emitForContext(context, {
1410
- ...yield* buildEventBase({
1411
- threadId,
1412
- turnId: turnId ?? context.activeTurnId
1413
- }),
1414
- type: "turn.aborted",
1415
- payload: { reason: "Interrupted by user." }
1416
- });
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
+ }
1417
1622
  });
1418
1623
  const respondToRequest = effect.Effect.fn("respondToRequest")(function* (threadId, requestId, decision) {
1419
1624
  const context = ensureSessionContext(sessions, threadId);
@@ -1522,7 +1727,6 @@ const OPENCODE_PRESENTATION = {
1522
1727
  displayName: "OpenCode",
1523
1728
  showInteractionModeToggle: false
1524
1729
  };
1525
- const MINIMUM_OPENCODE_VERSION = "1.14.19";
1526
1730
  var OpenCodeProbeError = class extends effect.Data.TaggedError("OpenCodeProbeError") {};
1527
1731
  function normalizeProbeMessage(message) {
1528
1732
  const trimmed = message.trim();
@@ -1737,8 +1941,8 @@ const checkOpenCodeProviderStatus = effect.Effect.fn("checkOpenCodeProviderStatu
1737
1941
  }))));
1738
1942
  if (versionExit._tag === "Failure") return fallback(effect.Cause.squash(versionExit.cause));
1739
1943
  version = require_bin.parseGenericCliVersion(versionExit.value.stdout) ?? null;
1740
- 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);
1741
- 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({
1742
1946
  presentation: OPENCODE_PRESENTATION,
1743
1947
  enabled: openCodeSettings.enabled,
1744
1948
  checkedAt,
@@ -1748,7 +1952,7 @@ const checkOpenCodeProviderStatus = effect.Effect.fn("checkOpenCodeProviderStatu
1748
1952
  version,
1749
1953
  status: "error",
1750
1954
  auth: { status: "unknown" },
1751
- 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.`
1752
1956
  }
1753
1957
  });
1754
1958
  }
@@ -1756,6 +1960,7 @@ const checkOpenCodeProviderStatus = effect.Effect.fn("checkOpenCodeProviderStatu
1756
1960
  const server = yield* openCodeRuntime.connectToOpenCodeServer({
1757
1961
  binaryPath: openCodeSettings.binaryPath,
1758
1962
  serverUrl: openCodeSettings.serverUrl,
1963
+ ...openCodeSettings.serverPassword ? { serverPassword: openCodeSettings.serverPassword } : {},
1759
1964
  environment
1760
1965
  }).pipe(effect.Effect.mapError((cause) => new OpenCodeProbeError({
1761
1966
  cause,
@@ -1764,19 +1969,27 @@ const checkOpenCodeProviderStatus = effect.Effect.fn("checkOpenCodeProviderStatu
1764
1969
  const client = yield* openCodeRuntime.createOpenCodeSdkClient({
1765
1970
  baseUrl: server.url,
1766
1971
  directory: cwd,
1767
- ...isExternalServer && openCodeSettings.serverPassword ? { serverPassword: openCodeSettings.serverPassword } : {}
1972
+ ...server.serverPassword ? { serverPassword: server.serverPassword } : {}
1768
1973
  }).pipe(effect.Effect.mapError((cause) => new OpenCodeProbeError({
1769
1974
  cause,
1770
1975
  detail: require_bin.openCodeRuntimeErrorDetail(cause)
1771
1976
  })));
1772
- 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({
1773
1978
  cause,
1774
1979
  detail: require_bin.openCodeRuntimeErrorDetail(cause)
1775
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
+ };
1776
1988
  })));
1777
1989
  if (inventoryExit._tag === "Failure") return fallback(effect.Cause.squash(inventoryExit.cause), version);
1778
- const models = require_bin.providerModelsFromSettings(flattenOpenCodeModels(inventoryExit.value), PROVIDER, customModels, DEFAULT_OPENCODE_MODEL_CAPABILITIES);
1779
- const connectedCount = new Set(inventoryExit.value.providerList.connected).size;
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;
1780
1993
  return require_bin.buildServerProvider({
1781
1994
  presentation: OPENCODE_PRESENTATION,
1782
1995
  enabled: true,
@@ -1805,8 +2018,7 @@ const checkOpenCodeProviderStatus = effect.Effect.fn("checkOpenCodeProviderStatu
1805
2018
  *
1806
2019
  * Two instances with different `serverUrl`s therefore talk to independent
1807
2020
  * OpenCode servers; when no `serverUrl` is set, the adapter + text-generation
1808
- * shares spin up their own scoped child processes, and those child
1809
- * processes are released when the registry scope closes.
2021
+ * shares reuse one scoped child process owned by the provider instance.
1810
2022
  *
1811
2023
  * @module provider/Drivers/OpenCodeDriver
1812
2024
  */
@@ -1867,12 +2079,14 @@ const OpenCodeDriver = {
1867
2079
  binaryPath: effectiveConfig.binaryPath,
1868
2080
  env: processEnv
1869
2081
  });
2082
+ const serverOwner = effectiveConfig.serverUrl.trim().length === 0 ? yield* makeOpenCodeServerOwner(effectiveConfig, processEnv) : void 0;
1870
2083
  const adapter = yield* makeOpenCodeAdapter(effectiveConfig, {
1871
2084
  instanceId,
1872
2085
  environment: processEnv,
2086
+ ...serverOwner ? { serverOwner } : {},
1873
2087
  ...eventLoggers.native ? { nativeEventLogger: eventLoggers.native } : {}
1874
2088
  });
1875
- const textGeneration = yield* makeOpenCodeTextGeneration(effectiveConfig, processEnv);
2089
+ const textGeneration = yield* makeOpenCodeTextGeneration(effectiveConfig, processEnv, serverOwner ? { serverOwner } : void 0);
1876
2090
  const checkProvider = checkOpenCodeProviderStatus(effectiveConfig, serverConfig.cwd, processEnv).pipe(effect.Effect.map(stampIdentity), effect.Effect.provideService(require_bin.OpenCodeRuntime, openCodeRuntime));
1877
2091
  const snapshot = yield* require_makeManagedServerProvider.makeManagedServerProvider({
1878
2092
  maintenanceCapabilities,
@@ -1882,6 +2096,7 @@ const OpenCodeDriver = {
1882
2096
  initialSnapshot: (settings) => stampIdentity(makePendingOpenCodeProvider(settings)),
1883
2097
  checkProvider,
1884
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,
1885
2100
  refreshInterval: null
1886
2101
  }).pipe(effect.Effect.mapError((cause) => new require_bin.ProviderDriverError({
1887
2102
  driver: DRIVER_KIND,