ryco-cli 0.1.30 → 0.1.31

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 (493) hide show
  1. package/dist/{AcpAdapter-DjP0IHpH.cjs → AcpAdapter-ByUp9-wk.cjs} +71 -51
  2. package/dist/{AcpAdapter-CKWzfB3Q.mjs → AcpAdapter-CY_ANTKu.mjs} +73 -53
  3. package/dist/{AcpNativeLogging-Do0LktDb.mjs → AcpNativeLogging-C7PC6imv.mjs} +30 -4
  4. package/dist/{AcpNativeLogging-5gTPK9Fq.cjs → AcpNativeLogging-OQeAya9d.cjs} +33 -1
  5. package/dist/{AcpRegistryDriver-BblCFfev.cjs → AcpRegistryDriver-CD9GN7rI.cjs} +3 -3
  6. package/dist/{AcpRegistryDriver-BzohT-PC.mjs → AcpRegistryDriver-DMZ5VBWJ.mjs} +4 -4
  7. package/dist/AzureDevOpsSourceControlProvider-5giVYoNi.mjs +2053 -0
  8. package/dist/AzureDevOpsSourceControlProvider-BKMXEUaN.cjs +2055 -0
  9. package/dist/{BitbucketSourceControlProvider-D5UVAc9z.mjs → BitbucketSourceControlProvider-BVUBsEUF.mjs} +63 -23
  10. package/dist/{BitbucketSourceControlProvider-Bvl_q1o2.cjs → BitbucketSourceControlProvider-BWnnrbch.cjs} +62 -22
  11. package/dist/{BunPTY-Dcl1Lp62.mjs → BunPTY-CMbDQ1Xb.mjs} +1 -1
  12. package/dist/{ClaudeDriver-DZkz0QPr.cjs → ClaudeDriver-DCrqouOR.cjs} +1373 -191
  13. package/dist/{ClaudeDriver-BuQ_azDw.mjs → ClaudeDriver-DVOss8cC.mjs} +1375 -193
  14. package/dist/{CodexDriver-6Ph2cjAW.cjs → CodexDriver-CBQPHJqU.cjs} +258 -28
  15. package/dist/{CodexDriver-Bi49RIL4.mjs → CodexDriver-DJoTky7Z.mjs} +261 -31
  16. package/dist/{CodexTextGeneration-C5TIspJA.mjs → CodexTextGeneration-BSgNgfZv.mjs} +6 -6
  17. package/dist/{CodexTextGeneration-sXPR9eld.cjs → CodexTextGeneration-C9MDQmZm.cjs} +7 -7
  18. package/dist/{CopilotDriver-Bcdpz6U_.mjs → CopilotDriver-CUkdPXcH.mjs} +78 -20
  19. package/dist/{CopilotDriver-D6P0xgRX.cjs → CopilotDriver-DbaMDH16.cjs} +76 -18
  20. package/dist/{CursorDriver-CRnDGwEv.mjs → CursorDriver-B-ZilXJB.mjs} +114 -97
  21. package/dist/{CursorDriver-DMJ7sGSx.cjs → CursorDriver-DKQqPbKH.cjs} +114 -97
  22. package/dist/{ForgejoSourceControlProvider-D4jGdaJX.cjs → ForgejoSourceControlProvider-CgpjFECj.cjs} +94 -60
  23. package/dist/{ForgejoSourceControlProvider-Dl_Fk3RY.mjs → ForgejoSourceControlProvider-DemMYUye.mjs} +95 -61
  24. package/dist/{GitHubSourceControlProvider-QMe-zymI.cjs → GitHubSourceControlProvider-C4un6hOK.cjs} +218 -119
  25. package/dist/{GitHubSourceControlProvider-DnwKf0ap.mjs → GitHubSourceControlProvider-CRSDYcjc.mjs} +206 -108
  26. package/dist/GitLabSourceControlProvider-D8W1ZLPh.cjs +2260 -0
  27. package/dist/GitLabSourceControlProvider-DpWkJ0M3.mjs +2258 -0
  28. package/dist/{GrokDriver-jy8JIvYY.cjs → GrokDriver-BQ6G_7ZZ.cjs} +6 -7
  29. package/dist/{GrokDriver-Bvq1jP3S.mjs → GrokDriver-Buvas9-q.mjs} +5 -6
  30. package/dist/{Metrics-CnmjpbWk.mjs → Metrics-C3vLS9rz.mjs} +123 -13
  31. package/dist/{Metrics-C0LSU8s7.cjs → Metrics-DjRPLE98.cjs} +170 -12
  32. package/dist/{NodePTY-D7tFWuQe.mjs → NodePTY-DgnuBruq.mjs} +1 -1
  33. package/dist/{OpenCodeDriver-DhyVaBMT.mjs → OpenCodeDriver-BWEZD841.mjs} +183 -49
  34. package/dist/{OpenCodeDriver-Bu5D19tl.cjs → OpenCodeDriver-qUiX0RLH.cjs} +183 -49
  35. package/dist/{SideQuestionIsolation-B-aE6aBz.mjs → SideQuestionIsolation-B1T-DsR0.mjs} +1 -1
  36. package/dist/{SideQuestionIsolation-CtJ4wX83.cjs → SideQuestionIsolation-BPC-Bxsz.cjs} +1 -1
  37. package/dist/bin.cjs +37021 -10253
  38. package/dist/bin.mjs +36892 -10178
  39. package/dist/client/assets/AccountSettings-B88Q_w9Y.js +1 -0
  40. package/dist/client/assets/AiFocusSettings-Bb0TrCPn.js +1 -0
  41. package/dist/client/assets/{AnimatedHeight-UXn4-nUd.js → AnimatedHeight-epXOsgdm.js} +1 -1
  42. package/dist/client/assets/AppearanceSettings-XS9WRVPU.js +1 -0
  43. package/dist/client/assets/AutomationsDialog-bZckh4Y3.js +1 -0
  44. package/dist/client/assets/AutomationsSummary-wPFZCF49.js +1 -0
  45. package/dist/client/assets/BranchToolbar.logic-DjzLKbbB.js +3 -0
  46. package/dist/client/assets/BrowserPanel-CdBLnnfz.js +1 -0
  47. package/dist/client/assets/ChatRightPanel-BCINd0vP.js +34 -0
  48. package/dist/client/assets/ChatThreadRouteView-BFZ0Si-l.js +1 -0
  49. package/dist/client/assets/ColorSwatchPicker-CGyo99o0.js +1 -0
  50. package/dist/client/assets/CommandPalette.logic-BIOMtnEQ.js +1 -0
  51. package/dist/client/assets/CommandPaletteDialog-Db4LH--z.js +2 -0
  52. package/dist/client/assets/CompositeRoot-DtnwMJKj.js +1 -0
  53. package/dist/client/assets/ComputerUseSettings-CkqCqDsU.js +1 -0
  54. package/dist/client/assets/ConnectionsSettings-B9mxExdG.js +7 -0
  55. package/dist/client/assets/CreatePullRequestDialog-CJ7pNCue.js +1 -0
  56. package/dist/client/assets/CreatePullRequestDialogHost-n4ZjdSr4.js +1 -0
  57. package/dist/client/assets/DiagnosticsSettings-f9rFG9re.js +2 -0
  58. package/dist/client/assets/DiagnosticsSettings.logic-Byf-Bu4S.js +1 -0
  59. package/dist/client/assets/DialogHandle-C0c_rK3I.js +1 -0
  60. package/dist/client/assets/{DialogPopup-NfwDyR5c.js → DialogPopup-BKW1PEEa.js} +1 -1
  61. package/dist/client/assets/DialogRoot-BIubqrv0.js +1 -0
  62. package/dist/client/assets/DialogTitle-BAX_FLoG.js +1 -0
  63. package/dist/client/assets/{DialogViewport-B6w_ROOE.js → DialogViewport-C2iOUx0O.js} +1 -1
  64. package/dist/client/assets/DiffPanel-BkqDt_SS.js +25 -0
  65. package/dist/client/assets/DisclosureRegion-B8556yU0.js +1 -0
  66. package/dist/client/assets/DraftChatThreadRouteView-BKgRKJ2w.js +1 -0
  67. package/dist/client/assets/{ExternalIdentityWeb.logic-BlKX8J9h.js → ExternalIdentityWeb.logic-Cu6suNrN.js} +1 -1
  68. package/dist/client/assets/GlassSurface-DLYYzRdP.js +1 -0
  69. package/dist/client/assets/HostedConnectionControls-CoVqtnrK.js +1 -0
  70. package/dist/client/assets/HostedHubRoot-CM2CwPUr.js +2 -0
  71. package/dist/client/assets/{HostedNativeAuthorizationRoute-j7oSlakZ.js → HostedNativeAuthorizationRoute-Bizmqrh_.js} +2 -2
  72. package/dist/client/assets/HostedNodeRenameDialog-SXWMsTO0.js +1 -0
  73. package/dist/client/assets/HostedRelayTrustNotice-BfTyrBi5.js +1 -0
  74. package/dist/client/assets/InboxStatusGlyph-BPTqzp7l.js +1 -0
  75. package/dist/client/assets/IntegrationsSettingsPanel-DAPvkV4i.js +1 -0
  76. package/dist/client/assets/KeybindingsSettings-B8g-YI2O.js +1 -0
  77. package/dist/client/assets/LazyBrowserPanel-Ds9cdOC_.js +2 -0
  78. package/dist/client/assets/McpServersSettings-Dw6G3ff3.js +6 -0
  79. package/dist/client/assets/MobileSheet-DfgXNWbd.js +1 -0
  80. package/dist/client/assets/ModelTuningDial-DQBAbuNL.js +1 -0
  81. package/dist/client/assets/NewWorktreeDialog-CDZAJmK6.js +4 -0
  82. package/dist/client/assets/NodeSecuritySettings-3MELA9ru.js +1 -0
  83. package/dist/client/assets/NullStore-gT_6_xZE.js +1 -0
  84. package/dist/client/assets/OnboardingDialog-CAAtNnJf.js +1 -0
  85. package/dist/client/assets/OpinionatedPluginsSettings-AiDB0Vl4.js +1 -0
  86. package/dist/client/assets/{PdfAttachmentPreview-C8-hT8KQ.js → PdfAttachmentPreview-BFNW2wjN.js} +2 -2
  87. package/dist/client/assets/{PhoneGetAppInterstitial-Zh0zpBgT.js → PhoneGetAppInterstitial-D8fwZ8E9.js} +1 -1
  88. package/dist/client/assets/PhoneHome-YHgHljA0.js +1 -0
  89. package/dist/client/assets/PhoneSettingsSurface-BVxJppvK.js +2 -0
  90. package/dist/client/assets/PreviewPanel-BYcEnkv9.js +643 -0
  91. package/dist/client/assets/ProjectScriptDialog-K34K2Kzm.js +1 -0
  92. package/dist/client/assets/ProjectsPage-DXnMYLjb.js +1 -0
  93. package/dist/client/assets/PromoteChatDialog-CAY7_wJ-.js +1 -0
  94. package/dist/client/assets/ProviderLimitWindow-CK04BSkM.js +1 -0
  95. package/dist/client/assets/ProviderUpdateLaunchNotification.logic-BMBrDDOC.js +1 -0
  96. package/dist/client/assets/ProvidersSettingsPanel-C85PX9Es.js +1 -0
  97. package/dist/client/assets/PullRequestsPage-C0rgfGwB.js +1 -0
  98. package/dist/client/assets/{QuitShortcutFeedback-Qs9XsuZ4.js → QuitShortcutFeedback-DSkKqETs.js} +1 -1
  99. package/dist/client/assets/RedactedSensitiveText-DQ0YveQd.js +1 -0
  100. package/dist/client/assets/RollingText-BzvpP5fa.js +1 -0
  101. package/dist/client/assets/RootAppShell-BYQ-eGNT.js +6 -0
  102. package/dist/client/assets/{Separator-B6Esv57Y.js → Separator-DpiW19Vw.js} +1 -1
  103. package/dist/client/assets/SettingsPage-BCFN7Ju2.js +2 -0
  104. package/dist/client/assets/SettingsPanels-CP6z2b1x.js +3 -0
  105. package/dist/client/assets/SettingsPanels.editor-D8U-TWWG.js +1 -0
  106. package/dist/client/assets/SettingsSelect-DEhNaz3E.js +1 -0
  107. package/dist/client/assets/Sidebar.logic-D_ODfSpl.js +1 -0
  108. package/dist/client/assets/SimulatorPanel-DCT6fZ0X.js +1 -0
  109. package/dist/client/assets/SourceControlSettings-DxUtvPMK.js +1 -0
  110. package/dist/client/assets/StatisticsPage-C9SrwtM4.js +1 -0
  111. package/dist/client/assets/StatisticsPanel-BMYLETs0.js +1 -0
  112. package/dist/client/assets/ThreadLinkList-BN5z5EpS.js +169 -0
  113. package/dist/client/assets/ThreadTerminalDrawer-CgIFOlR-.js +18 -0
  114. package/dist/client/assets/ThreadWorkspacePanel-DvXoqQPF.js +3 -0
  115. package/dist/client/assets/ToolbarRootContext-8FsV9Cpj.js +1 -0
  116. package/dist/client/assets/TraitsPicker-DcrpJahy.js +1 -0
  117. package/dist/client/assets/Virtualizer-CwXeUPla.js +1345 -0
  118. package/dist/client/assets/WorkspacePullRequestPanel-3mlcJn9G.js +1 -0
  119. package/dist/client/assets/WorkspaceReview-UGbCgXeK.js +2 -0
  120. package/dist/client/assets/{abnfDiagram-N423BO3Z-ByEe3mC0.js → abnfDiagram-N423BO3Z-DVEM6Scc.js} +1 -1
  121. package/dist/client/assets/{activity-CwTUF6lv.js → activity-DVCuAejY.js} +1 -1
  122. package/dist/client/assets/{alert-DQEkrtUJ.js → alert-FV7ZIit_.js} +1 -1
  123. package/dist/client/assets/alert-dialog-CgXR9tED.js +1 -0
  124. package/dist/client/assets/app-window-3xtwqZgI.js +1 -0
  125. package/dist/client/assets/appChrome-COCz-T7w.js +1 -0
  126. package/dist/client/assets/{appearancePreferences-nFx4MHoI.js → appearancePreferences-NnsvXwBe.js} +1 -1
  127. package/dist/client/assets/architecture-7GRP2DOG-DXXb_0_g.js +1 -0
  128. package/dist/client/assets/{architectureDiagram-T3A2C74G-Bd-yxaTr.js → architectureDiagram-T3A2C74G-B6pcKiCj.js} +1 -1
  129. package/dist/client/assets/{arrow-left-DUOpzEbP.js → arrow-left-Blu3LSE2.js} +1 -1
  130. package/dist/client/assets/{arrow-right-HOYJnPKw.js → arrow-right-CO3CH0ne.js} +1 -1
  131. package/dist/client/assets/arrow-up-B69gV2Bq.js +1 -0
  132. package/dist/client/assets/{arrow-up-right-DHnMKuVA.js → arrow-up-right-BbPGFOLA.js} +1 -1
  133. package/dist/client/assets/authorization-Ob6YwWiI.js +1 -0
  134. package/dist/client/assets/autocomplete-RVpjsrDv.js +1 -0
  135. package/dist/client/assets/ban-BIm2PVkE.js +1 -0
  136. package/dist/client/assets/{blockDiagram-VBNYF7ZC-CPDBonMC.js → blockDiagram-VBNYF7ZC-WNerGp9V.js} +1 -1
  137. package/dist/client/assets/{bot-DxjPA7Bw.js → bot-C9nWtaWq.js} +1 -1
  138. package/dist/client/assets/browserState-jt47YsqD.js +1 -0
  139. package/dist/client/assets/{c4Diagram-5PPSVZJV-BM6pAiqT.js → c4Diagram-5PPSVZJV-wp1ioOoM.js} +1 -1
  140. package/dist/client/assets/camera-C13VoW3c.js +1 -0
  141. package/dist/client/assets/capabilities-CfOhq009.js +1 -0
  142. package/dist/client/assets/channel-56r2qL2v.js +1 -0
  143. package/dist/client/assets/{chart-column-Cg7d41tb.js → chart-column-DRv0YtL_.js} +1 -1
  144. package/dist/client/assets/checkbox-CIIIY9FA.js +1 -0
  145. package/dist/client/assets/checks-Dw022Bvy.js +1 -0
  146. package/dist/client/assets/{chunk-2GRJ4B5K-DVKozJ41.js → chunk-2GRJ4B5K-DRl3ILpc.js} +1 -1
  147. package/dist/client/assets/{chunk-4I5QYGJK-BRoMwPkW.js → chunk-4I5QYGJK-CYTRl4bo.js} +1 -1
  148. package/dist/client/assets/{chunk-5RXB4S5H-DFMKyoqP.js → chunk-5RXB4S5H-VCNwRsOa.js} +1 -1
  149. package/dist/client/assets/{chunk-6Q2QTUOP-Ba6UENe9.js → chunk-6Q2QTUOP-DnSeKGPG.js} +1 -1
  150. package/dist/client/assets/{chunk-7Z6QIM7H-B87gYLWH.js → chunk-7Z6QIM7H-Cjilh9TF.js} +1 -1
  151. package/dist/client/assets/{chunk-GF5L2VYU-DZ840GRQ.js → chunk-GF5L2VYU-CGR7AW0t.js} +1 -1
  152. package/dist/client/assets/{chunk-I66GZJ75-BO6p4Aqg.js → chunk-I66GZJ75-CXSn8dDu.js} +1 -1
  153. package/dist/client/assets/{chunk-JQJVKLGR-5dTfVinz.js → chunk-JQJVKLGR-Dro-75lU.js} +1 -1
  154. package/dist/client/assets/{chunk-KBJHAD2P-BeWfBZdP.js → chunk-KBJHAD2P-BDqN2kVf.js} +1 -1
  155. package/dist/client/assets/{chunk-NSK5VX7P-DuRkdn5k.js → chunk-NSK5VX7P-DGo5UczH.js} +1 -1
  156. package/dist/client/assets/{chunk-QR6OTTB3-Duz4Y_uE.js → chunk-QR6OTTB3-RWuyWnBI.js} +1 -1
  157. package/dist/client/assets/{chunk-UBXNYLIW-D-z8URgN.js → chunk-UBXNYLIW-BPRzeB0w.js} +1 -1
  158. package/dist/client/assets/{chunk-W5SLKNZC-AGjFjjoJ.js → chunk-W5SLKNZC-DYWocTFi.js} +1 -1
  159. package/dist/client/assets/{chunk-WRU74C26-BgY3UiXB.js → chunk-WRU74C26-ChbB1jY3.js} +1 -1
  160. package/dist/client/assets/circle-stop-D8B4hRpY.js +1 -0
  161. package/dist/client/assets/circle-x-CNLfrTqR.js +1 -0
  162. package/dist/client/assets/classDiagram-JCYQIIEL-DGvmFev3.js +1 -0
  163. package/dist/client/assets/classDiagram-v2-OCEON4UE-DGvmFev3.js +1 -0
  164. package/dist/client/assets/{clipboard-copy-BWf3JuTE.js → clipboard-copy-DGi8FKNO.js} +1 -1
  165. package/dist/client/assets/clock-3-DmJ4_XPI.js +1 -0
  166. package/dist/client/assets/clock-DZIuPtNG.js +1 -0
  167. package/dist/client/assets/color-picker-BdBXje-a.js +1 -0
  168. package/dist/client/assets/columns-2-CWlMOClK.js +1 -0
  169. package/dist/client/assets/combobox-Dtjtf7AB.js +1 -0
  170. package/dist/client/assets/{cynefin-OW5HDTMX-BuOAGqlK.js → cynefin-OW5HDTMX-TuShvMuM.js} +1 -1
  171. package/dist/client/assets/{cynefinDiagram-MW4NZA55-DqV0Aokp.js → cynefinDiagram-MW4NZA55-B0Edt2Em.js} +1 -1
  172. package/dist/client/assets/{dagre-VZM6K2ZE-D_GFquDW.js → dagre-VZM6K2ZE-D-eiuqHx.js} +1 -1
  173. package/dist/client/assets/{data-list-BJCq3CVP.js → data-list-BAx6jBY1.js} +1 -1
  174. package/dist/client/assets/desktopUpdateAtoms-BjrLa3tl.js +1 -0
  175. package/dist/client/assets/desktopWorkspace-C2wXVBhc.js +1 -0
  176. package/dist/client/assets/{deviceName-C2N8ZRX3.js → deviceName-B4youG0v.js} +1 -1
  177. package/dist/client/assets/{diagram-7IWD3JNH-B1wlsNg2.js → diagram-7IWD3JNH-DgM6lMlR.js} +1 -1
  178. package/dist/client/assets/{diagram-B4RE2ZJO-D-CYoym7.js → diagram-B4RE2ZJO-CyHNDjzV.js} +1 -1
  179. package/dist/client/assets/{diagram-LBJQPF4R-DqJ9NCqt.js → diagram-LBJQPF4R-DDzuLIN5.js} +1 -1
  180. package/dist/client/assets/{diagram-Q27KOJAE-3yp1D2u4.js → diagram-Q27KOJAE-BaBvK9QB.js} +1 -1
  181. package/dist/client/assets/{diagram-UB23O5K3-Byp25nGC.js → diagram-UB23O5K3-CzZ2ewuZ.js} +1 -1
  182. package/dist/client/assets/dialogWords-Cg0YkJVg.js +1 -0
  183. package/dist/client/assets/diffRouteSearch-D2MKN_ah.js +1 -0
  184. package/dist/client/assets/disclosureMotion-cbMJn5-z.js +1 -0
  185. package/dist/client/assets/{download-DsYNYJeu.js → download-TvtXS4hE.js} +1 -1
  186. package/dist/client/assets/{ebnfDiagram-BXEA7PRR-B_IM1l6o.js → ebnfDiagram-BXEA7PRR-CL1vdOKi.js} +1 -1
  187. package/dist/client/assets/editorPreferences-DqKyA-2Z.js +1 -0
  188. package/dist/client/assets/ellipsis-CDK1dNFZ.js +1 -0
  189. package/dist/client/assets/ellipsis-vertical-CwzEUTwV.js +1 -0
  190. package/dist/client/assets/{empty-BbJHvskr.js → empty-BovKoxbn.js} +1 -1
  191. package/dist/client/assets/{erDiagram-JOGREHBK--OtcrCRJ.js → erDiagram-JOGREHBK-DmQR2if6.js} +1 -1
  192. package/dist/client/assets/eventmodeling-NTZA5JFV-D272GIcY.js +1 -0
  193. package/dist/client/assets/external-link-CJeVJZ7s.js +1 -0
  194. package/dist/client/assets/eye-BUmrXqzg.js +1 -0
  195. package/dist/client/assets/file-diff-BWc3mYsz.js +1 -0
  196. package/dist/client/assets/flowDiagram-UKHOOZJN-DLyS38Mm.js +1 -0
  197. package/dist/client/assets/folder-git-2-CPxg5wKP.js +1 -0
  198. package/dist/client/assets/folder-open-DcMymvp1.js +1 -0
  199. package/dist/client/assets/formatCount-B4KLI651.js +1 -0
  200. package/dist/client/assets/{ganttDiagram-PKOTCBZU-w0seBi3Q.js → ganttDiagram-PKOTCBZU-1q2nUL92.js} +1 -1
  201. package/dist/client/assets/git-pull-request-BFPwpm3c.js +1 -0
  202. package/dist/client/assets/{gitGraph-4MIJSDKK-BOJ0lcSW.js → gitGraph-4MIJSDKK-COtwmv2S.js} +1 -1
  203. package/dist/client/assets/{gitGraphDiagram-DS77QQ5N-BMfOCCYn.js → gitGraphDiagram-DS77QQ5N-ChsvaxX4.js} +1 -1
  204. package/dist/client/assets/{group-tVMKGp7Q.js → group-DWWn0dTx.js} +1 -1
  205. package/dist/client/assets/hammer-BXo-EU88.js +1 -0
  206. package/dist/client/assets/hostedConnectionCoordinator-BkAE-RhA.js +1 -0
  207. package/dist/client/assets/{index-BqZvnGNr.js → index-DARIYokI.js} +2 -2
  208. package/dist/client/assets/{info-A6RAGUB7-acjBTQ5o.js → info-A6RAGUB7-CI2qZ9wW.js} +1 -1
  209. package/dist/client/assets/{infoDiagram-6WML65LV-DB01Nc2m.js → infoDiagram-6WML65LV-BPmgcTPH.js} +1 -1
  210. package/dist/client/assets/{input-BDWSVClC.js → input-CCie4mm1.js} +1 -1
  211. package/dist/client/assets/{ishikawaDiagram-WSZJBQD7-KhZTvm-J.js → ishikawaDiagram-WSZJBQD7-LyS9p3Yg.js} +1 -1
  212. package/dist/client/assets/{journeyDiagram-NVQOT4AX-C3JCYk-2.js → journeyDiagram-NVQOT4AX-BYaAmN65.js} +1 -1
  213. package/dist/client/assets/{kanban-definition-27J2QSJJ-Dbo0C1s6.js → kanban-definition-27J2QSJJ-D-pwzqFt.js} +1 -1
  214. package/dist/client/assets/{key-round-CETZqe3h.js → key-round-BlrUTfxB.js} +1 -1
  215. package/dist/client/assets/keyboard-DlBdq6sz.js +1 -0
  216. package/dist/client/assets/label-ChtVI9lp.js +1 -0
  217. package/dist/client/assets/layers-BB-ruGvd.js +1 -0
  218. package/dist/client/assets/lifecycleSuggestionPolicy-0ERe_O53.js +1 -0
  219. package/dist/client/assets/list-checks-BkM_ZRsj.js +1 -0
  220. package/dist/client/assets/loader-3vQnfqIT.js +1 -0
  221. package/dist/client/assets/{log-out-D5-aSBAz.js → log-out-CKq9YiLY.js} +1 -1
  222. package/dist/client/assets/{logging-B_qXVrk6.js → logging-CCg76rgn.js} +1 -1
  223. package/dist/client/assets/main-Ch0bwS-M.js +9 -0
  224. package/dist/client/assets/main-Di0isH9D.css +2 -0
  225. package/dist/client/assets/{mermaid-parser.core-B6Q-3x_q.js → mermaid-parser.core-RK9ah5RM.js} +2 -2
  226. package/dist/client/assets/{mermaidEngine-DksLcesB.js → mermaidEngine-Dr8UsPhH.js} +3 -3
  227. package/dist/client/assets/message-circle-dashed-BrjwqS7-.js +1 -0
  228. package/dist/client/assets/messageQueueDrain-B7R7Qmq6.js +1 -0
  229. package/dist/client/assets/messages-square-cDTkDJv_.js +1 -0
  230. package/dist/client/assets/{mindmap-definition-FAOFIHXS-LaMzRxqw.js → mindmap-definition-FAOFIHXS-DVudWasx.js} +1 -1
  231. package/dist/client/assets/{packet-AYTQ26CC-BHhg59Si.js → packet-AYTQ26CC-DnkTsVhD.js} +1 -1
  232. package/dist/client/assets/panels-top-left-B7jZiLth.js +1 -0
  233. package/dist/client/assets/path-text-3Rfu6lt8.js +1 -0
  234. package/dist/client/assets/{pegDiagram-VL7TDLO6-s7l7UD9d.js → pegDiagram-VL7TDLO6-Do5PIp8B.js} +1 -1
  235. package/dist/client/assets/pencil-Bzg-nc6d.js +1 -0
  236. package/dist/client/assets/{pie-WAS4IAKB-DygX31Z9.js → pie-WAS4IAKB-B_nNQOzn.js} +1 -1
  237. package/dist/client/assets/{pieDiagram-7S7Q4E2Y-bb6I9TtZ.js → pieDiagram-7S7Q4E2Y-D_IG4xwA.js} +1 -1
  238. package/dist/client/assets/{play-DUvOxTpL.js → play-DpXXQ1qB.js} +1 -1
  239. package/dist/client/assets/popover-OWEv6cQz.js +48 -0
  240. package/dist/client/assets/presentationTier-DPVAxTK4.js +1 -0
  241. package/dist/client/assets/previewRouteSearch-BjZdTuSf.js +1 -0
  242. package/dist/client/assets/primary-Cf-xJExj.js +4 -0
  243. package/dist/client/assets/primitives-CxTBN7D4.js +1 -0
  244. package/dist/client/assets/projectCheckouts.logic-DUT4AxXr.js +1 -0
  245. package/dist/client/assets/projectPaths-B8aVmOZX.js +1 -0
  246. package/dist/client/assets/projectPreferences-CzWBItFj.js +1 -0
  247. package/dist/client/assets/providerCapabilities-B2YOPsLN.js +1 -0
  248. package/dist/client/assets/providerDriverMeta-BHHL9uw0.js +1 -0
  249. package/dist/client/assets/providerModels-v9PYbzRE.js +1 -0
  250. package/dist/client/assets/providerStatus-CDPaqb0S.js +1 -0
  251. package/dist/client/assets/pullRequestsModel.logic-Dv_om_C4.js +1 -0
  252. package/dist/client/assets/{qr-code-dbkTo07n.js → qr-code-BlbiBIwH.js} +1 -1
  253. package/dist/client/assets/{qr-code-D4CtBq2F.js → qr-code-DywzVgQC.js} +1 -1
  254. package/dist/client/assets/{quadrantDiagram-CIZ2JOQS-Cj1Y68ZF.js → quadrantDiagram-CIZ2JOQS-DY6fJyrM.js} +1 -1
  255. package/dist/client/assets/{radar-RG4KPBEZ-FHM3ftPp.js → radar-RG4KPBEZ-D9689I5m.js} +1 -1
  256. package/dist/client/assets/radio-group-DVwD6Cuy.js +1 -0
  257. package/dist/client/assets/{railroad-74A4TZTK-CPMn18Cm.js → railroad-74A4TZTK-DVzWbQnl.js} +1 -1
  258. package/dist/client/assets/railroad-abnf-HS5TGJTU-C_2P6umA.js +1 -0
  259. package/dist/client/assets/railroad-ebnf-LZEXJU2U-aGlR3R3z.js +1 -0
  260. package/dist/client/assets/railroad-peg-WCYAUIDC-DCB9oE8y.js +1 -0
  261. package/dist/client/assets/{railroadDiagram-AXF67PYL-DyV3SuDj.js → railroadDiagram-AXF67PYL-D1oJ6Jtl.js} +1 -1
  262. package/dist/client/assets/readCache-B7cDPz2O.js +1 -0
  263. package/dist/client/assets/{refresh-cw-CgDa2Ok_.js → refresh-cw-CRUTivd6.js} +1 -1
  264. package/dist/client/assets/{requirementDiagram-LRYGKXZP-_xEAGWaH.js → requirementDiagram-LRYGKXZP-7RM8iREp.js} +1 -1
  265. package/dist/client/assets/rotate-ccw-BE2ZCwL6.js +1 -0
  266. package/dist/client/assets/roving-radio-group-NMPWrDqe.js +1 -0
  267. package/dist/client/assets/rows-2-DDS4dGTX.js +1 -0
  268. package/dist/client/assets/runtime-DjjjAcTE.js +18 -0
  269. package/dist/client/assets/safePolygon-C1AzMRS4.js +1 -0
  270. package/dist/client/assets/{sankeyDiagram-W5VNT64P-Clf6oTLi.js → sankeyDiagram-W5VNT64P-C1tKAPGN.js} +1 -1
  271. package/dist/client/assets/{save-C8h0AMdl.js → save-OZdkPs_y.js} +1 -1
  272. package/dist/client/assets/scroll-area-80P7vbjw.js +1 -0
  273. package/dist/client/assets/{scrollEdges-BXYnwntN.js → scrollEdges-C0Oc-5qi.js} +1 -1
  274. package/dist/client/assets/select-Cb9FUPHD.js +1 -0
  275. package/dist/client/assets/separator-CO8bC7Wc.js +1 -0
  276. package/dist/client/assets/{sequenceDiagram-SI44F4Z6-CcYtQLSe.js → sequenceDiagram-SI44F4Z6-DGVpb7jL.js} +1 -1
  277. package/dist/client/assets/settings-2-PrRDu6Lc.js +1 -0
  278. package/dist/client/assets/settingsLayout-CRFNCk_D.js +1 -0
  279. package/dist/client/assets/sheet-C5DW7qVO.js +1 -0
  280. package/dist/client/assets/{shield-DPC4oHTi.js → shield-CBHYqlkR.js} +1 -1
  281. package/dist/client/assets/{shield-alert-CwH36qZb.js → shield-alert-Dc2cGwyR.js} +1 -1
  282. package/dist/client/assets/{shield-check-CGD7sEeF.js → shield-check-_wl7R4Js.js} +1 -1
  283. package/dist/client/assets/sidebar-0BBaFNm3.js +1 -0
  284. package/dist/client/assets/sidebarProjectFolders-BjWzbt8C.js +3 -0
  285. package/dist/client/assets/sidebarProjectGrouping-nQRStWrZ.js +1 -0
  286. package/dist/client/assets/sidebarStatusText-BBKuNies.js +1 -0
  287. package/dist/client/assets/sidebarUndo-Dfq1lvyF.js +1 -0
  288. package/dist/client/assets/{skeleton-rS3IgBob.js → skeleton-DfUe6VV_.js} +1 -1
  289. package/dist/client/assets/sliders-horizontal-BGXkwvKv.js +1 -0
  290. package/dist/client/assets/sliding-tabs-BnDSjRU3.js +39 -0
  291. package/dist/client/assets/{smartphone-DgVJfbv3.js → smartphone-OEAQOTdv.js} +1 -1
  292. package/dist/client/assets/spinner-lHRJWsym.js +1 -0
  293. package/dist/client/assets/square-B05NKv3e.js +1 -0
  294. package/dist/client/assets/{star-Cqay-Cae.js → star-C8mHmfZu.js} +1 -1
  295. package/dist/client/assets/{stateDiagram-OKZ733FA-DEKURpRP.js → stateDiagram-OKZ733FA-CCOAegCG.js} +1 -1
  296. package/dist/client/assets/stateDiagram-v2-UEYNNEHI-D60qqBed.js +1 -0
  297. package/dist/client/assets/storeSelectors-BichCKDC.js +1 -0
  298. package/dist/client/assets/surfaceMorph-BTRijmlU.js +1 -0
  299. package/dist/client/assets/{swimlanes-SLNWSIFB-DrR6sbi6.js → swimlanes-SLNWSIFB-CFsLYT4h.js} +1 -1
  300. package/dist/client/assets/swimlanesDiagram-ULZ7WXOC-D0SaJgSn.js +8 -0
  301. package/dist/client/assets/switch-oQc7Ifbl.js +1 -0
  302. package/dist/client/assets/text-wrap-DSRdSfDm.js +1 -0
  303. package/dist/client/assets/textarea-VyiIZ0wQ.js +1 -0
  304. package/dist/client/assets/threadPriorityRefreshRuntime-H656C1J_.js +1 -0
  305. package/dist/client/assets/ticker-CPutfhZ4.js +1 -0
  306. package/dist/client/assets/{timeline-definition-Z64GVDOM-bQJvmJx5.js → timeline-definition-Z64GVDOM-B4agmO7R.js} +1 -1
  307. package/dist/client/assets/toggle-DFqtCPt-.js +1 -0
  308. package/dist/client/assets/toggle-group-C5ICmqkI.js +1 -0
  309. package/dist/client/assets/{tokenModePresentation-BkS-mry_.js → tokenModePresentation-umDRm4k1.js} +1 -1
  310. package/dist/client/assets/tooltip-DbqhseXd.js +1 -0
  311. package/dist/client/assets/{treeView-Q6P3EWNA-D4Ex5QTp.js → treeView-Q6P3EWNA-C_S3udFB.js} +1 -1
  312. package/dist/client/assets/{treemap-WGGIJYW6-C4B6Y6qM.js → treemap-WGGIJYW6-B-kUSAkE.js} +1 -1
  313. package/dist/client/assets/undo-2-lyluTGMW.js +1 -0
  314. package/dist/client/assets/{unplug-B1dczi-t.js → unplug-D6iu-qlh.js} +1 -1
  315. package/dist/client/assets/usage-ClF-eUmy.js +1 -0
  316. package/dist/client/assets/useActiveIndicator-R5NWu8Fg.js +1 -0
  317. package/dist/client/assets/useAppSidebarCollapsed-BbMxfio5.js +1 -0
  318. package/dist/client/assets/useAppearancePreference-Ix13pMKy.js +1 -0
  319. package/dist/client/assets/useAtlassian-BYDCc9lv.js +0 -0
  320. package/dist/client/assets/useCheckoutResolution-CR-oOp5-.js +1 -0
  321. package/dist/client/assets/useDesktopRelaunchGuard-Jmh615iZ.js +1 -0
  322. package/dist/client/assets/useDiffFileNavigation-DeuzdD5E.js +15 -0
  323. package/dist/client/assets/useDiffLayout-DhcXwhBL.js +1 -0
  324. package/dist/client/assets/useEnvironmentSettingsTarget-DM6BRDT7.js +1 -0
  325. package/dist/client/assets/useFocus-CV0KIZwg.js +1 -0
  326. package/dist/client/assets/useGit-CUcs7h5_.js +1 -0
  327. package/dist/client/assets/useGitBranchSearch-CeKFtnCL.js +1 -0
  328. package/dist/client/assets/useHostedDraftExecutionTarget-DvQU5UOq.js +1 -0
  329. package/dist/client/assets/useLabelableId-CEgCRi6q.js +1 -0
  330. package/dist/client/assets/useLandingFlash-BfOOlFtW.js +1 -0
  331. package/dist/client/assets/useLogicalProjectSnapshots-CRNZke74.js +1 -0
  332. package/dist/client/assets/useNavigate-sQZthdyT.js +1 -0
  333. package/dist/client/assets/usePageLeadingInsetClass-Bf4nUvx4.js +1 -0
  334. package/dist/client/assets/usePhoneThreadActions-VaQ-mZex.js +1 -0
  335. package/dist/client/assets/usePopupHandleStore-DimKo2Yy.js +1 -0
  336. package/dist/client/assets/usePopupViewport-YeqX_UM3.js +1 -0
  337. package/dist/client/assets/usePresentationTier-B9kCQ4YH.js +1 -0
  338. package/dist/client/assets/useProject-Kt74Z12J.js +1 -0
  339. package/dist/client/assets/useProviderOptionsUpdater-CTzNh2B7.js +2 -0
  340. package/dist/client/assets/usePullRequestFilesViewed-D5Snmzys.js +1 -0
  341. package/dist/client/assets/usePullRequestsModel-DJL5HHbP.js +40 -0
  342. package/dist/client/assets/useScrollLock-CLZ31xsK.js +1 -0
  343. package/dist/client/assets/useSidebarThreadActions-n6EkLATf.js +6 -0
  344. package/dist/client/assets/{useStatistics-B76_r68I.js → useStatistics-DD0mYS4J.js} +14 -14
  345. package/dist/client/assets/{useTheme-B441xg4F.js → useTheme-Bdy-BDs-.js} +1 -1
  346. package/dist/client/assets/useValueChanged-DoumqMnV.js +1 -0
  347. package/dist/client/assets/{user-round-CLy1Qy1Y.js → user-round-BPDXr8Gq.js} +1 -1
  348. package/dist/client/assets/{vennDiagram-T6HMQDX7-8iiroXim.js → vennDiagram-T6HMQDX7-B1UEn_j_.js} +1 -1
  349. package/dist/client/assets/{vscode-icons-CJBVQtq5.js → vscode-icons-Ccy-gzFN.js} +1 -1
  350. package/dist/client/assets/{wardley-WFR3VGLG-DpyNUbTc.js → wardley-WFR3VGLG-gPdyDc-7.js} +1 -1
  351. package/dist/client/assets/{wardleyDiagram-T6FBY63Y-CI7is3QO.js → wardleyDiagram-T6FBY63Y-2aDcwOA4.js} +1 -1
  352. package/dist/client/assets/workspaceLifecycle-OJ1aKksw.js +3 -0
  353. package/dist/client/assets/workspaceMetadataProjection-CyEyJhUa.js +1 -0
  354. package/dist/client/assets/workspaceRouteSearch-CCavUdbH.js +1 -0
  355. package/dist/client/assets/{wrench-7pbbxqrZ.js → wrench-CPUCA_rn.js} +1 -1
  356. package/dist/client/assets/wsTransport-C88seBPA.js +15 -0
  357. package/dist/client/assets/{xychartDiagram-ELKLHX3M-BTEX3m2y.js → xychartDiagram-ELKLHX3M-C1_7Q-1i.js} +1 -1
  358. package/dist/client/favicon.svg +1 -1
  359. package/dist/client/index.html +1 -1
  360. package/dist/collectUint8StreamText-BsLSgI8i.mjs +710 -0
  361. package/dist/collectUint8StreamText-D5olwfpM.cjs +757 -0
  362. package/dist/{deviceHostWorker-L8C9wy38.mjs → deviceHostWorker-B-Dn-6An.mjs} +1 -1
  363. package/dist/{makeManagedServerProvider-CF776SAO.cjs → makeManagedServerProvider-B5tP7tvg.cjs} +1 -1
  364. package/dist/{makeManagedServerProvider-B90UKjnv.mjs → makeManagedServerProvider-B65ipCxM.mjs} +2 -2
  365. package/dist/resource-monitor/linux-arm64/ryco-resource-monitor +0 -0
  366. package/dist/resource-monitor/ryco-resource-monitor +0 -0
  367. package/dist/resource-monitor/ryco-resource-monitor.exe +0 -0
  368. package/dist/resource-monitor/win32-arm64/ryco-resource-monitor.exe +0 -0
  369. package/dist/resource-monitor/win32-x64/ryco-resource-monitor.exe +0 -0
  370. package/dist/{runtimeSession-V3RIy8Ao.mjs → runtimeSession-D_BZ-wRH.mjs} +1 -1
  371. package/dist/{src-CARHuYkT.cjs → src-FmeCeBJ9.cjs} +2291 -72
  372. package/dist/{src-CtsgPPhb.mjs → src-VTj60bUm.mjs} +1974 -61
  373. package/package.json +1 -1
  374. package/dist/AzureDevOpsSourceControlProvider-CKSvfuDS.cjs +0 -190
  375. package/dist/AzureDevOpsSourceControlProvider-DRWSXTml.mjs +0 -188
  376. package/dist/GitLabSourceControlProvider-Cj07OTBD.mjs +0 -186
  377. package/dist/GitLabSourceControlProvider-CvvN5pHt.cjs +0 -188
  378. package/dist/client/assets/AccountSettings-v6-r6gYl.js +0 -1
  379. package/dist/client/assets/AiFocusSettings-BVdLON0q.js +0 -1
  380. package/dist/client/assets/AppearanceSettings-DRChsQnN.js +0 -1
  381. package/dist/client/assets/BranchToolbar.logic-YN3KjVr9.js +0 -3
  382. package/dist/client/assets/BrowserPanel-Dxw3stFP.js +0 -1
  383. package/dist/client/assets/ChatRightPanel-CygpcJiF.js +0 -201
  384. package/dist/client/assets/ChatThreadRouteView-DYLZFHu0.js +0 -1
  385. package/dist/client/assets/CommandPaletteDialog-BRvBzP1R.js +0 -1
  386. package/dist/client/assets/CompositeRoot-BeEGGWwn.js +0 -1
  387. package/dist/client/assets/ComputerUseSettings-Cq8Pi0ZU.js +0 -1
  388. package/dist/client/assets/ConnectionsSettings-RSYtexxd.js +0 -7
  389. package/dist/client/assets/ContextHandoffEndpointLabel-CeGDLNA4.js +0 -4
  390. package/dist/client/assets/DiagnosticsSettings-CDa6MVx4.js +0 -2
  391. package/dist/client/assets/DialogHandle-BE7egDQQ.js +0 -1
  392. package/dist/client/assets/DialogRoot-C4mtzigX.js +0 -1
  393. package/dist/client/assets/DialogTitle-B_Q4DykI.js +0 -1
  394. package/dist/client/assets/DialogTrigger-BSqd4Crj.js +0 -1
  395. package/dist/client/assets/DraftChatThreadRouteView-JW_bXVrM.js +0 -1
  396. package/dist/client/assets/GlassSurface-DDG4eTlj.js +0 -1
  397. package/dist/client/assets/HostedConnectionControls-CscV6hm1.js +0 -1
  398. package/dist/client/assets/HostedHubRoot-gp7-ClBP.js +0 -2
  399. package/dist/client/assets/HostedNodeRenameDialog-D1DSiTpx.js +0 -1
  400. package/dist/client/assets/HostedRelayTrustNotice-B9jp4SRh.js +0 -1
  401. package/dist/client/assets/IntegrationsSettingsPanel-DH7SfWtV.js +0 -2
  402. package/dist/client/assets/KeybindingsSettings-DkgYYSHS.js +0 -7
  403. package/dist/client/assets/LazyBrowserPanel-D4e76vc_.js +0 -2
  404. package/dist/client/assets/McpServersSettings-Dc1kPa-X.js +0 -6
  405. package/dist/client/assets/MobileSheet-lT--mLEz.js +0 -1
  406. package/dist/client/assets/NodeSecuritySettings-DcfSx4KT.js +0 -1
  407. package/dist/client/assets/NullStore-8d2s-Re3.js +0 -1
  408. package/dist/client/assets/OnboardingDialog-CnLjwM6Z.js +0 -1
  409. package/dist/client/assets/OpinionatedPluginsSettings-BTJyS3rN.js +0 -1
  410. package/dist/client/assets/PhoneHome-CIMkuDJF.js +0 -1
  411. package/dist/client/assets/PhoneSettingsSurface-CfZQxJNI.js +0 -2
  412. package/dist/client/assets/ProvidersSettingsPanel-DAVSiwE1.js +0 -1
  413. package/dist/client/assets/RedactedSensitiveText-BHGbQJwB.js +0 -1
  414. package/dist/client/assets/RootAppShell-T056pByH.js +0 -7
  415. package/dist/client/assets/SettingsDialog-BERU2Qg7.js +0 -2
  416. package/dist/client/assets/SettingsPanels-De_XZOQF.js +0 -3
  417. package/dist/client/assets/SettingsPanels.editor-Dkva9gX_.js +0 -2
  418. package/dist/client/assets/SourceControlSettings-B4HS17cB.js +0 -1
  419. package/dist/client/assets/StatisticsPage-Bj2ftFdH.js +0 -1
  420. package/dist/client/assets/StatisticsPanel-Dw7GBBmd.js +0 -1
  421. package/dist/client/assets/StatisticsSettingsLink-_XL3ABoI.js +0 -1
  422. package/dist/client/assets/ThreadTerminalDrawer-CPPzQSXN.js +0 -18
  423. package/dist/client/assets/ThreadWorkspacePanel-DWKU7Omm.js +0 -2073
  424. package/dist/client/assets/appChrome-TkWLAGxk.js +0 -1
  425. package/dist/client/assets/architecture-7GRP2DOG-HS59zfrk.js +0 -1
  426. package/dist/client/assets/authorization-D8dOcEYq.js +0 -1
  427. package/dist/client/assets/badge-2AZ3HfVS.js +0 -1
  428. package/dist/client/assets/capabilities-CsHjxjab.js +0 -1
  429. package/dist/client/assets/channel-Dn3_cOkm.js +0 -1
  430. package/dist/client/assets/chevron-right-Dsw16yGn.js +0 -1
  431. package/dist/client/assets/classDiagram-JCYQIIEL-ZQvrS8No.js +0 -1
  432. package/dist/client/assets/classDiagram-v2-OCEON4UE-ZQvrS8No.js +0 -1
  433. package/dist/client/assets/compiler-runtime-C4g8XhC5.js +0 -1
  434. package/dist/client/assets/desktopWorkspace-_iM6B9Kf.js +0 -1
  435. package/dist/client/assets/editorPreferences-D8q1ItMW.js +0 -1
  436. package/dist/client/assets/eventmodeling-NTZA5JFV-Dj71kuPV.js +0 -1
  437. package/dist/client/assets/flowDiagram-UKHOOZJN-BaAiwuvL.js +0 -1
  438. package/dist/client/assets/hostedConnectionCoordinator-BuRWCvUG.js +0 -1
  439. package/dist/client/assets/hubRoutes-jcMPIFy3.js +0 -1
  440. package/dist/client/assets/kbd-Dxm5Elqj.js +0 -1
  441. package/dist/client/assets/layers-Dqez1Uq8.js +0 -1
  442. package/dist/client/assets/liquidGlass-CA2o_Cq0.js +0 -1
  443. package/dist/client/assets/liquidGlass.worker-icvLJKHf.js +0 -1
  444. package/dist/client/assets/main-BqSANuAs.css +0 -2
  445. package/dist/client/assets/main-DAbEANjY.js +0 -9
  446. package/dist/client/assets/motion-BdscFixQ.js +0 -1
  447. package/dist/client/assets/palette-92ylWqeC.js +0 -1
  448. package/dist/client/assets/perfInstrumentation-BT27w4tn.js +0 -1
  449. package/dist/client/assets/presentationTier-xlIjcFab.js +0 -1
  450. package/dist/client/assets/primary-DZjgHvyf.js +0 -5
  451. package/dist/client/assets/providerDriverMeta-T2YbXzuS.js +0 -1
  452. package/dist/client/assets/providerStatus-DBGvvkyF.js +0 -1
  453. package/dist/client/assets/radio-group-CRnHYWa8.js +0 -1
  454. package/dist/client/assets/railroad-abnf-HS5TGJTU-DxU7Mt1k.js +0 -1
  455. package/dist/client/assets/railroad-ebnf-LZEXJU2U-BYAPVjRd.js +0 -1
  456. package/dist/client/assets/railroad-peg-WCYAUIDC-BOqgR_X7.js +0 -1
  457. package/dist/client/assets/runtime-BwHA1GUS.js +0 -18
  458. package/dist/client/assets/scroll-area-7n2X_RLQ.js +0 -1
  459. package/dist/client/assets/separator-CL1qjMqJ.js +0 -1
  460. package/dist/client/assets/settingsLayout-DxsFwhF0.js +0 -1
  461. package/dist/client/assets/sheet-CGiaw8-i.js +0 -1
  462. package/dist/client/assets/sidebar-Cc6ANbOP.js +0 -1
  463. package/dist/client/assets/sidebarProjectFolders-DO2Uv84F.js +0 -4
  464. package/dist/client/assets/sidebarStatusText-B4AtFXZo.js +0 -1
  465. package/dist/client/assets/sidebarUndo-gdSrfa4O.js +0 -1
  466. package/dist/client/assets/square-Cr9X8U6y.js +0 -1
  467. package/dist/client/assets/src-C3Y_imaX.js +0 -14
  468. package/dist/client/assets/stateDiagram-v2-UEYNNEHI-CWtHILqh.js +0 -1
  469. package/dist/client/assets/storeSelectors-CTDWheMy.js +0 -1
  470. package/dist/client/assets/swimlanesDiagram-ULZ7WXOC-DuaPce9O.js +0 -8
  471. package/dist/client/assets/switch-DnpJB2xv.js +0 -48
  472. package/dist/client/assets/toggle-D10FsFoE.js +0 -1
  473. package/dist/client/assets/toggle-group-BhzbQPEQ.js +0 -1
  474. package/dist/client/assets/tooltip-BlweKBxc.js +0 -1
  475. package/dist/client/assets/usage-BBwaxMif.js +0 -1
  476. package/dist/client/assets/useAppSidebarCollapsed-CFy476E3.js +0 -1
  477. package/dist/client/assets/useAppearancePreference-Dlh9P8iu.js +0 -1
  478. package/dist/client/assets/useBaseUiId-DKOjzmu3.js +0 -1
  479. package/dist/client/assets/useLabelableId-DQbY2GG1.js +0 -1
  480. package/dist/client/assets/useNavigate-B8oXtF30.js +0 -1
  481. package/dist/client/assets/usePhoneThreadActions-6DCLiyJ5.js +0 -1
  482. package/dist/client/assets/usePopupViewport-CNWcP7Od.js +0 -1
  483. package/dist/client/assets/usePresentationTier-hxB7Yv_Q.js +0 -1
  484. package/dist/client/assets/useScrollLock-BbKeKZdj.js +0 -1
  485. package/dist/client/assets/useTriggerFocusGuards-BC4Wb3GI.js +0 -1
  486. package/dist/client/assets/useValueChanged-BkTbyZdO.js +0 -1
  487. package/dist/client/assets/workspaceMetadataProjection-aqZEXDrQ.js +0 -1
  488. package/dist/collectUint8StreamText-BAUF-vzz.mjs +0 -37
  489. package/dist/collectUint8StreamText-vagpNUMJ.cjs +0 -42
  490. package/dist/git-9xWsJYIH.mjs +0 -132
  491. package/dist/git-xIkXFy_l.cjs +0 -218
  492. package/dist/sourceControl-B0D1Op29.cjs +0 -253
  493. package/dist/sourceControl-BiEBxN01.mjs +0 -224
@@ -1,30 +1,30 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { Dt as ServerConfig, Ft as applyClaudePromptEffortPrefix, Ht as getProviderOptionDescriptors, It as createModelCapabilities, Kt as resolvePromptInjectedEffort, Rt as getModelSelectionBooleanOptionValue, Vt as getProviderOptionCurrentValue, X as ServerSettingsService, zt as getModelSelectionStringOptionValue } from "./Metrics-CnmjpbWk.mjs";
4
- import { Dr as TextGenerationError, Du as EventId, Fu as RuntimeRequestId, Kr as ClaudeSettings, Lu as RuntimeSubagentId, Nu as ProviderItemId, Pu as RuntimeItemId, Qo as ProviderInstanceId, Ru as RuntimeTaskId, Vu as TurnId, Zo as ProviderDriverKind, yu as ApprovalRequestId, zu as ThreadId } from "./src-CtsgPPhb.mjs";
5
- import { m as sanitizeFeatureBranchName, p as sanitizeBranchFragment } from "./git-9xWsJYIH.mjs";
6
- import { A as makeEventNdjsonLogger, At as spawnAndCollect, B as buildTokenReductionInstructions, Bt as ProviderAdapterSessionNotFoundError, Cr as sanitizePrTitle, Ct as buildServerProvider, Et as isCommandMissingCause, Ft as redactAgentControlSecrets, Ht as ProviderDriverError, It as createProcessDeviceToolBinding, Lt as ProviderAdapterProcessError, Mt as agentControlHostContext, Ot as parseGenericCliVersion, Pt as installAgentControlNativeHttp, Q as enrichProviderSnapshotWithVersionAdvisory, Rt as ProviderAdapterRequestError, Sr as sanitizeCommitSubject, Tr as toJsonSchemaObject, Tt as detailFromResult, V as checkRtkAvailability, Vt as ProviderAdapterValidationError, Z as ModelManifest, _r as buildSideQuestionPrompt, a as getActiveClaudeModelCatalog, bt as DEFAULT_TIMEOUT_MS, c as resolveClaudeCatalogApiModelId, ct as resolveAttachmentPath, d as setActiveClaudeModelCatalog, dr as validateRankInboxThreadsResult, dt as makeClaudeContinuationGroupKey, et as makePackageManagedProviderMaintenanceResolver, fr as buildBranchNamePrompt, ft as makeClaudeEnvironment, gr as buildPrContentPrompt, hr as buildIssueContentTitlePrompt, i as formatClaudeVersionUpgradeMessage, it as resolveProviderMaintenanceCapabilitiesEffect, jt as AGENT_CONTROL_INTERNAL_SERVER_NAME, k as ProviderEventLoggers, kt as providerModelsFromSettings, l as resolveClaudeModelCatalog, lt as classifyTaskAgentKind, mr as buildIssueContentPolishPrompt, mt as mergeProviderInstanceEnvironment, n as AgentControlSessionRegistry, o as getClaudeCatalogModelCapabilities, ot as isPersistableChatAttachment, p as isClaudeNativeCompaction, pr as buildCommitMessagePrompt, pt as resolveClaudeHomePath, rt as normalizeCommandPath, s as normalizeClaudeCatalogEffort, t as makeServerQueueMetrics, u as resolveClaudeModelsForVersion, ut as makeClaudeCapabilitiesCacheKey, vr as buildThreadPriorityPrompt, wr as sanitizeThreadTitle, xr as normalizeCliError, yr as buildThreadTitlePrompt, zt as ProviderAdapterSessionClosedError } from "./bin.mjs";
7
- import { i as formatAttachmentPathLines, n as stampRuntimeEvent, r as appendAttachmentPathLines, t as requireRuntimeSessionId } from "./runtimeSession-V3RIy8Ao.mjs";
3
+ import { $t as resolvePromptInjectedEffort, Gt as getModelSelectionBooleanOptionValue, Ht as applyClaudePromptEffortPrefix, Jt as getProviderOptionCurrentValue, Kt as getModelSelectionStringOptionValue, Nt as ServerConfig, Ut as createModelCapabilities, X as ServerSettingsService, Yt as getProviderOptionDescriptors } from "./Metrics-C3vLS9rz.mjs";
4
+ import { Ad as ProviderItemId, Fd as RuntimeTaskId, Id as ThreadId, Ks as ProviderDriverKind, Md as RuntimeRequestId, Pd as RuntimeSubagentId, Rd as TurnId, ei as TextGenerationError, gd as ApprovalRequestId, jd as RuntimeItemId, qs as ProviderInstanceId, wd as EventId, xi as ClaudeSettings } from "./src-VTj60bUm.mjs";
5
+ import { A as ProviderEventLoggers, At as isCommandMissingCause, Bt as createProcessDeviceToolBinding, Ci as sanitizeFeatureBranchName, Dt as buildServerProvider, Ft as AGENT_CONTROL_INTERNAL_SERVER_NAME, Gt as ProviderAdapterValidationError, H as checkRtkAvailability, Ht as ProviderAdapterRequestError, It as agentControlHostContext, J as resolveHtmlRenderToolKind, Kt as ProviderDriverError, Mt as parseGenericCliVersion, Nt as providerModelsFromSettings, Pt as spawnAndCollect, Qn as isPersistableChatAttachment, Rt as installAgentControlNativeHttp, Si as sanitizeBranchFragment, Ut as ProviderAdapterSessionClosedError, V as buildTokenReductionInstructions, Vt as ProviderAdapterProcessError, Wt as ProviderAdapterSessionNotFoundError, X as withoutHtmlRenderMarkup, Y as resolveHtmlRenderToolPresentation, _i as normalizeCliError, _t as mergeProviderInstanceEnvironment, at as enrichProviderSnapshotWithVersionAdvisory, bi as sanitizeThreadTitle, c as getClaudeCatalogModelCapabilities, ci as buildBranchNamePrompt, d as resolveClaudeModelCatalog, di as buildIssueContentTitlePrompt, dt as resolveProviderMaintenanceCapabilitiesEffect, er as resolveAttachmentPath, f as resolveClaudeModelsForVersion, fi as buildPrContentPrompt, ft as classifyTaskAgentKind, gt as resolveClaudeHomePath, h as isClaudeNativeCompaction, hi as buildThreadTitlePrompt, ht as makeClaudeEnvironment, i as AgentControlSessionRegistry, it as ModelManifest, j as makeEventNdjsonLogger, kt as detailFromResult, l as normalizeClaudeCatalogEffort, li as buildCommitMessagePrompt, mi as buildThreadPriorityPrompt, mt as makeClaudeContinuationGroupKey, n as usageLimitStateFromWindows, o as formatClaudeVersionUpgradeMessage, p as setActiveClaudeModelCatalog, pi as buildSideQuestionPrompt, pt as makeClaudeCapabilitiesCacheKey, qt as ProviderTurnNotSteerableError, r as makeServerQueueMetrics, s as getActiveClaudeModelCatalog, si as validateRankInboxThreadsResult, st as makePackageManagedProviderMaintenanceResolver, t as isRepresentableEpochMs, u as resolveClaudeCatalogApiModelId, ui as buildIssueContentPolishPrompt, ut as normalizeCommandPath, vi as sanitizeCommitSubject, wt as DEFAULT_TIMEOUT_MS, xi as toJsonSchemaObject, yi as sanitizePrTitle, zt as redactAgentControlSecrets } from "./bin.mjs";
6
+ import { i as formatAttachmentPathLines, n as stampRuntimeEvent, r as appendAttachmentPathLines, t as requireRuntimeSessionId } from "./runtimeSession-D_BZ-wRH.mjs";
8
7
  import { t as defaultProviderContinuationIdentity } from "./ProviderDriver-kCV60GKk.mjs";
9
- import { n as sideQuestionEnvironment, t as sideQuestionDirectory } from "./SideQuestionIsolation-B-aE6aBz.mjs";
8
+ import { n as sideQuestionEnvironment, t as sideQuestionDirectory } from "./SideQuestionIsolation-B1T-DsR0.mjs";
10
9
  import { t as formatSourceControlContextsForAgent } from "./sourceControlContextFormatter-DEwpnVAH.mjs";
11
10
  import { n as formatProjectCustomSystemPrompt } from "./ProjectCustomSystemPrompt-CS1nulhL.mjs";
12
- import { t as makeManagedServerProvider } from "./makeManagedServerProvider-B90UKjnv.mjs";
13
- import { Cache, Cause, DateTime, Deferred, Duration, Effect, Exit, Fiber, FileSystem, Option, Path, Queue, Ref, Result, Schema, Stream } from "effect";
11
+ import { t as makeManagedServerProvider } from "./makeManagedServerProvider-B65ipCxM.mjs";
12
+ import { Cache, Cause, Clock, DateTime, Deferred, Duration, Effect, Exit, Fiber, FileSystem, Option, Path, Queue, Ref, Result, Schema, Semaphore, Stream } from "effect";
14
13
  import { execFile } from "node:child_process";
15
14
  import * as NodePath from "node:path";
16
15
  import { HttpClient } from "effect/unstable/http";
17
16
  import * as NodeOS from "node:os";
18
17
  import * as NodeFS from "node:fs/promises";
19
18
  import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";
20
- import { query } from "@anthropic-ai/claude-agent-sdk";
19
+ import { getSessionMessages, query } from "@anthropic-ai/claude-agent-sdk";
21
20
  //#region src/provider/Layers/ClaudeProvider.ts
22
21
  const DEFAULT_CLAUDE_MODEL_CAPABILITIES = createModelCapabilities({ optionDescriptors: [] });
23
22
  const PROVIDER$1 = ProviderDriverKind.make("claudeAgent");
24
23
  const CLAUDE_PRESENTATION = {
25
24
  displayName: "Claude",
26
25
  showInteractionModeToggle: true,
27
- supportsAskMode: true
26
+ supportsAskMode: true,
27
+ supportsTurnSteering: true
28
28
  };
29
29
  function getClaudeModelCapabilities(model) {
30
30
  const capabilities = getClaudeCatalogModelCapabilities(getActiveClaudeModelCatalog(), model);
@@ -625,6 +625,7 @@ function observeClaudeCache(input) {
625
625
  providerInstanceId: input.providerInstanceId,
626
626
  model: input.model,
627
627
  ...input.modelSelection ? { modelSelection: input.modelSelection } : {},
628
+ ...input.cwd ? { cwd: input.cwd } : {},
628
629
  messageId: input.messageId,
629
630
  directInputTokens: counts.directInputTokens,
630
631
  cacheReadInputTokens: counts.cacheReadInputTokens,
@@ -633,6 +634,278 @@ function observeClaudeCache(input) {
633
634
  };
634
635
  }
635
636
  //#endregion
637
+ //#region src/provider/claudeContextUsage.ts
638
+ function knownContextWindow(value) {
639
+ return typeof value === "number" && Number.isSafeInteger(value) && value > 0 ? value : void 0;
640
+ }
641
+ /**
642
+ * `compact_boundary.compact_metadata.post_tokens` as a context gauge; undefined when absent or
643
+ * invalid. Compaction invalidated the cache evidence, so the gauge never carries `claudeCache`.
644
+ */
645
+ function claudePostCompactionUsage(compactMetadata, contextWindow) {
646
+ if (compactMetadata === null || typeof compactMetadata !== "object") return;
647
+ const postTokens = compactMetadata.post_tokens;
648
+ if (typeof postTokens !== "number" || !Number.isFinite(postTokens)) return;
649
+ const rounded = Math.round(postTokens);
650
+ if (rounded <= 0) return;
651
+ const maxTokens = knownContextWindow(contextWindow);
652
+ return {
653
+ usedTokens: maxTokens !== void 0 ? Math.min(rounded, maxTokens) : rounded,
654
+ ...maxTokens !== void 0 ? { maxTokens } : {}
655
+ };
656
+ }
657
+ /**
658
+ * The gauge a Claude result publishes. `result.usage` is cumulative across every API call of the
659
+ * turn, so the last main-loop gauge wins and the cumulative figure only rides along as
660
+ * `totalProcessedTokens`. Without a gauge the cumulative snapshot is a fallback, but never for a
661
+ * turn that crossed a compaction boundary: its cumulative input is the pre-compaction size.
662
+ */
663
+ function selectClaudeResultUsageGauge(input) {
664
+ const { lastGauge, cumulative, maxTokens } = input;
665
+ if (lastGauge === void 0) return input.cumulativeIsGauge ? cumulative : void 0;
666
+ const cumulativeTotal = cumulative?.totalProcessedTokens ?? cumulative?.usedTokens;
667
+ return {
668
+ ...lastGauge,
669
+ ...typeof maxTokens === "number" && Number.isFinite(maxTokens) && maxTokens > 0 ? { maxTokens } : {},
670
+ ...typeof cumulativeTotal === "number" && Number.isFinite(cumulativeTotal) && cumulativeTotal > lastGauge.usedTokens ? { totalProcessedTokens: cumulativeTotal } : {}
671
+ };
672
+ }
673
+ const ABORT_TERMINAL_REASONS = /* @__PURE__ */ new Set(["aborted_streaming", "aborted_tools"]);
674
+ function resultErrorsText(result) {
675
+ return "errors" in result && Array.isArray(result.errors) ? result.errors.join(" ").toLowerCase() : "";
676
+ }
677
+ function isInterruptedResult(result) {
678
+ const errors = resultErrorsText(result);
679
+ if (errors.includes("interrupt")) return true;
680
+ return result.subtype === "error_during_execution" && result.is_error === false && (errors.includes("request was aborted") || errors.includes("interrupted by user") || errors.includes("aborted"));
681
+ }
682
+ /** The CLI ended the segment by aborting it (a Stop or a `priority: "now"` steer). */
683
+ function isClaudeAbortTerminalReason(result) {
684
+ const terminalReason = Reflect.get(result, "terminal_reason");
685
+ return typeof terminalReason === "string" && ABORT_TERMINAL_REASONS.has(terminalReason);
686
+ }
687
+ function readStringArray(value) {
688
+ return Array.isArray(value) && value.every((entry) => typeof entry === "string") ? value : void 0;
689
+ }
690
+ function isRootFrame$1(message) {
691
+ const parentToolUseId = Reflect.get(message, "parent_tool_use_id");
692
+ return parentToolUseId === null || parentToolUseId === void 0;
693
+ }
694
+ /**
695
+ * The prompt uuids a frame echoes. Results echo every user message the CLI turn consumed. The
696
+ * CLI turn's first reply frame echoes the messages that started it (early echo): its first
697
+ * non-ping stream event, or its first root assistant message when it streamed nothing (a request
698
+ * that failed at the API replies with a synthetic error message).
699
+ */
700
+ function claudeEchoedPromptUuids(message) {
701
+ if (message.type !== "result" && message.type !== "stream_event" && !(message.type === "assistant" && isRootFrame$1(message))) return [];
702
+ const uuids = readStringArray(Reflect.get(message, "user_message_uuids"));
703
+ if (uuids !== void 0 && uuids.length > 0) return uuids;
704
+ const uuid = Reflect.get(message, "user_message_uuid");
705
+ return typeof uuid === "string" && uuid.length > 0 ? [uuid] : [];
706
+ }
707
+ function classifyClaudeResultKind(result) {
708
+ if (result.subtype === "success" && !result.is_error) return "success";
709
+ if (isClaudeAbortTerminalReason(result)) return "abort";
710
+ if (Reflect.get(result, "terminal_reason") === void 0 && isInterruptedResult(result)) return "abort";
711
+ return "failure";
712
+ }
713
+ /** Whether an echo names the turn's prompt or one of its steers. */
714
+ function claudeEchoNamesTurn(input) {
715
+ return input.echoed.some((uuid) => uuid === input.promptUuid || input.steerPromptUuids.has(uuid));
716
+ }
717
+ /**
718
+ * Whether a result belongs to the open prompt turn. It does when it echoes the prompt or any of
719
+ * the turn's steers. Without an echo (older CLIs) it belongs unless its origin is not human.
720
+ * Callers skip the check for provider turns (no prompt uuid).
721
+ */
722
+ function claudeResultBelongsToTurn(input) {
723
+ if (input.echoed.length > 0) return claudeEchoNamesTurn(input);
724
+ return input.origin === void 0 || input.origin.kind === "human";
725
+ }
726
+ /**
727
+ * The turn waits only when Stop was not requested, a steer is still unsettled, the segment ended
728
+ * by abort or success, and the CLI positively promised another result (`queued_turn_count > 0`).
729
+ * Every other result completes the turn, so no waiting is unbounded.
730
+ */
731
+ function decideClaudeTurnResult(input) {
732
+ const echoed = new Set(input.echoedPromptUuids);
733
+ const newlySettled = [];
734
+ const unsettled = [];
735
+ for (const uuid of input.steerPromptUuids) {
736
+ if (input.settledSteerPromptUuids.has(uuid)) continue;
737
+ if (echoed.has(uuid)) newlySettled.push(uuid);
738
+ else unsettled.push(uuid);
739
+ }
740
+ const awaitSteer = !input.interruptRequested && unsettled.length > 0 && (input.kind === "abort" || input.kind === "success") && typeof input.queuedTurnCount === "number" && input.queuedTurnCount > 0;
741
+ const completingWithSteers = !awaitSteer && unsettled.length > 0;
742
+ return {
743
+ decision: awaitSteer ? "await-steer" : "complete",
744
+ newlySettled,
745
+ unsettled,
746
+ discardUnsettled: completingWithSteers && (input.interruptRequested || input.kind === "failure"),
747
+ abortedBySteer: completingWithSteers && !input.interruptRequested && input.kind === "abort"
748
+ };
749
+ }
750
+ /**
751
+ * The status a completing turn reports. It follows the result except where the result's status
752
+ * would misstate what happened to the turn: Ryco's own discard re-interrupt or a steer's abort is
753
+ * never a Stop (which would hold the client queue), a Stop always ends as interrupted, and a
754
+ * failure that drops a pending steer is always reported as one (so the queue holds and the user
755
+ * sees why the steer got no reply).
756
+ */
757
+ function decideClaudeTurnClose(input) {
758
+ if (input.foldedIntoDiscardedCliTurn) return input.interruptRequested ? {
759
+ status: "interrupted",
760
+ cause: "stopped"
761
+ } : {
762
+ status: "failed",
763
+ cause: "folded-into-discarded-cli-turn"
764
+ };
765
+ if (input.resultStatus === "completed") {
766
+ const endsSteerSegment = input.echoedPromptUuids.some((uuid) => input.steerPromptUuids.has(uuid)) && (input.promptUuid === void 0 || !input.echoedPromptUuids.includes(input.promptUuid));
767
+ if (input.interruptRequested && endsSteerSegment) return {
768
+ status: "interrupted",
769
+ cause: "stopped"
770
+ };
771
+ if (!input.interruptRequested && input.decision.discardUnsettled) return {
772
+ status: "failed",
773
+ cause: "failed-segment-dropped-steers"
774
+ };
775
+ }
776
+ if (input.decision.abortedBySteer) return {
777
+ status: "completed",
778
+ cause: "aborted-by-steer"
779
+ };
780
+ return {
781
+ status: input.resultStatus,
782
+ cause: "result"
783
+ };
784
+ }
785
+ /** Defensive: anything but a `still_queued` string array is "no receipt" (older CLIs). */
786
+ function readClaudeInterruptReceipt(value) {
787
+ if (value === null || typeof value !== "object") return void 0;
788
+ const stillQueued = readStringArray(Reflect.get(value, "still_queued"));
789
+ if (stillQueued === void 0) return void 0;
790
+ return {
791
+ stillQueued,
792
+ cancelled: readStringArray(Reflect.get(value, "cancelled"))
793
+ };
794
+ }
795
+ /**
796
+ * Stop with steers pending. A steer that already streamed into the turn, or that the receipt
797
+ * does not list as queued or cancelled (in transit), counts as running, so its own aborted
798
+ * result closes the turn. The discard and release lists hold whether or not the stopped turn is
799
+ * still open.
800
+ */
801
+ function decideClaudeStop(input) {
802
+ if (input.receipt === void 0) return {
803
+ forceClose: input.awaitingSteerContinuation,
804
+ discard: [...input.unsettledSteers],
805
+ release: []
806
+ };
807
+ const cancelled = new Set(input.receipt.cancelled ?? []);
808
+ const outstanding = /* @__PURE__ */ new Set([...input.receipt.stillQueued, ...cancelled]);
809
+ const runningSteers = input.unsettledSteers.filter((uuid) => input.startedSteers.has(uuid) || !outstanding.has(uuid));
810
+ const isReleased = (uuid) => cancelled.has(uuid) && !input.startedSteers.has(uuid);
811
+ return {
812
+ forceClose: (input.sealedSegmentCount > 0 || input.promptUuid !== void 0 && cancelled.has(input.promptUuid)) && runningSteers.length === 0,
813
+ discard: input.unsettledSteers.filter((uuid) => !isReleased(uuid)),
814
+ release: input.unsettledSteers.filter(isReleased)
815
+ };
816
+ }
817
+ /** FIFO-bounded insert. */
818
+ function rememberDiscardedSteer(set, uuid, cap = 64) {
819
+ if (set.has(uuid)) return;
820
+ while (set.size >= cap) {
821
+ const oldest = set.values().next();
822
+ if (oldest.done) break;
823
+ set.delete(oldest.value);
824
+ }
825
+ set.add(uuid);
826
+ }
827
+ /** Capabilities a CLI advertises on `system/init`; empty when the field is absent. */
828
+ function parseClaudeCliCapabilities(initMessage) {
829
+ const capabilities = Reflect.get(initMessage, "capabilities");
830
+ return new Set(Array.isArray(capabilities) ? capabilities.filter((entry) => typeof entry === "string") : []);
831
+ }
832
+ /**
833
+ * Root model-turn content frames: a CLI segment's output, as opposed to system, subagent or
834
+ * keep-alive frames. A CLI turn's first such frame carries its echo: a stream event, or the
835
+ * assistant message when nothing streamed. System frames (`api_retry`, compaction) carry no
836
+ * echo, so they never qualify.
837
+ */
838
+ function isClaudeRootTurnFrame(message) {
839
+ if (message.type !== "stream_event" && message.type !== "assistant" && message.type !== "user") return false;
840
+ if (message.type === "stream_event") {
841
+ const event = Reflect.get(message, "event");
842
+ if (typeof event === "object" && event !== null && Reflect.get(event, "type") === "ping") return false;
843
+ }
844
+ return isRootFrame$1(message);
845
+ }
846
+ /**
847
+ * A synthetic API-error reply: the request failed after its retries and the CLI turn ends with
848
+ * the next result, so interrupting it again could only reach whatever the CLI runs next.
849
+ * `max_output_tokens` is excluded because the CLI can continue that turn.
850
+ */
851
+ function isClaudeApiErrorReply(message) {
852
+ if (message.type !== "assistant") return false;
853
+ const error = Reflect.get(message, "error");
854
+ return typeof error === "string" && error !== "max_output_tokens";
855
+ }
856
+ //#endregion
857
+ //#region src/provider/claudeWakeTurn.ts
858
+ /**
859
+ * Claude can start a turn without a prompt (a "wake"): background work finished, a schedule or
860
+ * monitor fired, a rate limit lifted. These rules decide when such a provider turn opens and
861
+ * which frames prove it is alive.
862
+ */
863
+ /** Longest a wake-signal turn may stay open without any root output before it is aborted. */
864
+ const CLAUDE_WAKE_TURN_FIRST_OUTPUT_TIMEOUT_MS = 12e4;
865
+ /** How long Stop waits for the CLI to end a provider turn before finishing it locally. */
866
+ const CLAUDE_PROVIDER_TURN_STOP_GRACE_MS = 5e3;
867
+ function isRootFrame(message) {
868
+ const parentToolUseId = message.parent_tool_use_id;
869
+ return parentToolUseId === null || parentToolUseId === void 0;
870
+ }
871
+ /**
872
+ * Root system/status (requesting|compacting) → "status"; root system/init → "init"; else
873
+ * undefined. A frame with a non-null parent_tool_use_id is never a signal.
874
+ */
875
+ function claudeWakeSignal(message) {
876
+ if (message.type !== "system" || !isRootFrame(message)) return;
877
+ if (message.subtype === "status") return message.status === "requesting" || message.status === "compacting" ? "status" : void 0;
878
+ return message.subtype === "init" ? "init" : void 0;
879
+ }
880
+ /**
881
+ * Deny-list gate; "init" opens only when the CLI was never seen to emit `status: requesting`
882
+ * (legacy CLIs). There is deliberately no allow list: every kind of wake is covered.
883
+ */
884
+ function shouldOpenClaudeWakeTurn(gate) {
885
+ if (gate.hasOpenTurn || gate.sessionStopped || !gate.promptSent || gate.turnInstallsInFlight > 0) return false;
886
+ return gate.signal === "status" || !gate.requestingStatusObserved;
887
+ }
888
+ /**
889
+ * Root frames that prove Claude is producing the current turn (watchdog liveness). A positive
890
+ * list, so a future periodic background frame cannot keep a phantom turn alive.
891
+ */
892
+ function isClaudeRootTurnOutput(message) {
893
+ if (!isRootFrame(message)) return false;
894
+ switch (message.type) {
895
+ case "stream_event":
896
+ case "assistant":
897
+ case "user":
898
+ case "result": return true;
899
+ case "system": switch (message.subtype) {
900
+ case "compact_boundary":
901
+ case "api_retry": return true;
902
+ case "status": return message.status === "compacting";
903
+ default: return false;
904
+ }
905
+ default: return false;
906
+ }
907
+ }
908
+ //#endregion
636
909
  //#region ../../packages/shared/src/cliArgs.ts
637
910
  /**
638
911
  * Parse CLI-style arguments into flags and positionals.
@@ -768,6 +1041,70 @@ function disableContextCompaction(state, generation) {
768
1041
  };
769
1042
  }
770
1043
  //#endregion
1044
+ //#region src/provider/Layers/claudeUsageLimits.ts
1045
+ const CLAUDE_USAGE_LIMIT_FALLBACK_MESSAGE = "Claude usage limit reached.";
1046
+ const MESSAGE_MAX_LENGTH = 500;
1047
+ function resetIso(resetsAtSeconds) {
1048
+ if (resetsAtSeconds === void 0 || !Number.isFinite(resetsAtSeconds)) return null;
1049
+ const ms = resetsAtSeconds * 1e3;
1050
+ return isRepresentableEpochMs(ms) ? new Date(ms).toISOString() : null;
1051
+ }
1052
+ /** Applies one `rate_limit_event` to the session's rejected windows. */
1053
+ function applyClaudeRateLimitInfo(windows, info) {
1054
+ const limitType = info.rateLimitType ?? "unknown";
1055
+ const overageAllowed = info.overageStatus === "allowed" || info.overageStatus === "allowed_warning" || info.isUsingOverage === true || info.overageInUse === true;
1056
+ const blocked = info.status === "rejected" && !overageAllowed;
1057
+ const resetAt = resetIso(info.resetsAt);
1058
+ if (blocked) windows.set(limitType, resetAt);
1059
+ else windows.delete(limitType);
1060
+ return {
1061
+ blocked,
1062
+ key: `${limitType}:${info.resetsAt ?? "unknown"}`,
1063
+ limitType,
1064
+ resetAt
1065
+ };
1066
+ }
1067
+ /** Current state of the rejected windows; windows whose known reset passed are ignored. */
1068
+ function claudeUsageLimitState(windows, nowMs) {
1069
+ return usageLimitStateFromWindows([...windows.values()].map((resetAt) => ({
1070
+ exhausted: true,
1071
+ resetAtMs: resetAt === null ? null : Date.parse(resetAt)
1072
+ })), nowMs);
1073
+ }
1074
+ function trimmed(value) {
1075
+ if (typeof value !== "string") return void 0;
1076
+ const text = value.trim();
1077
+ return text.length > 0 ? text : void 0;
1078
+ }
1079
+ function limitMessage(result) {
1080
+ const message = (result.subtype === "success" ? trimmed(result.result) : trimmed(result.errors?.[0] ?? "")) ?? "Claude usage limit reached.";
1081
+ return message.length > MESSAGE_MAX_LENGTH ? message.slice(0, MESSAGE_MAX_LENGTH) : message;
1082
+ }
1083
+ /**
1084
+ * Whether a turn's result is a usage-limit stop. Only call it for a result that belongs
1085
+ * to an open turn and was not interrupted or cancelled.
1086
+ */
1087
+ function classifyClaudeUsageLimitResult(input) {
1088
+ const { result } = input;
1089
+ const state = claudeUsageLimitState(input.windows, input.nowMs);
1090
+ const terminalReason = result.terminal_reason;
1091
+ if (terminalReason === "blocking_limit") return {
1092
+ message: limitMessage(result),
1093
+ resetAt: state.resetAt
1094
+ };
1095
+ if (!state.exhausted) return null;
1096
+ if (!(result.subtype !== "success" || result.is_error === true)) return null;
1097
+ if (terminalReason !== void 0 && terminalReason !== null && terminalReason !== "api_error") return null;
1098
+ if (result.subtype === "success") {
1099
+ const status = result.api_error_status;
1100
+ if (status !== void 0 && status !== null && status !== 429) return null;
1101
+ }
1102
+ return {
1103
+ message: limitMessage(result),
1104
+ resetAt: state.resetAt
1105
+ };
1106
+ }
1107
+ //#endregion
771
1108
  //#region src/provider/Layers/ClaudeAdapter.ts
772
1109
  /**
773
1110
  * ClaudeAdapterLive - Scoped live implementation for the Claude Agent provider adapter.
@@ -778,20 +1115,49 @@ function disableContextCompaction(state, generation) {
778
1115
  * @module ClaudeAdapterLive
779
1116
  */
780
1117
  const PROVIDER = ProviderDriverKind.make("claudeAgent");
781
- const CLAUDE_SUBAGENT_ATTRIBUTION_CACHE_CAP = 256;
782
- function rememberClaudeSubagentLaunchInput(context, toolUseId, input) {
783
- if (!context.subagentLaunchInputByToolUseId.has(toolUseId) && context.subagentLaunchInputByToolUseId.size >= CLAUDE_SUBAGENT_ATTRIBUTION_CACHE_CAP) {
784
- const oldestToolUseId = context.subagentLaunchInputByToolUseId.keys().next().value;
785
- if (oldestToolUseId !== void 0) context.subagentLaunchInputByToolUseId.delete(oldestToolUseId);
786
- }
787
- context.subagentLaunchInputByToolUseId.set(toolUseId, input);
1118
+ const WAKE_NO_OUTPUT_REASON = "Claude started a background turn but produced no output.";
1119
+ const PROVIDER_TURN_STOP_REASON = "Claude did not end the background turn after Stop.";
1120
+ const DISCARDED_STEER_TURN_REASON = "Claude started a turn for a message Stop cancelled.";
1121
+ const FOLDED_INTO_DISCARDED_STEER_REASON = "Claude Code merged this message into a cancelled steer's request, so no reply is shown. Send it again.";
1122
+ const STEER_TURN_ENDED_DETAIL = "The turn finished before this message could be steered. It stays queued and is sent next.";
1123
+ const CLAUDE_TURN_HEADS_CAP = 64;
1124
+ const CLAUDE_REWIND_PROBE_TIMEOUT = "30 seconds";
1125
+ const CLAUDE_REWIND_TRANSCRIPT_TIMEOUT = "10 seconds";
1126
+ const CLAUDE_REWIND_QUERY_EXIT_MS = 5e3;
1127
+ /** The only turn-state constructor: prompt and provider turns must share one shape. */
1128
+ function makeClaudeTurnState(input) {
1129
+ return {
1130
+ turnId: input.turnId,
1131
+ ...input.promptUuid !== void 0 ? { promptUuid: input.promptUuid } : {},
1132
+ openedBy: input.openedBy,
1133
+ startedAt: input.startedAt,
1134
+ items: [],
1135
+ assistantTextBlocks: /* @__PURE__ */ new Map(),
1136
+ assistantTextBlockOrder: [],
1137
+ capturedProposedPlanKeys: /* @__PURE__ */ new Set(),
1138
+ nextSyntheticAssistantBlockIndex: -1,
1139
+ reasoningBlocks: /* @__PURE__ */ new Map(),
1140
+ reasoningBlockCount: 0,
1141
+ rootOutputObserved: input.openedBy !== "wake-signal",
1142
+ lastChainUuid: void 0,
1143
+ rootContentObserved: input.openedBy !== "wake-signal",
1144
+ completion: void 0,
1145
+ steerPromptUuids: /* @__PURE__ */ new Set(),
1146
+ settledSteerPromptUuids: /* @__PURE__ */ new Set(),
1147
+ startedSteerPromptUuids: /* @__PURE__ */ new Set(),
1148
+ reinterruptedEchoKeys: /* @__PURE__ */ new Set(),
1149
+ interruptRequested: false,
1150
+ sealedSegmentCount: 0,
1151
+ awaitingSteerContinuation: void 0
1152
+ };
788
1153
  }
789
- function rememberClaudeSubagentModel(context, toolUseId, model) {
790
- if (!context.subagentModelByToolUseId.has(toolUseId) && context.subagentModelByToolUseId.size >= CLAUDE_SUBAGENT_ATTRIBUTION_CACHE_CAP) {
791
- const oldestToolUseId = context.subagentModelByToolUseId.keys().next().value;
792
- if (oldestToolUseId !== void 0) context.subagentModelByToolUseId.delete(oldestToolUseId);
1154
+ const CLAUDE_SUBAGENT_ATTRIBUTION_CACHE_CAP = 256;
1155
+ function rememberClaudeSubagentAttribution(cache, toolUseId, value) {
1156
+ if (!cache.has(toolUseId) && cache.size >= CLAUDE_SUBAGENT_ATTRIBUTION_CACHE_CAP) {
1157
+ const oldestToolUseId = cache.keys().next().value;
1158
+ if (oldestToolUseId !== void 0) cache.delete(oldestToolUseId);
793
1159
  }
794
- context.subagentModelByToolUseId.set(toolUseId, model);
1160
+ cache.set(toolUseId, value);
795
1161
  }
796
1162
  function claudeSubagentLaunchModel(input) {
797
1163
  const model = trimmedClaudeString(input?.model);
@@ -811,6 +1177,12 @@ function toMessage(cause, fallback) {
811
1177
  if (cause instanceof Error && cause.message.length > 0) return cause.message;
812
1178
  return fallback;
813
1179
  }
1180
+ /** A typed adapter error's user-level text: its `detail` or `issue`, not its prefixed message. */
1181
+ function adapterFailureDetail(error) {
1182
+ const fields = error;
1183
+ for (const value of [fields.detail, fields.issue]) if (typeof value === "string" && value.trim().length > 0) return value.trim();
1184
+ return error.message;
1185
+ }
814
1186
  function toError(cause, fallback) {
815
1187
  return cause instanceof Error ? cause : new Error(toMessage(cause, fallback));
816
1188
  }
@@ -844,14 +1216,6 @@ function interruptionMessageFromClaudeCause(cause) {
844
1216
  const message = messageFromClaudeStreamCause(cause, "Claude runtime interrupted.");
845
1217
  return isClaudeInterruptedMessage(message) ? "Claude runtime interrupted." : message;
846
1218
  }
847
- function resultErrorsText(result) {
848
- return "errors" in result && Array.isArray(result.errors) ? result.errors.join(" ").toLowerCase() : "";
849
- }
850
- function isInterruptedResult(result) {
851
- const errors = resultErrorsText(result);
852
- if (errors.includes("interrupt")) return true;
853
- return result.subtype === "error_during_execution" && result.is_error === false && (errors.includes("request was aborted") || errors.includes("interrupted by user") || errors.includes("aborted"));
854
- }
855
1219
  function asRuntimeItemId(value) {
856
1220
  return RuntimeItemId.make(value);
857
1221
  }
@@ -905,14 +1269,27 @@ function readClaudeResumeState(resumeCursor) {
905
1269
  const resumeCandidate = typeof cursor.resume === "string" ? cursor.resume : typeof cursor.sessionId === "string" ? cursor.sessionId : void 0;
906
1270
  const resume = resumeCandidate && isUuid(resumeCandidate) ? resumeCandidate : void 0;
907
1271
  const resumeSessionAt = typeof cursor.resumeSessionAt === "string" ? cursor.resumeSessionAt : void 0;
1272
+ const rewind = resumeCursor.rewind;
1273
+ const rewindAt = rewind !== null && typeof rewind === "object" && typeof rewind.at === "string" && rewind.at.length > 0 ? rewind.at : void 0;
908
1274
  const turnCountValue = typeof cursor.turnCount === "number" ? cursor.turnCount : void 0;
909
1275
  return {
910
1276
  ...threadId ? { threadId } : {},
911
1277
  ...resume ? { resume } : {},
912
1278
  ...resumeSessionAt ? { resumeSessionAt } : {},
1279
+ ...rewindAt ? { rewindAt } : {},
913
1280
  ...turnCountValue !== void 0 && Number.isInteger(turnCountValue) && turnCountValue >= 0 ? { turnCount: turnCountValue } : {}
914
1281
  };
915
1282
  }
1283
+ /**
1284
+ * The uuid of a main-chain transcript entry (user, assistant, compaction
1285
+ * boundary), or undefined for subagent sidechains and non-chain frames.
1286
+ */
1287
+ function claudeMainChainUuid(message) {
1288
+ if (!(message.type === "user" || message.type === "assistant" || message.type === "system" && message.subtype === "compact_boundary")) return void 0;
1289
+ const uuid = message.uuid;
1290
+ const parentToolUseId = message.parent_tool_use_id;
1291
+ return typeof uuid === "string" && uuid.length > 0 && (parentToolUseId === null || parentToolUseId === void 0) ? uuid : void 0;
1292
+ }
916
1293
  function trimmedClaudeString(value) {
917
1294
  return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
918
1295
  }
@@ -1161,6 +1538,11 @@ function extractPlanStepsFromTodoInput(input) {
1161
1538
  }));
1162
1539
  }
1163
1540
  function summarizeToolRequest(toolName, input) {
1541
+ const htmlRender = resolveHtmlRenderToolPresentation({
1542
+ toolName,
1543
+ input
1544
+ });
1545
+ if (htmlRender) return htmlRender.detail ? `${toolName}: ${htmlRender.detail}` : toolName;
1164
1546
  const commandValue = input.command ?? input.cmd;
1165
1547
  const command = typeof commandValue === "string" ? commandValue : void 0;
1166
1548
  if (command && command.trim().length > 0) return `${toolName}: ${command.trim().slice(0, 400)}`;
@@ -1174,6 +1556,24 @@ function summarizeToolRequest(toolName, input) {
1174
1556
  if (serialized.length <= 400) return `${toolName}: ${serialized}`;
1175
1557
  return `${toolName}: ${serialized.slice(0, 397)}...`;
1176
1558
  }
1559
+ /** Work-log detail of a tool item: an HTML tool shows its page title or viewport alone. */
1560
+ function toolItemDetail(toolName, input) {
1561
+ const htmlRender = resolveHtmlRenderToolPresentation({
1562
+ toolName,
1563
+ input
1564
+ });
1565
+ return htmlRender ? htmlRender.detail : summarizeToolRequest(toolName, input);
1566
+ }
1567
+ function toolItemTitle(toolName, itemType) {
1568
+ return resolveHtmlRenderToolPresentation({
1569
+ toolName,
1570
+ input: void 0
1571
+ })?.title ?? titleForTool(itemType);
1572
+ }
1573
+ /** Tool input as carried on runtime events: an HTML tool's page is reduced to its length. */
1574
+ function toolEventInput(toolName, input) {
1575
+ return resolveHtmlRenderToolKind(toolName) === void 0 ? input : withoutHtmlRenderMarkup(input);
1576
+ }
1177
1577
  function titleForTool(itemType) {
1178
1578
  switch (itemType) {
1179
1579
  case "command_execution": return "Command run";
@@ -1291,11 +1691,25 @@ const buildUserMessageEffect = Effect.fn("buildUserMessageEffect")(function* (in
1291
1691
  });
1292
1692
  function turnStatusFromResult(result) {
1293
1693
  if (result.subtype === "success") return "completed";
1694
+ if (isClaudeAbortTerminalReason(result)) return "interrupted";
1294
1695
  const errors = resultErrorsText(result);
1295
1696
  if (isInterruptedResult(result)) return "interrupted";
1296
1697
  if (errors.includes("cancel")) return "cancelled";
1297
1698
  return "failed";
1298
1699
  }
1700
+ /** The error a completing turn reports, by why it reports its status (`decideClaudeTurnClose`). */
1701
+ function claudeTurnCloseErrorMessage(cause, result) {
1702
+ switch (cause) {
1703
+ case "result": return result.subtype === "success" ? void 0 : result.errors[0];
1704
+ case "aborted-by-steer": return;
1705
+ case "stopped": return "Interrupted by user.";
1706
+ case "failed-segment-dropped-steers": {
1707
+ const text = result.subtype === "success" ? result.result.trim() : result.errors[0];
1708
+ return text !== void 0 && text.length > 0 ? text : "Claude turn failed.";
1709
+ }
1710
+ case "folded-into-discarded-cli-turn": return FOLDED_INTO_DISCARDED_STEER_REASON;
1711
+ }
1712
+ }
1299
1713
  function streamKindFromDeltaType(deltaType) {
1300
1714
  return deltaType.includes("thinking") ? "reasoning_text" : "assistant_text";
1301
1715
  }
@@ -1336,6 +1750,35 @@ function extractExitPlanModePlan(value) {
1336
1750
  function exitPlanCaptureKey(input) {
1337
1751
  return input.toolUseId && input.toolUseId.length > 0 ? `tool:${input.toolUseId}` : `plan:${input.planMarkdown}`;
1338
1752
  }
1753
+ const EMPTY_STREAMED_JSON_SCAN = {
1754
+ depth: 0,
1755
+ inString: false,
1756
+ escaped: false,
1757
+ opened: false
1758
+ };
1759
+ function scanStreamedJson(scan, chunk) {
1760
+ let { depth, inString, escaped, opened } = scan;
1761
+ for (let index = 0; index < chunk.length; index += 1) {
1762
+ const code = chunk.charCodeAt(index);
1763
+ if (inString) {
1764
+ if (escaped) escaped = false;
1765
+ else if (code === 92) escaped = true;
1766
+ else if (code === 34) inString = false;
1767
+ } else if (code === 34) inString = true;
1768
+ else if (code === 123 || code === 91) {
1769
+ depth += 1;
1770
+ opened = true;
1771
+ } else if (code === 125 || code === 93) depth -= 1;
1772
+ }
1773
+ return {
1774
+ depth,
1775
+ inString,
1776
+ escaped,
1777
+ opened
1778
+ };
1779
+ }
1780
+ /** Every complete JSON object passes this, so skipping the parse otherwise changes nothing. */
1781
+ const mayBeCompleteJson = (scan) => scan.opened && scan.depth === 0 && !scan.inString;
1339
1782
  function tryParseJsonRecord(value) {
1340
1783
  try {
1341
1784
  const parsed = JSON.parse(value);
@@ -1443,13 +1886,19 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
1443
1886
  const serverConfig = yield* ServerConfig;
1444
1887
  const claudeEnvironment = yield* makeClaudeEnvironment(claudeSettings, options?.environment).pipe(Effect.provideService(Path.Path, path));
1445
1888
  const nativeEventLogger = options?.nativeEventLogger ?? (options?.nativeEventLogPath !== void 0 ? yield* makeEventNdjsonLogger(options.nativeEventLogPath, { stream: "native" }) : void 0);
1889
+ const readSessionMessages = options?.readSessionMessages ?? ((sessionId, readOptions) => getSessionMessages(sessionId, {
1890
+ ...readOptions.dir !== void 0 ? { dir: readOptions.dir } : {},
1891
+ includeSystemMessages: readOptions.includeSystemMessages
1892
+ }));
1893
+ /** Threads whose session is being closed and reopened by a checkpoint revert. */
1894
+ const rewindingThreads = /* @__PURE__ */ new Set();
1446
1895
  const createQuery = options?.createQuery ?? ((input) => query({
1447
1896
  prompt: input.prompt,
1448
1897
  options: input.options
1449
1898
  }));
1450
1899
  const sessions = /* @__PURE__ */ new Map();
1451
1900
  let nextSessionGeneration = 0;
1452
- const runtimeEventQueue = yield* Queue.bounded(2048);
1901
+ const runtimeEventQueue = yield* Queue.bounded(options?.runtimeEventQueueCapacity ?? 2048);
1453
1902
  const runtimeEventQueueMetrics = yield* makeServerQueueMetrics({
1454
1903
  queue: "provider.adapter.runtimeEvents",
1455
1904
  component: "ClaudeAdapter",
@@ -1591,18 +2040,19 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
1591
2040
  };
1592
2041
  });
1593
2042
  const updateResumeCursor = Effect.fn("updateResumeCursor")(function* (context) {
1594
- const threadId = context.session.threadId;
1595
- if (!threadId) return;
2043
+ if (!context.session.threadId) return;
2044
+ const updatedAt = yield* nowIso;
1596
2045
  const resumeCursor = {
1597
- threadId,
2046
+ threadId: context.session.threadId,
1598
2047
  ...context.resumeSessionId ? { resume: context.resumeSessionId } : {},
1599
2048
  ...context.lastAssistantUuid ? { resumeSessionAt: context.lastAssistantUuid } : {},
2049
+ ...context.pendingRewind ? { rewind: { at: context.pendingRewind.at } } : {},
1600
2050
  turnCount: context.turns.length
1601
2051
  };
1602
2052
  context.session = {
1603
2053
  ...context.session,
1604
2054
  resumeCursor,
1605
- updatedAt: yield* nowIso
2055
+ updatedAt
1606
2056
  };
1607
2057
  });
1608
2058
  const ensureAssistantTextBlock = Effect.fn("ensureAssistantTextBlock")(function* (context, blockIndex, options) {
@@ -1741,7 +2191,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
1741
2191
  });
1742
2192
  }
1743
2193
  });
1744
- const emitRuntimeError = Effect.fn("emitRuntimeError")(function* (context, message, cause) {
2194
+ const emitRuntimeError = Effect.fn("emitRuntimeError")(function* (context, message, cause, options) {
1745
2195
  if (cause !== void 0) {}
1746
2196
  const turnState = context.turnState;
1747
2197
  const stamp = yield* makeEventStamp();
@@ -1754,8 +2204,9 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
1754
2204
  ...turnState ? { turnId: asCanonicalTurnId(turnState.turnId) } : {},
1755
2205
  payload: {
1756
2206
  message,
1757
- class: "provider_error",
1758
- ...cause !== void 0 ? { detail: cause } : {}
2207
+ class: options?.class ?? "provider_error",
2208
+ ...cause !== void 0 ? { detail: cause } : {},
2209
+ ...options?.resetAt !== void 0 ? { resetAt: options.resetAt } : {}
1759
2210
  },
1760
2211
  providerRefs: nativeProviderRefs(context)
1761
2212
  });
@@ -1838,7 +2289,8 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
1838
2289
  yield* emitCompactionUnavailableWarning(context);
1839
2290
  }
1840
2291
  });
1841
- const completeTurn = Effect.fn("completeTurn")(function* (context, status, errorMessage, result) {
2292
+ /** The context gauge a result (or a local close without one) publishes. */
2293
+ const resolveResultUsageSnapshot = Effect.fn("resolveResultUsageSnapshot")(function* (context, result) {
1842
2294
  const resultCounts = readClaudeCacheCounts(result?.usage);
1843
2295
  if (context.cacheObservation && resultCounts?.outputTokens !== void 0) context.cacheObservation = {
1844
2296
  ...context.cacheObservation,
@@ -1852,41 +2304,46 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
1852
2304
  const resultContextWindow = mainClaudeContextWindowFromModelUsage(result?.modelUsage, context.cacheObservation?.model ?? context.currentApiModelId);
1853
2305
  if (resultContextWindow !== void 0) context.lastKnownContextWindow = resultContextWindow;
1854
2306
  const accumulatedSnapshot = normalizeClaudeTokenUsage(result?.usage, resultContextWindow ?? context.lastKnownContextWindow);
1855
- const accumulatedTotalProcessedTokens = accumulatedSnapshot?.totalProcessedTokens ?? accumulatedSnapshot?.usedTokens;
1856
- const lastGoodUsage = context.lastKnownTokenUsage;
1857
- const maxTokens = resultContextWindow ?? context.lastKnownContextWindow;
1858
- const rawUsageSnapshot = lastGoodUsage ? {
1859
- ...lastGoodUsage,
1860
- ...typeof maxTokens === "number" && Number.isFinite(maxTokens) && maxTokens > 0 ? { maxTokens } : {},
1861
- ...typeof accumulatedTotalProcessedTokens === "number" && Number.isFinite(accumulatedTotalProcessedTokens) && accumulatedTotalProcessedTokens > lastGoodUsage.usedTokens ? { totalProcessedTokens: accumulatedTotalProcessedTokens } : {}
1862
- } : accumulatedSnapshot;
1863
- const usageSnapshot = rawUsageSnapshot ? withAutomaticCompactionCapability({
2307
+ const rawUsageSnapshot = selectClaudeResultUsageGauge({
2308
+ lastGauge: context.lastKnownTokenUsage,
2309
+ cumulative: accumulatedSnapshot,
2310
+ maxTokens: resultContextWindow ?? context.lastKnownContextWindow,
2311
+ cumulativeIsGauge: !context.cumulativeUsageSpansCompaction
2312
+ });
2313
+ if (result !== void 0) context.cumulativeUsageSpansCompaction = false;
2314
+ return rawUsageSnapshot ? withAutomaticCompactionCapability({
1864
2315
  ...rawUsageSnapshot,
2316
+ ...accumulatedSnapshot ? { processedUsage: {
2317
+ scope: "turn",
2318
+ inputTokens: accumulatedSnapshot.inputTokens ?? 0,
2319
+ cachedInputTokens: accumulatedSnapshot.cachedInputTokens ?? 0,
2320
+ outputTokens: accumulatedSnapshot.outputTokens ?? 0,
2321
+ reasoningOutputTokens: accumulatedSnapshot.reasoningOutputTokens ?? 0,
2322
+ totalTokens: accumulatedSnapshot.totalProcessedTokens ?? accumulatedSnapshot.usedTokens
2323
+ } } : {},
1865
2324
  ...context.cacheObservation ? { claudeCache: context.cacheObservation } : {}
1866
2325
  }, context.supportsAutomaticCompaction) : void 0;
1867
- const turnState = context.turnState;
1868
- if (!turnState) {
1869
- if (usageSnapshot) {
1870
- const usageStamp = yield* makeEventStamp();
1871
- yield* offerRuntimeEventForContext(context, {
1872
- type: "thread.token-usage.updated",
1873
- eventId: usageStamp.eventId,
1874
- provider: PROVIDER,
1875
- createdAt: usageStamp.createdAt,
1876
- threadId: context.session.threadId,
1877
- payload: { usage: usageSnapshot },
1878
- providerRefs: {}
1879
- });
1880
- }
1881
- yield* Effect.logInfo("claude.turn.result-without-active-turn", {
1882
- threadId: context.session.threadId,
1883
- status,
1884
- numTurns: result?.num_turns,
1885
- hasUsage: result?.usage !== void 0,
1886
- ...errorMessage ? { errorMessage } : {}
1887
- });
1888
- return;
1889
- }
2326
+ });
2327
+ /** Publishes a context-gauge snapshot, attributed to a turn when one is given. */
2328
+ const emitTokenUsageSnapshot = Effect.fn("emitTokenUsageSnapshot")(function* (context, usageSnapshot, turnId) {
2329
+ if (!usageSnapshot) return;
2330
+ const usageStamp = yield* makeEventStamp();
2331
+ yield* offerRuntimeEventForContext(context, {
2332
+ type: "thread.token-usage.updated",
2333
+ eventId: usageStamp.eventId,
2334
+ provider: PROVIDER,
2335
+ createdAt: usageStamp.createdAt,
2336
+ threadId: context.session.threadId,
2337
+ ...turnId !== void 0 ? { turnId } : {},
2338
+ payload: { usage: usageSnapshot },
2339
+ providerRefs: nativeProviderRefs(context)
2340
+ });
2341
+ });
2342
+ /**
2343
+ * Closes everything a CLI segment left open (in-flight tools, assistant text and reasoning
2344
+ * blocks) while the turn itself may stay open: between a steer's segments and at completion.
2345
+ */
2346
+ const sealTurnSegment = Effect.fn("sealTurnSegment")(function* (context, turnState, status, result) {
1890
2347
  for (const [index, tool] of context.inFlightTools.entries()) {
1891
2348
  const toolStamp = yield* makeEventStamp();
1892
2349
  yield* offerRuntimeEventForContext(context, {
@@ -1904,7 +2361,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
1904
2361
  ...tool.detail ? { detail: tool.detail } : {},
1905
2362
  data: {
1906
2363
  toolName: tool.toolName,
1907
- input: tool.input
2364
+ input: toolEventInput(tool.toolName, tool.input)
1908
2365
  }
1909
2366
  },
1910
2367
  providerRefs: nativeProviderRefs(context, { providerItemId: tool.itemId }),
@@ -1923,25 +2380,73 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
1923
2380
  rawMethod: "claude/result",
1924
2381
  rawPayload: result ?? { status }
1925
2382
  });
2383
+ turnState.assistantTextBlockOrder.length = 0;
2384
+ for (const reasoningBlock of turnState.reasoningBlocks.values()) {
2385
+ const stamp = yield* makeEventStamp();
2386
+ yield* offerRuntimeEventForContext(context, {
2387
+ type: "item.completed",
2388
+ eventId: stamp.eventId,
2389
+ provider: PROVIDER,
2390
+ createdAt: stamp.createdAt,
2391
+ threadId: context.session.threadId,
2392
+ turnId: asCanonicalTurnId(turnState.turnId),
2393
+ itemId: asRuntimeItemId(reasoningBlock.itemId),
2394
+ payload: {
2395
+ itemType: "reasoning",
2396
+ status: status === "failed" ? "failed" : "completed",
2397
+ title: "Reasoning"
2398
+ },
2399
+ providerRefs: nativeProviderRefs(context),
2400
+ raw: {
2401
+ source: "claude.sdk.message",
2402
+ method: "claude/result",
2403
+ payload: result ?? { status }
2404
+ }
2405
+ });
2406
+ }
2407
+ turnState.reasoningBlocks.clear();
2408
+ });
2409
+ /** A result (or local close) with no open turn: keep usage, never publish a lifecycle event. */
2410
+ const publishTurnlessResult = Effect.fn("publishTurnlessResult")(function* (context, status, errorMessage, result) {
2411
+ yield* emitTokenUsageSnapshot(context, yield* resolveResultUsageSnapshot(context, result), void 0);
2412
+ yield* Effect.logInfo("claude.turn.result-without-active-turn", {
2413
+ threadId: context.session.threadId,
2414
+ status,
2415
+ numTurns: result?.num_turns,
2416
+ hasUsage: result?.usage !== void 0,
2417
+ ...errorMessage ? { errorMessage } : {}
2418
+ });
2419
+ });
2420
+ /** Finishes a turn this fiber claimed in `completeTurn`. Never call it directly. */
2421
+ const finishClaimedTurn = Effect.fn("finishClaimedTurn")(function* (context, turnState, completion, status, errorMessage, result, options) {
2422
+ const usageSnapshot = yield* resolveResultUsageSnapshot(context, result);
2423
+ yield* sealTurnSegment(context, turnState, status, result);
1926
2424
  context.turns.push({
1927
2425
  id: turnState.turnId,
1928
2426
  items: [...turnState.items]
1929
2427
  });
1930
- if (usageSnapshot) {
1931
- const usageStamp = yield* makeEventStamp();
1932
- yield* offerRuntimeEventForContext(context, {
1933
- type: "thread.token-usage.updated",
1934
- eventId: usageStamp.eventId,
1935
- provider: PROVIDER,
1936
- createdAt: usageStamp.createdAt,
1937
- threadId: context.session.threadId,
2428
+ if (turnState.lastChainUuid !== void 0) {
2429
+ context.turnHeads.push({
1938
2430
  turnId: turnState.turnId,
1939
- payload: { usage: usageSnapshot },
1940
- providerRefs: nativeProviderRefs(context)
2431
+ head: turnState.lastChainUuid
1941
2432
  });
2433
+ if (context.turnHeads.length > CLAUDE_TURN_HEADS_CAP) context.turnHeads.shift();
1942
2434
  }
2435
+ if (status === "completed") context.pendingRewind = void 0;
2436
+ yield* updateResumeCursor(context);
2437
+ yield* emitTokenUsageSnapshot(context, usageSnapshot, turnState.turnId);
1943
2438
  const stamp = yield* makeEventStamp();
1944
- yield* offerRuntimeEventForContext(context, {
2439
+ if (options?.abortReason !== void 0) yield* offerRuntimeEventForContext(context, {
2440
+ type: "turn.aborted",
2441
+ eventId: stamp.eventId,
2442
+ provider: PROVIDER,
2443
+ createdAt: stamp.createdAt,
2444
+ threadId: context.session.threadId,
2445
+ turnId: turnState.turnId,
2446
+ payload: { reason: options.abortReason },
2447
+ providerRefs: nativeProviderRefs(context)
2448
+ });
2449
+ else yield* offerRuntimeEventForContext(context, {
1945
2450
  type: "turn.completed",
1946
2451
  eventId: stamp.eventId,
1947
2452
  provider: PROVIDER,
@@ -1959,18 +2464,45 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
1959
2464
  providerRefs: nativeProviderRefs(context)
1960
2465
  });
1961
2466
  const updatedAt = yield* nowIso;
1962
- context.turnState = void 0;
1963
- context.session = {
1964
- ...context.session,
1965
- status: "ready",
1966
- activeTurnId: void 0,
1967
- updatedAt,
1968
- ...status === "failed" && errorMessage ? { lastError: errorMessage } : {}
1969
- };
2467
+ if (context.turnState === turnState) {
2468
+ context.turnState = void 0;
2469
+ context.session = {
2470
+ ...context.session,
2471
+ status: "ready",
2472
+ activeTurnId: void 0,
2473
+ updatedAt,
2474
+ ...status === "failed" && errorMessage ? { lastError: errorMessage } : {}
2475
+ };
2476
+ }
2477
+ Deferred.doneUnsafe(completion, Effect.void);
1970
2478
  if (context.agentControl) yield* context.agentControl.retireTurn(turnState.turnId);
1971
- yield* updateResumeCursor(context);
1972
2479
  if (status === "completed" && usageSnapshot) yield* maybeEnableAutomaticCompaction(context, usageSnapshot);
1973
2480
  });
2481
+ /**
2482
+ * The single owner of turn completion. The open turn is claimed synchronously at entry, so a
2483
+ * concurrent close (sendTurn, Stop grace, watchdog, stream exit) waits for the claimer instead
2484
+ * of emitting a second lifecycle event.
2485
+ */
2486
+ const completeTurn = Effect.fn("completeTurn")(function* (context, status, errorMessage, result, options) {
2487
+ const turnState = context.turnState;
2488
+ if (options?.expectedTurnState !== void 0 && turnState !== options.expectedTurnState) return;
2489
+ if (turnState?.completion !== void 0) {
2490
+ if (result !== void 0) yield* Effect.logInfo("claude.turn.result-during-completion", {
2491
+ threadId: context.session.threadId,
2492
+ turnId: turnState.turnId,
2493
+ status
2494
+ });
2495
+ yield* Deferred.await(turnState.completion);
2496
+ return;
2497
+ }
2498
+ if (turnState === void 0) return yield* publishTurnlessResult(context, status, errorMessage, result);
2499
+ const completion = Deferred.makeUnsafe();
2500
+ turnState.completion = completion;
2501
+ yield* finishClaimedTurn(context, turnState, completion, status, errorMessage, result, options).pipe(Effect.ensuring(Effect.sync(() => {
2502
+ if (context.turnState === turnState) turnState.completion = void 0;
2503
+ Deferred.doneUnsafe(completion, Effect.void);
2504
+ })));
2505
+ });
1974
2506
  const handleStreamEvent = Effect.fn("handleStreamEvent")(function* (context, message) {
1975
2507
  if (message.type !== "stream_event") return;
1976
2508
  const { event } = message;
@@ -1999,10 +2531,8 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
1999
2531
  const deltaText = event.delta.type === "text_delta" ? event.delta.text : typeof event.delta.thinking === "string" ? event.delta.thinking : "";
2000
2532
  if (deltaText.length === 0) return;
2001
2533
  const streamKind = streamKindFromDeltaType(event.delta.type);
2002
- const assistantBlockEntry = event.delta.type === "text_delta" ? yield* ensureAssistantTextBlock(context, event.index) : context.turnState.assistantTextBlocks.get(event.index) ? {
2003
- blockIndex: event.index,
2004
- block: context.turnState.assistantTextBlocks.get(event.index)
2005
- } : void 0;
2534
+ const reasoningBlock = event.delta.type === "thinking_delta" ? context.turnState.reasoningBlocks.get(event.index) : void 0;
2535
+ const assistantBlockEntry = event.delta.type === "text_delta" ? yield* ensureAssistantTextBlock(context, event.index) : void 0;
2006
2536
  if (assistantBlockEntry?.block && event.delta.type === "text_delta") assistantBlockEntry.block.emittedTextDelta = true;
2007
2537
  const stamp = yield* makeEventStamp();
2008
2538
  yield* offerRuntimeEventForContext(context, {
@@ -2012,7 +2542,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
2012
2542
  createdAt: stamp.createdAt,
2013
2543
  threadId: context.session.threadId,
2014
2544
  turnId: context.turnState.turnId,
2015
- ...assistantBlockEntry?.block ? { itemId: asRuntimeItemId(assistantBlockEntry.block.itemId) } : {},
2545
+ ...assistantBlockEntry?.block ? { itemId: asRuntimeItemId(assistantBlockEntry.block.itemId) } : reasoningBlock ? { itemId: asRuntimeItemId(reasoningBlock.itemId) } : {},
2016
2546
  payload: {
2017
2547
  streamKind,
2018
2548
  delta: deltaText
@@ -2030,17 +2560,19 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
2030
2560
  const tool = context.inFlightTools.get(event.index);
2031
2561
  if (!tool || typeof event.delta.partial_json !== "string") return;
2032
2562
  const partialInputJson = tool.partialInputJson + event.delta.partial_json;
2033
- const parsedInput = tryParseJsonRecord(partialInputJson);
2034
- const detail = parsedInput ? summarizeToolRequest(tool.toolName, parsedInput) : tool.detail;
2563
+ const partialInputScan = scanStreamedJson(tool.partialInputScan, event.delta.partial_json);
2564
+ const parsedInput = mayBeCompleteJson(partialInputScan) ? tryParseJsonRecord(partialInputJson) : void 0;
2565
+ const detail = parsedInput ? toolItemDetail(tool.toolName, parsedInput) : tool.detail;
2035
2566
  let nextTool = {
2036
2567
  ...tool,
2037
2568
  partialInputJson,
2569
+ partialInputScan,
2038
2570
  ...parsedInput ? { input: parsedInput } : {},
2039
2571
  ...detail ? { detail } : {}
2040
2572
  };
2041
2573
  const nextFingerprint = parsedInput && Object.keys(parsedInput).length > 0 ? toolInputFingerprint(parsedInput) : void 0;
2042
2574
  context.inFlightTools.set(event.index, nextTool);
2043
- if (nextTool.itemType === "collab_agent_tool_call" && parsedInput) rememberClaudeSubagentLaunchInput(context, nextTool.itemId, parsedInput);
2575
+ if (nextTool.itemType === "collab_agent_tool_call" && parsedInput) rememberClaudeSubagentAttribution(context.subagentLaunchInputByToolUseId, nextTool.itemId, parsedInput);
2044
2576
  if (!parsedInput || !nextFingerprint || tool.lastEmittedInputFingerprint === nextFingerprint) return;
2045
2577
  nextTool = {
2046
2578
  ...nextTool,
@@ -2065,7 +2597,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
2065
2597
  ...nextTool.parentToolUseId ? { parentToolUseId: nextTool.parentToolUseId } : {},
2066
2598
  data: {
2067
2599
  toolName: nextTool.toolName,
2068
- input: nextTool.input
2600
+ input: toolEventInput(nextTool.toolName, nextTool.input)
2069
2601
  }
2070
2602
  },
2071
2603
  providerRefs: nativeProviderRefs(context, { providerItemId: nextTool.itemId }),
@@ -2100,12 +2632,40 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
2100
2632
  yield* ensureAssistantTextBlock(context, index, { fallbackText: extractContentBlockText(block) });
2101
2633
  return;
2102
2634
  }
2635
+ if (block.type === "thinking" && context.turnState) {
2636
+ const turnState = context.turnState;
2637
+ turnState.reasoningBlockCount += 1;
2638
+ const itemId = `${turnState.turnId}:thinking:${turnState.reasoningBlockCount}`;
2639
+ turnState.reasoningBlocks.set(index, { itemId });
2640
+ const stamp = yield* makeEventStamp();
2641
+ yield* offerRuntimeEventForContext(context, {
2642
+ type: "item.started",
2643
+ eventId: stamp.eventId,
2644
+ provider: PROVIDER,
2645
+ createdAt: stamp.createdAt,
2646
+ threadId: context.session.threadId,
2647
+ turnId: asCanonicalTurnId(turnState.turnId),
2648
+ itemId: asRuntimeItemId(itemId),
2649
+ payload: {
2650
+ itemType: "reasoning",
2651
+ status: "inProgress",
2652
+ title: "Reasoning"
2653
+ },
2654
+ providerRefs: nativeProviderRefs(context),
2655
+ raw: {
2656
+ source: "claude.sdk.message",
2657
+ method: "claude/stream_event/content_block_start",
2658
+ payload: message
2659
+ }
2660
+ });
2661
+ return;
2662
+ }
2103
2663
  if (block.type !== "tool_use" && block.type !== "server_tool_use" && block.type !== "mcp_tool_use") return;
2104
2664
  const toolName = block.name;
2105
2665
  const itemType = classifyToolItemType(toolName);
2106
2666
  const toolInput = typeof block.input === "object" && block.input !== null ? block.input : {};
2107
2667
  const itemId = block.id;
2108
- const detail = summarizeToolRequest(toolName, toolInput);
2668
+ const detail = toolItemDetail(toolName, toolInput);
2109
2669
  const inputFingerprint = Object.keys(toolInput).length > 0 ? toolInputFingerprint(toolInput) : void 0;
2110
2670
  const parentToolUseId = message.parent_tool_use_id ?? void 0;
2111
2671
  const owningAgentId = agentIdForParentToolUse(context.taskAgents, parentToolUseId);
@@ -2113,16 +2673,17 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
2113
2673
  itemId,
2114
2674
  itemType,
2115
2675
  toolName,
2116
- title: titleForTool(itemType),
2117
- detail,
2676
+ title: toolItemTitle(toolName, itemType),
2677
+ ...detail ? { detail } : {},
2118
2678
  input: toolInput,
2119
2679
  partialInputJson: "",
2680
+ partialInputScan: EMPTY_STREAMED_JSON_SCAN,
2120
2681
  ...inputFingerprint ? { lastEmittedInputFingerprint: inputFingerprint } : {},
2121
2682
  ...owningAgentId ? { agentId: owningAgentId } : {},
2122
2683
  ...parentToolUseId ? { parentToolUseId } : {}
2123
2684
  };
2124
2685
  context.inFlightTools.set(index, tool);
2125
- if (itemType === "collab_agent_tool_call") rememberClaudeSubagentLaunchInput(context, itemId, toolInput);
2686
+ if (itemType === "collab_agent_tool_call") rememberClaudeSubagentAttribution(context.subagentLaunchInputByToolUseId, itemId, toolInput);
2126
2687
  const stamp = yield* makeEventStamp();
2127
2688
  yield* offerRuntimeEventForContext(context, {
2128
2689
  type: "item.started",
@@ -2141,7 +2702,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
2141
2702
  ...tool.parentToolUseId ? { parentToolUseId: tool.parentToolUseId } : {},
2142
2703
  data: {
2143
2704
  toolName: tool.toolName,
2144
- input: toolInput
2705
+ input: toolEventInput(tool.toolName, toolInput)
2145
2706
  }
2146
2707
  },
2147
2708
  providerRefs: nativeProviderRefs(context, { providerItemId: tool.itemId }),
@@ -2155,6 +2716,32 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
2155
2716
  }
2156
2717
  if (event.type === "content_block_stop") {
2157
2718
  const { index } = event;
2719
+ const reasoningBlock = context.turnState?.reasoningBlocks.get(index);
2720
+ if (reasoningBlock && context.turnState) {
2721
+ context.turnState.reasoningBlocks.delete(index);
2722
+ const stamp = yield* makeEventStamp();
2723
+ yield* offerRuntimeEventForContext(context, {
2724
+ type: "item.completed",
2725
+ eventId: stamp.eventId,
2726
+ provider: PROVIDER,
2727
+ createdAt: stamp.createdAt,
2728
+ threadId: context.session.threadId,
2729
+ turnId: asCanonicalTurnId(context.turnState.turnId),
2730
+ itemId: asRuntimeItemId(reasoningBlock.itemId),
2731
+ payload: {
2732
+ itemType: "reasoning",
2733
+ status: "completed",
2734
+ title: "Reasoning"
2735
+ },
2736
+ providerRefs: nativeProviderRefs(context),
2737
+ raw: {
2738
+ source: "claude.sdk.message",
2739
+ method: "claude/stream_event/content_block_stop",
2740
+ payload: message
2741
+ }
2742
+ });
2743
+ return;
2744
+ }
2158
2745
  const assistantBlock = context.turnState?.assistantTextBlocks.get(index);
2159
2746
  if (assistantBlock) {
2160
2747
  assistantBlock.streamClosed = true;
@@ -2177,7 +2764,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
2177
2764
  const itemStatus = toolResult.isError ? "failed" : "completed";
2178
2765
  const toolData = {
2179
2766
  toolName: tool.toolName,
2180
- input: tool.input,
2767
+ input: toolEventInput(tool.toolName, tool.input),
2181
2768
  result: toolResult.block
2182
2769
  };
2183
2770
  const updatedStamp = yield* makeEventStamp();
@@ -2282,6 +2869,49 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
2282
2869
  context.inFlightTools.delete(index);
2283
2870
  }
2284
2871
  });
2872
+ /**
2873
+ * Opens a provider turn: one Claude started without a prompt, either at its turn-start signal
2874
+ * ("wake-signal") or, when no signal opened one, at its first root assistant output. Never
2875
+ * bound to Agent Control authority; exact-turn binding stays prompt-only.
2876
+ */
2877
+ const startProviderTurn = Effect.fn("startProviderTurn")(function* (context, openedBy) {
2878
+ const turnId = TurnId.make(yield* Effect.sync(() => crypto.randomUUID()));
2879
+ const startedAt = yield* nowIso;
2880
+ if (context.turnState !== void 0 || context.stopped) return;
2881
+ if (openedBy === "wake-signal" && (context.turnInstallsInFlight > 0 || !context.promptSent)) return;
2882
+ const turnState = makeClaudeTurnState({
2883
+ turnId,
2884
+ startedAt,
2885
+ openedBy
2886
+ });
2887
+ context.turnState = turnState;
2888
+ context.session = {
2889
+ ...context.session,
2890
+ status: "running",
2891
+ activeTurnId: turnId,
2892
+ updatedAt: startedAt
2893
+ };
2894
+ const turnStartedStamp = yield* makeEventStamp();
2895
+ yield* offerRuntimeEventForContext(context, {
2896
+ type: "turn.started",
2897
+ eventId: turnStartedStamp.eventId,
2898
+ provider: PROVIDER,
2899
+ createdAt: turnStartedStamp.createdAt,
2900
+ threadId: context.session.threadId,
2901
+ turnId,
2902
+ payload: {},
2903
+ providerRefs: {
2904
+ ...nativeProviderRefs(context),
2905
+ providerTurnId: turnId
2906
+ },
2907
+ raw: {
2908
+ source: "claude.sdk.message",
2909
+ method: "claude/synthetic-turn-start",
2910
+ payload: { openedBy }
2911
+ }
2912
+ });
2913
+ if (openedBy === "wake-signal") yield* Effect.sleep(Duration.millis(CLAUDE_WAKE_TURN_FIRST_OUTPUT_TIMEOUT_MS)).pipe(Effect.andThen(Effect.suspend(() => context.turnState === turnState && !turnState.rootOutputObserved && !context.stopped ? completeTurn(context, "interrupted", WAKE_NO_OUTPUT_REASON, void 0, { abortReason: WAKE_NO_OUTPUT_REASON }) : Effect.void)), Effect.ignoreCause({ log: true }), Effect.forkDetach);
2914
+ });
2285
2915
  const handleAssistantMessage = Effect.fn("handleAssistantMessage")(function* (context, message) {
2286
2916
  if (message.type !== "assistant") return;
2287
2917
  const assistantParentToolUseId = message.parent_tool_use_id;
@@ -2289,8 +2919,39 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
2289
2919
  const owningTaskId = agentIdForParentToolUse(context.taskAgents, assistantParentToolUseId);
2290
2920
  const snapshotModel = trimmedClaudeString(message.message.model);
2291
2921
  const owningAgent = owningTaskId ? context.taskAgents.get(owningTaskId) : void 0;
2292
- if (owningAgent && snapshotModel) owningAgent.model = snapshotModel;
2293
- else if (snapshotModel) rememberClaudeSubagentModel(context, assistantParentToolUseId, snapshotModel);
2922
+ if (owningAgent && snapshotModel && owningAgent.model !== snapshotModel) {
2923
+ owningAgent.model = snapshotModel;
2924
+ const stamp = yield* makeEventStamp();
2925
+ yield* offerRuntimeEventForContext(context, {
2926
+ ...stamp,
2927
+ type: "task.updated",
2928
+ provider: PROVIDER,
2929
+ threadId: context.session.threadId,
2930
+ ...context.turnState ? { turnId: asCanonicalTurnId(context.turnState.turnId) } : {},
2931
+ providerRefs: nativeProviderRefs(context),
2932
+ payload: {
2933
+ taskId: RuntimeTaskId.make(owningAgent.taskId),
2934
+ ...taskLinkageFor(context.taskAgents, owningAgent.taskId)
2935
+ }
2936
+ });
2937
+ const existingSubagent = context.subagentByTaskId.get(owningAgent.taskId);
2938
+ if (existingSubagent) {
2939
+ const subagent = {
2940
+ ...existingSubagent,
2941
+ model: snapshotModel
2942
+ };
2943
+ context.subagentByTaskId.set(owningAgent.taskId, subagent);
2944
+ yield* emitClaudeSubagentUpdated(context, {
2945
+ subagent,
2946
+ raw: message
2947
+ });
2948
+ }
2949
+ } else if (!owningAgent && snapshotModel) rememberClaudeSubagentAttribution(context.subagentModelByToolUseId, assistantParentToolUseId, snapshotModel);
2950
+ for (const block of message.message.content) {
2951
+ if (block.type !== "tool_use") continue;
2952
+ rememberClaudeSubagentAttribution(context.subagentParentByToolUseId, block.id, assistantParentToolUseId);
2953
+ if (classifyToolItemType(block.name) === "collab_agent_tool_call" && block.input !== null && typeof block.input === "object" && !Array.isArray(block.input)) rememberClaudeSubagentAttribution(context.subagentLaunchInputByToolUseId, block.id, block.input);
2954
+ }
2294
2955
  context.lastAssistantUuid = message.uuid;
2295
2956
  yield* updateResumeCursor(context);
2296
2957
  return;
@@ -2302,11 +2963,13 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
2302
2963
  messageId: message.message.id,
2303
2964
  model: message.message.model,
2304
2965
  ...context.cacheModelSelection ? { modelSelection: context.cacheModelSelection } : {},
2966
+ ...context.session.cwd ? { cwd: context.session.cwd } : {},
2305
2967
  runtimeSessionId: context.session.runtimeSessionId,
2306
2968
  providerInstanceId: context.session.providerInstanceId,
2307
2969
  observedAt: cacheStamp.createdAt,
2308
2970
  ...previousCache ? { previous: previousCache } : {}
2309
2971
  });
2972
+ if (context.cacheObservation) context.mainLoopUsageObserved = true;
2310
2973
  if (context.cacheObservation && context.cacheObservation !== previousCache) {
2311
2974
  const observation = context.cacheObservation;
2312
2975
  const usedTokens = observation.directInputTokens + observation.cacheReadInputTokens + observation.cacheWriteInputTokens;
@@ -2329,44 +2992,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
2329
2992
  providerRefs: {}
2330
2993
  });
2331
2994
  }
2332
- if (!context.turnState) {
2333
- const turnId = TurnId.make(yield* Effect.sync(() => crypto.randomUUID()));
2334
- const startedAt = yield* nowIso;
2335
- context.turnState = {
2336
- turnId,
2337
- startedAt,
2338
- items: [],
2339
- assistantTextBlocks: /* @__PURE__ */ new Map(),
2340
- assistantTextBlockOrder: [],
2341
- capturedProposedPlanKeys: /* @__PURE__ */ new Set(),
2342
- nextSyntheticAssistantBlockIndex: -1
2343
- };
2344
- context.session = {
2345
- ...context.session,
2346
- status: "running",
2347
- activeTurnId: turnId,
2348
- updatedAt: startedAt
2349
- };
2350
- const turnStartedStamp = yield* makeEventStamp();
2351
- yield* offerRuntimeEventForContext(context, {
2352
- type: "turn.started",
2353
- eventId: turnStartedStamp.eventId,
2354
- provider: PROVIDER,
2355
- createdAt: turnStartedStamp.createdAt,
2356
- threadId: context.session.threadId,
2357
- turnId,
2358
- payload: {},
2359
- providerRefs: {
2360
- ...nativeProviderRefs(context),
2361
- providerTurnId: turnId
2362
- },
2363
- raw: {
2364
- source: "claude.sdk.message",
2365
- method: "claude/synthetic-turn-start",
2366
- payload: {}
2367
- }
2368
- });
2369
- }
2995
+ if (!context.turnState) yield* startProviderTurn(context, "assistant-output");
2370
2996
  const content = message.message?.content;
2371
2997
  if (Array.isArray(content)) for (const block of content) {
2372
2998
  if (!block || typeof block !== "object") continue;
@@ -2389,12 +3015,106 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
2389
3015
  context.lastAssistantUuid = message.uuid;
2390
3016
  yield* updateResumeCursor(context);
2391
3017
  });
2392
- const handleResultMessage = Effect.fn("handleResultMessage")(function* (context, message) {
3018
+ const handleResultMessage = Effect.fn("handleResultMessage")(function* (context, message, options) {
2393
3019
  if (message.type !== "result") return;
2394
- const status = turnStatusFromResult(message);
2395
- const errorMessage = message.subtype === "success" ? void 0 : message.errors[0];
2396
- if (status === "failed") yield* emitRuntimeError(context, errorMessage ?? "Claude turn failed.");
2397
- yield* completeTurn(context, status, errorMessage, message);
3020
+ if (context.probing && context.turnState === void 0) {
3021
+ if (message.subtype !== "success" || message.is_error) {
3022
+ const detail = (message.subtype !== "success" ? message.errors[0] : void 0) ?? `Claude reported ${message.subtype} while reopening the conversation.`;
3023
+ if (context.probeFailure) yield* Deferred.succeed(context.probeFailure, detail);
3024
+ }
3025
+ return;
3026
+ }
3027
+ const turnState = context.turnState;
3028
+ const echoedPromptUuids = claudeEchoedPromptUuids(message);
3029
+ if (turnState?.promptUuid !== void 0 && !claudeResultBelongsToTurn({
3030
+ echoed: echoedPromptUuids,
3031
+ origin: message.origin,
3032
+ promptUuid: turnState.promptUuid,
3033
+ steerPromptUuids: turnState.steerPromptUuids
3034
+ })) {
3035
+ yield* Effect.logInfo("claude.turn.result-for-other-prompt", {
3036
+ threadId: context.session.threadId,
3037
+ turnId: turnState.turnId,
3038
+ origin: message.origin?.kind
3039
+ });
3040
+ return;
3041
+ }
3042
+ const resultStatus = turnStatusFromResult(message);
3043
+ let close = {
3044
+ status: resultStatus,
3045
+ cause: "result"
3046
+ };
3047
+ if (turnState) {
3048
+ const decision = decideClaudeTurnResult({
3049
+ kind: classifyClaudeResultKind(message),
3050
+ echoedPromptUuids,
3051
+ queuedTurnCount: message.queued_turn_count,
3052
+ steerPromptUuids: turnState.steerPromptUuids,
3053
+ settledSteerPromptUuids: turnState.settledSteerPromptUuids,
3054
+ interruptRequested: turnState.interruptRequested
3055
+ });
3056
+ for (const uuid of decision.newlySettled) {
3057
+ turnState.settledSteerPromptUuids.add(uuid);
3058
+ context.discardedSteerPromptUuids.delete(uuid);
3059
+ }
3060
+ if (decision.decision === "await-steer") {
3061
+ yield* sealTurnSegment(context, turnState, resultStatus, message);
3062
+ yield* emitTokenUsageSnapshot(context, yield* resolveResultUsageSnapshot(context, message), turnState.turnId);
3063
+ turnState.sealedSegmentCount += 1;
3064
+ turnState.awaitingSteerContinuation = {
3065
+ since: yield* nowIso,
3066
+ segmentStatus: resultStatus
3067
+ };
3068
+ yield* Effect.logInfo("claude.turn.awaiting-steer-continuation", {
3069
+ threadId: context.session.threadId,
3070
+ turnId: turnState.turnId,
3071
+ queuedTurnCount: message.queued_turn_count,
3072
+ unsettled: decision.unsettled.length,
3073
+ terminalReason: message.terminal_reason
3074
+ });
3075
+ return;
3076
+ }
3077
+ if (decision.discardUnsettled) for (const uuid of decision.unsettled) rememberDiscardedSteer(context.discardedSteerPromptUuids, uuid);
3078
+ close = decideClaudeTurnClose({
3079
+ resultStatus,
3080
+ decision,
3081
+ interruptRequested: turnState.interruptRequested,
3082
+ echoedPromptUuids,
3083
+ promptUuid: turnState.promptUuid,
3084
+ steerPromptUuids: turnState.steerPromptUuids,
3085
+ foldedIntoDiscardedCliTurn: options?.foldedIntoDiscardedCliTurn === true
3086
+ });
3087
+ if (close.cause !== "result") {
3088
+ if (close.status !== "failed") yield* sealTurnSegment(context, turnState, resultStatus, message);
3089
+ yield* Effect.logInfo("claude.turn.closed-as", {
3090
+ threadId: context.session.threadId,
3091
+ turnId: turnState.turnId,
3092
+ cause: close.cause,
3093
+ resultStatus,
3094
+ status: close.status,
3095
+ queuedTurnCount: message.queued_turn_count,
3096
+ unsettled: decision.unsettled.length,
3097
+ terminalReason: message.terminal_reason
3098
+ });
3099
+ }
3100
+ }
3101
+ const notInterrupted = (status) => status !== "interrupted" && status !== "cancelled";
3102
+ const usageLimit = context.turnState && notInterrupted(resultStatus) && notInterrupted(close.status) ? classifyClaudeUsageLimitResult({
3103
+ result: message,
3104
+ windows: context.rejectedRateLimitWindows,
3105
+ nowMs: yield* Clock.currentTimeMillis
3106
+ }) : null;
3107
+ if (usageLimit) {
3108
+ yield* emitRuntimeError(context, usageLimit.message, void 0, {
3109
+ class: "usage_limit",
3110
+ resetAt: usageLimit.resetAt
3111
+ });
3112
+ yield* completeTurn(context, "failed", usageLimit.message, message);
3113
+ return;
3114
+ }
3115
+ const errorMessage = claudeTurnCloseErrorMessage(close.cause, message);
3116
+ if (close.status === "failed") yield* emitRuntimeError(context, errorMessage ?? "Claude turn failed.");
3117
+ yield* completeTurn(context, close.status, errorMessage, message);
2398
3118
  });
2399
3119
  /**
2400
3120
  * Synthesizes per-member task.progress rows from the coordinator's
@@ -2463,6 +3183,19 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
2463
3183
  });
2464
3184
  const handleSystemMessage = Effect.fn("handleSystemMessage")(function* (context, message) {
2465
3185
  if (message.type !== "system") return;
3186
+ if (message.subtype === "status" && message.status === "requesting") context.requestingStatusObserved = true;
3187
+ const wakeSignal = claudeWakeSignal(message);
3188
+ if (wakeSignal !== void 0 && shouldOpenClaudeWakeTurn({
3189
+ signal: wakeSignal,
3190
+ hasOpenTurn: context.turnState !== void 0,
3191
+ sessionStopped: context.stopped,
3192
+ promptSent: context.promptSent,
3193
+ turnInstallsInFlight: context.turnInstallsInFlight,
3194
+ requestingStatusObserved: context.requestingStatusObserved
3195
+ })) {
3196
+ if (context.discardedSteerPromptUuids.size > 0) context.wakeSignalDeferred = true;
3197
+ else yield* startProviderTurn(context, "wake-signal");
3198
+ }
2466
3199
  const stamp = yield* makeEventStamp();
2467
3200
  const base = {
2468
3201
  eventId: stamp.eventId,
@@ -2576,6 +3309,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
2576
3309
  }
2577
3310
  switch (message.subtype) {
2578
3311
  case "init":
3312
+ context.cliCapabilities = parseClaudeCliCapabilities(message);
2579
3313
  yield* offerRuntimeEventForContext(context, {
2580
3314
  ...base,
2581
3315
  type: "session.configured",
@@ -2598,10 +3332,12 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
2598
3332
  }
2599
3333
  });
2600
3334
  return;
2601
- case "compact_boundary":
3335
+ case "compact_boundary": {
2602
3336
  context.compactionPolicy = settleContextCompaction(context.compactionPolicy, context.generation);
2603
- context.lastKnownTokenUsage = void 0;
3337
+ const postCompactionUsage = claudePostCompactionUsage(message.compact_metadata, context.lastKnownContextWindow);
3338
+ context.lastKnownTokenUsage = postCompactionUsage;
2604
3339
  context.cacheObservation = void 0;
3340
+ context.cumulativeUsageSpansCompaction = true;
2605
3341
  yield* offerRuntimeEventForContext(context, {
2606
3342
  ...base,
2607
3343
  type: "thread.state.changed",
@@ -2610,7 +3346,18 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
2610
3346
  detail: message
2611
3347
  }
2612
3348
  });
3349
+ if (postCompactionUsage) {
3350
+ const usageStamp = yield* makeEventStamp();
3351
+ yield* offerRuntimeEventForContext(context, {
3352
+ ...base,
3353
+ eventId: usageStamp.eventId,
3354
+ createdAt: usageStamp.createdAt,
3355
+ type: "thread.token-usage.updated",
3356
+ payload: { usage: withAutomaticCompactionCapability(postCompactionUsage, context.supportsAutomaticCompaction) }
3357
+ });
3358
+ }
2613
3359
  return;
3360
+ }
2614
3361
  case "hook_started":
2615
3362
  yield* offerRuntimeEventForContext(context, {
2616
3363
  ...base,
@@ -2650,7 +3397,9 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
2650
3397
  return;
2651
3398
  case "task_started": {
2652
3399
  const launchingTool = message.tool_use_id ? Array.from(context.inFlightTools.values()).find((tool) => tool.itemId === message.tool_use_id) : void 0;
2653
- const owningAgentId = launchingTool?.agentId;
3400
+ const parentToolUseId = message.tool_use_id ? context.subagentParentByToolUseId.get(message.tool_use_id) : void 0;
3401
+ const owningAgentId = launchingTool?.agentId ?? agentIdForParentToolUse(context.taskAgents, parentToolUseId);
3402
+ if (message.tool_use_id) context.subagentParentByToolUseId.delete(message.tool_use_id);
2654
3403
  const launchInput = launchingTool?.input ?? (message.tool_use_id ? context.subagentLaunchInputByToolUseId.get(message.tool_use_id) : void 0);
2655
3404
  const backgroundFlag = message.is_backgrounded;
2656
3405
  if (backgroundFlag === true || backgroundFlag === void 0 && launchInput?.run_in_background === true) context.backgroundedTaskIds.add(message.task_id);
@@ -2707,7 +3456,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
2707
3456
  return;
2708
3457
  }
2709
3458
  case "task_progress": {
2710
- if (message.usage && !context.cacheObservation && !isClaudeSubagentTaskMessage(message) && !context.taskAgents.get(message.task_id)?.toolUseId) {
3459
+ if (message.usage && !context.mainLoopUsageObserved && !isClaudeSubagentTaskMessage(message) && !context.taskAgents.get(message.task_id)?.toolUseId) {
2711
3460
  const normalizedUsage = normalizeClaudeTokenUsage(message.usage, context.lastKnownContextWindow);
2712
3461
  if (normalizedUsage) {
2713
3462
  context.lastKnownTokenUsage = normalizedUsage;
@@ -2789,7 +3538,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
2789
3538
  case "task_notification": {
2790
3539
  context.liveTaskIds.delete(message.task_id);
2791
3540
  context.backgroundedTaskIds.delete(message.task_id);
2792
- if (message.usage && !context.cacheObservation && !isClaudeSubagentTaskMessage(message) && !context.taskAgents.get(message.task_id)?.toolUseId) {
3541
+ if (message.usage && !context.mainLoopUsageObserved && !isClaudeSubagentTaskMessage(message) && !context.taskAgents.get(message.task_id)?.toolUseId) {
2793
3542
  const normalizedUsage = normalizeClaudeTokenUsage(message.usage, context.lastKnownContextWindow);
2794
3543
  if (normalizedUsage) {
2795
3544
  context.lastKnownTokenUsage = normalizedUsage;
@@ -2924,17 +3673,175 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
2924
3673
  return;
2925
3674
  }
2926
3675
  if (message.type === "rate_limit_event") {
3676
+ const transition = message.rate_limit_info ? applyClaudeRateLimitInfo(context.rejectedRateLimitWindows, message.rate_limit_info) : void 0;
2927
3677
  yield* offerRuntimeEventForContext(context, {
2928
3678
  ...base,
2929
3679
  type: "account.rate-limits.updated",
2930
- payload: { rateLimits: message }
3680
+ payload: {
3681
+ rateLimits: message,
3682
+ usageLimitState: claudeUsageLimitState(context.rejectedRateLimitWindows, yield* Clock.currentTimeMillis)
3683
+ }
2931
3684
  });
3685
+ const turnState = context.turnState;
3686
+ if (transition?.blocked && turnState) {
3687
+ const announced = turnState.announcedUsageLimitKeys ??= /* @__PURE__ */ new Set();
3688
+ if (!announced.has(transition.key)) {
3689
+ announced.add(transition.key);
3690
+ yield* emitRuntimeWarning(context, CLAUDE_USAGE_LIMIT_FALLBACK_MESSAGE, { usageLimit: {
3691
+ limitType: transition.limitType,
3692
+ resetAt: transition.resetAt
3693
+ } });
3694
+ }
3695
+ }
2932
3696
  return;
2933
3697
  }
2934
3698
  });
3699
+ /** Plain interrupt for a CLI segment Stop already ended; bounded, failures only logged. */
3700
+ const forkReinterrupt = (context, reason) => Effect.tryPromise({
3701
+ try: () => context.query.interrupt(),
3702
+ catch: (cause) => toRequestError(context.session.threadId, "turn/interrupt", cause)
3703
+ }).pipe(Effect.timeoutOption("5 seconds"), Effect.tap(() => Effect.logInfo("claude.turn.reinterrupted", {
3704
+ threadId: context.session.threadId,
3705
+ reason
3706
+ })), Effect.ignoreCause({ log: true }), Effect.forkDetach, Effect.asVoid);
3707
+ /**
3708
+ * A discarded steer's CLI turn turned out to be the one a provider turn was opened for (by its
3709
+ * `status: requesting`, legacy `init`, `api_retry` or compaction frame, before its echo). That
3710
+ * turn has routed no content: retract it.
3711
+ */
3712
+ const retractDiscardedSteerWakeTurn = Effect.fn("retractDiscardedSteerWakeTurn")(function* (context) {
3713
+ const turnState = context.turnState;
3714
+ if (turnState === void 0 || turnState.openedBy !== "wake-signal" || turnState.rootContentObserved || turnState.steerPromptUuids.size > 0) return;
3715
+ yield* completeTurn(context, "interrupted", DISCARDED_STEER_TURN_REASON, void 0, {
3716
+ abortReason: DISCARDED_STEER_TURN_REASON,
3717
+ expectedTurnState: turnState
3718
+ });
3719
+ });
3720
+ /**
3721
+ * The discarded CLI turn's result: forget its uuids, then drop it (keeping its usage). Returns
3722
+ * whether it was consumed. Only this result can end the open turn when:
3723
+ * - it echoes the open turn's prompt or steer, which the CLI folded into the discarded CLI turn
3724
+ * (a fold shows only on the result). That turn's reply went with the dropped frames, and the
3725
+ * discard's re-interrupt usually aborted it, so the result closes it here as failed (never as
3726
+ * a Stop the user did not press);
3727
+ * - the CLI turn's output already reached an open provider turn (its frames carried no echo,
3728
+ * or beat Stop's bookkeeping). The result is routed on and completes that turn.
3729
+ */
3730
+ const endDiscardedSteerCliTurn = Effect.fn("endDiscardedSteerCliTurn")(function* (context, message, uuids) {
3731
+ let count = 0;
3732
+ for (const uuid of uuids) {
3733
+ context.discardedSteerPromptUuids.delete(uuid);
3734
+ count += 1;
3735
+ }
3736
+ context.discardingCliTurn = void 0;
3737
+ context.wakeSignalDeferred = false;
3738
+ const open = context.turnState;
3739
+ if (open !== void 0) {
3740
+ const logContext = {
3741
+ threadId: context.session.threadId,
3742
+ turnId: open.turnId,
3743
+ openedBy: open.openedBy,
3744
+ uuids: count
3745
+ };
3746
+ if (claudeEchoNamesTurn({
3747
+ echoed: claudeEchoedPromptUuids(message),
3748
+ promptUuid: open.promptUuid,
3749
+ steerPromptUuids: open.steerPromptUuids
3750
+ })) {
3751
+ yield* Effect.logInfo("claude.turn.discarded-steer-folded-open-turn", logContext);
3752
+ yield* handleResultMessage(context, message, { foldedIntoDiscardedCliTurn: true });
3753
+ return true;
3754
+ }
3755
+ if (open.promptUuid === void 0 && open.rootContentObserved) {
3756
+ yield* Effect.logInfo("claude.turn.discarded-steer-output-leaked", logContext);
3757
+ return false;
3758
+ }
3759
+ }
3760
+ yield* emitTokenUsageSnapshot(context, yield* resolveResultUsageSnapshot(context, message), void 0);
3761
+ yield* retractDiscardedSteerWakeTurn(context);
3762
+ yield* Effect.logInfo("claude.turn.discarded-cancelled-steer", {
3763
+ threadId: context.session.threadId,
3764
+ uuids: count
3765
+ });
3766
+ return true;
3767
+ });
3768
+ /**
3769
+ * Routes frames of CLI segments started by steers. Returns true when the frame was consumed
3770
+ * (dropped, or a result that already closed the open turn). The echo is read on a CLI turn's
3771
+ * first reply frame (its first stream event, or its first root assistant message when it
3772
+ * streamed nothing) and on its result. A CLI turn whose echo holds only steers Stop (or a failed
3773
+ * segment) discarded is interrupted again (unless its reply is an API error, which ends it
3774
+ * anyway) and dropped up to and including its result; a result with such an echo and no reply
3775
+ * before it is dropped alone. Either result still ends the open turn when only it can (see
3776
+ * `endDiscardedSteerCliTurn`). The open turn owns its own steers' segments; after Stop, one that
3777
+ * starts is interrupted again too, with the same API-error exception.
3778
+ */
3779
+ const routeSteerFrame = Effect.fn("routeSteerFrame")(function* (context, message) {
3780
+ const discarding = context.discardingCliTurn;
3781
+ if (discarding !== void 0) switch (message.type) {
3782
+ case "result": return yield* endDiscardedSteerCliTurn(context, message, [...discarding.uuids, ...claudeEchoedPromptUuids(message)]);
3783
+ case "stream_event":
3784
+ case "assistant":
3785
+ case "user":
3786
+ case "tool_progress":
3787
+ case "tool_use_summary": return true;
3788
+ default: return false;
3789
+ }
3790
+ if (message.type !== "stream_event" && message.type !== "assistant" && message.type !== "result") return false;
3791
+ const echoed = claudeEchoedPromptUuids(message);
3792
+ if (echoed.length === 0) return false;
3793
+ const discarded = context.discardedSteerPromptUuids;
3794
+ const turnState = context.turnState;
3795
+ const owned = turnState !== void 0 && claudeEchoNamesTurn({
3796
+ echoed,
3797
+ promptUuid: turnState.promptUuid,
3798
+ steerPromptUuids: turnState.steerPromptUuids
3799
+ });
3800
+ const reinterruptable = !isClaudeApiErrorReply(message);
3801
+ if (owned || !echoed.every((uuid) => discarded.has(uuid))) {
3802
+ if (owned && message.type !== "result") {
3803
+ for (const uuid of echoed) if (turnState.steerPromptUuids.has(uuid)) turnState.startedSteerPromptUuids.add(uuid);
3804
+ const echoKey = [...echoed].toSorted().join(" ");
3805
+ if (reinterruptable && turnState.interruptRequested && echoed.some((uuid) => turnState.steerPromptUuids.has(uuid) && !turnState.settledSteerPromptUuids.has(uuid)) && !turnState.reinterruptedEchoKeys.has(echoKey)) {
3806
+ turnState.reinterruptedEchoKeys.add(echoKey);
3807
+ yield* forkReinterrupt(context, "steer-segment-after-stop");
3808
+ }
3809
+ }
3810
+ for (const uuid of echoed) discarded.delete(uuid);
3811
+ return false;
3812
+ }
3813
+ if (message.type === "result") return yield* endDiscardedSteerCliTurn(context, message, echoed);
3814
+ context.discardingCliTurn = { uuids: new Set(echoed) };
3815
+ context.wakeSignalDeferred = false;
3816
+ if (reinterruptable) yield* forkReinterrupt(context, "discarded-steer-segment");
3817
+ yield* Effect.logInfo("claude.turn.discarding-cancelled-steer", {
3818
+ threadId: context.session.threadId,
3819
+ uuids: echoed.length
3820
+ });
3821
+ yield* retractDiscardedSteerWakeTurn(context);
3822
+ return true;
3823
+ });
2935
3824
  const handleSdkMessage = Effect.fn("handleSdkMessage")(function* (context, message) {
2936
3825
  yield* logNativeSdkMessage(context, message);
2937
3826
  yield* ensureThreadId(context, message);
3827
+ if (yield* routeSteerFrame(context, message)) return;
3828
+ const chainUuid = claudeMainChainUuid(message);
3829
+ if (chainUuid !== void 0 && context.turnState) context.turnState.lastChainUuid = chainUuid;
3830
+ const rootContent = isClaudeRootTurnFrame(message);
3831
+ if (context.wakeSignalDeferred) {
3832
+ if (rootContent) {
3833
+ context.wakeSignalDeferred = false;
3834
+ if (context.turnState === void 0) yield* startProviderTurn(context, "wake-signal");
3835
+ } else if (message.type === "result") context.wakeSignalDeferred = false;
3836
+ }
3837
+ const waiting = context.turnState;
3838
+ if (waiting?.awaitingSteerContinuation !== void 0 && rootContent) waiting.awaitingSteerContinuation = void 0;
3839
+ yield* routeSdkMessage(context, message);
3840
+ const open = context.turnState;
3841
+ if (open && !open.rootOutputObserved && isClaudeRootTurnOutput(message)) open.rootOutputObserved = true;
3842
+ if (open && rootContent) open.rootContentObserved = true;
3843
+ });
3844
+ const routeSdkMessage = Effect.fn("routeSdkMessage")(function* (context, message) {
2938
3845
  switch (message.type) {
2939
3846
  case "stream_event":
2940
3847
  yield* handleStreamEvent(context, message);
@@ -2962,7 +3869,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
2962
3869
  return;
2963
3870
  }
2964
3871
  });
2965
- const runSdkStream = (context) => Stream.fromAsyncIterable(context.query, (cause) => toError(cause, "Claude runtime stream failed.")).pipe(Stream.takeWhile(() => !context.stopped), Stream.runForEach((message) => handleSdkMessage(context, message)));
3872
+ const runSdkStream = (context) => Stream.fromAsyncIterable(context.query, (cause) => toError(cause, "Claude runtime stream failed.")).pipe(Stream.takeWhile(() => !context.stopped), Stream.runForEach((message) => context.turnLock.withPermits(1)(handleSdkMessage(context, message))));
2966
3873
  const handleStreamExit = Effect.fn("handleStreamExit")(function* (context, exit) {
2967
3874
  if (context.stopped) return;
2968
3875
  if (Exit.isFailure(exit)) {
@@ -2979,6 +3886,9 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
2979
3886
  const stopSessionInternal = Effect.fn("stopSessionInternal")(function* (context, options) {
2980
3887
  if (context.stopped) return;
2981
3888
  context.stopped = true;
3889
+ context.discardedSteerPromptUuids.clear();
3890
+ context.discardingCliTurn = void 0;
3891
+ context.wakeSignalDeferred = false;
2982
3892
  context.deviceToolBinding?.dispose();
2983
3893
  if (context.agentControl) yield* context.agentControl.revoke("runtime-teardown");
2984
3894
  for (const [requestId, pending] of context.pendingApprovals) {
@@ -3005,11 +3915,22 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
3005
3915
  yield* Queue.shutdown(context.promptQueue);
3006
3916
  const streamFiber = context.streamFiber;
3007
3917
  context.streamFiber = void 0;
3008
- if (streamFiber && streamFiber.pollUnsafe() === void 0) yield* Fiber.interrupt(streamFiber);
3009
- try {
3010
- context.query.close();
3011
- } catch (cause) {
3012
- yield* emitRuntimeError(context, "Failed to close Claude runtime query.", cause);
3918
+ const closeQuery = Effect.gen(function* () {
3919
+ try {
3920
+ context.query.close();
3921
+ } catch (cause) {
3922
+ yield* emitRuntimeError(context, "Failed to close Claude runtime query.", cause);
3923
+ }
3924
+ });
3925
+ if (options?.awaitQueryExitMs !== void 0) {
3926
+ yield* closeQuery;
3927
+ if (streamFiber && streamFiber.pollUnsafe() === void 0) {
3928
+ const exited = yield* Fiber.await(streamFiber).pipe(Effect.timeoutOption(Duration.millis(options.awaitQueryExitMs)));
3929
+ if (Option.isNone(exited)) yield* Fiber.interrupt(streamFiber);
3930
+ }
3931
+ } else {
3932
+ if (streamFiber && streamFiber.pollUnsafe() === void 0) yield* Fiber.interrupt(streamFiber);
3933
+ yield* closeQuery;
3013
3934
  }
3014
3935
  const updatedAt = yield* nowIso;
3015
3936
  context.session = {
@@ -3059,6 +3980,11 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
3059
3980
  issue: `Expected provider instance '${boundInstanceId}' but received '${input.providerInstanceId}'.`
3060
3981
  });
3061
3982
  const runtimeSessionId = yield* requireRuntimeSessionId(PROVIDER, input);
3983
+ if (rewindingThreads.has(input.threadId)) return yield* new ProviderAdapterValidationError({
3984
+ provider: PROVIDER,
3985
+ operation: "startSession",
3986
+ issue: "Claude is rewinding this thread; try again in a moment."
3987
+ });
3062
3988
  const existingContext = sessions.get(input.threadId);
3063
3989
  if (existingContext) {
3064
3990
  if (existingContext.session.runtimeSessionId === runtimeSessionId) return existingContext.session;
@@ -3068,6 +3994,15 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
3068
3994
  issue: `Thread '${input.threadId}' still has runtime '${existingContext.session.runtimeSessionId ?? "legacy"}'; stop it before starting '${runtimeSessionId}'.`
3069
3995
  });
3070
3996
  }
3997
+ return { ...(yield* openSessionContext(input, {})).session };
3998
+ });
3999
+ /**
4000
+ * Opens a query for `input` and registers its context. With `probe`, the
4001
+ * reopened CLI must accept a control request before this succeeds; a failed
4002
+ * probe stops the context silently (no runtime.error or session.exited).
4003
+ */
4004
+ const openSessionContext = Effect.fn("openSessionContext")(function* (input, openOptions) {
4005
+ const runtimeSessionId = yield* requireRuntimeSessionId(PROVIDER, input);
3071
4006
  const startedAt = yield* nowIso;
3072
4007
  const effectiveResumeCursor = input.resumePolicy === "fresh" ? void 0 : input.resumeCursor;
3073
4008
  const resumeState = readClaudeResumeState(effectiveResumeCursor);
@@ -3299,7 +4234,10 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
3299
4234
  });
3300
4235
  const canUseTool = (toolName, toolInput, callbackOptions) => runPromise(canUseToolEffect(toolName, toolInput, callbackOptions));
3301
4236
  const claudeBinaryPath = claudeSettings.binaryPath;
3302
- const extraArgs = parseCliArgs(claudeSettings.launchArgs).flags;
4237
+ const extraArgs = {
4238
+ "thinking-display": "summarized",
4239
+ ...parseCliArgs(claudeSettings.launchArgs).flags
4240
+ };
3303
4241
  const modelSelection = input.modelSelection?.instanceId === boundInstanceId ? input.modelSelection : void 0;
3304
4242
  const caps = getClaudeModelCapabilities(modelSelection?.model);
3305
4243
  const descriptors = getProviderOptionDescriptors({ caps });
@@ -3356,6 +4294,8 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
3356
4294
  ...permissionMode === "bypassPermissions" ? { allowDangerouslySkipPermissions: true } : {},
3357
4295
  ...Object.keys(settings).length > 0 ? { settings } : {},
3358
4296
  ...existingResumeSessionId ? { resume: existingResumeSessionId } : {},
4297
+ ...existingResumeSessionId && resumeState?.rewindAt ? { resumeSessionAt: resumeState.rewindAt } : {},
4298
+ ...existingResumeSessionId && resumeState?.rewindAt && openOptions.resumeDropsTurn ? { resumeDropsTurn: openOptions.resumeDropsTurn } : {},
3359
4299
  ...newSessionId ? { sessionId: newSessionId } : {},
3360
4300
  includePartialMessages: true,
3361
4301
  canUseTool,
@@ -3429,6 +4369,7 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
3429
4369
  ...threadId ? { threadId } : {},
3430
4370
  ...sessionId ? { resume: sessionId } : {},
3431
4371
  ...resumeState?.resumeSessionAt ? { resumeSessionAt: resumeState.resumeSessionAt } : {},
4372
+ ...existingResumeSessionId && resumeState?.rewindAt ? { rewind: { at: resumeState.rewindAt } } : {},
3432
4373
  turnCount: resumeState?.turnCount ?? 0
3433
4374
  },
3434
4375
  createdAt: startedAt,
@@ -3436,9 +4377,15 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
3436
4377
  };
3437
4378
  const generation = ++nextSessionGeneration;
3438
4379
  const supportsAutomaticCompaction = typeof queryRuntime.applyFlagSettings === "function";
4380
+ const { resumeCursor: _resumeCursor, resumePolicy: _resumePolicy, ...startInput } = input;
3439
4381
  const context = {
3440
4382
  generation,
3441
4383
  session,
4384
+ startInput,
4385
+ turnHeads: [...openOptions.turnHeads ?? []],
4386
+ pendingRewind: existingResumeSessionId && resumeState?.rewindAt ? { at: resumeState.rewindAt } : void 0,
4387
+ probing: openOptions.probe === true,
4388
+ probeFailure: openOptions.probe === true ? Deferred.makeUnsafe() : void 0,
3442
4389
  promptQueue,
3443
4390
  query: queryRuntime,
3444
4391
  deviceToolBinding,
@@ -3459,7 +4406,9 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
3459
4406
  taskAgents: /* @__PURE__ */ new Map(),
3460
4407
  subagentLaunchInputByToolUseId: /* @__PURE__ */ new Map(),
3461
4408
  subagentModelByToolUseId: /* @__PURE__ */ new Map(),
4409
+ subagentParentByToolUseId: /* @__PURE__ */ new Map(),
3462
4410
  workflowMemberFingerprints: /* @__PURE__ */ new Map(),
4411
+ rejectedRateLimitWindows: /* @__PURE__ */ new Map(),
3463
4412
  workflowPhasesByTaskId: /* @__PURE__ */ new Map(),
3464
4413
  liveTaskIds: /* @__PURE__ */ new Set(),
3465
4414
  backgroundedTaskIds: /* @__PURE__ */ new Set(),
@@ -3467,6 +4416,8 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
3467
4416
  lastKnownContextWindow: void 0,
3468
4417
  lastKnownTokenUsage: void 0,
3469
4418
  cacheObservation: void 0,
4419
+ mainLoopUsageObserved: false,
4420
+ cumulativeUsageSpansCompaction: false,
3470
4421
  cacheModelSelection: modelSelection,
3471
4422
  compactionPolicy: initialContextCompactionPolicyState(generation),
3472
4423
  supportsAutomaticCompaction,
@@ -3476,7 +4427,15 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
3476
4427
  subagentByTaskId: /* @__PURE__ */ new Map(),
3477
4428
  startedSubagentIds: /* @__PURE__ */ new Set(),
3478
4429
  completedSubagentIds: /* @__PURE__ */ new Set(),
3479
- stopped: false
4430
+ stopped: false,
4431
+ promptSent: false,
4432
+ turnInstallsInFlight: 0,
4433
+ requestingStatusObserved: false,
4434
+ cliCapabilities: void 0,
4435
+ discardedSteerPromptUuids: /* @__PURE__ */ new Set(),
4436
+ discardingCliTurn: void 0,
4437
+ wakeSignalDeferred: false,
4438
+ turnLock: yield* Semaphore.make(1)
3480
4439
  };
3481
4440
  deviceToolContext = context;
3482
4441
  yield* Ref.set(contextRef, context);
@@ -3521,18 +4480,35 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
3521
4480
  streamFiber = runFork(Effect.exit(runSdkStream(context)).pipe(Effect.flatMap((exit) => {
3522
4481
  if (context.stopped) return Effect.void;
3523
4482
  if (context.streamFiber === streamFiber) context.streamFiber = void 0;
4483
+ if (context.probing && context.probeFailure) return Deferred.succeed(context.probeFailure, Exit.isFailure(exit) ? messageFromClaudeStreamCause(exit.cause, "Claude runtime stream failed.") : "Claude exited while reopening the conversation.").pipe(Effect.asVoid);
3524
4484
  return handleStreamExit(context, exit);
3525
4485
  })));
3526
4486
  context.streamFiber = streamFiber;
3527
4487
  streamFiber.addObserver(() => {
3528
4488
  if (context.streamFiber === streamFiber) context.streamFiber = void 0;
3529
4489
  });
3530
- return { ...session };
4490
+ if (context.probing && context.probeFailure) {
4491
+ const probeFailure = context.probeFailure;
4492
+ const controlRequest = Effect.tryPromise({
4493
+ try: () => queryRuntime.initializationResult?.() ?? queryRuntime.mcpServerStatus?.() ?? Promise.resolve(),
4494
+ catch: (cause) => toMessage(cause, "Claude rejected the reopened conversation.")
4495
+ });
4496
+ const probe = yield* Effect.raceFirst(controlRequest.pipe(Effect.asVoid), Deferred.await(probeFailure).pipe(Effect.flatMap((detail) => Effect.fail(detail)))).pipe(Effect.timeoutOption(CLAUDE_REWIND_PROBE_TIMEOUT), Effect.result);
4497
+ context.probing = false;
4498
+ const failure = probe._tag === "Failure" ? probe.failure : Option.isNone(probe.success) ? "Claude did not respond while reopening the conversation." : Deferred.isDoneUnsafe(probeFailure) ? "Claude exited while reopening the conversation." : void 0;
4499
+ if (failure !== void 0) {
4500
+ yield* stopSessionInternal(context, { emitExitEvent: false });
4501
+ return yield* new ProviderAdapterProcessError({
4502
+ provider: PROVIDER,
4503
+ threadId,
4504
+ detail: failure
4505
+ });
4506
+ }
4507
+ }
4508
+ return context;
3531
4509
  });
3532
- const sendTurn = Effect.fn("sendTurn")(function* (input) {
3533
- const context = yield* requireSession(input.threadId);
4510
+ const sendTurnOnContext = Effect.fn("sendTurnOnContext")(function* (context, input) {
3534
4511
  const modelSelection = input.modelSelection !== void 0 && input.modelSelection.instanceId === boundInstanceId ? input.modelSelection : void 0;
3535
- if (context.turnState) yield* completeTurn(context, "completed");
3536
4512
  if (modelSelection?.model) {
3537
4513
  const apiModelId = resolveClaudeApiModelId(modelSelection);
3538
4514
  if (context.currentApiModelId !== apiModelId) {
@@ -3559,24 +4535,23 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
3559
4535
  try: () => context.query.setPermissionMode(context.basePermissionMode ?? "default"),
3560
4536
  catch: (cause) => toRequestError(input.threadId, "turn/setPermissionMode", cause)
3561
4537
  });
3562
- const turnId = TurnId.make(yield* Effect.sync(() => crypto.randomUUID()));
3563
- const turnState = {
4538
+ const promptUuid = yield* Effect.sync(() => crypto.randomUUID());
4539
+ const turnId = TurnId.make(promptUuid);
4540
+ const startedAt = yield* nowIso;
4541
+ while (context.turnState !== void 0) yield* completeTurn(context, "completed");
4542
+ context.turnState = makeClaudeTurnState({
3564
4543
  turnId,
3565
- startedAt: yield* nowIso,
3566
- items: [],
3567
- assistantTextBlocks: /* @__PURE__ */ new Map(),
3568
- assistantTextBlockOrder: [],
3569
- capturedProposedPlanKeys: /* @__PURE__ */ new Set(),
3570
- nextSyntheticAssistantBlockIndex: -1
3571
- };
3572
- const updatedAt = yield* nowIso;
3573
- context.turnState = turnState;
4544
+ promptUuid,
4545
+ startedAt,
4546
+ openedBy: "prompt"
4547
+ });
3574
4548
  context.session = {
3575
4549
  ...context.session,
3576
4550
  status: "running",
3577
4551
  activeTurnId: turnId,
3578
- updatedAt
4552
+ updatedAt: startedAt
3579
4553
  };
4554
+ context.promptSent = true;
3580
4555
  const turnStartedStamp = yield* makeEventStamp();
3581
4556
  yield* offerRuntimeEventForContext(context, {
3582
4557
  type: "turn.started",
@@ -3600,7 +4575,10 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
3600
4575
  });
3601
4576
  yield* Queue.offer(context.promptQueue, {
3602
4577
  type: "message",
3603
- message
4578
+ message: {
4579
+ ...message,
4580
+ uuid: promptUuid
4581
+ }
3604
4582
  }).pipe(Effect.mapError((cause) => toRequestError(input.threadId, "turn/start", cause)));
3605
4583
  if (context.agentControl) yield* context.agentControl.bindTurn(turnId).pipe(Effect.catchCause((cause) => Effect.logWarning("failed to bind Agent Control turn authority", {
3606
4584
  threadId: input.threadId,
@@ -3613,9 +4591,73 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
3613
4591
  ...context.session.resumeCursor !== void 0 ? { resumeCursor: context.session.resumeCursor } : {}
3614
4592
  };
3615
4593
  });
3616
- const interruptTurn = Effect.fn("interruptTurn")(function* (threadId, _turnId) {
4594
+ const sendTurn = Effect.fn("sendTurn")(function* (input) {
4595
+ const context = yield* requireSession(input.threadId);
4596
+ return yield* Effect.acquireUseRelease(Effect.sync(() => {
4597
+ context.turnInstallsInFlight += 1;
4598
+ }), () => sendTurnOnContext(context, input), () => Effect.sync(() => {
4599
+ context.turnInstallsInFlight -= 1;
4600
+ }));
4601
+ });
4602
+ /**
4603
+ * Adds a user message to the exact running turn: an SDK user message with `priority: "now"`
4604
+ * and its own uuid. The Ryco turn keeps its id and absorbs the CLI segments the steer starts.
4605
+ * Refusals are `ProviderTurnNotSteerableError`, so the message stays queued as the next turn.
4606
+ */
4607
+ const steerTurn = Effect.fn("steerTurn")(function* (input) {
4608
+ const context = yield* requireSession(input.threadId);
4609
+ const refuse = (reason, detail) => new ProviderTurnNotSteerableError({
4610
+ provider: PROVIDER,
4611
+ threadId: input.threadId,
4612
+ turnId: input.expectedTurnId,
4613
+ reason,
4614
+ detail
4615
+ });
4616
+ const turnState = context.turnState;
4617
+ if (!turnState || turnState.turnId !== input.expectedTurnId || context.session.activeTurnId !== input.expectedTurnId || turnState.interruptRequested) return yield* refuse("turn-ended", STEER_TURN_ENDED_DETAIL);
4618
+ if (context.pendingApprovals.size > 0 || context.pendingUserInputs.size > 0) return yield* refuse("busy", "Claude is waiting for an approval or answer. The message stays queued.");
4619
+ if (!context.cliCapabilities?.has("interrupt_receipt_v1")) return yield* refuse("unsupported", "This Claude Code version can't steer a running turn. The message stays queued.");
4620
+ if (input.input?.trimStart().startsWith("/")) return yield* refuse("unsupported", "Slash commands can't be steered into a running turn. The message stays queued.");
4621
+ const message = yield* buildUserMessageEffect({
4622
+ threadId: input.threadId,
4623
+ ...input.input ? { input: input.input } : {},
4624
+ attachments: input.attachments ?? [],
4625
+ ...context.cacheModelSelection ? { modelSelection: context.cacheModelSelection } : {}
4626
+ }, {
4627
+ fileSystem,
4628
+ attachmentsDir: serverConfig.attachmentsDir,
4629
+ boundInstanceId
4630
+ });
4631
+ const steerUuid = yield* Effect.sync(() => crypto.randomUUID());
4632
+ if (!(yield* context.turnLock.withPermits(1)(Effect.gen(function* () {
4633
+ if (sessions.get(input.threadId) !== context || context.stopped || context.turnState !== turnState || turnState.interruptRequested || turnState.completion !== void 0) return false;
4634
+ turnState.steerPromptUuids.add(steerUuid);
4635
+ const offered = yield* Queue.offer(context.promptQueue, {
4636
+ type: "message",
4637
+ message: {
4638
+ ...message,
4639
+ uuid: steerUuid,
4640
+ priority: "now"
4641
+ }
4642
+ });
4643
+ if (!offered) turnState.steerPromptUuids.delete(steerUuid);
4644
+ return offered;
4645
+ })))) return yield* refuse("turn-ended", STEER_TURN_ENDED_DETAIL);
4646
+ yield* Effect.logInfo("claude.turn.steered", {
4647
+ threadId: input.threadId,
4648
+ turnId: turnState.turnId,
4649
+ awaiting: turnState.awaitingSteerContinuation !== void 0
4650
+ });
4651
+ return {
4652
+ threadId: context.session.threadId,
4653
+ turnId: turnState.turnId
4654
+ };
4655
+ });
4656
+ const interruptTurn = Effect.fn("interruptTurn")(function* (threadId, turnId) {
3617
4657
  const context = yield* requireSession(threadId);
3618
- if (context.agentControl) yield* context.agentControl.retireTurn(_turnId);
4658
+ const target = context.turnState;
4659
+ if (target) target.interruptRequested = true;
4660
+ if (context.agentControl) yield* context.agentControl.retireTurn(turnId);
3619
4661
  if (context.query.stopTask && context.liveTaskIds.size > 0) {
3620
4662
  const liveIds = Array.from(context.liveTaskIds);
3621
4663
  yield* Effect.forEach(liveIds, (taskId) => Effect.gen(function* () {
@@ -3644,10 +4686,47 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
3644
4686
  discard: true
3645
4687
  }).pipe(Effect.timeoutOption("10 seconds"), Effect.ignore);
3646
4688
  }
3647
- yield* Effect.tryPromise({
3648
- try: () => context.query.interrupt(),
4689
+ const cancelQueued = (target ? [...target.steerPromptUuids].filter((uuid) => !target.settledSteerPromptUuids.has(uuid)) : []).length > 0 && context.cliCapabilities?.has("interrupt_cancel_queued_v1") === true;
4690
+ const rawReceipt = yield* Effect.tryPromise({
4691
+ try: () => cancelQueued ? context.query.interrupt({ cancelQueued: true }) : context.query.interrupt(),
3649
4692
  catch: (cause) => toRequestError(threadId, "turn/interrupt", cause)
3650
4693
  });
4694
+ if (target !== void 0 && target.steerPromptUuids.size > 0) {
4695
+ const receipt = readClaudeInterruptReceipt(rawReceipt);
4696
+ yield* Effect.logInfo("claude.turn.interrupt-receipt", {
4697
+ threadId: context.session.threadId,
4698
+ turnId: target.turnId,
4699
+ cancelQueued,
4700
+ hasReceipt: receipt !== void 0,
4701
+ stillQueued: receipt?.stillQueued.length ?? 0,
4702
+ cancelled: receipt?.cancelled?.length ?? 0
4703
+ });
4704
+ yield* context.turnLock.withPermits(1)(Effect.gen(function* () {
4705
+ if (context.stopped) return;
4706
+ const stop = decideClaudeStop({
4707
+ unsettledSteers: [...target.steerPromptUuids].filter((uuid) => !target.settledSteerPromptUuids.has(uuid)),
4708
+ startedSteers: target.startedSteerPromptUuids,
4709
+ promptUuid: target.promptUuid,
4710
+ sealedSegmentCount: target.sealedSegmentCount,
4711
+ awaitingSteerContinuation: target.awaitingSteerContinuation !== void 0,
4712
+ receipt
4713
+ });
4714
+ if (context.turnState === target) for (const uuid of stop.discard) rememberDiscardedSteer(context.discardedSteerPromptUuids, uuid);
4715
+ for (const uuid of stop.release) {
4716
+ context.discardedSteerPromptUuids.delete(uuid);
4717
+ target.settledSteerPromptUuids.add(uuid);
4718
+ }
4719
+ if (stop.forceClose && context.turnState === target) yield* completeTurn(context, "interrupted", "Interrupted by user.", void 0, { expectedTurnState: target });
4720
+ }));
4721
+ }
4722
+ if (target !== void 0 && target.openedBy !== "prompt" && (turnId === void 0 || target.turnId === turnId)) yield* Effect.sleep(Duration.millis(CLAUDE_PROVIDER_TURN_STOP_GRACE_MS)).pipe(Effect.andThen(Effect.suspend(() => {
4723
+ if (context.turnState !== target || target.completion !== void 0 || context.stopped) return Effect.void;
4724
+ return Effect.logInfo("claude.turn.provider-turn-finalized-after-stop", {
4725
+ threadId: context.session.threadId,
4726
+ turnId: target.turnId,
4727
+ openedBy: target.openedBy
4728
+ }).pipe(Effect.andThen(completeTurn(context, "interrupted", PROVIDER_TURN_STOP_REASON)));
4729
+ })), Effect.ignoreCause({ log: true }), Effect.forkDetach);
3651
4730
  });
3652
4731
  const stopBackgroundTask = Effect.fn("stopBackgroundTask")(function* (threadId, taskId, expected) {
3653
4732
  const context = yield* requireSession(threadId);
@@ -3682,12 +4761,109 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
3682
4761
  const context = yield* requireSession(threadId);
3683
4762
  return yield* snapshotThread(context);
3684
4763
  });
3685
- const rollbackThread = Effect.fn("rollbackThread")(function* (threadId, numTurns) {
4764
+ /** The session's main transcript chain, oldest first. Errors and timeouts read as empty. */
4765
+ const readMainTranscriptChain = Effect.fn("readMainTranscriptChain")(function* (sessionId, cwd) {
4766
+ const read = (dir) => Effect.tryPromise(() => readSessionMessages(sessionId, {
4767
+ ...dir !== void 0 ? { dir } : {},
4768
+ includeSystemMessages: true
4769
+ })).pipe(Effect.timeoutOption(CLAUDE_REWIND_TRANSCRIPT_TIMEOUT), Effect.map((entries) => Option.getOrElse(entries, () => [])), Effect.catch(() => Effect.succeed([])), Effect.map((entries) => entries.filter((entry) => typeof entry.uuid === "string" && (entry.parent_tool_use_id === null || entry.parent_tool_use_id === void 0))));
4770
+ const inCwd = yield* read(cwd);
4771
+ return inCwd.length > 0 || cwd === void 0 ? inCwd : yield* read(void 0);
4772
+ });
4773
+ /**
4774
+ * Makes Claude forget the newest turns: close the live query, wait for the
4775
+ * CLI to exit, and reopen the transcript truncated just before the first
4776
+ * dropped prompt (or a fresh session for checkpoint 0). A reopen the CLI
4777
+ * refuses restores the previous conversation and reports the refusal.
4778
+ */
4779
+ const rollbackThread = Effect.fn("rollbackThread")(function* (threadId, input) {
3686
4780
  const context = yield* requireSession(threadId);
3687
- const nextLength = Math.max(0, context.turns.length - numTurns);
3688
- context.turns.splice(nextLength);
3689
- yield* updateResumeCursor(context);
3690
- return yield* snapshotThread(context);
4781
+ const refuse = (detail) => new ProviderAdapterRequestError({
4782
+ provider: PROVIDER,
4783
+ method: "thread/rollback",
4784
+ detail
4785
+ });
4786
+ if (context.turnState) return yield* refuse("A Claude turn is still running.");
4787
+ if (context.liveTaskIds.size > 0) return yield* refuse("Claude still has background tasks running. Stop them, then revert again.");
4788
+ if (context.pendingApprovals.size > 0 || context.pendingUserInputs.size > 0) return yield* refuse("Claude is waiting for your answer. Answer it, then revert again.");
4789
+ if (rewindingThreads.has(threadId)) return yield* refuse("Claude is already rewinding this thread.");
4790
+ let plan;
4791
+ if (input.targetTurnId === null) plan = { kind: "fresh" };
4792
+ else {
4793
+ const firstDropped = input.droppedTurnIds[0];
4794
+ const chain = context.resumeSessionId !== void 0 && firstDropped !== void 0 ? yield* readMainTranscriptChain(context.resumeSessionId, context.session.cwd) : [];
4795
+ const index = firstDropped === void 0 ? -1 : chain.findIndex((entry) => entry.uuid === firstDropped);
4796
+ if (index > 0) plan = {
4797
+ kind: "rewind",
4798
+ at: chain[index - 1].uuid,
4799
+ ...input.droppedTurnIds.length === 1 && firstDropped !== void 0 ? { dropsTurn: firstDropped } : {}
4800
+ };
4801
+ else if (index === 0) plan = { kind: "fresh" };
4802
+ else {
4803
+ const head = context.turnHeads.find((entry) => entry.turnId === input.targetTurnId)?.head;
4804
+ if (head !== void 0) plan = {
4805
+ kind: "rewind",
4806
+ at: head
4807
+ };
4808
+ }
4809
+ }
4810
+ if (plan === void 0) return yield* refuse("Claude has no recorded transcript position for this checkpoint. Revert to an earlier checkpoint or start a new thread.");
4811
+ const rewindPlan = plan;
4812
+ rewindingThreads.add(threadId);
4813
+ return yield* Effect.gen(function* () {
4814
+ const previousCursor = context.session.resumeCursor;
4815
+ const dropped = new Set(input.droppedTurnIds);
4816
+ const keptTurnHeads = context.turnHeads.filter((entry) => !dropped.has(entry.turnId));
4817
+ yield* stopSessionInternal(context, {
4818
+ emitExitEvent: false,
4819
+ awaitQueryExitMs: CLAUDE_REWIND_QUERY_EXIT_MS
4820
+ });
4821
+ const previousTurnCount = readClaudeResumeState(previousCursor)?.turnCount ?? context.turns.length;
4822
+ const nextCursor = rewindPlan.kind === "fresh" || context.resumeSessionId === void 0 ? { threadId } : {
4823
+ threadId,
4824
+ resume: context.resumeSessionId,
4825
+ rewind: { at: rewindPlan.at },
4826
+ turnCount: Math.max(0, previousTurnCount - input.numTurns)
4827
+ };
4828
+ const reopenInput = {
4829
+ ...context.startInput,
4830
+ runtimeMode: context.session.runtimeMode,
4831
+ ...context.session.tokenMode !== void 0 ? { tokenMode: context.session.tokenMode } : {},
4832
+ ...context.cacheModelSelection ?? context.startInput.modelSelection ? { modelSelection: context.cacheModelSelection ?? context.startInput.modelSelection } : {},
4833
+ ...context.session.runtimeSessionId !== void 0 ? { runtimeSessionId: context.session.runtimeSessionId } : {}
4834
+ };
4835
+ const reopened = yield* Effect.result(openSessionContext({
4836
+ ...reopenInput,
4837
+ resumeCursor: nextCursor
4838
+ }, {
4839
+ probe: true,
4840
+ turnHeads: keptTurnHeads
4841
+ }));
4842
+ if (reopened._tag === "Success") return yield* snapshotThread(reopened.success);
4843
+ const refusal = adapterFailureDetail(reopened.failure);
4844
+ if ((yield* Effect.result(openSessionContext({
4845
+ ...reopenInput,
4846
+ resumeCursor: previousCursor
4847
+ }, {
4848
+ probe: true,
4849
+ turnHeads: context.turnHeads
4850
+ })))._tag === "Failure") {
4851
+ const stamp = yield* makeEventStamp();
4852
+ yield* offerRuntimeEventForContext(context, {
4853
+ type: "session.exited",
4854
+ eventId: stamp.eventId,
4855
+ provider: PROVIDER,
4856
+ createdAt: stamp.createdAt,
4857
+ threadId,
4858
+ payload: {
4859
+ reason: "Claude could not restart after a failed rewind",
4860
+ exitKind: "error"
4861
+ },
4862
+ providerRefs: {}
4863
+ });
4864
+ }
4865
+ return yield* refuse(`Claude refused to rewind this conversation, so nothing was changed. ${refusal}`);
4866
+ }).pipe(Effect.ensuring(Effect.sync(() => rewindingThreads.delete(threadId))));
3691
4867
  });
3692
4868
  const respondToRequest = Effect.fn("respondToRequest")(function* (threadId, requestId, decision) {
3693
4869
  const context = yield* requireSession(threadId);
@@ -3724,9 +4900,15 @@ const makeClaudeAdapter = Effect.fn("makeClaudeAdapter")(function* (claudeSettin
3724
4900
  yield* Effect.addFinalizer(() => Effect.forEach(sessions, ([, context]) => stopSessionInternal(context, { emitExitEvent: false }), { discard: true }).pipe(Effect.tap(() => runtimeEventQueueMetrics.reset), Effect.tap(() => Queue.shutdown(runtimeEventQueue))));
3725
4901
  return {
3726
4902
  provider: PROVIDER,
3727
- capabilities: { sessionModelSwitch: "in-session" },
4903
+ capabilities: {
4904
+ sessionModelSwitch: "in-session",
4905
+ conversationRollback: "native",
4906
+ turnSteering: "native",
4907
+ resumeSurvivesCwdChange: false
4908
+ },
3728
4909
  startSession,
3729
4910
  sendTurn,
4911
+ steerTurn,
3730
4912
  interruptTurn,
3731
4913
  stopBackgroundTask,
3732
4914
  readThread,