ryco-cli 0.1.29 → 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 (500) hide show
  1. package/README.md +37 -0
  2. package/dist/{AcpAdapter-8CSe4HK7.cjs → AcpAdapter-ByUp9-wk.cjs} +74 -54
  3. package/dist/{AcpAdapter-CG1wRWcf.mjs → AcpAdapter-CY_ANTKu.mjs} +74 -54
  4. package/dist/{AcpNativeLogging-B6TtnnKL.mjs → AcpNativeLogging-C7PC6imv.mjs} +30 -4
  5. package/dist/{AcpNativeLogging-DbjnRnTf.cjs → AcpNativeLogging-OQeAya9d.cjs} +33 -1
  6. package/dist/{AcpRegistryDriver-16ZTxUs3.cjs → AcpRegistryDriver-CD9GN7rI.cjs} +3 -3
  7. package/dist/{AcpRegistryDriver-DZFasKaz.mjs → AcpRegistryDriver-DMZ5VBWJ.mjs} +4 -4
  8. package/dist/AzureDevOpsSourceControlProvider-5giVYoNi.mjs +2053 -0
  9. package/dist/AzureDevOpsSourceControlProvider-BKMXEUaN.cjs +2055 -0
  10. package/dist/{BitbucketSourceControlProvider-DplKc8Wo.mjs → BitbucketSourceControlProvider-BVUBsEUF.mjs} +63 -23
  11. package/dist/{BitbucketSourceControlProvider-B-ZwKj72.cjs → BitbucketSourceControlProvider-BWnnrbch.cjs} +62 -22
  12. package/dist/{BunPTY-Dcl1Lp62.mjs → BunPTY-CMbDQ1Xb.mjs} +1 -1
  13. package/dist/{ClaudeDriver-r0lJ9vmE.cjs → ClaudeDriver-DCrqouOR.cjs} +1376 -194
  14. package/dist/{ClaudeDriver-0gGVop27.mjs → ClaudeDriver-DVOss8cC.mjs} +1377 -195
  15. package/dist/{CodexDriver-bJAbhSwY.cjs → CodexDriver-CBQPHJqU.cjs} +259 -29
  16. package/dist/{CodexDriver-baT02xVb.mjs → CodexDriver-DJoTky7Z.mjs} +261 -31
  17. package/dist/{CodexTextGeneration-Dwp6X3dq.mjs → CodexTextGeneration-BSgNgfZv.mjs} +6 -6
  18. package/dist/{CodexTextGeneration-DFZ5y4gj.cjs → CodexTextGeneration-C9MDQmZm.cjs} +7 -7
  19. package/dist/{CopilotDriver-C0OhnSB1.mjs → CopilotDriver-CUkdPXcH.mjs} +78 -20
  20. package/dist/{CopilotDriver-B_jEqfYQ.cjs → CopilotDriver-DbaMDH16.cjs} +76 -18
  21. package/dist/{CursorDriver-DinXkGP9.mjs → CursorDriver-B-ZilXJB.mjs} +115 -98
  22. package/dist/{CursorDriver-BBFEW7ZI.cjs → CursorDriver-DKQqPbKH.cjs} +116 -99
  23. package/dist/{ForgejoSourceControlProvider-iG9o7aZB.cjs → ForgejoSourceControlProvider-CgpjFECj.cjs} +94 -60
  24. package/dist/{ForgejoSourceControlProvider-Dr0fxfud.mjs → ForgejoSourceControlProvider-DemMYUye.mjs} +95 -61
  25. package/dist/{GitHubSourceControlProvider-L1yFpep4.cjs → GitHubSourceControlProvider-C4un6hOK.cjs} +218 -119
  26. package/dist/{GitHubSourceControlProvider-CnIu0n2Y.mjs → GitHubSourceControlProvider-CRSDYcjc.mjs} +206 -108
  27. package/dist/GitLabSourceControlProvider-D8W1ZLPh.cjs +2260 -0
  28. package/dist/GitLabSourceControlProvider-DpWkJ0M3.mjs +2258 -0
  29. package/dist/{GrokDriver-D_Ylzh5z.cjs → GrokDriver-BQ6G_7ZZ.cjs} +11 -12
  30. package/dist/{GrokDriver-pX-N6HGS.mjs → GrokDriver-Buvas9-q.mjs} +7 -8
  31. package/dist/{Metrics-BjqGlIP4.mjs → Metrics-C3vLS9rz.mjs} +1264 -1151
  32. package/dist/{Metrics-Bf96NJ4j.cjs → Metrics-DjRPLE98.cjs} +1295 -1134
  33. package/dist/{NodePTY-D7tFWuQe.mjs → NodePTY-DgnuBruq.mjs} +1 -1
  34. package/dist/{NodeSqliteClient-BGg70C7Q.cjs → NodeSqliteClient-D8bzGgPN.cjs} +1 -1
  35. package/dist/{OpenCodeDriver-Byu1pf_i.mjs → OpenCodeDriver-BWEZD841.mjs} +184 -50
  36. package/dist/{OpenCodeDriver-BFEw5t09.cjs → OpenCodeDriver-qUiX0RLH.cjs} +185 -51
  37. package/dist/{SideQuestionIsolation-81IoAuoi.mjs → SideQuestionIsolation-B1T-DsR0.mjs} +1 -1
  38. package/dist/{SideQuestionIsolation-CMPkCUP0.cjs → SideQuestionIsolation-BPC-Bxsz.cjs} +1 -1
  39. package/dist/bin.cjs +50689 -15659
  40. package/dist/bin.mjs +50578 -15585
  41. package/dist/client/assets/AccountSettings-B88Q_w9Y.js +1 -0
  42. package/dist/client/assets/AiFocusSettings-Bb0TrCPn.js +1 -0
  43. package/dist/client/assets/{AnimatedHeight-BNg7wnTK.js → AnimatedHeight-epXOsgdm.js} +1 -1
  44. package/dist/client/assets/AppearanceSettings-XS9WRVPU.js +1 -0
  45. package/dist/client/assets/AutomationsDialog-bZckh4Y3.js +1 -0
  46. package/dist/client/assets/AutomationsSummary-wPFZCF49.js +1 -0
  47. package/dist/client/assets/BranchToolbar.logic-DjzLKbbB.js +3 -0
  48. package/dist/client/assets/BrowserPanel-CdBLnnfz.js +1 -0
  49. package/dist/client/assets/ChatRightPanel-BCINd0vP.js +34 -0
  50. package/dist/client/assets/ChatThreadRouteView-BFZ0Si-l.js +1 -0
  51. package/dist/client/assets/ColorSwatchPicker-CGyo99o0.js +1 -0
  52. package/dist/client/assets/CommandPalette.logic-BIOMtnEQ.js +1 -0
  53. package/dist/client/assets/CommandPaletteDialog-Db4LH--z.js +2 -0
  54. package/dist/client/assets/CompositeRoot-DtnwMJKj.js +1 -0
  55. package/dist/client/assets/ComputerUseSettings-CkqCqDsU.js +1 -0
  56. package/dist/client/assets/ConnectionsSettings-B9mxExdG.js +7 -0
  57. package/dist/client/assets/CreatePullRequestDialog-CJ7pNCue.js +1 -0
  58. package/dist/client/assets/CreatePullRequestDialogHost-n4ZjdSr4.js +1 -0
  59. package/dist/client/assets/DiagnosticsSettings-f9rFG9re.js +2 -0
  60. package/dist/client/assets/DiagnosticsSettings.logic-Byf-Bu4S.js +1 -0
  61. package/dist/client/assets/DialogHandle-C0c_rK3I.js +1 -0
  62. package/dist/client/assets/{DialogPopup-DdZlhHuQ.js → DialogPopup-BKW1PEEa.js} +1 -1
  63. package/dist/client/assets/DialogRoot-BIubqrv0.js +1 -0
  64. package/dist/client/assets/DialogTitle-BAX_FLoG.js +1 -0
  65. package/dist/client/assets/{DialogViewport-BwuqbGLY.js → DialogViewport-C2iOUx0O.js} +1 -1
  66. package/dist/client/assets/DiffPanel-BkqDt_SS.js +25 -0
  67. package/dist/client/assets/DisclosureRegion-B8556yU0.js +1 -0
  68. package/dist/client/assets/DraftChatThreadRouteView-BKgRKJ2w.js +1 -0
  69. package/dist/client/assets/{ExternalIdentityWeb.logic-DsTJQkg-.js → ExternalIdentityWeb.logic-Cu6suNrN.js} +1 -1
  70. package/dist/client/assets/GlassSurface-DLYYzRdP.js +1 -0
  71. package/dist/client/assets/HostedConnectionControls-CoVqtnrK.js +1 -0
  72. package/dist/client/assets/HostedHubRoot-CM2CwPUr.js +2 -0
  73. package/dist/client/assets/{HostedNativeAuthorizationRoute-BSq_AlY2.js → HostedNativeAuthorizationRoute-Bizmqrh_.js} +2 -2
  74. package/dist/client/assets/HostedNodeRenameDialog-SXWMsTO0.js +1 -0
  75. package/dist/client/assets/HostedRelayTrustNotice-BfTyrBi5.js +1 -0
  76. package/dist/client/assets/InboxStatusGlyph-BPTqzp7l.js +1 -0
  77. package/dist/client/assets/IntegrationsSettingsPanel-DAPvkV4i.js +1 -0
  78. package/dist/client/assets/KeybindingsSettings-B8g-YI2O.js +1 -0
  79. package/dist/client/assets/LazyBrowserPanel-Ds9cdOC_.js +2 -0
  80. package/dist/client/assets/McpServersSettings-Dw6G3ff3.js +6 -0
  81. package/dist/client/assets/MobileSheet-DfgXNWbd.js +1 -0
  82. package/dist/client/assets/ModelTuningDial-DQBAbuNL.js +1 -0
  83. package/dist/client/assets/NewWorktreeDialog-CDZAJmK6.js +4 -0
  84. package/dist/client/assets/NodeSecuritySettings-3MELA9ru.js +1 -0
  85. package/dist/client/assets/NullStore-gT_6_xZE.js +1 -0
  86. package/dist/client/assets/OnboardingDialog-CAAtNnJf.js +1 -0
  87. package/dist/client/assets/OpinionatedPluginsSettings-AiDB0Vl4.js +1 -0
  88. package/dist/client/assets/{PdfAttachmentPreview-CTo1AyZs.js → PdfAttachmentPreview-BFNW2wjN.js} +2 -2
  89. package/dist/client/assets/{PhoneGetAppInterstitial-DwopOWnQ.js → PhoneGetAppInterstitial-D8fwZ8E9.js} +1 -1
  90. package/dist/client/assets/PhoneHome-YHgHljA0.js +1 -0
  91. package/dist/client/assets/PhoneSettingsSurface-BVxJppvK.js +2 -0
  92. package/dist/client/assets/PreviewPanel-BYcEnkv9.js +643 -0
  93. package/dist/client/assets/ProjectScriptDialog-K34K2Kzm.js +1 -0
  94. package/dist/client/assets/ProjectsPage-DXnMYLjb.js +1 -0
  95. package/dist/client/assets/PromoteChatDialog-CAY7_wJ-.js +1 -0
  96. package/dist/client/assets/ProviderLimitWindow-CK04BSkM.js +1 -0
  97. package/dist/client/assets/ProviderUpdateLaunchNotification.logic-BMBrDDOC.js +1 -0
  98. package/dist/client/assets/ProvidersSettingsPanel-C85PX9Es.js +1 -0
  99. package/dist/client/assets/PullRequestsPage-C0rgfGwB.js +1 -0
  100. package/dist/client/assets/{QuitShortcutFeedback-eCvP_MNj.js → QuitShortcutFeedback-DSkKqETs.js} +1 -1
  101. package/dist/client/assets/RedactedSensitiveText-DQ0YveQd.js +1 -0
  102. package/dist/client/assets/RollingText-BzvpP5fa.js +1 -0
  103. package/dist/client/assets/RootAppShell-BYQ-eGNT.js +6 -0
  104. package/dist/client/assets/{Separator-BiINUUQl.js → Separator-DpiW19Vw.js} +1 -1
  105. package/dist/client/assets/SettingsPage-BCFN7Ju2.js +2 -0
  106. package/dist/client/assets/SettingsPanels-CP6z2b1x.js +3 -0
  107. package/dist/client/assets/SettingsPanels.editor-D8U-TWWG.js +1 -0
  108. package/dist/client/assets/SettingsSelect-DEhNaz3E.js +1 -0
  109. package/dist/client/assets/Sidebar.logic-D_ODfSpl.js +1 -0
  110. package/dist/client/assets/SimulatorPanel-DCT6fZ0X.js +1 -0
  111. package/dist/client/assets/SourceControlSettings-DxUtvPMK.js +1 -0
  112. package/dist/client/assets/StatisticsPage-C9SrwtM4.js +1 -0
  113. package/dist/client/assets/StatisticsPanel-BMYLETs0.js +1 -0
  114. package/dist/client/assets/ThreadLinkList-BN5z5EpS.js +169 -0
  115. package/dist/client/assets/ThreadTerminalDrawer-CgIFOlR-.js +18 -0
  116. package/dist/client/assets/ThreadWorkspacePanel-DvXoqQPF.js +3 -0
  117. package/dist/client/assets/ToolbarRootContext-8FsV9Cpj.js +1 -0
  118. package/dist/client/assets/TraitsPicker-DcrpJahy.js +1 -0
  119. package/dist/client/assets/Virtualizer-CwXeUPla.js +1345 -0
  120. package/dist/client/assets/WorkspacePullRequestPanel-3mlcJn9G.js +1 -0
  121. package/dist/client/assets/WorkspaceReview-UGbCgXeK.js +2 -0
  122. package/dist/client/assets/{abnfDiagram-N423BO3Z-DAmGykdr.js → abnfDiagram-N423BO3Z-DVEM6Scc.js} +1 -1
  123. package/dist/client/assets/{activity-DRZlu-MC.js → activity-DVCuAejY.js} +1 -1
  124. package/dist/client/assets/{alert-CwrDisFU.js → alert-FV7ZIit_.js} +1 -1
  125. package/dist/client/assets/alert-dialog-CgXR9tED.js +1 -0
  126. package/dist/client/assets/app-window-3xtwqZgI.js +1 -0
  127. package/dist/client/assets/appChrome-COCz-T7w.js +1 -0
  128. package/dist/client/assets/{appearancePreferences-nFx4MHoI.js → appearancePreferences-NnsvXwBe.js} +1 -1
  129. package/dist/client/assets/architecture-7GRP2DOG-DXXb_0_g.js +1 -0
  130. package/dist/client/assets/{architectureDiagram-T3A2C74G-DypU2ERW.js → architectureDiagram-T3A2C74G-B6pcKiCj.js} +1 -1
  131. package/dist/client/assets/{arrow-left-XhcJWpRy.js → arrow-left-Blu3LSE2.js} +1 -1
  132. package/dist/client/assets/{arrow-right-BBs6iTUL.js → arrow-right-CO3CH0ne.js} +1 -1
  133. package/dist/client/assets/arrow-up-B69gV2Bq.js +1 -0
  134. package/dist/client/assets/{arrow-up-right-CJ9Vq7nK.js → arrow-up-right-BbPGFOLA.js} +1 -1
  135. package/dist/client/assets/authorization-Ob6YwWiI.js +1 -0
  136. package/dist/client/assets/autocomplete-RVpjsrDv.js +1 -0
  137. package/dist/client/assets/ban-BIm2PVkE.js +1 -0
  138. package/dist/client/assets/{blockDiagram-VBNYF7ZC-B9MhR9hY.js → blockDiagram-VBNYF7ZC-WNerGp9V.js} +1 -1
  139. package/dist/client/assets/{bot-D5wgL7pu.js → bot-C9nWtaWq.js} +1 -1
  140. package/dist/client/assets/browserState-jt47YsqD.js +1 -0
  141. package/dist/client/assets/{c4Diagram-5PPSVZJV-C22FWSoE.js → c4Diagram-5PPSVZJV-wp1ioOoM.js} +1 -1
  142. package/dist/client/assets/camera-C13VoW3c.js +1 -0
  143. package/dist/client/assets/capabilities-CfOhq009.js +1 -0
  144. package/dist/client/assets/channel-56r2qL2v.js +1 -0
  145. package/dist/client/assets/{chart-column-D6Lnkklk.js → chart-column-DRv0YtL_.js} +1 -1
  146. package/dist/client/assets/checkbox-CIIIY9FA.js +1 -0
  147. package/dist/client/assets/checks-Dw022Bvy.js +1 -0
  148. package/dist/client/assets/{chunk-2GRJ4B5K-D1tZuCzA.js → chunk-2GRJ4B5K-DRl3ILpc.js} +1 -1
  149. package/dist/client/assets/{chunk-4I5QYGJK-Clf86zK0.js → chunk-4I5QYGJK-CYTRl4bo.js} +1 -1
  150. package/dist/client/assets/{chunk-5RXB4S5H-B36N5RYZ.js → chunk-5RXB4S5H-VCNwRsOa.js} +1 -1
  151. package/dist/client/assets/{chunk-6Q2QTUOP-IAxdzsQJ.js → chunk-6Q2QTUOP-DnSeKGPG.js} +1 -1
  152. package/dist/client/assets/{chunk-7Z6QIM7H-Ctqebv_4.js → chunk-7Z6QIM7H-Cjilh9TF.js} +1 -1
  153. package/dist/client/assets/{chunk-GF5L2VYU-CAfciJae.js → chunk-GF5L2VYU-CGR7AW0t.js} +1 -1
  154. package/dist/client/assets/{chunk-I66GZJ75-BZ7XtZf4.js → chunk-I66GZJ75-CXSn8dDu.js} +1 -1
  155. package/dist/client/assets/{chunk-JQJVKLGR-DVuZCWnv.js → chunk-JQJVKLGR-Dro-75lU.js} +1 -1
  156. package/dist/client/assets/{chunk-KBJHAD2P-DtWbzsRm.js → chunk-KBJHAD2P-BDqN2kVf.js} +1 -1
  157. package/dist/client/assets/{chunk-NSK5VX7P-BVMz_Hc4.js → chunk-NSK5VX7P-DGo5UczH.js} +1 -1
  158. package/dist/client/assets/{chunk-QR6OTTB3-DWitTCy-.js → chunk-QR6OTTB3-RWuyWnBI.js} +1 -1
  159. package/dist/client/assets/{chunk-UBXNYLIW-BuxXXP2s.js → chunk-UBXNYLIW-BPRzeB0w.js} +1 -1
  160. package/dist/client/assets/{chunk-W5SLKNZC-Bnf3sQl4.js → chunk-W5SLKNZC-DYWocTFi.js} +1 -1
  161. package/dist/client/assets/{chunk-WRU74C26-xu-KDOon.js → chunk-WRU74C26-ChbB1jY3.js} +1 -1
  162. package/dist/client/assets/circle-stop-D8B4hRpY.js +1 -0
  163. package/dist/client/assets/circle-x-CNLfrTqR.js +1 -0
  164. package/dist/client/assets/classDiagram-JCYQIIEL-DGvmFev3.js +1 -0
  165. package/dist/client/assets/classDiagram-v2-OCEON4UE-DGvmFev3.js +1 -0
  166. package/dist/client/assets/{clipboard-copy-oDSkUUg4.js → clipboard-copy-DGi8FKNO.js} +1 -1
  167. package/dist/client/assets/clock-3-DmJ4_XPI.js +1 -0
  168. package/dist/client/assets/clock-DZIuPtNG.js +1 -0
  169. package/dist/client/assets/color-picker-BdBXje-a.js +1 -0
  170. package/dist/client/assets/columns-2-CWlMOClK.js +1 -0
  171. package/dist/client/assets/combobox-Dtjtf7AB.js +1 -0
  172. package/dist/client/assets/{cynefin-OW5HDTMX-DGNyiNSf.js → cynefin-OW5HDTMX-TuShvMuM.js} +1 -1
  173. package/dist/client/assets/{cynefinDiagram-MW4NZA55-_ctibv4i.js → cynefinDiagram-MW4NZA55-B0Edt2Em.js} +1 -1
  174. package/dist/client/assets/{dagre-VZM6K2ZE-Bo-bS1Y0.js → dagre-VZM6K2ZE-D-eiuqHx.js} +1 -1
  175. package/dist/client/assets/{data-list-DLsM39Hp.js → data-list-BAx6jBY1.js} +1 -1
  176. package/dist/client/assets/desktopUpdateAtoms-BjrLa3tl.js +1 -0
  177. package/dist/client/assets/desktopWorkspace-C2wXVBhc.js +1 -0
  178. package/dist/client/assets/{deviceName-z0ZWSq0z.js → deviceName-B4youG0v.js} +1 -1
  179. package/dist/client/assets/{diagram-7IWD3JNH-DSjtw1SY.js → diagram-7IWD3JNH-DgM6lMlR.js} +1 -1
  180. package/dist/client/assets/{diagram-B4RE2ZJO-B7fWEvIa.js → diagram-B4RE2ZJO-CyHNDjzV.js} +1 -1
  181. package/dist/client/assets/{diagram-LBJQPF4R-trRYCE5d.js → diagram-LBJQPF4R-DDzuLIN5.js} +1 -1
  182. package/dist/client/assets/{diagram-Q27KOJAE-_DYcRggk.js → diagram-Q27KOJAE-BaBvK9QB.js} +1 -1
  183. package/dist/client/assets/{diagram-UB23O5K3-BkMzOHX8.js → diagram-UB23O5K3-CzZ2ewuZ.js} +1 -1
  184. package/dist/client/assets/dialogWords-Cg0YkJVg.js +1 -0
  185. package/dist/client/assets/diffRouteSearch-D2MKN_ah.js +1 -0
  186. package/dist/client/assets/disclosureMotion-cbMJn5-z.js +1 -0
  187. package/dist/client/assets/{download-CHdS3R_v.js → download-TvtXS4hE.js} +1 -1
  188. package/dist/client/assets/{ebnfDiagram-BXEA7PRR-DubiOMCG.js → ebnfDiagram-BXEA7PRR-CL1vdOKi.js} +1 -1
  189. package/dist/client/assets/editorPreferences-DqKyA-2Z.js +1 -0
  190. package/dist/client/assets/ellipsis-CDK1dNFZ.js +1 -0
  191. package/dist/client/assets/ellipsis-vertical-CwzEUTwV.js +1 -0
  192. package/dist/client/assets/{empty-BlBl_Vvw.js → empty-BovKoxbn.js} +1 -1
  193. package/dist/client/assets/{erDiagram-JOGREHBK-CFDiNfSJ.js → erDiagram-JOGREHBK-DmQR2if6.js} +1 -1
  194. package/dist/client/assets/eventmodeling-NTZA5JFV-D272GIcY.js +1 -0
  195. package/dist/client/assets/external-link-CJeVJZ7s.js +1 -0
  196. package/dist/client/assets/eye-BUmrXqzg.js +1 -0
  197. package/dist/client/assets/file-diff-BWc3mYsz.js +1 -0
  198. package/dist/client/assets/flowDiagram-UKHOOZJN-DLyS38Mm.js +1 -0
  199. package/dist/client/assets/folder-git-2-CPxg5wKP.js +1 -0
  200. package/dist/client/assets/folder-open-DcMymvp1.js +1 -0
  201. package/dist/client/assets/formatCount-B4KLI651.js +1 -0
  202. package/dist/client/assets/{ganttDiagram-PKOTCBZU-DT2XhE-m.js → ganttDiagram-PKOTCBZU-1q2nUL92.js} +1 -1
  203. package/dist/client/assets/git-pull-request-BFPwpm3c.js +1 -0
  204. package/dist/client/assets/{gitGraph-4MIJSDKK-BI5UGiqb.js → gitGraph-4MIJSDKK-COtwmv2S.js} +1 -1
  205. package/dist/client/assets/{gitGraphDiagram-DS77QQ5N-CzAB97Rd.js → gitGraphDiagram-DS77QQ5N-ChsvaxX4.js} +1 -1
  206. package/dist/client/assets/{group-DZJuSiJL.js → group-DWWn0dTx.js} +1 -1
  207. package/dist/client/assets/hammer-BXo-EU88.js +1 -0
  208. package/dist/client/assets/hostedConnectionCoordinator-BkAE-RhA.js +1 -0
  209. package/dist/client/assets/hostedPairing-5n5srRC9.js +1 -0
  210. package/dist/client/assets/{index-BAJdq3TK.js → index-DARIYokI.js} +2 -2
  211. package/dist/client/assets/{info-A6RAGUB7-DdGYYgLX.js → info-A6RAGUB7-CI2qZ9wW.js} +1 -1
  212. package/dist/client/assets/{infoDiagram-6WML65LV-zhUpER6a.js → infoDiagram-6WML65LV-BPmgcTPH.js} +1 -1
  213. package/dist/client/assets/{input-CzU08wbL.js → input-CCie4mm1.js} +1 -1
  214. package/dist/client/assets/{ishikawaDiagram-WSZJBQD7-BQLkqykE.js → ishikawaDiagram-WSZJBQD7-LyS9p3Yg.js} +1 -1
  215. package/dist/client/assets/{journeyDiagram-NVQOT4AX-DBgsbKOF.js → journeyDiagram-NVQOT4AX-BYaAmN65.js} +1 -1
  216. package/dist/client/assets/{kanban-definition-27J2QSJJ-DF-Rr-xs.js → kanban-definition-27J2QSJJ-D-pwzqFt.js} +1 -1
  217. package/dist/client/assets/{key-round-CvyrSjb2.js → key-round-BlrUTfxB.js} +1 -1
  218. package/dist/client/assets/keyboard-DlBdq6sz.js +1 -0
  219. package/dist/client/assets/label-ChtVI9lp.js +1 -0
  220. package/dist/client/assets/layers-BB-ruGvd.js +1 -0
  221. package/dist/client/assets/lifecycleSuggestionPolicy-0ERe_O53.js +1 -0
  222. package/dist/client/assets/list-checks-BkM_ZRsj.js +1 -0
  223. package/dist/client/assets/loader-3vQnfqIT.js +1 -0
  224. package/dist/client/assets/{log-out-D3rICSt5.js → log-out-CKq9YiLY.js} +1 -1
  225. package/dist/client/assets/{logging-C6tXZlGQ.js → logging-CCg76rgn.js} +1 -1
  226. package/dist/client/assets/main-Ch0bwS-M.js +9 -0
  227. package/dist/client/assets/main-Di0isH9D.css +2 -0
  228. package/dist/client/assets/{mermaid-parser.core-BiGKtilP.js → mermaid-parser.core-RK9ah5RM.js} +2 -2
  229. package/dist/client/assets/{mermaidEngine-Cjfgf3Bg.js → mermaidEngine-Dr8UsPhH.js} +3 -3
  230. package/dist/client/assets/message-circle-dashed-BrjwqS7-.js +1 -0
  231. package/dist/client/assets/messageQueueDrain-B7R7Qmq6.js +1 -0
  232. package/dist/client/assets/messages-square-cDTkDJv_.js +1 -0
  233. package/dist/client/assets/{mindmap-definition-FAOFIHXS-SiU9JwWJ.js → mindmap-definition-FAOFIHXS-DVudWasx.js} +1 -1
  234. package/dist/client/assets/{packet-AYTQ26CC-F-HuW5Dr.js → packet-AYTQ26CC-DnkTsVhD.js} +1 -1
  235. package/dist/client/assets/{pairingUrl-rQM9kSGT.js → pairingUrl-Dn1e2CVw.js} +1 -1
  236. package/dist/client/assets/panels-top-left-B7jZiLth.js +1 -0
  237. package/dist/client/assets/path-text-3Rfu6lt8.js +1 -0
  238. package/dist/client/assets/{pegDiagram-VL7TDLO6-cC-QUd7I.js → pegDiagram-VL7TDLO6-Do5PIp8B.js} +1 -1
  239. package/dist/client/assets/pencil-Bzg-nc6d.js +1 -0
  240. package/dist/client/assets/{pie-WAS4IAKB-BI3XUcLN.js → pie-WAS4IAKB-B_nNQOzn.js} +1 -1
  241. package/dist/client/assets/{pieDiagram-7S7Q4E2Y-BP4gJ4ZK.js → pieDiagram-7S7Q4E2Y-D_IG4xwA.js} +1 -1
  242. package/dist/client/assets/{play-BJZrOx6T.js → play-DpXXQ1qB.js} +1 -1
  243. package/dist/client/assets/popover-OWEv6cQz.js +48 -0
  244. package/dist/client/assets/presentationTier-DPVAxTK4.js +1 -0
  245. package/dist/client/assets/previewRouteSearch-BjZdTuSf.js +1 -0
  246. package/dist/client/assets/primary-Cf-xJExj.js +4 -0
  247. package/dist/client/assets/primitives-CxTBN7D4.js +1 -0
  248. package/dist/client/assets/projectCheckouts.logic-DUT4AxXr.js +1 -0
  249. package/dist/client/assets/projectPaths-B8aVmOZX.js +1 -0
  250. package/dist/client/assets/projectPreferences-CzWBItFj.js +1 -0
  251. package/dist/client/assets/providerCapabilities-B2YOPsLN.js +1 -0
  252. package/dist/client/assets/providerDriverMeta-BHHL9uw0.js +1 -0
  253. package/dist/client/assets/providerModels-v9PYbzRE.js +1 -0
  254. package/dist/client/assets/providerStatus-CDPaqb0S.js +1 -0
  255. package/dist/client/assets/pullRequestsModel.logic-Dv_om_C4.js +1 -0
  256. package/dist/client/assets/{qr-code-BFO8lV1M.js → qr-code-BlbiBIwH.js} +1 -1
  257. package/dist/client/assets/{qr-code-Cmfz5JKf.js → qr-code-DywzVgQC.js} +1 -1
  258. package/dist/client/assets/{quadrantDiagram-CIZ2JOQS-DO-N1m-q.js → quadrantDiagram-CIZ2JOQS-DY6fJyrM.js} +1 -1
  259. package/dist/client/assets/{radar-RG4KPBEZ-CfayXQ5F.js → radar-RG4KPBEZ-D9689I5m.js} +1 -1
  260. package/dist/client/assets/radio-group-DVwD6Cuy.js +1 -0
  261. package/dist/client/assets/{railroad-74A4TZTK-CT6f-etT.js → railroad-74A4TZTK-DVzWbQnl.js} +1 -1
  262. package/dist/client/assets/railroad-abnf-HS5TGJTU-C_2P6umA.js +1 -0
  263. package/dist/client/assets/railroad-ebnf-LZEXJU2U-aGlR3R3z.js +1 -0
  264. package/dist/client/assets/railroad-peg-WCYAUIDC-DCB9oE8y.js +1 -0
  265. package/dist/client/assets/{railroadDiagram-AXF67PYL-DC8egbob.js → railroadDiagram-AXF67PYL-D1oJ6Jtl.js} +1 -1
  266. package/dist/client/assets/readCache-B7cDPz2O.js +1 -0
  267. package/dist/client/assets/{refresh-cw-K_hU8_ld.js → refresh-cw-CRUTivd6.js} +1 -1
  268. package/dist/client/assets/{requirementDiagram-LRYGKXZP-DJMzcLk_.js → requirementDiagram-LRYGKXZP-7RM8iREp.js} +1 -1
  269. package/dist/client/assets/rotate-ccw-BE2ZCwL6.js +1 -0
  270. package/dist/client/assets/roving-radio-group-NMPWrDqe.js +1 -0
  271. package/dist/client/assets/rows-2-DDS4dGTX.js +1 -0
  272. package/dist/client/assets/runtime-DjjjAcTE.js +18 -0
  273. package/dist/client/assets/safePolygon-C1AzMRS4.js +1 -0
  274. package/dist/client/assets/{sankeyDiagram-W5VNT64P-YR6aIYLj.js → sankeyDiagram-W5VNT64P-C1tKAPGN.js} +1 -1
  275. package/dist/client/assets/{save-Mh-PA_2P.js → save-OZdkPs_y.js} +1 -1
  276. package/dist/client/assets/scroll-area-80P7vbjw.js +1 -0
  277. package/dist/client/assets/{scrollEdges-Zcpuz3un.js → scrollEdges-C0Oc-5qi.js} +1 -1
  278. package/dist/client/assets/select-Cb9FUPHD.js +1 -0
  279. package/dist/client/assets/separator-CO8bC7Wc.js +1 -0
  280. package/dist/client/assets/{sequenceDiagram-SI44F4Z6-BVeSqWDA.js → sequenceDiagram-SI44F4Z6-DGVpb7jL.js} +1 -1
  281. package/dist/client/assets/settings-2-PrRDu6Lc.js +1 -0
  282. package/dist/client/assets/settingsLayout-CRFNCk_D.js +1 -0
  283. package/dist/client/assets/sheet-C5DW7qVO.js +1 -0
  284. package/dist/client/assets/{shield-i098Bm_B.js → shield-CBHYqlkR.js} +1 -1
  285. package/dist/client/assets/{shield-alert-CXmR7fM9.js → shield-alert-Dc2cGwyR.js} +1 -1
  286. package/dist/client/assets/{shield-check-CdFhWT_o.js → shield-check-_wl7R4Js.js} +1 -1
  287. package/dist/client/assets/sidebar-0BBaFNm3.js +1 -0
  288. package/dist/client/assets/sidebarProjectFolders-BjWzbt8C.js +3 -0
  289. package/dist/client/assets/sidebarProjectGrouping-nQRStWrZ.js +1 -0
  290. package/dist/client/assets/sidebarStatusText-BBKuNies.js +1 -0
  291. package/dist/client/assets/sidebarUndo-Dfq1lvyF.js +1 -0
  292. package/dist/client/assets/{skeleton-BwFgUtuE.js → skeleton-DfUe6VV_.js} +1 -1
  293. package/dist/client/assets/sliders-horizontal-BGXkwvKv.js +1 -0
  294. package/dist/client/assets/sliding-tabs-BnDSjRU3.js +39 -0
  295. package/dist/client/assets/{smartphone-DGfizz51.js → smartphone-OEAQOTdv.js} +1 -1
  296. package/dist/client/assets/spinner-lHRJWsym.js +1 -0
  297. package/dist/client/assets/square-B05NKv3e.js +1 -0
  298. package/dist/client/assets/{star-J3x3fktG.js → star-C8mHmfZu.js} +1 -1
  299. package/dist/client/assets/{stateDiagram-OKZ733FA-DoIZN669.js → stateDiagram-OKZ733FA-CCOAegCG.js} +1 -1
  300. package/dist/client/assets/stateDiagram-v2-UEYNNEHI-D60qqBed.js +1 -0
  301. package/dist/client/assets/storeSelectors-BichCKDC.js +1 -0
  302. package/dist/client/assets/surfaceMorph-BTRijmlU.js +1 -0
  303. package/dist/client/assets/{swimlanes-SLNWSIFB-BoFLigyK.js → swimlanes-SLNWSIFB-CFsLYT4h.js} +1 -1
  304. package/dist/client/assets/swimlanesDiagram-ULZ7WXOC-D0SaJgSn.js +8 -0
  305. package/dist/client/assets/switch-oQc7Ifbl.js +1 -0
  306. package/dist/client/assets/text-wrap-DSRdSfDm.js +1 -0
  307. package/dist/client/assets/textarea-VyiIZ0wQ.js +1 -0
  308. package/dist/client/assets/threadPriorityRefreshRuntime-H656C1J_.js +1 -0
  309. package/dist/client/assets/ticker-CPutfhZ4.js +1 -0
  310. package/dist/client/assets/{timeline-definition-Z64GVDOM-D65EmNWc.js → timeline-definition-Z64GVDOM-B4agmO7R.js} +1 -1
  311. package/dist/client/assets/toggle-DFqtCPt-.js +1 -0
  312. package/dist/client/assets/toggle-group-C5ICmqkI.js +1 -0
  313. package/dist/client/assets/{tokenModePresentation-C0-NgmX5.js → tokenModePresentation-umDRm4k1.js} +1 -1
  314. package/dist/client/assets/tooltip-DbqhseXd.js +1 -0
  315. package/dist/client/assets/{treeView-Q6P3EWNA-C2S-OPgI.js → treeView-Q6P3EWNA-C_S3udFB.js} +1 -1
  316. package/dist/client/assets/{treemap-WGGIJYW6-6Ovsu9iH.js → treemap-WGGIJYW6-B-kUSAkE.js} +1 -1
  317. package/dist/client/assets/undo-2-lyluTGMW.js +1 -0
  318. package/dist/client/assets/{unplug-BEfcl9Ht.js → unplug-D6iu-qlh.js} +1 -1
  319. package/dist/client/assets/usage-ClF-eUmy.js +1 -0
  320. package/dist/client/assets/useActiveIndicator-R5NWu8Fg.js +1 -0
  321. package/dist/client/assets/useAppSidebarCollapsed-BbMxfio5.js +1 -0
  322. package/dist/client/assets/useAppearancePreference-Ix13pMKy.js +1 -0
  323. package/dist/client/assets/useAtlassian-BYDCc9lv.js +0 -0
  324. package/dist/client/assets/useCheckoutResolution-CR-oOp5-.js +1 -0
  325. package/dist/client/assets/useDesktopRelaunchGuard-Jmh615iZ.js +1 -0
  326. package/dist/client/assets/useDiffFileNavigation-DeuzdD5E.js +15 -0
  327. package/dist/client/assets/useDiffLayout-DhcXwhBL.js +1 -0
  328. package/dist/client/assets/useEnvironmentSettingsTarget-DM6BRDT7.js +1 -0
  329. package/dist/client/assets/useFocus-CV0KIZwg.js +1 -0
  330. package/dist/client/assets/useGit-CUcs7h5_.js +1 -0
  331. package/dist/client/assets/useGitBranchSearch-CeKFtnCL.js +1 -0
  332. package/dist/client/assets/useHostedDraftExecutionTarget-DvQU5UOq.js +1 -0
  333. package/dist/client/assets/useLabelableId-CEgCRi6q.js +1 -0
  334. package/dist/client/assets/useLandingFlash-BfOOlFtW.js +1 -0
  335. package/dist/client/assets/useLogicalProjectSnapshots-CRNZke74.js +1 -0
  336. package/dist/client/assets/useNavigate-sQZthdyT.js +1 -0
  337. package/dist/client/assets/usePageLeadingInsetClass-Bf4nUvx4.js +1 -0
  338. package/dist/client/assets/usePhoneThreadActions-VaQ-mZex.js +1 -0
  339. package/dist/client/assets/usePopupHandleStore-DimKo2Yy.js +1 -0
  340. package/dist/client/assets/usePopupViewport-YeqX_UM3.js +1 -0
  341. package/dist/client/assets/usePresentationTier-B9kCQ4YH.js +1 -0
  342. package/dist/client/assets/useProject-Kt74Z12J.js +1 -0
  343. package/dist/client/assets/useProviderOptionsUpdater-CTzNh2B7.js +2 -0
  344. package/dist/client/assets/usePullRequestFilesViewed-D5Snmzys.js +1 -0
  345. package/dist/client/assets/usePullRequestsModel-DJL5HHbP.js +40 -0
  346. package/dist/client/assets/useScrollLock-CLZ31xsK.js +1 -0
  347. package/dist/client/assets/useSidebarThreadActions-n6EkLATf.js +6 -0
  348. package/dist/client/assets/{useStatistics-D55-xLMz.js → useStatistics-DD0mYS4J.js} +14 -14
  349. package/dist/client/assets/{useTheme-B441xg4F.js → useTheme-Bdy-BDs-.js} +1 -1
  350. package/dist/client/assets/useValueChanged-DoumqMnV.js +1 -0
  351. package/dist/client/assets/{user-round-C-U7TZKG.js → user-round-BPDXr8Gq.js} +1 -1
  352. package/dist/client/assets/{vennDiagram-T6HMQDX7-fZAexcYr.js → vennDiagram-T6HMQDX7-B1UEn_j_.js} +1 -1
  353. package/dist/client/assets/{vscode-icons-BYX6fBsM.js → vscode-icons-Ccy-gzFN.js} +1 -1
  354. package/dist/client/assets/{wardley-WFR3VGLG-gdYWSMxK.js → wardley-WFR3VGLG-gPdyDc-7.js} +1 -1
  355. package/dist/client/assets/{wardleyDiagram-T6FBY63Y-iDJxQb70.js → wardleyDiagram-T6FBY63Y-2aDcwOA4.js} +1 -1
  356. package/dist/client/assets/workspaceLifecycle-OJ1aKksw.js +3 -0
  357. package/dist/client/assets/workspaceMetadataProjection-CyEyJhUa.js +1 -0
  358. package/dist/client/assets/workspaceRouteSearch-CCavUdbH.js +1 -0
  359. package/dist/client/assets/{wrench-D79uBUSl.js → wrench-CPUCA_rn.js} +1 -1
  360. package/dist/client/assets/wsTransport-C88seBPA.js +15 -0
  361. package/dist/client/assets/{xychartDiagram-ELKLHX3M-B4cfMwpJ.js → xychartDiagram-ELKLHX3M-C1_7Q-1i.js} +1 -1
  362. package/dist/client/favicon.svg +1 -1
  363. package/dist/client/index.html +1 -1
  364. package/dist/collectUint8StreamText-BsLSgI8i.mjs +710 -0
  365. package/dist/collectUint8StreamText-D5olwfpM.cjs +757 -0
  366. package/dist/{deviceHostWorker-L8C9wy38.mjs → deviceHostWorker-B-Dn-6An.mjs} +1 -1
  367. package/dist/{deviceHostWorker-CYnrwfrv.cjs → deviceHostWorker-D4HauWIV.cjs} +1 -1
  368. package/dist/{makeManagedServerProvider-CUwxc0Pn.cjs → makeManagedServerProvider-B5tP7tvg.cjs} +2 -2
  369. package/dist/{makeManagedServerProvider-B_lPFNpL.mjs → makeManagedServerProvider-B65ipCxM.mjs} +2 -2
  370. package/dist/resource-monitor/linux-arm64/ryco-resource-monitor +0 -0
  371. package/dist/resource-monitor/ryco-resource-monitor +0 -0
  372. package/dist/resource-monitor/ryco-resource-monitor.exe +0 -0
  373. package/dist/resource-monitor/win32-arm64/ryco-resource-monitor.exe +0 -0
  374. package/dist/resource-monitor/win32-x64/ryco-resource-monitor.exe +0 -0
  375. package/dist/{rolldown-runtime-LGfotAqq.cjs → rolldown-runtime-HbSU0i7K.cjs} +7 -0
  376. package/dist/{runtimeSession-V3RIy8Ao.mjs → runtimeSession-D_BZ-wRH.mjs} +1 -1
  377. package/dist/{src-BzVJd3Me.cjs → src-FmeCeBJ9.cjs} +3408 -308
  378. package/dist/{src-7E1M4gTQ.mjs → src-VTj60bUm.mjs} +2154 -140
  379. package/package.json +1 -1
  380. package/dist/AzureDevOpsSourceControlProvider-DmJD1-WL.cjs +0 -190
  381. package/dist/AzureDevOpsSourceControlProvider-d5Ogsspk.mjs +0 -188
  382. package/dist/GitLabSourceControlProvider-BZdwXdJl.mjs +0 -186
  383. package/dist/GitLabSourceControlProvider-CrcBR6KQ.cjs +0 -188
  384. package/dist/client/assets/AccountSettings-FN7pwqYA.js +0 -1
  385. package/dist/client/assets/AiFocusSettings-xcDAMaqH.js +0 -1
  386. package/dist/client/assets/AppearanceSettings-BvsvAOsG.js +0 -1
  387. package/dist/client/assets/BranchToolbar.logic-DFsXV3Qs.js +0 -3
  388. package/dist/client/assets/BrowserPanel-D-g_xDZs.js +0 -1
  389. package/dist/client/assets/ChatRightPanel-Bm906qNi.js +0 -201
  390. package/dist/client/assets/ChatThreadRouteView-CATwakjI.js +0 -1
  391. package/dist/client/assets/CommandPaletteDialog-Obv1bvxj.js +0 -1
  392. package/dist/client/assets/CompositeRoot-CfkIdky8.js +0 -1
  393. package/dist/client/assets/ComputerUseSettings-ljYmTHea.js +0 -1
  394. package/dist/client/assets/ConnectionsSettings-CIXs7x_E.js +0 -7
  395. package/dist/client/assets/ContextHandoffEndpointLabel-BzI4Wi1i.js +0 -4
  396. package/dist/client/assets/DiagnosticsSettings-DGX_2T2M.js +0 -2
  397. package/dist/client/assets/DialogHandle-CTtSYpsC.js +0 -1
  398. package/dist/client/assets/DialogRoot-k2_0SNKA.js +0 -1
  399. package/dist/client/assets/DialogTitle-Du7CAbaO.js +0 -1
  400. package/dist/client/assets/DialogTrigger-VpFh8Xza.js +0 -1
  401. package/dist/client/assets/DraftChatThreadRouteView-Cmc5HpWf.js +0 -1
  402. package/dist/client/assets/GlassSurface-BlWIlQ0s.js +0 -1
  403. package/dist/client/assets/HostedConnectionControls-ySHqwr4K.js +0 -1
  404. package/dist/client/assets/HostedHubRoot-Caz8PElK.js +0 -2
  405. package/dist/client/assets/HostedNodeRenameDialog-ChxJdr-Z.js +0 -1
  406. package/dist/client/assets/HostedRelayTrustNotice-DPVrIfj_.js +0 -1
  407. package/dist/client/assets/IntegrationsSettingsPanel-eAq5h-D5.js +0 -2
  408. package/dist/client/assets/KeybindingsSettings-D1XaEVGH.js +0 -7
  409. package/dist/client/assets/LazyBrowserPanel-B6POLJh3.js +0 -2
  410. package/dist/client/assets/McpServersSettings-DqLA6n5v.js +0 -6
  411. package/dist/client/assets/MobileSheet-CtQIYRlY.js +0 -1
  412. package/dist/client/assets/NodeSecuritySettings-Skm7GQDl.js +0 -1
  413. package/dist/client/assets/NullStore-b8PhjwPZ.js +0 -1
  414. package/dist/client/assets/OnboardingDialog-8-fKvY5H.js +0 -1
  415. package/dist/client/assets/OpinionatedPluginsSettings-BIJfJ34L.js +0 -1
  416. package/dist/client/assets/PhoneHome-CUzxhhR4.js +0 -1
  417. package/dist/client/assets/PhoneSettingsSurface-BK2RHmYJ.js +0 -2
  418. package/dist/client/assets/ProvidersSettingsPanel-DPxL7AsR.js +0 -1
  419. package/dist/client/assets/RedactedSensitiveText-DH4mWpB6.js +0 -1
  420. package/dist/client/assets/RootAppShell-DwiWD4Cy.js +0 -7
  421. package/dist/client/assets/SettingsDialog-CE8qy0qL.js +0 -2
  422. package/dist/client/assets/SettingsPanels-BYknk6GO.js +0 -3
  423. package/dist/client/assets/SettingsPanels.editor-64bM0lhg.js +0 -2
  424. package/dist/client/assets/SourceControlSettings-BbveiAj3.js +0 -1
  425. package/dist/client/assets/StatisticsPage-CAO_tCeC.js +0 -1
  426. package/dist/client/assets/StatisticsPanel-SNlgMv2o.js +0 -1
  427. package/dist/client/assets/StatisticsSettingsLink-BpkNubL2.js +0 -1
  428. package/dist/client/assets/ThreadTerminalDrawer-9x_kqQPy.js +0 -18
  429. package/dist/client/assets/ThreadWorkspacePanel-BXE17C4x.js +0 -2073
  430. package/dist/client/assets/appChrome-B_VWWDFj.js +0 -1
  431. package/dist/client/assets/architecture-7GRP2DOG-CQNNG5gU.js +0 -1
  432. package/dist/client/assets/authorization-BugIGt5e.js +0 -1
  433. package/dist/client/assets/badge-BswOCwph.js +0 -1
  434. package/dist/client/assets/capabilities-Bj_X9FZ-.js +0 -1
  435. package/dist/client/assets/channel-BtX-w3CK.js +0 -1
  436. package/dist/client/assets/chevron-right-Ddq5gL-L.js +0 -1
  437. package/dist/client/assets/classDiagram-JCYQIIEL-BgDa3HFl.js +0 -1
  438. package/dist/client/assets/classDiagram-v2-OCEON4UE-BgDa3HFl.js +0 -1
  439. package/dist/client/assets/compiler-runtime-C4g8XhC5.js +0 -1
  440. package/dist/client/assets/desktopWorkspace-Ocqt625W.js +0 -1
  441. package/dist/client/assets/editorPreferences-DVhg0CXd.js +0 -1
  442. package/dist/client/assets/eventmodeling-NTZA5JFV-DpzGHjmu.js +0 -1
  443. package/dist/client/assets/flowDiagram-UKHOOZJN-CaDVMm72.js +0 -1
  444. package/dist/client/assets/hostedConnectionCoordinator-BztHfGNt.js +0 -1
  445. package/dist/client/assets/hostedPairing-CqhLPQqG.js +0 -1
  446. package/dist/client/assets/hubRoutes-DExWSvVE.js +0 -1
  447. package/dist/client/assets/kbd-DKuvGqFP.js +0 -1
  448. package/dist/client/assets/layers-CwP65mnC.js +0 -1
  449. package/dist/client/assets/liquidGlass-CA2o_Cq0.js +0 -1
  450. package/dist/client/assets/liquidGlass.worker-icvLJKHf.js +0 -1
  451. package/dist/client/assets/main-BqSANuAs.css +0 -2
  452. package/dist/client/assets/main-RFllWEko.js +0 -9
  453. package/dist/client/assets/motion-C9rN_t9p.js +0 -1
  454. package/dist/client/assets/palette-gaqgtube.js +0 -1
  455. package/dist/client/assets/perfInstrumentation-BT27w4tn.js +0 -1
  456. package/dist/client/assets/presentationTier-xlIjcFab.js +0 -1
  457. package/dist/client/assets/primary-CQh_KHGG.js +0 -5
  458. package/dist/client/assets/providerDriverMeta-LJ2vJxm-.js +0 -1
  459. package/dist/client/assets/providerStatus-DBGvvkyF.js +0 -1
  460. package/dist/client/assets/radio-group-BueX1AVO.js +0 -1
  461. package/dist/client/assets/railroad-abnf-HS5TGJTU-B890iayj.js +0 -1
  462. package/dist/client/assets/railroad-ebnf-LZEXJU2U-C079Tzw6.js +0 -1
  463. package/dist/client/assets/railroad-peg-WCYAUIDC-DxvOX5Rh.js +0 -1
  464. package/dist/client/assets/runtime-OM-uAtaj.js +0 -18
  465. package/dist/client/assets/scroll-area-BC-LB_zE.js +0 -1
  466. package/dist/client/assets/separator-yx1r9ZDw.js +0 -1
  467. package/dist/client/assets/settingsLayout-BbjDM-p0.js +0 -1
  468. package/dist/client/assets/sheet-CpEwjOWn.js +0 -1
  469. package/dist/client/assets/sidebar-DayQTDZp.js +0 -1
  470. package/dist/client/assets/sidebarProjectFolders-DXqx3OlZ.js +0 -4
  471. package/dist/client/assets/sidebarStatusText-kdA6QMZS.js +0 -1
  472. package/dist/client/assets/sidebarUndo-BHFfJj0k.js +0 -1
  473. package/dist/client/assets/square-Cd2WS1gv.js +0 -1
  474. package/dist/client/assets/src-DHNjfMxR.js +0 -14
  475. package/dist/client/assets/stateDiagram-v2-UEYNNEHI-BnzsGHaN.js +0 -1
  476. package/dist/client/assets/storeSelectors-D60AAN01.js +0 -1
  477. package/dist/client/assets/swimlanesDiagram-ULZ7WXOC-BnA-oDvU.js +0 -8
  478. package/dist/client/assets/switch-D9inWKdd.js +0 -48
  479. package/dist/client/assets/toggle-group-YNqzWsK0.js +0 -1
  480. package/dist/client/assets/toggle-wMq3LLn1.js +0 -1
  481. package/dist/client/assets/tooltip-mwOCSCXF.js +0 -1
  482. package/dist/client/assets/usage-DF8oQrsy.js +0 -1
  483. package/dist/client/assets/useAppSidebarCollapsed-C0jpPtER.js +0 -1
  484. package/dist/client/assets/useAppearancePreference-Dlh9P8iu.js +0 -1
  485. package/dist/client/assets/useBaseUiId-Bz8dcyjd.js +0 -1
  486. package/dist/client/assets/useLabelableId-C8bc9a0F.js +0 -1
  487. package/dist/client/assets/useNavigate-01O5dMQe.js +0 -1
  488. package/dist/client/assets/usePhoneThreadActions-BIdh81kF.js +0 -1
  489. package/dist/client/assets/usePopupViewport-DYYZwfTW.js +0 -1
  490. package/dist/client/assets/usePresentationTier-hxB7Yv_Q.js +0 -1
  491. package/dist/client/assets/useScrollLock-BO185DkJ.js +0 -1
  492. package/dist/client/assets/useTriggerFocusGuards-CMLVr18J.js +0 -1
  493. package/dist/client/assets/useValueChanged-DSyRHPje.js +0 -1
  494. package/dist/client/assets/workspaceMetadataProjection-So9-wSEZ.js +0 -1
  495. package/dist/collectUint8StreamText-BAUF-vzz.mjs +0 -37
  496. package/dist/collectUint8StreamText-vagpNUMJ.cjs +0 -42
  497. package/dist/git-BKwGfw8A.mjs +0 -132
  498. package/dist/git-Dn5wrgFY.cjs +0 -218
  499. package/dist/sourceControl-B0D1Op29.cjs +0 -253
  500. package/dist/sourceControl-BiEBxN01.mjs +0 -224
@@ -1,23 +1,22 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const require_rolldown_runtime = require("./rolldown-runtime-LGfotAqq.cjs");
4
- const require_src = require("./src-BzVJd3Me.cjs");
5
- const require_Metrics = require("./Metrics-Bf96NJ4j.cjs");
6
- const require_git = require("./git-Dn5wrgFY.cjs");
3
+ const require_rolldown_runtime = require("./rolldown-runtime-HbSU0i7K.cjs");
4
+ const require_Metrics = require("./Metrics-DjRPLE98.cjs");
5
+ const require_src = require("./src-FmeCeBJ9.cjs");
7
6
  const require_bin = require("./bin.cjs");
8
7
  const require_runtimeSession = require("./runtimeSession-Bj0OUcNJ.cjs");
9
8
  const require_ProviderDriver = require("./ProviderDriver--rNeAi3B.cjs");
10
- const require_SideQuestionIsolation = require("./SideQuestionIsolation-CMPkCUP0.cjs");
9
+ const require_SideQuestionIsolation = require("./SideQuestionIsolation-BPC-Bxsz.cjs");
11
10
  const require_sourceControlContextFormatter = require("./sourceControlContextFormatter-BDZqn-4T.cjs");
12
11
  const require_ProjectCustomSystemPrompt = require("./ProjectCustomSystemPrompt-B8SUlNGa.cjs");
13
- const require_makeManagedServerProvider = require("./makeManagedServerProvider-CUwxc0Pn.cjs");
12
+ const require_makeManagedServerProvider = require("./makeManagedServerProvider-B5tP7tvg.cjs");
14
13
  let effect = require("effect");
15
- let effect_unstable_http = require("effect/unstable/http");
14
+ let node_child_process = require("node:child_process");
16
15
  let node_path = require("node:path");
17
16
  node_path = require_rolldown_runtime.__toESM(node_path, 1);
17
+ let effect_unstable_http = require("effect/unstable/http");
18
18
  let node_os = require("node:os");
19
19
  node_os = require_rolldown_runtime.__toESM(node_os, 1);
20
- let node_child_process = require("node:child_process");
21
20
  let node_fs_promises = require("node:fs/promises");
22
21
  node_fs_promises = require_rolldown_runtime.__toESM(node_fs_promises, 1);
23
22
  let effect_unstable_process = require("effect/unstable/process");
@@ -28,7 +27,8 @@ const PROVIDER$1 = require_src.ProviderDriverKind.make("claudeAgent");
28
27
  const CLAUDE_PRESENTATION = {
29
28
  displayName: "Claude",
30
29
  showInteractionModeToggle: true,
31
- supportsAskMode: true
30
+ supportsAskMode: true,
31
+ supportsTurnSteering: true
32
32
  };
33
33
  function getClaudeModelCapabilities(model) {
34
34
  const capabilities = require_bin.getClaudeCatalogModelCapabilities(require_bin.getActiveClaudeModelCatalog(), model);
@@ -488,7 +488,7 @@ const makeClaudeTextGeneration = effect.Effect.fn("makeClaudeTextGeneration")(fu
488
488
  return {
489
489
  subject: require_bin.sanitizeCommitSubject(generated.subject),
490
490
  body: generated.body.trim(),
491
- ..."branch" in generated && typeof generated.branch === "string" ? { branch: require_git.sanitizeFeatureBranchName(generated.branch) } : {}
491
+ ..."branch" in generated && typeof generated.branch === "string" ? { branch: require_bin.sanitizeFeatureBranchName(generated.branch) } : {}
492
492
  };
493
493
  });
494
494
  const generatePrContent = effect.Effect.fn("ClaudeTextGeneration.generatePrContent")(function* (input) {
@@ -523,7 +523,7 @@ const makeClaudeTextGeneration = effect.Effect.fn("makeClaudeTextGeneration")(fu
523
523
  outputSchemaJson: outputSchema,
524
524
  modelSelection: input.modelSelection
525
525
  });
526
- return { branch: require_git.sanitizeBranchFragment(generated.branch) };
526
+ return { branch: require_bin.sanitizeBranchFragment(generated.branch) };
527
527
  });
528
528
  const generateThreadTitle = effect.Effect.fn("ClaudeTextGeneration.generateThreadTitle")(function* (input) {
529
529
  const { prompt, outputSchema } = require_bin.buildThreadTitlePrompt({
@@ -629,6 +629,7 @@ function observeClaudeCache(input) {
629
629
  providerInstanceId: input.providerInstanceId,
630
630
  model: input.model,
631
631
  ...input.modelSelection ? { modelSelection: input.modelSelection } : {},
632
+ ...input.cwd ? { cwd: input.cwd } : {},
632
633
  messageId: input.messageId,
633
634
  directInputTokens: counts.directInputTokens,
634
635
  cacheReadInputTokens: counts.cacheReadInputTokens,
@@ -637,6 +638,278 @@ function observeClaudeCache(input) {
637
638
  };
638
639
  }
639
640
  //#endregion
641
+ //#region src/provider/claudeContextUsage.ts
642
+ function knownContextWindow(value) {
643
+ return typeof value === "number" && Number.isSafeInteger(value) && value > 0 ? value : void 0;
644
+ }
645
+ /**
646
+ * `compact_boundary.compact_metadata.post_tokens` as a context gauge; undefined when absent or
647
+ * invalid. Compaction invalidated the cache evidence, so the gauge never carries `claudeCache`.
648
+ */
649
+ function claudePostCompactionUsage(compactMetadata, contextWindow) {
650
+ if (compactMetadata === null || typeof compactMetadata !== "object") return;
651
+ const postTokens = compactMetadata.post_tokens;
652
+ if (typeof postTokens !== "number" || !Number.isFinite(postTokens)) return;
653
+ const rounded = Math.round(postTokens);
654
+ if (rounded <= 0) return;
655
+ const maxTokens = knownContextWindow(contextWindow);
656
+ return {
657
+ usedTokens: maxTokens !== void 0 ? Math.min(rounded, maxTokens) : rounded,
658
+ ...maxTokens !== void 0 ? { maxTokens } : {}
659
+ };
660
+ }
661
+ /**
662
+ * The gauge a Claude result publishes. `result.usage` is cumulative across every API call of the
663
+ * turn, so the last main-loop gauge wins and the cumulative figure only rides along as
664
+ * `totalProcessedTokens`. Without a gauge the cumulative snapshot is a fallback, but never for a
665
+ * turn that crossed a compaction boundary: its cumulative input is the pre-compaction size.
666
+ */
667
+ function selectClaudeResultUsageGauge(input) {
668
+ const { lastGauge, cumulative, maxTokens } = input;
669
+ if (lastGauge === void 0) return input.cumulativeIsGauge ? cumulative : void 0;
670
+ const cumulativeTotal = cumulative?.totalProcessedTokens ?? cumulative?.usedTokens;
671
+ return {
672
+ ...lastGauge,
673
+ ...typeof maxTokens === "number" && Number.isFinite(maxTokens) && maxTokens > 0 ? { maxTokens } : {},
674
+ ...typeof cumulativeTotal === "number" && Number.isFinite(cumulativeTotal) && cumulativeTotal > lastGauge.usedTokens ? { totalProcessedTokens: cumulativeTotal } : {}
675
+ };
676
+ }
677
+ const ABORT_TERMINAL_REASONS = /* @__PURE__ */ new Set(["aborted_streaming", "aborted_tools"]);
678
+ function resultErrorsText(result) {
679
+ return "errors" in result && Array.isArray(result.errors) ? result.errors.join(" ").toLowerCase() : "";
680
+ }
681
+ function isInterruptedResult(result) {
682
+ const errors = resultErrorsText(result);
683
+ if (errors.includes("interrupt")) return true;
684
+ return result.subtype === "error_during_execution" && result.is_error === false && (errors.includes("request was aborted") || errors.includes("interrupted by user") || errors.includes("aborted"));
685
+ }
686
+ /** The CLI ended the segment by aborting it (a Stop or a `priority: "now"` steer). */
687
+ function isClaudeAbortTerminalReason(result) {
688
+ const terminalReason = Reflect.get(result, "terminal_reason");
689
+ return typeof terminalReason === "string" && ABORT_TERMINAL_REASONS.has(terminalReason);
690
+ }
691
+ function readStringArray(value) {
692
+ return Array.isArray(value) && value.every((entry) => typeof entry === "string") ? value : void 0;
693
+ }
694
+ function isRootFrame$1(message) {
695
+ const parentToolUseId = Reflect.get(message, "parent_tool_use_id");
696
+ return parentToolUseId === null || parentToolUseId === void 0;
697
+ }
698
+ /**
699
+ * The prompt uuids a frame echoes. Results echo every user message the CLI turn consumed. The
700
+ * CLI turn's first reply frame echoes the messages that started it (early echo): its first
701
+ * non-ping stream event, or its first root assistant message when it streamed nothing (a request
702
+ * that failed at the API replies with a synthetic error message).
703
+ */
704
+ function claudeEchoedPromptUuids(message) {
705
+ if (message.type !== "result" && message.type !== "stream_event" && !(message.type === "assistant" && isRootFrame$1(message))) return [];
706
+ const uuids = readStringArray(Reflect.get(message, "user_message_uuids"));
707
+ if (uuids !== void 0 && uuids.length > 0) return uuids;
708
+ const uuid = Reflect.get(message, "user_message_uuid");
709
+ return typeof uuid === "string" && uuid.length > 0 ? [uuid] : [];
710
+ }
711
+ function classifyClaudeResultKind(result) {
712
+ if (result.subtype === "success" && !result.is_error) return "success";
713
+ if (isClaudeAbortTerminalReason(result)) return "abort";
714
+ if (Reflect.get(result, "terminal_reason") === void 0 && isInterruptedResult(result)) return "abort";
715
+ return "failure";
716
+ }
717
+ /** Whether an echo names the turn's prompt or one of its steers. */
718
+ function claudeEchoNamesTurn(input) {
719
+ return input.echoed.some((uuid) => uuid === input.promptUuid || input.steerPromptUuids.has(uuid));
720
+ }
721
+ /**
722
+ * Whether a result belongs to the open prompt turn. It does when it echoes the prompt or any of
723
+ * the turn's steers. Without an echo (older CLIs) it belongs unless its origin is not human.
724
+ * Callers skip the check for provider turns (no prompt uuid).
725
+ */
726
+ function claudeResultBelongsToTurn(input) {
727
+ if (input.echoed.length > 0) return claudeEchoNamesTurn(input);
728
+ return input.origin === void 0 || input.origin.kind === "human";
729
+ }
730
+ /**
731
+ * The turn waits only when Stop was not requested, a steer is still unsettled, the segment ended
732
+ * by abort or success, and the CLI positively promised another result (`queued_turn_count > 0`).
733
+ * Every other result completes the turn, so no waiting is unbounded.
734
+ */
735
+ function decideClaudeTurnResult(input) {
736
+ const echoed = new Set(input.echoedPromptUuids);
737
+ const newlySettled = [];
738
+ const unsettled = [];
739
+ for (const uuid of input.steerPromptUuids) {
740
+ if (input.settledSteerPromptUuids.has(uuid)) continue;
741
+ if (echoed.has(uuid)) newlySettled.push(uuid);
742
+ else unsettled.push(uuid);
743
+ }
744
+ const awaitSteer = !input.interruptRequested && unsettled.length > 0 && (input.kind === "abort" || input.kind === "success") && typeof input.queuedTurnCount === "number" && input.queuedTurnCount > 0;
745
+ const completingWithSteers = !awaitSteer && unsettled.length > 0;
746
+ return {
747
+ decision: awaitSteer ? "await-steer" : "complete",
748
+ newlySettled,
749
+ unsettled,
750
+ discardUnsettled: completingWithSteers && (input.interruptRequested || input.kind === "failure"),
751
+ abortedBySteer: completingWithSteers && !input.interruptRequested && input.kind === "abort"
752
+ };
753
+ }
754
+ /**
755
+ * The status a completing turn reports. It follows the result except where the result's status
756
+ * would misstate what happened to the turn: Ryco's own discard re-interrupt or a steer's abort is
757
+ * never a Stop (which would hold the client queue), a Stop always ends as interrupted, and a
758
+ * failure that drops a pending steer is always reported as one (so the queue holds and the user
759
+ * sees why the steer got no reply).
760
+ */
761
+ function decideClaudeTurnClose(input) {
762
+ if (input.foldedIntoDiscardedCliTurn) return input.interruptRequested ? {
763
+ status: "interrupted",
764
+ cause: "stopped"
765
+ } : {
766
+ status: "failed",
767
+ cause: "folded-into-discarded-cli-turn"
768
+ };
769
+ if (input.resultStatus === "completed") {
770
+ const endsSteerSegment = input.echoedPromptUuids.some((uuid) => input.steerPromptUuids.has(uuid)) && (input.promptUuid === void 0 || !input.echoedPromptUuids.includes(input.promptUuid));
771
+ if (input.interruptRequested && endsSteerSegment) return {
772
+ status: "interrupted",
773
+ cause: "stopped"
774
+ };
775
+ if (!input.interruptRequested && input.decision.discardUnsettled) return {
776
+ status: "failed",
777
+ cause: "failed-segment-dropped-steers"
778
+ };
779
+ }
780
+ if (input.decision.abortedBySteer) return {
781
+ status: "completed",
782
+ cause: "aborted-by-steer"
783
+ };
784
+ return {
785
+ status: input.resultStatus,
786
+ cause: "result"
787
+ };
788
+ }
789
+ /** Defensive: anything but a `still_queued` string array is "no receipt" (older CLIs). */
790
+ function readClaudeInterruptReceipt(value) {
791
+ if (value === null || typeof value !== "object") return void 0;
792
+ const stillQueued = readStringArray(Reflect.get(value, "still_queued"));
793
+ if (stillQueued === void 0) return void 0;
794
+ return {
795
+ stillQueued,
796
+ cancelled: readStringArray(Reflect.get(value, "cancelled"))
797
+ };
798
+ }
799
+ /**
800
+ * Stop with steers pending. A steer that already streamed into the turn, or that the receipt
801
+ * does not list as queued or cancelled (in transit), counts as running, so its own aborted
802
+ * result closes the turn. The discard and release lists hold whether or not the stopped turn is
803
+ * still open.
804
+ */
805
+ function decideClaudeStop(input) {
806
+ if (input.receipt === void 0) return {
807
+ forceClose: input.awaitingSteerContinuation,
808
+ discard: [...input.unsettledSteers],
809
+ release: []
810
+ };
811
+ const cancelled = new Set(input.receipt.cancelled ?? []);
812
+ const outstanding = /* @__PURE__ */ new Set([...input.receipt.stillQueued, ...cancelled]);
813
+ const runningSteers = input.unsettledSteers.filter((uuid) => input.startedSteers.has(uuid) || !outstanding.has(uuid));
814
+ const isReleased = (uuid) => cancelled.has(uuid) && !input.startedSteers.has(uuid);
815
+ return {
816
+ forceClose: (input.sealedSegmentCount > 0 || input.promptUuid !== void 0 && cancelled.has(input.promptUuid)) && runningSteers.length === 0,
817
+ discard: input.unsettledSteers.filter((uuid) => !isReleased(uuid)),
818
+ release: input.unsettledSteers.filter(isReleased)
819
+ };
820
+ }
821
+ /** FIFO-bounded insert. */
822
+ function rememberDiscardedSteer(set, uuid, cap = 64) {
823
+ if (set.has(uuid)) return;
824
+ while (set.size >= cap) {
825
+ const oldest = set.values().next();
826
+ if (oldest.done) break;
827
+ set.delete(oldest.value);
828
+ }
829
+ set.add(uuid);
830
+ }
831
+ /** Capabilities a CLI advertises on `system/init`; empty when the field is absent. */
832
+ function parseClaudeCliCapabilities(initMessage) {
833
+ const capabilities = Reflect.get(initMessage, "capabilities");
834
+ return new Set(Array.isArray(capabilities) ? capabilities.filter((entry) => typeof entry === "string") : []);
835
+ }
836
+ /**
837
+ * Root model-turn content frames: a CLI segment's output, as opposed to system, subagent or
838
+ * keep-alive frames. A CLI turn's first such frame carries its echo: a stream event, or the
839
+ * assistant message when nothing streamed. System frames (`api_retry`, compaction) carry no
840
+ * echo, so they never qualify.
841
+ */
842
+ function isClaudeRootTurnFrame(message) {
843
+ if (message.type !== "stream_event" && message.type !== "assistant" && message.type !== "user") return false;
844
+ if (message.type === "stream_event") {
845
+ const event = Reflect.get(message, "event");
846
+ if (typeof event === "object" && event !== null && Reflect.get(event, "type") === "ping") return false;
847
+ }
848
+ return isRootFrame$1(message);
849
+ }
850
+ /**
851
+ * A synthetic API-error reply: the request failed after its retries and the CLI turn ends with
852
+ * the next result, so interrupting it again could only reach whatever the CLI runs next.
853
+ * `max_output_tokens` is excluded because the CLI can continue that turn.
854
+ */
855
+ function isClaudeApiErrorReply(message) {
856
+ if (message.type !== "assistant") return false;
857
+ const error = Reflect.get(message, "error");
858
+ return typeof error === "string" && error !== "max_output_tokens";
859
+ }
860
+ //#endregion
861
+ //#region src/provider/claudeWakeTurn.ts
862
+ /**
863
+ * Claude can start a turn without a prompt (a "wake"): background work finished, a schedule or
864
+ * monitor fired, a rate limit lifted. These rules decide when such a provider turn opens and
865
+ * which frames prove it is alive.
866
+ */
867
+ /** Longest a wake-signal turn may stay open without any root output before it is aborted. */
868
+ const CLAUDE_WAKE_TURN_FIRST_OUTPUT_TIMEOUT_MS = 12e4;
869
+ /** How long Stop waits for the CLI to end a provider turn before finishing it locally. */
870
+ const CLAUDE_PROVIDER_TURN_STOP_GRACE_MS = 5e3;
871
+ function isRootFrame(message) {
872
+ const parentToolUseId = message.parent_tool_use_id;
873
+ return parentToolUseId === null || parentToolUseId === void 0;
874
+ }
875
+ /**
876
+ * Root system/status (requesting|compacting) → "status"; root system/init → "init"; else
877
+ * undefined. A frame with a non-null parent_tool_use_id is never a signal.
878
+ */
879
+ function claudeWakeSignal(message) {
880
+ if (message.type !== "system" || !isRootFrame(message)) return;
881
+ if (message.subtype === "status") return message.status === "requesting" || message.status === "compacting" ? "status" : void 0;
882
+ return message.subtype === "init" ? "init" : void 0;
883
+ }
884
+ /**
885
+ * Deny-list gate; "init" opens only when the CLI was never seen to emit `status: requesting`
886
+ * (legacy CLIs). There is deliberately no allow list: every kind of wake is covered.
887
+ */
888
+ function shouldOpenClaudeWakeTurn(gate) {
889
+ if (gate.hasOpenTurn || gate.sessionStopped || !gate.promptSent || gate.turnInstallsInFlight > 0) return false;
890
+ return gate.signal === "status" || !gate.requestingStatusObserved;
891
+ }
892
+ /**
893
+ * Root frames that prove Claude is producing the current turn (watchdog liveness). A positive
894
+ * list, so a future periodic background frame cannot keep a phantom turn alive.
895
+ */
896
+ function isClaudeRootTurnOutput(message) {
897
+ if (!isRootFrame(message)) return false;
898
+ switch (message.type) {
899
+ case "stream_event":
900
+ case "assistant":
901
+ case "user":
902
+ case "result": return true;
903
+ case "system": switch (message.subtype) {
904
+ case "compact_boundary":
905
+ case "api_retry": return true;
906
+ case "status": return message.status === "compacting";
907
+ default: return false;
908
+ }
909
+ default: return false;
910
+ }
911
+ }
912
+ //#endregion
640
913
  //#region ../../packages/shared/src/cliArgs.ts
641
914
  /**
642
915
  * Parse CLI-style arguments into flags and positionals.
@@ -772,6 +1045,70 @@ function disableContextCompaction(state, generation) {
772
1045
  };
773
1046
  }
774
1047
  //#endregion
1048
+ //#region src/provider/Layers/claudeUsageLimits.ts
1049
+ const CLAUDE_USAGE_LIMIT_FALLBACK_MESSAGE = "Claude usage limit reached.";
1050
+ const MESSAGE_MAX_LENGTH = 500;
1051
+ function resetIso(resetsAtSeconds) {
1052
+ if (resetsAtSeconds === void 0 || !Number.isFinite(resetsAtSeconds)) return null;
1053
+ const ms = resetsAtSeconds * 1e3;
1054
+ return require_bin.isRepresentableEpochMs(ms) ? new Date(ms).toISOString() : null;
1055
+ }
1056
+ /** Applies one `rate_limit_event` to the session's rejected windows. */
1057
+ function applyClaudeRateLimitInfo(windows, info) {
1058
+ const limitType = info.rateLimitType ?? "unknown";
1059
+ const overageAllowed = info.overageStatus === "allowed" || info.overageStatus === "allowed_warning" || info.isUsingOverage === true || info.overageInUse === true;
1060
+ const blocked = info.status === "rejected" && !overageAllowed;
1061
+ const resetAt = resetIso(info.resetsAt);
1062
+ if (blocked) windows.set(limitType, resetAt);
1063
+ else windows.delete(limitType);
1064
+ return {
1065
+ blocked,
1066
+ key: `${limitType}:${info.resetsAt ?? "unknown"}`,
1067
+ limitType,
1068
+ resetAt
1069
+ };
1070
+ }
1071
+ /** Current state of the rejected windows; windows whose known reset passed are ignored. */
1072
+ function claudeUsageLimitState(windows, nowMs) {
1073
+ return require_bin.usageLimitStateFromWindows([...windows.values()].map((resetAt) => ({
1074
+ exhausted: true,
1075
+ resetAtMs: resetAt === null ? null : Date.parse(resetAt)
1076
+ })), nowMs);
1077
+ }
1078
+ function trimmed(value) {
1079
+ if (typeof value !== "string") return void 0;
1080
+ const text = value.trim();
1081
+ return text.length > 0 ? text : void 0;
1082
+ }
1083
+ function limitMessage(result) {
1084
+ const message = (result.subtype === "success" ? trimmed(result.result) : trimmed(result.errors?.[0] ?? "")) ?? "Claude usage limit reached.";
1085
+ return message.length > MESSAGE_MAX_LENGTH ? message.slice(0, MESSAGE_MAX_LENGTH) : message;
1086
+ }
1087
+ /**
1088
+ * Whether a turn's result is a usage-limit stop. Only call it for a result that belongs
1089
+ * to an open turn and was not interrupted or cancelled.
1090
+ */
1091
+ function classifyClaudeUsageLimitResult(input) {
1092
+ const { result } = input;
1093
+ const state = claudeUsageLimitState(input.windows, input.nowMs);
1094
+ const terminalReason = result.terminal_reason;
1095
+ if (terminalReason === "blocking_limit") return {
1096
+ message: limitMessage(result),
1097
+ resetAt: state.resetAt
1098
+ };
1099
+ if (!state.exhausted) return null;
1100
+ if (!(result.subtype !== "success" || result.is_error === true)) return null;
1101
+ if (terminalReason !== void 0 && terminalReason !== null && terminalReason !== "api_error") return null;
1102
+ if (result.subtype === "success") {
1103
+ const status = result.api_error_status;
1104
+ if (status !== void 0 && status !== null && status !== 429) return null;
1105
+ }
1106
+ return {
1107
+ message: limitMessage(result),
1108
+ resetAt: state.resetAt
1109
+ };
1110
+ }
1111
+ //#endregion
775
1112
  //#region src/provider/Layers/ClaudeAdapter.ts
776
1113
  /**
777
1114
  * ClaudeAdapterLive - Scoped live implementation for the Claude Agent provider adapter.
@@ -782,20 +1119,49 @@ function disableContextCompaction(state, generation) {
782
1119
  * @module ClaudeAdapterLive
783
1120
  */
784
1121
  const PROVIDER = require_src.ProviderDriverKind.make("claudeAgent");
785
- const CLAUDE_SUBAGENT_ATTRIBUTION_CACHE_CAP = 256;
786
- function rememberClaudeSubagentLaunchInput(context, toolUseId, input) {
787
- if (!context.subagentLaunchInputByToolUseId.has(toolUseId) && context.subagentLaunchInputByToolUseId.size >= CLAUDE_SUBAGENT_ATTRIBUTION_CACHE_CAP) {
788
- const oldestToolUseId = context.subagentLaunchInputByToolUseId.keys().next().value;
789
- if (oldestToolUseId !== void 0) context.subagentLaunchInputByToolUseId.delete(oldestToolUseId);
790
- }
791
- context.subagentLaunchInputByToolUseId.set(toolUseId, input);
1122
+ const WAKE_NO_OUTPUT_REASON = "Claude started a background turn but produced no output.";
1123
+ const PROVIDER_TURN_STOP_REASON = "Claude did not end the background turn after Stop.";
1124
+ const DISCARDED_STEER_TURN_REASON = "Claude started a turn for a message Stop cancelled.";
1125
+ 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.";
1126
+ const STEER_TURN_ENDED_DETAIL = "The turn finished before this message could be steered. It stays queued and is sent next.";
1127
+ const CLAUDE_TURN_HEADS_CAP = 64;
1128
+ const CLAUDE_REWIND_PROBE_TIMEOUT = "30 seconds";
1129
+ const CLAUDE_REWIND_TRANSCRIPT_TIMEOUT = "10 seconds";
1130
+ const CLAUDE_REWIND_QUERY_EXIT_MS = 5e3;
1131
+ /** The only turn-state constructor: prompt and provider turns must share one shape. */
1132
+ function makeClaudeTurnState(input) {
1133
+ return {
1134
+ turnId: input.turnId,
1135
+ ...input.promptUuid !== void 0 ? { promptUuid: input.promptUuid } : {},
1136
+ openedBy: input.openedBy,
1137
+ startedAt: input.startedAt,
1138
+ items: [],
1139
+ assistantTextBlocks: /* @__PURE__ */ new Map(),
1140
+ assistantTextBlockOrder: [],
1141
+ capturedProposedPlanKeys: /* @__PURE__ */ new Set(),
1142
+ nextSyntheticAssistantBlockIndex: -1,
1143
+ reasoningBlocks: /* @__PURE__ */ new Map(),
1144
+ reasoningBlockCount: 0,
1145
+ rootOutputObserved: input.openedBy !== "wake-signal",
1146
+ lastChainUuid: void 0,
1147
+ rootContentObserved: input.openedBy !== "wake-signal",
1148
+ completion: void 0,
1149
+ steerPromptUuids: /* @__PURE__ */ new Set(),
1150
+ settledSteerPromptUuids: /* @__PURE__ */ new Set(),
1151
+ startedSteerPromptUuids: /* @__PURE__ */ new Set(),
1152
+ reinterruptedEchoKeys: /* @__PURE__ */ new Set(),
1153
+ interruptRequested: false,
1154
+ sealedSegmentCount: 0,
1155
+ awaitingSteerContinuation: void 0
1156
+ };
792
1157
  }
793
- function rememberClaudeSubagentModel(context, toolUseId, model) {
794
- if (!context.subagentModelByToolUseId.has(toolUseId) && context.subagentModelByToolUseId.size >= CLAUDE_SUBAGENT_ATTRIBUTION_CACHE_CAP) {
795
- const oldestToolUseId = context.subagentModelByToolUseId.keys().next().value;
796
- if (oldestToolUseId !== void 0) context.subagentModelByToolUseId.delete(oldestToolUseId);
1158
+ const CLAUDE_SUBAGENT_ATTRIBUTION_CACHE_CAP = 256;
1159
+ function rememberClaudeSubagentAttribution(cache, toolUseId, value) {
1160
+ if (!cache.has(toolUseId) && cache.size >= CLAUDE_SUBAGENT_ATTRIBUTION_CACHE_CAP) {
1161
+ const oldestToolUseId = cache.keys().next().value;
1162
+ if (oldestToolUseId !== void 0) cache.delete(oldestToolUseId);
797
1163
  }
798
- context.subagentModelByToolUseId.set(toolUseId, model);
1164
+ cache.set(toolUseId, value);
799
1165
  }
800
1166
  function claudeSubagentLaunchModel(input) {
801
1167
  const model = trimmedClaudeString(input?.model);
@@ -815,6 +1181,12 @@ function toMessage(cause, fallback) {
815
1181
  if (cause instanceof Error && cause.message.length > 0) return cause.message;
816
1182
  return fallback;
817
1183
  }
1184
+ /** A typed adapter error's user-level text: its `detail` or `issue`, not its prefixed message. */
1185
+ function adapterFailureDetail(error) {
1186
+ const fields = error;
1187
+ for (const value of [fields.detail, fields.issue]) if (typeof value === "string" && value.trim().length > 0) return value.trim();
1188
+ return error.message;
1189
+ }
818
1190
  function toError(cause, fallback) {
819
1191
  return cause instanceof Error ? cause : new Error(toMessage(cause, fallback));
820
1192
  }
@@ -848,14 +1220,6 @@ function interruptionMessageFromClaudeCause(cause) {
848
1220
  const message = messageFromClaudeStreamCause(cause, "Claude runtime interrupted.");
849
1221
  return isClaudeInterruptedMessage(message) ? "Claude runtime interrupted." : message;
850
1222
  }
851
- function resultErrorsText(result) {
852
- return "errors" in result && Array.isArray(result.errors) ? result.errors.join(" ").toLowerCase() : "";
853
- }
854
- function isInterruptedResult(result) {
855
- const errors = resultErrorsText(result);
856
- if (errors.includes("interrupt")) return true;
857
- return result.subtype === "error_during_execution" && result.is_error === false && (errors.includes("request was aborted") || errors.includes("interrupted by user") || errors.includes("aborted"));
858
- }
859
1223
  function asRuntimeItemId(value) {
860
1224
  return require_src.RuntimeItemId.make(value);
861
1225
  }
@@ -909,14 +1273,27 @@ function readClaudeResumeState(resumeCursor) {
909
1273
  const resumeCandidate = typeof cursor.resume === "string" ? cursor.resume : typeof cursor.sessionId === "string" ? cursor.sessionId : void 0;
910
1274
  const resume = resumeCandidate && isUuid(resumeCandidate) ? resumeCandidate : void 0;
911
1275
  const resumeSessionAt = typeof cursor.resumeSessionAt === "string" ? cursor.resumeSessionAt : void 0;
1276
+ const rewind = resumeCursor.rewind;
1277
+ const rewindAt = rewind !== null && typeof rewind === "object" && typeof rewind.at === "string" && rewind.at.length > 0 ? rewind.at : void 0;
912
1278
  const turnCountValue = typeof cursor.turnCount === "number" ? cursor.turnCount : void 0;
913
1279
  return {
914
1280
  ...threadId ? { threadId } : {},
915
1281
  ...resume ? { resume } : {},
916
1282
  ...resumeSessionAt ? { resumeSessionAt } : {},
1283
+ ...rewindAt ? { rewindAt } : {},
917
1284
  ...turnCountValue !== void 0 && Number.isInteger(turnCountValue) && turnCountValue >= 0 ? { turnCount: turnCountValue } : {}
918
1285
  };
919
1286
  }
1287
+ /**
1288
+ * The uuid of a main-chain transcript entry (user, assistant, compaction
1289
+ * boundary), or undefined for subagent sidechains and non-chain frames.
1290
+ */
1291
+ function claudeMainChainUuid(message) {
1292
+ if (!(message.type === "user" || message.type === "assistant" || message.type === "system" && message.subtype === "compact_boundary")) return void 0;
1293
+ const uuid = message.uuid;
1294
+ const parentToolUseId = message.parent_tool_use_id;
1295
+ return typeof uuid === "string" && uuid.length > 0 && (parentToolUseId === null || parentToolUseId === void 0) ? uuid : void 0;
1296
+ }
920
1297
  function trimmedClaudeString(value) {
921
1298
  return typeof value === "string" && value.trim().length > 0 ? value.trim() : void 0;
922
1299
  }
@@ -1165,6 +1542,11 @@ function extractPlanStepsFromTodoInput(input) {
1165
1542
  }));
1166
1543
  }
1167
1544
  function summarizeToolRequest(toolName, input) {
1545
+ const htmlRender = require_bin.resolveHtmlRenderToolPresentation({
1546
+ toolName,
1547
+ input
1548
+ });
1549
+ if (htmlRender) return htmlRender.detail ? `${toolName}: ${htmlRender.detail}` : toolName;
1168
1550
  const commandValue = input.command ?? input.cmd;
1169
1551
  const command = typeof commandValue === "string" ? commandValue : void 0;
1170
1552
  if (command && command.trim().length > 0) return `${toolName}: ${command.trim().slice(0, 400)}`;
@@ -1178,6 +1560,24 @@ function summarizeToolRequest(toolName, input) {
1178
1560
  if (serialized.length <= 400) return `${toolName}: ${serialized}`;
1179
1561
  return `${toolName}: ${serialized.slice(0, 397)}...`;
1180
1562
  }
1563
+ /** Work-log detail of a tool item: an HTML tool shows its page title or viewport alone. */
1564
+ function toolItemDetail(toolName, input) {
1565
+ const htmlRender = require_bin.resolveHtmlRenderToolPresentation({
1566
+ toolName,
1567
+ input
1568
+ });
1569
+ return htmlRender ? htmlRender.detail : summarizeToolRequest(toolName, input);
1570
+ }
1571
+ function toolItemTitle(toolName, itemType) {
1572
+ return require_bin.resolveHtmlRenderToolPresentation({
1573
+ toolName,
1574
+ input: void 0
1575
+ })?.title ?? titleForTool(itemType);
1576
+ }
1577
+ /** Tool input as carried on runtime events: an HTML tool's page is reduced to its length. */
1578
+ function toolEventInput(toolName, input) {
1579
+ return require_bin.resolveHtmlRenderToolKind(toolName) === void 0 ? input : require_bin.withoutHtmlRenderMarkup(input);
1580
+ }
1181
1581
  function titleForTool(itemType) {
1182
1582
  switch (itemType) {
1183
1583
  case "command_execution": return "Command run";
@@ -1295,11 +1695,25 @@ const buildUserMessageEffect = effect.Effect.fn("buildUserMessageEffect")(functi
1295
1695
  });
1296
1696
  function turnStatusFromResult(result) {
1297
1697
  if (result.subtype === "success") return "completed";
1698
+ if (isClaudeAbortTerminalReason(result)) return "interrupted";
1298
1699
  const errors = resultErrorsText(result);
1299
1700
  if (isInterruptedResult(result)) return "interrupted";
1300
1701
  if (errors.includes("cancel")) return "cancelled";
1301
1702
  return "failed";
1302
1703
  }
1704
+ /** The error a completing turn reports, by why it reports its status (`decideClaudeTurnClose`). */
1705
+ function claudeTurnCloseErrorMessage(cause, result) {
1706
+ switch (cause) {
1707
+ case "result": return result.subtype === "success" ? void 0 : result.errors[0];
1708
+ case "aborted-by-steer": return;
1709
+ case "stopped": return "Interrupted by user.";
1710
+ case "failed-segment-dropped-steers": {
1711
+ const text = result.subtype === "success" ? result.result.trim() : result.errors[0];
1712
+ return text !== void 0 && text.length > 0 ? text : "Claude turn failed.";
1713
+ }
1714
+ case "folded-into-discarded-cli-turn": return FOLDED_INTO_DISCARDED_STEER_REASON;
1715
+ }
1716
+ }
1303
1717
  function streamKindFromDeltaType(deltaType) {
1304
1718
  return deltaType.includes("thinking") ? "reasoning_text" : "assistant_text";
1305
1719
  }
@@ -1340,6 +1754,35 @@ function extractExitPlanModePlan(value) {
1340
1754
  function exitPlanCaptureKey(input) {
1341
1755
  return input.toolUseId && input.toolUseId.length > 0 ? `tool:${input.toolUseId}` : `plan:${input.planMarkdown}`;
1342
1756
  }
1757
+ const EMPTY_STREAMED_JSON_SCAN = {
1758
+ depth: 0,
1759
+ inString: false,
1760
+ escaped: false,
1761
+ opened: false
1762
+ };
1763
+ function scanStreamedJson(scan, chunk) {
1764
+ let { depth, inString, escaped, opened } = scan;
1765
+ for (let index = 0; index < chunk.length; index += 1) {
1766
+ const code = chunk.charCodeAt(index);
1767
+ if (inString) {
1768
+ if (escaped) escaped = false;
1769
+ else if (code === 92) escaped = true;
1770
+ else if (code === 34) inString = false;
1771
+ } else if (code === 34) inString = true;
1772
+ else if (code === 123 || code === 91) {
1773
+ depth += 1;
1774
+ opened = true;
1775
+ } else if (code === 125 || code === 93) depth -= 1;
1776
+ }
1777
+ return {
1778
+ depth,
1779
+ inString,
1780
+ escaped,
1781
+ opened
1782
+ };
1783
+ }
1784
+ /** Every complete JSON object passes this, so skipping the parse otherwise changes nothing. */
1785
+ const mayBeCompleteJson = (scan) => scan.opened && scan.depth === 0 && !scan.inString;
1343
1786
  function tryParseJsonRecord(value) {
1344
1787
  try {
1345
1788
  const parsed = JSON.parse(value);
@@ -1447,13 +1890,19 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
1447
1890
  const serverConfig = yield* require_Metrics.ServerConfig;
1448
1891
  const claudeEnvironment = yield* require_bin.makeClaudeEnvironment(claudeSettings, options?.environment).pipe(effect.Effect.provideService(effect.Path.Path, path));
1449
1892
  const nativeEventLogger = options?.nativeEventLogger ?? (options?.nativeEventLogPath !== void 0 ? yield* require_bin.makeEventNdjsonLogger(options.nativeEventLogPath, { stream: "native" }) : void 0);
1893
+ const readSessionMessages = options?.readSessionMessages ?? ((sessionId, readOptions) => (0, _anthropic_ai_claude_agent_sdk.getSessionMessages)(sessionId, {
1894
+ ...readOptions.dir !== void 0 ? { dir: readOptions.dir } : {},
1895
+ includeSystemMessages: readOptions.includeSystemMessages
1896
+ }));
1897
+ /** Threads whose session is being closed and reopened by a checkpoint revert. */
1898
+ const rewindingThreads = /* @__PURE__ */ new Set();
1450
1899
  const createQuery = options?.createQuery ?? ((input) => (0, _anthropic_ai_claude_agent_sdk.query)({
1451
1900
  prompt: input.prompt,
1452
1901
  options: input.options
1453
1902
  }));
1454
1903
  const sessions = /* @__PURE__ */ new Map();
1455
1904
  let nextSessionGeneration = 0;
1456
- const runtimeEventQueue = yield* effect.Queue.bounded(2048);
1905
+ const runtimeEventQueue = yield* effect.Queue.bounded(options?.runtimeEventQueueCapacity ?? 2048);
1457
1906
  const runtimeEventQueueMetrics = yield* require_bin.makeServerQueueMetrics({
1458
1907
  queue: "provider.adapter.runtimeEvents",
1459
1908
  component: "ClaudeAdapter",
@@ -1595,18 +2044,19 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
1595
2044
  };
1596
2045
  });
1597
2046
  const updateResumeCursor = effect.Effect.fn("updateResumeCursor")(function* (context) {
1598
- const threadId = context.session.threadId;
1599
- if (!threadId) return;
2047
+ if (!context.session.threadId) return;
2048
+ const updatedAt = yield* nowIso;
1600
2049
  const resumeCursor = {
1601
- threadId,
2050
+ threadId: context.session.threadId,
1602
2051
  ...context.resumeSessionId ? { resume: context.resumeSessionId } : {},
1603
2052
  ...context.lastAssistantUuid ? { resumeSessionAt: context.lastAssistantUuid } : {},
2053
+ ...context.pendingRewind ? { rewind: { at: context.pendingRewind.at } } : {},
1604
2054
  turnCount: context.turns.length
1605
2055
  };
1606
2056
  context.session = {
1607
2057
  ...context.session,
1608
2058
  resumeCursor,
1609
- updatedAt: yield* nowIso
2059
+ updatedAt
1610
2060
  };
1611
2061
  });
1612
2062
  const ensureAssistantTextBlock = effect.Effect.fn("ensureAssistantTextBlock")(function* (context, blockIndex, options) {
@@ -1745,7 +2195,7 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
1745
2195
  });
1746
2196
  }
1747
2197
  });
1748
- const emitRuntimeError = effect.Effect.fn("emitRuntimeError")(function* (context, message, cause) {
2198
+ const emitRuntimeError = effect.Effect.fn("emitRuntimeError")(function* (context, message, cause, options) {
1749
2199
  if (cause !== void 0) {}
1750
2200
  const turnState = context.turnState;
1751
2201
  const stamp = yield* makeEventStamp();
@@ -1758,8 +2208,9 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
1758
2208
  ...turnState ? { turnId: asCanonicalTurnId(turnState.turnId) } : {},
1759
2209
  payload: {
1760
2210
  message,
1761
- class: "provider_error",
1762
- ...cause !== void 0 ? { detail: cause } : {}
2211
+ class: options?.class ?? "provider_error",
2212
+ ...cause !== void 0 ? { detail: cause } : {},
2213
+ ...options?.resetAt !== void 0 ? { resetAt: options.resetAt } : {}
1763
2214
  },
1764
2215
  providerRefs: nativeProviderRefs(context)
1765
2216
  });
@@ -1842,7 +2293,8 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
1842
2293
  yield* emitCompactionUnavailableWarning(context);
1843
2294
  }
1844
2295
  });
1845
- const completeTurn = effect.Effect.fn("completeTurn")(function* (context, status, errorMessage, result) {
2296
+ /** The context gauge a result (or a local close without one) publishes. */
2297
+ const resolveResultUsageSnapshot = effect.Effect.fn("resolveResultUsageSnapshot")(function* (context, result) {
1846
2298
  const resultCounts = readClaudeCacheCounts(result?.usage);
1847
2299
  if (context.cacheObservation && resultCounts?.outputTokens !== void 0) context.cacheObservation = {
1848
2300
  ...context.cacheObservation,
@@ -1856,41 +2308,46 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
1856
2308
  const resultContextWindow = mainClaudeContextWindowFromModelUsage(result?.modelUsage, context.cacheObservation?.model ?? context.currentApiModelId);
1857
2309
  if (resultContextWindow !== void 0) context.lastKnownContextWindow = resultContextWindow;
1858
2310
  const accumulatedSnapshot = normalizeClaudeTokenUsage(result?.usage, resultContextWindow ?? context.lastKnownContextWindow);
1859
- const accumulatedTotalProcessedTokens = accumulatedSnapshot?.totalProcessedTokens ?? accumulatedSnapshot?.usedTokens;
1860
- const lastGoodUsage = context.lastKnownTokenUsage;
1861
- const maxTokens = resultContextWindow ?? context.lastKnownContextWindow;
1862
- const rawUsageSnapshot = lastGoodUsage ? {
1863
- ...lastGoodUsage,
1864
- ...typeof maxTokens === "number" && Number.isFinite(maxTokens) && maxTokens > 0 ? { maxTokens } : {},
1865
- ...typeof accumulatedTotalProcessedTokens === "number" && Number.isFinite(accumulatedTotalProcessedTokens) && accumulatedTotalProcessedTokens > lastGoodUsage.usedTokens ? { totalProcessedTokens: accumulatedTotalProcessedTokens } : {}
1866
- } : accumulatedSnapshot;
1867
- const usageSnapshot = rawUsageSnapshot ? withAutomaticCompactionCapability({
2311
+ const rawUsageSnapshot = selectClaudeResultUsageGauge({
2312
+ lastGauge: context.lastKnownTokenUsage,
2313
+ cumulative: accumulatedSnapshot,
2314
+ maxTokens: resultContextWindow ?? context.lastKnownContextWindow,
2315
+ cumulativeIsGauge: !context.cumulativeUsageSpansCompaction
2316
+ });
2317
+ if (result !== void 0) context.cumulativeUsageSpansCompaction = false;
2318
+ return rawUsageSnapshot ? withAutomaticCompactionCapability({
1868
2319
  ...rawUsageSnapshot,
2320
+ ...accumulatedSnapshot ? { processedUsage: {
2321
+ scope: "turn",
2322
+ inputTokens: accumulatedSnapshot.inputTokens ?? 0,
2323
+ cachedInputTokens: accumulatedSnapshot.cachedInputTokens ?? 0,
2324
+ outputTokens: accumulatedSnapshot.outputTokens ?? 0,
2325
+ reasoningOutputTokens: accumulatedSnapshot.reasoningOutputTokens ?? 0,
2326
+ totalTokens: accumulatedSnapshot.totalProcessedTokens ?? accumulatedSnapshot.usedTokens
2327
+ } } : {},
1869
2328
  ...context.cacheObservation ? { claudeCache: context.cacheObservation } : {}
1870
2329
  }, context.supportsAutomaticCompaction) : void 0;
1871
- const turnState = context.turnState;
1872
- if (!turnState) {
1873
- if (usageSnapshot) {
1874
- const usageStamp = yield* makeEventStamp();
1875
- yield* offerRuntimeEventForContext(context, {
1876
- type: "thread.token-usage.updated",
1877
- eventId: usageStamp.eventId,
1878
- provider: PROVIDER,
1879
- createdAt: usageStamp.createdAt,
1880
- threadId: context.session.threadId,
1881
- payload: { usage: usageSnapshot },
1882
- providerRefs: {}
1883
- });
1884
- }
1885
- yield* effect.Effect.logInfo("claude.turn.result-without-active-turn", {
1886
- threadId: context.session.threadId,
1887
- status,
1888
- numTurns: result?.num_turns,
1889
- hasUsage: result?.usage !== void 0,
1890
- ...errorMessage ? { errorMessage } : {}
1891
- });
1892
- return;
1893
- }
2330
+ });
2331
+ /** Publishes a context-gauge snapshot, attributed to a turn when one is given. */
2332
+ const emitTokenUsageSnapshot = effect.Effect.fn("emitTokenUsageSnapshot")(function* (context, usageSnapshot, turnId) {
2333
+ if (!usageSnapshot) return;
2334
+ const usageStamp = yield* makeEventStamp();
2335
+ yield* offerRuntimeEventForContext(context, {
2336
+ type: "thread.token-usage.updated",
2337
+ eventId: usageStamp.eventId,
2338
+ provider: PROVIDER,
2339
+ createdAt: usageStamp.createdAt,
2340
+ threadId: context.session.threadId,
2341
+ ...turnId !== void 0 ? { turnId } : {},
2342
+ payload: { usage: usageSnapshot },
2343
+ providerRefs: nativeProviderRefs(context)
2344
+ });
2345
+ });
2346
+ /**
2347
+ * Closes everything a CLI segment left open (in-flight tools, assistant text and reasoning
2348
+ * blocks) while the turn itself may stay open: between a steer's segments and at completion.
2349
+ */
2350
+ const sealTurnSegment = effect.Effect.fn("sealTurnSegment")(function* (context, turnState, status, result) {
1894
2351
  for (const [index, tool] of context.inFlightTools.entries()) {
1895
2352
  const toolStamp = yield* makeEventStamp();
1896
2353
  yield* offerRuntimeEventForContext(context, {
@@ -1908,7 +2365,7 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
1908
2365
  ...tool.detail ? { detail: tool.detail } : {},
1909
2366
  data: {
1910
2367
  toolName: tool.toolName,
1911
- input: tool.input
2368
+ input: toolEventInput(tool.toolName, tool.input)
1912
2369
  }
1913
2370
  },
1914
2371
  providerRefs: nativeProviderRefs(context, { providerItemId: tool.itemId }),
@@ -1927,25 +2384,73 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
1927
2384
  rawMethod: "claude/result",
1928
2385
  rawPayload: result ?? { status }
1929
2386
  });
2387
+ turnState.assistantTextBlockOrder.length = 0;
2388
+ for (const reasoningBlock of turnState.reasoningBlocks.values()) {
2389
+ const stamp = yield* makeEventStamp();
2390
+ yield* offerRuntimeEventForContext(context, {
2391
+ type: "item.completed",
2392
+ eventId: stamp.eventId,
2393
+ provider: PROVIDER,
2394
+ createdAt: stamp.createdAt,
2395
+ threadId: context.session.threadId,
2396
+ turnId: asCanonicalTurnId(turnState.turnId),
2397
+ itemId: asRuntimeItemId(reasoningBlock.itemId),
2398
+ payload: {
2399
+ itemType: "reasoning",
2400
+ status: status === "failed" ? "failed" : "completed",
2401
+ title: "Reasoning"
2402
+ },
2403
+ providerRefs: nativeProviderRefs(context),
2404
+ raw: {
2405
+ source: "claude.sdk.message",
2406
+ method: "claude/result",
2407
+ payload: result ?? { status }
2408
+ }
2409
+ });
2410
+ }
2411
+ turnState.reasoningBlocks.clear();
2412
+ });
2413
+ /** A result (or local close) with no open turn: keep usage, never publish a lifecycle event. */
2414
+ const publishTurnlessResult = effect.Effect.fn("publishTurnlessResult")(function* (context, status, errorMessage, result) {
2415
+ yield* emitTokenUsageSnapshot(context, yield* resolveResultUsageSnapshot(context, result), void 0);
2416
+ yield* effect.Effect.logInfo("claude.turn.result-without-active-turn", {
2417
+ threadId: context.session.threadId,
2418
+ status,
2419
+ numTurns: result?.num_turns,
2420
+ hasUsage: result?.usage !== void 0,
2421
+ ...errorMessage ? { errorMessage } : {}
2422
+ });
2423
+ });
2424
+ /** Finishes a turn this fiber claimed in `completeTurn`. Never call it directly. */
2425
+ const finishClaimedTurn = effect.Effect.fn("finishClaimedTurn")(function* (context, turnState, completion, status, errorMessage, result, options) {
2426
+ const usageSnapshot = yield* resolveResultUsageSnapshot(context, result);
2427
+ yield* sealTurnSegment(context, turnState, status, result);
1930
2428
  context.turns.push({
1931
2429
  id: turnState.turnId,
1932
2430
  items: [...turnState.items]
1933
2431
  });
1934
- if (usageSnapshot) {
1935
- const usageStamp = yield* makeEventStamp();
1936
- yield* offerRuntimeEventForContext(context, {
1937
- type: "thread.token-usage.updated",
1938
- eventId: usageStamp.eventId,
1939
- provider: PROVIDER,
1940
- createdAt: usageStamp.createdAt,
1941
- threadId: context.session.threadId,
2432
+ if (turnState.lastChainUuid !== void 0) {
2433
+ context.turnHeads.push({
1942
2434
  turnId: turnState.turnId,
1943
- payload: { usage: usageSnapshot },
1944
- providerRefs: nativeProviderRefs(context)
2435
+ head: turnState.lastChainUuid
1945
2436
  });
2437
+ if (context.turnHeads.length > CLAUDE_TURN_HEADS_CAP) context.turnHeads.shift();
1946
2438
  }
2439
+ if (status === "completed") context.pendingRewind = void 0;
2440
+ yield* updateResumeCursor(context);
2441
+ yield* emitTokenUsageSnapshot(context, usageSnapshot, turnState.turnId);
1947
2442
  const stamp = yield* makeEventStamp();
1948
- yield* offerRuntimeEventForContext(context, {
2443
+ if (options?.abortReason !== void 0) yield* offerRuntimeEventForContext(context, {
2444
+ type: "turn.aborted",
2445
+ eventId: stamp.eventId,
2446
+ provider: PROVIDER,
2447
+ createdAt: stamp.createdAt,
2448
+ threadId: context.session.threadId,
2449
+ turnId: turnState.turnId,
2450
+ payload: { reason: options.abortReason },
2451
+ providerRefs: nativeProviderRefs(context)
2452
+ });
2453
+ else yield* offerRuntimeEventForContext(context, {
1949
2454
  type: "turn.completed",
1950
2455
  eventId: stamp.eventId,
1951
2456
  provider: PROVIDER,
@@ -1963,18 +2468,45 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
1963
2468
  providerRefs: nativeProviderRefs(context)
1964
2469
  });
1965
2470
  const updatedAt = yield* nowIso;
1966
- context.turnState = void 0;
1967
- context.session = {
1968
- ...context.session,
1969
- status: "ready",
1970
- activeTurnId: void 0,
1971
- updatedAt,
1972
- ...status === "failed" && errorMessage ? { lastError: errorMessage } : {}
1973
- };
2471
+ if (context.turnState === turnState) {
2472
+ context.turnState = void 0;
2473
+ context.session = {
2474
+ ...context.session,
2475
+ status: "ready",
2476
+ activeTurnId: void 0,
2477
+ updatedAt,
2478
+ ...status === "failed" && errorMessage ? { lastError: errorMessage } : {}
2479
+ };
2480
+ }
2481
+ effect.Deferred.doneUnsafe(completion, effect.Effect.void);
1974
2482
  if (context.agentControl) yield* context.agentControl.retireTurn(turnState.turnId);
1975
- yield* updateResumeCursor(context);
1976
2483
  if (status === "completed" && usageSnapshot) yield* maybeEnableAutomaticCompaction(context, usageSnapshot);
1977
2484
  });
2485
+ /**
2486
+ * The single owner of turn completion. The open turn is claimed synchronously at entry, so a
2487
+ * concurrent close (sendTurn, Stop grace, watchdog, stream exit) waits for the claimer instead
2488
+ * of emitting a second lifecycle event.
2489
+ */
2490
+ const completeTurn = effect.Effect.fn("completeTurn")(function* (context, status, errorMessage, result, options) {
2491
+ const turnState = context.turnState;
2492
+ if (options?.expectedTurnState !== void 0 && turnState !== options.expectedTurnState) return;
2493
+ if (turnState?.completion !== void 0) {
2494
+ if (result !== void 0) yield* effect.Effect.logInfo("claude.turn.result-during-completion", {
2495
+ threadId: context.session.threadId,
2496
+ turnId: turnState.turnId,
2497
+ status
2498
+ });
2499
+ yield* effect.Deferred.await(turnState.completion);
2500
+ return;
2501
+ }
2502
+ if (turnState === void 0) return yield* publishTurnlessResult(context, status, errorMessage, result);
2503
+ const completion = effect.Deferred.makeUnsafe();
2504
+ turnState.completion = completion;
2505
+ yield* finishClaimedTurn(context, turnState, completion, status, errorMessage, result, options).pipe(effect.Effect.ensuring(effect.Effect.sync(() => {
2506
+ if (context.turnState === turnState) turnState.completion = void 0;
2507
+ effect.Deferred.doneUnsafe(completion, effect.Effect.void);
2508
+ })));
2509
+ });
1978
2510
  const handleStreamEvent = effect.Effect.fn("handleStreamEvent")(function* (context, message) {
1979
2511
  if (message.type !== "stream_event") return;
1980
2512
  const { event } = message;
@@ -2003,10 +2535,8 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
2003
2535
  const deltaText = event.delta.type === "text_delta" ? event.delta.text : typeof event.delta.thinking === "string" ? event.delta.thinking : "";
2004
2536
  if (deltaText.length === 0) return;
2005
2537
  const streamKind = streamKindFromDeltaType(event.delta.type);
2006
- const assistantBlockEntry = event.delta.type === "text_delta" ? yield* ensureAssistantTextBlock(context, event.index) : context.turnState.assistantTextBlocks.get(event.index) ? {
2007
- blockIndex: event.index,
2008
- block: context.turnState.assistantTextBlocks.get(event.index)
2009
- } : void 0;
2538
+ const reasoningBlock = event.delta.type === "thinking_delta" ? context.turnState.reasoningBlocks.get(event.index) : void 0;
2539
+ const assistantBlockEntry = event.delta.type === "text_delta" ? yield* ensureAssistantTextBlock(context, event.index) : void 0;
2010
2540
  if (assistantBlockEntry?.block && event.delta.type === "text_delta") assistantBlockEntry.block.emittedTextDelta = true;
2011
2541
  const stamp = yield* makeEventStamp();
2012
2542
  yield* offerRuntimeEventForContext(context, {
@@ -2016,7 +2546,7 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
2016
2546
  createdAt: stamp.createdAt,
2017
2547
  threadId: context.session.threadId,
2018
2548
  turnId: context.turnState.turnId,
2019
- ...assistantBlockEntry?.block ? { itemId: asRuntimeItemId(assistantBlockEntry.block.itemId) } : {},
2549
+ ...assistantBlockEntry?.block ? { itemId: asRuntimeItemId(assistantBlockEntry.block.itemId) } : reasoningBlock ? { itemId: asRuntimeItemId(reasoningBlock.itemId) } : {},
2020
2550
  payload: {
2021
2551
  streamKind,
2022
2552
  delta: deltaText
@@ -2034,17 +2564,19 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
2034
2564
  const tool = context.inFlightTools.get(event.index);
2035
2565
  if (!tool || typeof event.delta.partial_json !== "string") return;
2036
2566
  const partialInputJson = tool.partialInputJson + event.delta.partial_json;
2037
- const parsedInput = tryParseJsonRecord(partialInputJson);
2038
- const detail = parsedInput ? summarizeToolRequest(tool.toolName, parsedInput) : tool.detail;
2567
+ const partialInputScan = scanStreamedJson(tool.partialInputScan, event.delta.partial_json);
2568
+ const parsedInput = mayBeCompleteJson(partialInputScan) ? tryParseJsonRecord(partialInputJson) : void 0;
2569
+ const detail = parsedInput ? toolItemDetail(tool.toolName, parsedInput) : tool.detail;
2039
2570
  let nextTool = {
2040
2571
  ...tool,
2041
2572
  partialInputJson,
2573
+ partialInputScan,
2042
2574
  ...parsedInput ? { input: parsedInput } : {},
2043
2575
  ...detail ? { detail } : {}
2044
2576
  };
2045
2577
  const nextFingerprint = parsedInput && Object.keys(parsedInput).length > 0 ? toolInputFingerprint(parsedInput) : void 0;
2046
2578
  context.inFlightTools.set(event.index, nextTool);
2047
- if (nextTool.itemType === "collab_agent_tool_call" && parsedInput) rememberClaudeSubagentLaunchInput(context, nextTool.itemId, parsedInput);
2579
+ if (nextTool.itemType === "collab_agent_tool_call" && parsedInput) rememberClaudeSubagentAttribution(context.subagentLaunchInputByToolUseId, nextTool.itemId, parsedInput);
2048
2580
  if (!parsedInput || !nextFingerprint || tool.lastEmittedInputFingerprint === nextFingerprint) return;
2049
2581
  nextTool = {
2050
2582
  ...nextTool,
@@ -2069,7 +2601,7 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
2069
2601
  ...nextTool.parentToolUseId ? { parentToolUseId: nextTool.parentToolUseId } : {},
2070
2602
  data: {
2071
2603
  toolName: nextTool.toolName,
2072
- input: nextTool.input
2604
+ input: toolEventInput(nextTool.toolName, nextTool.input)
2073
2605
  }
2074
2606
  },
2075
2607
  providerRefs: nativeProviderRefs(context, { providerItemId: nextTool.itemId }),
@@ -2104,12 +2636,40 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
2104
2636
  yield* ensureAssistantTextBlock(context, index, { fallbackText: extractContentBlockText(block) });
2105
2637
  return;
2106
2638
  }
2639
+ if (block.type === "thinking" && context.turnState) {
2640
+ const turnState = context.turnState;
2641
+ turnState.reasoningBlockCount += 1;
2642
+ const itemId = `${turnState.turnId}:thinking:${turnState.reasoningBlockCount}`;
2643
+ turnState.reasoningBlocks.set(index, { itemId });
2644
+ const stamp = yield* makeEventStamp();
2645
+ yield* offerRuntimeEventForContext(context, {
2646
+ type: "item.started",
2647
+ eventId: stamp.eventId,
2648
+ provider: PROVIDER,
2649
+ createdAt: stamp.createdAt,
2650
+ threadId: context.session.threadId,
2651
+ turnId: asCanonicalTurnId(turnState.turnId),
2652
+ itemId: asRuntimeItemId(itemId),
2653
+ payload: {
2654
+ itemType: "reasoning",
2655
+ status: "inProgress",
2656
+ title: "Reasoning"
2657
+ },
2658
+ providerRefs: nativeProviderRefs(context),
2659
+ raw: {
2660
+ source: "claude.sdk.message",
2661
+ method: "claude/stream_event/content_block_start",
2662
+ payload: message
2663
+ }
2664
+ });
2665
+ return;
2666
+ }
2107
2667
  if (block.type !== "tool_use" && block.type !== "server_tool_use" && block.type !== "mcp_tool_use") return;
2108
2668
  const toolName = block.name;
2109
2669
  const itemType = classifyToolItemType(toolName);
2110
2670
  const toolInput = typeof block.input === "object" && block.input !== null ? block.input : {};
2111
2671
  const itemId = block.id;
2112
- const detail = summarizeToolRequest(toolName, toolInput);
2672
+ const detail = toolItemDetail(toolName, toolInput);
2113
2673
  const inputFingerprint = Object.keys(toolInput).length > 0 ? toolInputFingerprint(toolInput) : void 0;
2114
2674
  const parentToolUseId = message.parent_tool_use_id ?? void 0;
2115
2675
  const owningAgentId = agentIdForParentToolUse(context.taskAgents, parentToolUseId);
@@ -2117,16 +2677,17 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
2117
2677
  itemId,
2118
2678
  itemType,
2119
2679
  toolName,
2120
- title: titleForTool(itemType),
2121
- detail,
2680
+ title: toolItemTitle(toolName, itemType),
2681
+ ...detail ? { detail } : {},
2122
2682
  input: toolInput,
2123
2683
  partialInputJson: "",
2684
+ partialInputScan: EMPTY_STREAMED_JSON_SCAN,
2124
2685
  ...inputFingerprint ? { lastEmittedInputFingerprint: inputFingerprint } : {},
2125
2686
  ...owningAgentId ? { agentId: owningAgentId } : {},
2126
2687
  ...parentToolUseId ? { parentToolUseId } : {}
2127
2688
  };
2128
2689
  context.inFlightTools.set(index, tool);
2129
- if (itemType === "collab_agent_tool_call") rememberClaudeSubagentLaunchInput(context, itemId, toolInput);
2690
+ if (itemType === "collab_agent_tool_call") rememberClaudeSubagentAttribution(context.subagentLaunchInputByToolUseId, itemId, toolInput);
2130
2691
  const stamp = yield* makeEventStamp();
2131
2692
  yield* offerRuntimeEventForContext(context, {
2132
2693
  type: "item.started",
@@ -2145,7 +2706,7 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
2145
2706
  ...tool.parentToolUseId ? { parentToolUseId: tool.parentToolUseId } : {},
2146
2707
  data: {
2147
2708
  toolName: tool.toolName,
2148
- input: toolInput
2709
+ input: toolEventInput(tool.toolName, toolInput)
2149
2710
  }
2150
2711
  },
2151
2712
  providerRefs: nativeProviderRefs(context, { providerItemId: tool.itemId }),
@@ -2159,6 +2720,32 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
2159
2720
  }
2160
2721
  if (event.type === "content_block_stop") {
2161
2722
  const { index } = event;
2723
+ const reasoningBlock = context.turnState?.reasoningBlocks.get(index);
2724
+ if (reasoningBlock && context.turnState) {
2725
+ context.turnState.reasoningBlocks.delete(index);
2726
+ const stamp = yield* makeEventStamp();
2727
+ yield* offerRuntimeEventForContext(context, {
2728
+ type: "item.completed",
2729
+ eventId: stamp.eventId,
2730
+ provider: PROVIDER,
2731
+ createdAt: stamp.createdAt,
2732
+ threadId: context.session.threadId,
2733
+ turnId: asCanonicalTurnId(context.turnState.turnId),
2734
+ itemId: asRuntimeItemId(reasoningBlock.itemId),
2735
+ payload: {
2736
+ itemType: "reasoning",
2737
+ status: "completed",
2738
+ title: "Reasoning"
2739
+ },
2740
+ providerRefs: nativeProviderRefs(context),
2741
+ raw: {
2742
+ source: "claude.sdk.message",
2743
+ method: "claude/stream_event/content_block_stop",
2744
+ payload: message
2745
+ }
2746
+ });
2747
+ return;
2748
+ }
2162
2749
  const assistantBlock = context.turnState?.assistantTextBlocks.get(index);
2163
2750
  if (assistantBlock) {
2164
2751
  assistantBlock.streamClosed = true;
@@ -2181,7 +2768,7 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
2181
2768
  const itemStatus = toolResult.isError ? "failed" : "completed";
2182
2769
  const toolData = {
2183
2770
  toolName: tool.toolName,
2184
- input: tool.input,
2771
+ input: toolEventInput(tool.toolName, tool.input),
2185
2772
  result: toolResult.block
2186
2773
  };
2187
2774
  const updatedStamp = yield* makeEventStamp();
@@ -2286,6 +2873,49 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
2286
2873
  context.inFlightTools.delete(index);
2287
2874
  }
2288
2875
  });
2876
+ /**
2877
+ * Opens a provider turn: one Claude started without a prompt, either at its turn-start signal
2878
+ * ("wake-signal") or, when no signal opened one, at its first root assistant output. Never
2879
+ * bound to Agent Control authority; exact-turn binding stays prompt-only.
2880
+ */
2881
+ const startProviderTurn = effect.Effect.fn("startProviderTurn")(function* (context, openedBy) {
2882
+ const turnId = require_src.TurnId.make(yield* effect.Effect.sync(() => crypto.randomUUID()));
2883
+ const startedAt = yield* nowIso;
2884
+ if (context.turnState !== void 0 || context.stopped) return;
2885
+ if (openedBy === "wake-signal" && (context.turnInstallsInFlight > 0 || !context.promptSent)) return;
2886
+ const turnState = makeClaudeTurnState({
2887
+ turnId,
2888
+ startedAt,
2889
+ openedBy
2890
+ });
2891
+ context.turnState = turnState;
2892
+ context.session = {
2893
+ ...context.session,
2894
+ status: "running",
2895
+ activeTurnId: turnId,
2896
+ updatedAt: startedAt
2897
+ };
2898
+ const turnStartedStamp = yield* makeEventStamp();
2899
+ yield* offerRuntimeEventForContext(context, {
2900
+ type: "turn.started",
2901
+ eventId: turnStartedStamp.eventId,
2902
+ provider: PROVIDER,
2903
+ createdAt: turnStartedStamp.createdAt,
2904
+ threadId: context.session.threadId,
2905
+ turnId,
2906
+ payload: {},
2907
+ providerRefs: {
2908
+ ...nativeProviderRefs(context),
2909
+ providerTurnId: turnId
2910
+ },
2911
+ raw: {
2912
+ source: "claude.sdk.message",
2913
+ method: "claude/synthetic-turn-start",
2914
+ payload: { openedBy }
2915
+ }
2916
+ });
2917
+ if (openedBy === "wake-signal") yield* effect.Effect.sleep(effect.Duration.millis(CLAUDE_WAKE_TURN_FIRST_OUTPUT_TIMEOUT_MS)).pipe(effect.Effect.andThen(effect.Effect.suspend(() => context.turnState === turnState && !turnState.rootOutputObserved && !context.stopped ? completeTurn(context, "interrupted", WAKE_NO_OUTPUT_REASON, void 0, { abortReason: WAKE_NO_OUTPUT_REASON }) : effect.Effect.void)), effect.Effect.ignoreCause({ log: true }), effect.Effect.forkDetach);
2918
+ });
2289
2919
  const handleAssistantMessage = effect.Effect.fn("handleAssistantMessage")(function* (context, message) {
2290
2920
  if (message.type !== "assistant") return;
2291
2921
  const assistantParentToolUseId = message.parent_tool_use_id;
@@ -2293,8 +2923,39 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
2293
2923
  const owningTaskId = agentIdForParentToolUse(context.taskAgents, assistantParentToolUseId);
2294
2924
  const snapshotModel = trimmedClaudeString(message.message.model);
2295
2925
  const owningAgent = owningTaskId ? context.taskAgents.get(owningTaskId) : void 0;
2296
- if (owningAgent && snapshotModel) owningAgent.model = snapshotModel;
2297
- else if (snapshotModel) rememberClaudeSubagentModel(context, assistantParentToolUseId, snapshotModel);
2926
+ if (owningAgent && snapshotModel && owningAgent.model !== snapshotModel) {
2927
+ owningAgent.model = snapshotModel;
2928
+ const stamp = yield* makeEventStamp();
2929
+ yield* offerRuntimeEventForContext(context, {
2930
+ ...stamp,
2931
+ type: "task.updated",
2932
+ provider: PROVIDER,
2933
+ threadId: context.session.threadId,
2934
+ ...context.turnState ? { turnId: asCanonicalTurnId(context.turnState.turnId) } : {},
2935
+ providerRefs: nativeProviderRefs(context),
2936
+ payload: {
2937
+ taskId: require_src.RuntimeTaskId.make(owningAgent.taskId),
2938
+ ...taskLinkageFor(context.taskAgents, owningAgent.taskId)
2939
+ }
2940
+ });
2941
+ const existingSubagent = context.subagentByTaskId.get(owningAgent.taskId);
2942
+ if (existingSubagent) {
2943
+ const subagent = {
2944
+ ...existingSubagent,
2945
+ model: snapshotModel
2946
+ };
2947
+ context.subagentByTaskId.set(owningAgent.taskId, subagent);
2948
+ yield* emitClaudeSubagentUpdated(context, {
2949
+ subagent,
2950
+ raw: message
2951
+ });
2952
+ }
2953
+ } else if (!owningAgent && snapshotModel) rememberClaudeSubagentAttribution(context.subagentModelByToolUseId, assistantParentToolUseId, snapshotModel);
2954
+ for (const block of message.message.content) {
2955
+ if (block.type !== "tool_use") continue;
2956
+ rememberClaudeSubagentAttribution(context.subagentParentByToolUseId, block.id, assistantParentToolUseId);
2957
+ 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);
2958
+ }
2298
2959
  context.lastAssistantUuid = message.uuid;
2299
2960
  yield* updateResumeCursor(context);
2300
2961
  return;
@@ -2306,11 +2967,13 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
2306
2967
  messageId: message.message.id,
2307
2968
  model: message.message.model,
2308
2969
  ...context.cacheModelSelection ? { modelSelection: context.cacheModelSelection } : {},
2970
+ ...context.session.cwd ? { cwd: context.session.cwd } : {},
2309
2971
  runtimeSessionId: context.session.runtimeSessionId,
2310
2972
  providerInstanceId: context.session.providerInstanceId,
2311
2973
  observedAt: cacheStamp.createdAt,
2312
2974
  ...previousCache ? { previous: previousCache } : {}
2313
2975
  });
2976
+ if (context.cacheObservation) context.mainLoopUsageObserved = true;
2314
2977
  if (context.cacheObservation && context.cacheObservation !== previousCache) {
2315
2978
  const observation = context.cacheObservation;
2316
2979
  const usedTokens = observation.directInputTokens + observation.cacheReadInputTokens + observation.cacheWriteInputTokens;
@@ -2333,44 +2996,7 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
2333
2996
  providerRefs: {}
2334
2997
  });
2335
2998
  }
2336
- if (!context.turnState) {
2337
- const turnId = require_src.TurnId.make(yield* effect.Effect.sync(() => crypto.randomUUID()));
2338
- const startedAt = yield* nowIso;
2339
- context.turnState = {
2340
- turnId,
2341
- startedAt,
2342
- items: [],
2343
- assistantTextBlocks: /* @__PURE__ */ new Map(),
2344
- assistantTextBlockOrder: [],
2345
- capturedProposedPlanKeys: /* @__PURE__ */ new Set(),
2346
- nextSyntheticAssistantBlockIndex: -1
2347
- };
2348
- context.session = {
2349
- ...context.session,
2350
- status: "running",
2351
- activeTurnId: turnId,
2352
- updatedAt: startedAt
2353
- };
2354
- const turnStartedStamp = yield* makeEventStamp();
2355
- yield* offerRuntimeEventForContext(context, {
2356
- type: "turn.started",
2357
- eventId: turnStartedStamp.eventId,
2358
- provider: PROVIDER,
2359
- createdAt: turnStartedStamp.createdAt,
2360
- threadId: context.session.threadId,
2361
- turnId,
2362
- payload: {},
2363
- providerRefs: {
2364
- ...nativeProviderRefs(context),
2365
- providerTurnId: turnId
2366
- },
2367
- raw: {
2368
- source: "claude.sdk.message",
2369
- method: "claude/synthetic-turn-start",
2370
- payload: {}
2371
- }
2372
- });
2373
- }
2999
+ if (!context.turnState) yield* startProviderTurn(context, "assistant-output");
2374
3000
  const content = message.message?.content;
2375
3001
  if (Array.isArray(content)) for (const block of content) {
2376
3002
  if (!block || typeof block !== "object") continue;
@@ -2393,12 +3019,106 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
2393
3019
  context.lastAssistantUuid = message.uuid;
2394
3020
  yield* updateResumeCursor(context);
2395
3021
  });
2396
- const handleResultMessage = effect.Effect.fn("handleResultMessage")(function* (context, message) {
3022
+ const handleResultMessage = effect.Effect.fn("handleResultMessage")(function* (context, message, options) {
2397
3023
  if (message.type !== "result") return;
2398
- const status = turnStatusFromResult(message);
2399
- const errorMessage = message.subtype === "success" ? void 0 : message.errors[0];
2400
- if (status === "failed") yield* emitRuntimeError(context, errorMessage ?? "Claude turn failed.");
2401
- yield* completeTurn(context, status, errorMessage, message);
3024
+ if (context.probing && context.turnState === void 0) {
3025
+ if (message.subtype !== "success" || message.is_error) {
3026
+ const detail = (message.subtype !== "success" ? message.errors[0] : void 0) ?? `Claude reported ${message.subtype} while reopening the conversation.`;
3027
+ if (context.probeFailure) yield* effect.Deferred.succeed(context.probeFailure, detail);
3028
+ }
3029
+ return;
3030
+ }
3031
+ const turnState = context.turnState;
3032
+ const echoedPromptUuids = claudeEchoedPromptUuids(message);
3033
+ if (turnState?.promptUuid !== void 0 && !claudeResultBelongsToTurn({
3034
+ echoed: echoedPromptUuids,
3035
+ origin: message.origin,
3036
+ promptUuid: turnState.promptUuid,
3037
+ steerPromptUuids: turnState.steerPromptUuids
3038
+ })) {
3039
+ yield* effect.Effect.logInfo("claude.turn.result-for-other-prompt", {
3040
+ threadId: context.session.threadId,
3041
+ turnId: turnState.turnId,
3042
+ origin: message.origin?.kind
3043
+ });
3044
+ return;
3045
+ }
3046
+ const resultStatus = turnStatusFromResult(message);
3047
+ let close = {
3048
+ status: resultStatus,
3049
+ cause: "result"
3050
+ };
3051
+ if (turnState) {
3052
+ const decision = decideClaudeTurnResult({
3053
+ kind: classifyClaudeResultKind(message),
3054
+ echoedPromptUuids,
3055
+ queuedTurnCount: message.queued_turn_count,
3056
+ steerPromptUuids: turnState.steerPromptUuids,
3057
+ settledSteerPromptUuids: turnState.settledSteerPromptUuids,
3058
+ interruptRequested: turnState.interruptRequested
3059
+ });
3060
+ for (const uuid of decision.newlySettled) {
3061
+ turnState.settledSteerPromptUuids.add(uuid);
3062
+ context.discardedSteerPromptUuids.delete(uuid);
3063
+ }
3064
+ if (decision.decision === "await-steer") {
3065
+ yield* sealTurnSegment(context, turnState, resultStatus, message);
3066
+ yield* emitTokenUsageSnapshot(context, yield* resolveResultUsageSnapshot(context, message), turnState.turnId);
3067
+ turnState.sealedSegmentCount += 1;
3068
+ turnState.awaitingSteerContinuation = {
3069
+ since: yield* nowIso,
3070
+ segmentStatus: resultStatus
3071
+ };
3072
+ yield* effect.Effect.logInfo("claude.turn.awaiting-steer-continuation", {
3073
+ threadId: context.session.threadId,
3074
+ turnId: turnState.turnId,
3075
+ queuedTurnCount: message.queued_turn_count,
3076
+ unsettled: decision.unsettled.length,
3077
+ terminalReason: message.terminal_reason
3078
+ });
3079
+ return;
3080
+ }
3081
+ if (decision.discardUnsettled) for (const uuid of decision.unsettled) rememberDiscardedSteer(context.discardedSteerPromptUuids, uuid);
3082
+ close = decideClaudeTurnClose({
3083
+ resultStatus,
3084
+ decision,
3085
+ interruptRequested: turnState.interruptRequested,
3086
+ echoedPromptUuids,
3087
+ promptUuid: turnState.promptUuid,
3088
+ steerPromptUuids: turnState.steerPromptUuids,
3089
+ foldedIntoDiscardedCliTurn: options?.foldedIntoDiscardedCliTurn === true
3090
+ });
3091
+ if (close.cause !== "result") {
3092
+ if (close.status !== "failed") yield* sealTurnSegment(context, turnState, resultStatus, message);
3093
+ yield* effect.Effect.logInfo("claude.turn.closed-as", {
3094
+ threadId: context.session.threadId,
3095
+ turnId: turnState.turnId,
3096
+ cause: close.cause,
3097
+ resultStatus,
3098
+ status: close.status,
3099
+ queuedTurnCount: message.queued_turn_count,
3100
+ unsettled: decision.unsettled.length,
3101
+ terminalReason: message.terminal_reason
3102
+ });
3103
+ }
3104
+ }
3105
+ const notInterrupted = (status) => status !== "interrupted" && status !== "cancelled";
3106
+ const usageLimit = context.turnState && notInterrupted(resultStatus) && notInterrupted(close.status) ? classifyClaudeUsageLimitResult({
3107
+ result: message,
3108
+ windows: context.rejectedRateLimitWindows,
3109
+ nowMs: yield* effect.Clock.currentTimeMillis
3110
+ }) : null;
3111
+ if (usageLimit) {
3112
+ yield* emitRuntimeError(context, usageLimit.message, void 0, {
3113
+ class: "usage_limit",
3114
+ resetAt: usageLimit.resetAt
3115
+ });
3116
+ yield* completeTurn(context, "failed", usageLimit.message, message);
3117
+ return;
3118
+ }
3119
+ const errorMessage = claudeTurnCloseErrorMessage(close.cause, message);
3120
+ if (close.status === "failed") yield* emitRuntimeError(context, errorMessage ?? "Claude turn failed.");
3121
+ yield* completeTurn(context, close.status, errorMessage, message);
2402
3122
  });
2403
3123
  /**
2404
3124
  * Synthesizes per-member task.progress rows from the coordinator's
@@ -2467,6 +3187,19 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
2467
3187
  });
2468
3188
  const handleSystemMessage = effect.Effect.fn("handleSystemMessage")(function* (context, message) {
2469
3189
  if (message.type !== "system") return;
3190
+ if (message.subtype === "status" && message.status === "requesting") context.requestingStatusObserved = true;
3191
+ const wakeSignal = claudeWakeSignal(message);
3192
+ if (wakeSignal !== void 0 && shouldOpenClaudeWakeTurn({
3193
+ signal: wakeSignal,
3194
+ hasOpenTurn: context.turnState !== void 0,
3195
+ sessionStopped: context.stopped,
3196
+ promptSent: context.promptSent,
3197
+ turnInstallsInFlight: context.turnInstallsInFlight,
3198
+ requestingStatusObserved: context.requestingStatusObserved
3199
+ })) {
3200
+ if (context.discardedSteerPromptUuids.size > 0) context.wakeSignalDeferred = true;
3201
+ else yield* startProviderTurn(context, "wake-signal");
3202
+ }
2470
3203
  const stamp = yield* makeEventStamp();
2471
3204
  const base = {
2472
3205
  eventId: stamp.eventId,
@@ -2580,6 +3313,7 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
2580
3313
  }
2581
3314
  switch (message.subtype) {
2582
3315
  case "init":
3316
+ context.cliCapabilities = parseClaudeCliCapabilities(message);
2583
3317
  yield* offerRuntimeEventForContext(context, {
2584
3318
  ...base,
2585
3319
  type: "session.configured",
@@ -2602,10 +3336,12 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
2602
3336
  }
2603
3337
  });
2604
3338
  return;
2605
- case "compact_boundary":
3339
+ case "compact_boundary": {
2606
3340
  context.compactionPolicy = settleContextCompaction(context.compactionPolicy, context.generation);
2607
- context.lastKnownTokenUsage = void 0;
3341
+ const postCompactionUsage = claudePostCompactionUsage(message.compact_metadata, context.lastKnownContextWindow);
3342
+ context.lastKnownTokenUsage = postCompactionUsage;
2608
3343
  context.cacheObservation = void 0;
3344
+ context.cumulativeUsageSpansCompaction = true;
2609
3345
  yield* offerRuntimeEventForContext(context, {
2610
3346
  ...base,
2611
3347
  type: "thread.state.changed",
@@ -2614,7 +3350,18 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
2614
3350
  detail: message
2615
3351
  }
2616
3352
  });
3353
+ if (postCompactionUsage) {
3354
+ const usageStamp = yield* makeEventStamp();
3355
+ yield* offerRuntimeEventForContext(context, {
3356
+ ...base,
3357
+ eventId: usageStamp.eventId,
3358
+ createdAt: usageStamp.createdAt,
3359
+ type: "thread.token-usage.updated",
3360
+ payload: { usage: withAutomaticCompactionCapability(postCompactionUsage, context.supportsAutomaticCompaction) }
3361
+ });
3362
+ }
2617
3363
  return;
3364
+ }
2618
3365
  case "hook_started":
2619
3366
  yield* offerRuntimeEventForContext(context, {
2620
3367
  ...base,
@@ -2654,7 +3401,9 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
2654
3401
  return;
2655
3402
  case "task_started": {
2656
3403
  const launchingTool = message.tool_use_id ? Array.from(context.inFlightTools.values()).find((tool) => tool.itemId === message.tool_use_id) : void 0;
2657
- const owningAgentId = launchingTool?.agentId;
3404
+ const parentToolUseId = message.tool_use_id ? context.subagentParentByToolUseId.get(message.tool_use_id) : void 0;
3405
+ const owningAgentId = launchingTool?.agentId ?? agentIdForParentToolUse(context.taskAgents, parentToolUseId);
3406
+ if (message.tool_use_id) context.subagentParentByToolUseId.delete(message.tool_use_id);
2658
3407
  const launchInput = launchingTool?.input ?? (message.tool_use_id ? context.subagentLaunchInputByToolUseId.get(message.tool_use_id) : void 0);
2659
3408
  const backgroundFlag = message.is_backgrounded;
2660
3409
  if (backgroundFlag === true || backgroundFlag === void 0 && launchInput?.run_in_background === true) context.backgroundedTaskIds.add(message.task_id);
@@ -2711,7 +3460,7 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
2711
3460
  return;
2712
3461
  }
2713
3462
  case "task_progress": {
2714
- if (message.usage && !context.cacheObservation && !isClaudeSubagentTaskMessage(message) && !context.taskAgents.get(message.task_id)?.toolUseId) {
3463
+ if (message.usage && !context.mainLoopUsageObserved && !isClaudeSubagentTaskMessage(message) && !context.taskAgents.get(message.task_id)?.toolUseId) {
2715
3464
  const normalizedUsage = normalizeClaudeTokenUsage(message.usage, context.lastKnownContextWindow);
2716
3465
  if (normalizedUsage) {
2717
3466
  context.lastKnownTokenUsage = normalizedUsage;
@@ -2793,7 +3542,7 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
2793
3542
  case "task_notification": {
2794
3543
  context.liveTaskIds.delete(message.task_id);
2795
3544
  context.backgroundedTaskIds.delete(message.task_id);
2796
- if (message.usage && !context.cacheObservation && !isClaudeSubagentTaskMessage(message) && !context.taskAgents.get(message.task_id)?.toolUseId) {
3545
+ if (message.usage && !context.mainLoopUsageObserved && !isClaudeSubagentTaskMessage(message) && !context.taskAgents.get(message.task_id)?.toolUseId) {
2797
3546
  const normalizedUsage = normalizeClaudeTokenUsage(message.usage, context.lastKnownContextWindow);
2798
3547
  if (normalizedUsage) {
2799
3548
  context.lastKnownTokenUsage = normalizedUsage;
@@ -2928,17 +3677,175 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
2928
3677
  return;
2929
3678
  }
2930
3679
  if (message.type === "rate_limit_event") {
3680
+ const transition = message.rate_limit_info ? applyClaudeRateLimitInfo(context.rejectedRateLimitWindows, message.rate_limit_info) : void 0;
2931
3681
  yield* offerRuntimeEventForContext(context, {
2932
3682
  ...base,
2933
3683
  type: "account.rate-limits.updated",
2934
- payload: { rateLimits: message }
3684
+ payload: {
3685
+ rateLimits: message,
3686
+ usageLimitState: claudeUsageLimitState(context.rejectedRateLimitWindows, yield* effect.Clock.currentTimeMillis)
3687
+ }
2935
3688
  });
3689
+ const turnState = context.turnState;
3690
+ if (transition?.blocked && turnState) {
3691
+ const announced = turnState.announcedUsageLimitKeys ??= /* @__PURE__ */ new Set();
3692
+ if (!announced.has(transition.key)) {
3693
+ announced.add(transition.key);
3694
+ yield* emitRuntimeWarning(context, CLAUDE_USAGE_LIMIT_FALLBACK_MESSAGE, { usageLimit: {
3695
+ limitType: transition.limitType,
3696
+ resetAt: transition.resetAt
3697
+ } });
3698
+ }
3699
+ }
2936
3700
  return;
2937
3701
  }
2938
3702
  });
3703
+ /** Plain interrupt for a CLI segment Stop already ended; bounded, failures only logged. */
3704
+ const forkReinterrupt = (context, reason) => effect.Effect.tryPromise({
3705
+ try: () => context.query.interrupt(),
3706
+ catch: (cause) => toRequestError(context.session.threadId, "turn/interrupt", cause)
3707
+ }).pipe(effect.Effect.timeoutOption("5 seconds"), effect.Effect.tap(() => effect.Effect.logInfo("claude.turn.reinterrupted", {
3708
+ threadId: context.session.threadId,
3709
+ reason
3710
+ })), effect.Effect.ignoreCause({ log: true }), effect.Effect.forkDetach, effect.Effect.asVoid);
3711
+ /**
3712
+ * A discarded steer's CLI turn turned out to be the one a provider turn was opened for (by its
3713
+ * `status: requesting`, legacy `init`, `api_retry` or compaction frame, before its echo). That
3714
+ * turn has routed no content: retract it.
3715
+ */
3716
+ const retractDiscardedSteerWakeTurn = effect.Effect.fn("retractDiscardedSteerWakeTurn")(function* (context) {
3717
+ const turnState = context.turnState;
3718
+ if (turnState === void 0 || turnState.openedBy !== "wake-signal" || turnState.rootContentObserved || turnState.steerPromptUuids.size > 0) return;
3719
+ yield* completeTurn(context, "interrupted", DISCARDED_STEER_TURN_REASON, void 0, {
3720
+ abortReason: DISCARDED_STEER_TURN_REASON,
3721
+ expectedTurnState: turnState
3722
+ });
3723
+ });
3724
+ /**
3725
+ * The discarded CLI turn's result: forget its uuids, then drop it (keeping its usage). Returns
3726
+ * whether it was consumed. Only this result can end the open turn when:
3727
+ * - it echoes the open turn's prompt or steer, which the CLI folded into the discarded CLI turn
3728
+ * (a fold shows only on the result). That turn's reply went with the dropped frames, and the
3729
+ * discard's re-interrupt usually aborted it, so the result closes it here as failed (never as
3730
+ * a Stop the user did not press);
3731
+ * - the CLI turn's output already reached an open provider turn (its frames carried no echo,
3732
+ * or beat Stop's bookkeeping). The result is routed on and completes that turn.
3733
+ */
3734
+ const endDiscardedSteerCliTurn = effect.Effect.fn("endDiscardedSteerCliTurn")(function* (context, message, uuids) {
3735
+ let count = 0;
3736
+ for (const uuid of uuids) {
3737
+ context.discardedSteerPromptUuids.delete(uuid);
3738
+ count += 1;
3739
+ }
3740
+ context.discardingCliTurn = void 0;
3741
+ context.wakeSignalDeferred = false;
3742
+ const open = context.turnState;
3743
+ if (open !== void 0) {
3744
+ const logContext = {
3745
+ threadId: context.session.threadId,
3746
+ turnId: open.turnId,
3747
+ openedBy: open.openedBy,
3748
+ uuids: count
3749
+ };
3750
+ if (claudeEchoNamesTurn({
3751
+ echoed: claudeEchoedPromptUuids(message),
3752
+ promptUuid: open.promptUuid,
3753
+ steerPromptUuids: open.steerPromptUuids
3754
+ })) {
3755
+ yield* effect.Effect.logInfo("claude.turn.discarded-steer-folded-open-turn", logContext);
3756
+ yield* handleResultMessage(context, message, { foldedIntoDiscardedCliTurn: true });
3757
+ return true;
3758
+ }
3759
+ if (open.promptUuid === void 0 && open.rootContentObserved) {
3760
+ yield* effect.Effect.logInfo("claude.turn.discarded-steer-output-leaked", logContext);
3761
+ return false;
3762
+ }
3763
+ }
3764
+ yield* emitTokenUsageSnapshot(context, yield* resolveResultUsageSnapshot(context, message), void 0);
3765
+ yield* retractDiscardedSteerWakeTurn(context);
3766
+ yield* effect.Effect.logInfo("claude.turn.discarded-cancelled-steer", {
3767
+ threadId: context.session.threadId,
3768
+ uuids: count
3769
+ });
3770
+ return true;
3771
+ });
3772
+ /**
3773
+ * Routes frames of CLI segments started by steers. Returns true when the frame was consumed
3774
+ * (dropped, or a result that already closed the open turn). The echo is read on a CLI turn's
3775
+ * first reply frame (its first stream event, or its first root assistant message when it
3776
+ * streamed nothing) and on its result. A CLI turn whose echo holds only steers Stop (or a failed
3777
+ * segment) discarded is interrupted again (unless its reply is an API error, which ends it
3778
+ * anyway) and dropped up to and including its result; a result with such an echo and no reply
3779
+ * before it is dropped alone. Either result still ends the open turn when only it can (see
3780
+ * `endDiscardedSteerCliTurn`). The open turn owns its own steers' segments; after Stop, one that
3781
+ * starts is interrupted again too, with the same API-error exception.
3782
+ */
3783
+ const routeSteerFrame = effect.Effect.fn("routeSteerFrame")(function* (context, message) {
3784
+ const discarding = context.discardingCliTurn;
3785
+ if (discarding !== void 0) switch (message.type) {
3786
+ case "result": return yield* endDiscardedSteerCliTurn(context, message, [...discarding.uuids, ...claudeEchoedPromptUuids(message)]);
3787
+ case "stream_event":
3788
+ case "assistant":
3789
+ case "user":
3790
+ case "tool_progress":
3791
+ case "tool_use_summary": return true;
3792
+ default: return false;
3793
+ }
3794
+ if (message.type !== "stream_event" && message.type !== "assistant" && message.type !== "result") return false;
3795
+ const echoed = claudeEchoedPromptUuids(message);
3796
+ if (echoed.length === 0) return false;
3797
+ const discarded = context.discardedSteerPromptUuids;
3798
+ const turnState = context.turnState;
3799
+ const owned = turnState !== void 0 && claudeEchoNamesTurn({
3800
+ echoed,
3801
+ promptUuid: turnState.promptUuid,
3802
+ steerPromptUuids: turnState.steerPromptUuids
3803
+ });
3804
+ const reinterruptable = !isClaudeApiErrorReply(message);
3805
+ if (owned || !echoed.every((uuid) => discarded.has(uuid))) {
3806
+ if (owned && message.type !== "result") {
3807
+ for (const uuid of echoed) if (turnState.steerPromptUuids.has(uuid)) turnState.startedSteerPromptUuids.add(uuid);
3808
+ const echoKey = [...echoed].toSorted().join(" ");
3809
+ if (reinterruptable && turnState.interruptRequested && echoed.some((uuid) => turnState.steerPromptUuids.has(uuid) && !turnState.settledSteerPromptUuids.has(uuid)) && !turnState.reinterruptedEchoKeys.has(echoKey)) {
3810
+ turnState.reinterruptedEchoKeys.add(echoKey);
3811
+ yield* forkReinterrupt(context, "steer-segment-after-stop");
3812
+ }
3813
+ }
3814
+ for (const uuid of echoed) discarded.delete(uuid);
3815
+ return false;
3816
+ }
3817
+ if (message.type === "result") return yield* endDiscardedSteerCliTurn(context, message, echoed);
3818
+ context.discardingCliTurn = { uuids: new Set(echoed) };
3819
+ context.wakeSignalDeferred = false;
3820
+ if (reinterruptable) yield* forkReinterrupt(context, "discarded-steer-segment");
3821
+ yield* effect.Effect.logInfo("claude.turn.discarding-cancelled-steer", {
3822
+ threadId: context.session.threadId,
3823
+ uuids: echoed.length
3824
+ });
3825
+ yield* retractDiscardedSteerWakeTurn(context);
3826
+ return true;
3827
+ });
2939
3828
  const handleSdkMessage = effect.Effect.fn("handleSdkMessage")(function* (context, message) {
2940
3829
  yield* logNativeSdkMessage(context, message);
2941
3830
  yield* ensureThreadId(context, message);
3831
+ if (yield* routeSteerFrame(context, message)) return;
3832
+ const chainUuid = claudeMainChainUuid(message);
3833
+ if (chainUuid !== void 0 && context.turnState) context.turnState.lastChainUuid = chainUuid;
3834
+ const rootContent = isClaudeRootTurnFrame(message);
3835
+ if (context.wakeSignalDeferred) {
3836
+ if (rootContent) {
3837
+ context.wakeSignalDeferred = false;
3838
+ if (context.turnState === void 0) yield* startProviderTurn(context, "wake-signal");
3839
+ } else if (message.type === "result") context.wakeSignalDeferred = false;
3840
+ }
3841
+ const waiting = context.turnState;
3842
+ if (waiting?.awaitingSteerContinuation !== void 0 && rootContent) waiting.awaitingSteerContinuation = void 0;
3843
+ yield* routeSdkMessage(context, message);
3844
+ const open = context.turnState;
3845
+ if (open && !open.rootOutputObserved && isClaudeRootTurnOutput(message)) open.rootOutputObserved = true;
3846
+ if (open && rootContent) open.rootContentObserved = true;
3847
+ });
3848
+ const routeSdkMessage = effect.Effect.fn("routeSdkMessage")(function* (context, message) {
2942
3849
  switch (message.type) {
2943
3850
  case "stream_event":
2944
3851
  yield* handleStreamEvent(context, message);
@@ -2966,7 +3873,7 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
2966
3873
  return;
2967
3874
  }
2968
3875
  });
2969
- const runSdkStream = (context) => effect.Stream.fromAsyncIterable(context.query, (cause) => toError(cause, "Claude runtime stream failed.")).pipe(effect.Stream.takeWhile(() => !context.stopped), effect.Stream.runForEach((message) => handleSdkMessage(context, message)));
3876
+ const runSdkStream = (context) => effect.Stream.fromAsyncIterable(context.query, (cause) => toError(cause, "Claude runtime stream failed.")).pipe(effect.Stream.takeWhile(() => !context.stopped), effect.Stream.runForEach((message) => context.turnLock.withPermits(1)(handleSdkMessage(context, message))));
2970
3877
  const handleStreamExit = effect.Effect.fn("handleStreamExit")(function* (context, exit) {
2971
3878
  if (context.stopped) return;
2972
3879
  if (effect.Exit.isFailure(exit)) {
@@ -2983,6 +3890,9 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
2983
3890
  const stopSessionInternal = effect.Effect.fn("stopSessionInternal")(function* (context, options) {
2984
3891
  if (context.stopped) return;
2985
3892
  context.stopped = true;
3893
+ context.discardedSteerPromptUuids.clear();
3894
+ context.discardingCliTurn = void 0;
3895
+ context.wakeSignalDeferred = false;
2986
3896
  context.deviceToolBinding?.dispose();
2987
3897
  if (context.agentControl) yield* context.agentControl.revoke("runtime-teardown");
2988
3898
  for (const [requestId, pending] of context.pendingApprovals) {
@@ -3009,11 +3919,22 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
3009
3919
  yield* effect.Queue.shutdown(context.promptQueue);
3010
3920
  const streamFiber = context.streamFiber;
3011
3921
  context.streamFiber = void 0;
3012
- if (streamFiber && streamFiber.pollUnsafe() === void 0) yield* effect.Fiber.interrupt(streamFiber);
3013
- try {
3014
- context.query.close();
3015
- } catch (cause) {
3016
- yield* emitRuntimeError(context, "Failed to close Claude runtime query.", cause);
3922
+ const closeQuery = effect.Effect.gen(function* () {
3923
+ try {
3924
+ context.query.close();
3925
+ } catch (cause) {
3926
+ yield* emitRuntimeError(context, "Failed to close Claude runtime query.", cause);
3927
+ }
3928
+ });
3929
+ if (options?.awaitQueryExitMs !== void 0) {
3930
+ yield* closeQuery;
3931
+ if (streamFiber && streamFiber.pollUnsafe() === void 0) {
3932
+ const exited = yield* effect.Fiber.await(streamFiber).pipe(effect.Effect.timeoutOption(effect.Duration.millis(options.awaitQueryExitMs)));
3933
+ if (effect.Option.isNone(exited)) yield* effect.Fiber.interrupt(streamFiber);
3934
+ }
3935
+ } else {
3936
+ if (streamFiber && streamFiber.pollUnsafe() === void 0) yield* effect.Fiber.interrupt(streamFiber);
3937
+ yield* closeQuery;
3017
3938
  }
3018
3939
  const updatedAt = yield* nowIso;
3019
3940
  context.session = {
@@ -3063,6 +3984,11 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
3063
3984
  issue: `Expected provider instance '${boundInstanceId}' but received '${input.providerInstanceId}'.`
3064
3985
  });
3065
3986
  const runtimeSessionId = yield* require_runtimeSession.requireRuntimeSessionId(PROVIDER, input);
3987
+ if (rewindingThreads.has(input.threadId)) return yield* new require_bin.ProviderAdapterValidationError({
3988
+ provider: PROVIDER,
3989
+ operation: "startSession",
3990
+ issue: "Claude is rewinding this thread; try again in a moment."
3991
+ });
3066
3992
  const existingContext = sessions.get(input.threadId);
3067
3993
  if (existingContext) {
3068
3994
  if (existingContext.session.runtimeSessionId === runtimeSessionId) return existingContext.session;
@@ -3072,6 +3998,15 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
3072
3998
  issue: `Thread '${input.threadId}' still has runtime '${existingContext.session.runtimeSessionId ?? "legacy"}'; stop it before starting '${runtimeSessionId}'.`
3073
3999
  });
3074
4000
  }
4001
+ return { ...(yield* openSessionContext(input, {})).session };
4002
+ });
4003
+ /**
4004
+ * Opens a query for `input` and registers its context. With `probe`, the
4005
+ * reopened CLI must accept a control request before this succeeds; a failed
4006
+ * probe stops the context silently (no runtime.error or session.exited).
4007
+ */
4008
+ const openSessionContext = effect.Effect.fn("openSessionContext")(function* (input, openOptions) {
4009
+ const runtimeSessionId = yield* require_runtimeSession.requireRuntimeSessionId(PROVIDER, input);
3075
4010
  const startedAt = yield* nowIso;
3076
4011
  const effectiveResumeCursor = input.resumePolicy === "fresh" ? void 0 : input.resumeCursor;
3077
4012
  const resumeState = readClaudeResumeState(effectiveResumeCursor);
@@ -3303,7 +4238,10 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
3303
4238
  });
3304
4239
  const canUseTool = (toolName, toolInput, callbackOptions) => runPromise(canUseToolEffect(toolName, toolInput, callbackOptions));
3305
4240
  const claudeBinaryPath = claudeSettings.binaryPath;
3306
- const extraArgs = parseCliArgs(claudeSettings.launchArgs).flags;
4241
+ const extraArgs = {
4242
+ "thinking-display": "summarized",
4243
+ ...parseCliArgs(claudeSettings.launchArgs).flags
4244
+ };
3307
4245
  const modelSelection = input.modelSelection?.instanceId === boundInstanceId ? input.modelSelection : void 0;
3308
4246
  const caps = getClaudeModelCapabilities(modelSelection?.model);
3309
4247
  const descriptors = require_Metrics.getProviderOptionDescriptors({ caps });
@@ -3360,6 +4298,8 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
3360
4298
  ...permissionMode === "bypassPermissions" ? { allowDangerouslySkipPermissions: true } : {},
3361
4299
  ...Object.keys(settings).length > 0 ? { settings } : {},
3362
4300
  ...existingResumeSessionId ? { resume: existingResumeSessionId } : {},
4301
+ ...existingResumeSessionId && resumeState?.rewindAt ? { resumeSessionAt: resumeState.rewindAt } : {},
4302
+ ...existingResumeSessionId && resumeState?.rewindAt && openOptions.resumeDropsTurn ? { resumeDropsTurn: openOptions.resumeDropsTurn } : {},
3363
4303
  ...newSessionId ? { sessionId: newSessionId } : {},
3364
4304
  includePartialMessages: true,
3365
4305
  canUseTool,
@@ -3433,6 +4373,7 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
3433
4373
  ...threadId ? { threadId } : {},
3434
4374
  ...sessionId ? { resume: sessionId } : {},
3435
4375
  ...resumeState?.resumeSessionAt ? { resumeSessionAt: resumeState.resumeSessionAt } : {},
4376
+ ...existingResumeSessionId && resumeState?.rewindAt ? { rewind: { at: resumeState.rewindAt } } : {},
3436
4377
  turnCount: resumeState?.turnCount ?? 0
3437
4378
  },
3438
4379
  createdAt: startedAt,
@@ -3440,9 +4381,15 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
3440
4381
  };
3441
4382
  const generation = ++nextSessionGeneration;
3442
4383
  const supportsAutomaticCompaction = typeof queryRuntime.applyFlagSettings === "function";
4384
+ const { resumeCursor: _resumeCursor, resumePolicy: _resumePolicy, ...startInput } = input;
3443
4385
  const context = {
3444
4386
  generation,
3445
4387
  session,
4388
+ startInput,
4389
+ turnHeads: [...openOptions.turnHeads ?? []],
4390
+ pendingRewind: existingResumeSessionId && resumeState?.rewindAt ? { at: resumeState.rewindAt } : void 0,
4391
+ probing: openOptions.probe === true,
4392
+ probeFailure: openOptions.probe === true ? effect.Deferred.makeUnsafe() : void 0,
3446
4393
  promptQueue,
3447
4394
  query: queryRuntime,
3448
4395
  deviceToolBinding,
@@ -3463,7 +4410,9 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
3463
4410
  taskAgents: /* @__PURE__ */ new Map(),
3464
4411
  subagentLaunchInputByToolUseId: /* @__PURE__ */ new Map(),
3465
4412
  subagentModelByToolUseId: /* @__PURE__ */ new Map(),
4413
+ subagentParentByToolUseId: /* @__PURE__ */ new Map(),
3466
4414
  workflowMemberFingerprints: /* @__PURE__ */ new Map(),
4415
+ rejectedRateLimitWindows: /* @__PURE__ */ new Map(),
3467
4416
  workflowPhasesByTaskId: /* @__PURE__ */ new Map(),
3468
4417
  liveTaskIds: /* @__PURE__ */ new Set(),
3469
4418
  backgroundedTaskIds: /* @__PURE__ */ new Set(),
@@ -3471,6 +4420,8 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
3471
4420
  lastKnownContextWindow: void 0,
3472
4421
  lastKnownTokenUsage: void 0,
3473
4422
  cacheObservation: void 0,
4423
+ mainLoopUsageObserved: false,
4424
+ cumulativeUsageSpansCompaction: false,
3474
4425
  cacheModelSelection: modelSelection,
3475
4426
  compactionPolicy: initialContextCompactionPolicyState(generation),
3476
4427
  supportsAutomaticCompaction,
@@ -3480,7 +4431,15 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
3480
4431
  subagentByTaskId: /* @__PURE__ */ new Map(),
3481
4432
  startedSubagentIds: /* @__PURE__ */ new Set(),
3482
4433
  completedSubagentIds: /* @__PURE__ */ new Set(),
3483
- stopped: false
4434
+ stopped: false,
4435
+ promptSent: false,
4436
+ turnInstallsInFlight: 0,
4437
+ requestingStatusObserved: false,
4438
+ cliCapabilities: void 0,
4439
+ discardedSteerPromptUuids: /* @__PURE__ */ new Set(),
4440
+ discardingCliTurn: void 0,
4441
+ wakeSignalDeferred: false,
4442
+ turnLock: yield* effect.Semaphore.make(1)
3484
4443
  };
3485
4444
  deviceToolContext = context;
3486
4445
  yield* effect.Ref.set(contextRef, context);
@@ -3525,18 +4484,35 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
3525
4484
  streamFiber = runFork(effect.Effect.exit(runSdkStream(context)).pipe(effect.Effect.flatMap((exit) => {
3526
4485
  if (context.stopped) return effect.Effect.void;
3527
4486
  if (context.streamFiber === streamFiber) context.streamFiber = void 0;
4487
+ if (context.probing && context.probeFailure) return effect.Deferred.succeed(context.probeFailure, effect.Exit.isFailure(exit) ? messageFromClaudeStreamCause(exit.cause, "Claude runtime stream failed.") : "Claude exited while reopening the conversation.").pipe(effect.Effect.asVoid);
3528
4488
  return handleStreamExit(context, exit);
3529
4489
  })));
3530
4490
  context.streamFiber = streamFiber;
3531
4491
  streamFiber.addObserver(() => {
3532
4492
  if (context.streamFiber === streamFiber) context.streamFiber = void 0;
3533
4493
  });
3534
- return { ...session };
4494
+ if (context.probing && context.probeFailure) {
4495
+ const probeFailure = context.probeFailure;
4496
+ const controlRequest = effect.Effect.tryPromise({
4497
+ try: () => queryRuntime.initializationResult?.() ?? queryRuntime.mcpServerStatus?.() ?? Promise.resolve(),
4498
+ catch: (cause) => toMessage(cause, "Claude rejected the reopened conversation.")
4499
+ });
4500
+ const probe = yield* effect.Effect.raceFirst(controlRequest.pipe(effect.Effect.asVoid), effect.Deferred.await(probeFailure).pipe(effect.Effect.flatMap((detail) => effect.Effect.fail(detail)))).pipe(effect.Effect.timeoutOption(CLAUDE_REWIND_PROBE_TIMEOUT), effect.Effect.result);
4501
+ context.probing = false;
4502
+ const failure = probe._tag === "Failure" ? probe.failure : effect.Option.isNone(probe.success) ? "Claude did not respond while reopening the conversation." : effect.Deferred.isDoneUnsafe(probeFailure) ? "Claude exited while reopening the conversation." : void 0;
4503
+ if (failure !== void 0) {
4504
+ yield* stopSessionInternal(context, { emitExitEvent: false });
4505
+ return yield* new require_bin.ProviderAdapterProcessError({
4506
+ provider: PROVIDER,
4507
+ threadId,
4508
+ detail: failure
4509
+ });
4510
+ }
4511
+ }
4512
+ return context;
3535
4513
  });
3536
- const sendTurn = effect.Effect.fn("sendTurn")(function* (input) {
3537
- const context = yield* requireSession(input.threadId);
4514
+ const sendTurnOnContext = effect.Effect.fn("sendTurnOnContext")(function* (context, input) {
3538
4515
  const modelSelection = input.modelSelection !== void 0 && input.modelSelection.instanceId === boundInstanceId ? input.modelSelection : void 0;
3539
- if (context.turnState) yield* completeTurn(context, "completed");
3540
4516
  if (modelSelection?.model) {
3541
4517
  const apiModelId = resolveClaudeApiModelId(modelSelection);
3542
4518
  if (context.currentApiModelId !== apiModelId) {
@@ -3563,24 +4539,23 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
3563
4539
  try: () => context.query.setPermissionMode(context.basePermissionMode ?? "default"),
3564
4540
  catch: (cause) => toRequestError(input.threadId, "turn/setPermissionMode", cause)
3565
4541
  });
3566
- const turnId = require_src.TurnId.make(yield* effect.Effect.sync(() => crypto.randomUUID()));
3567
- const turnState = {
4542
+ const promptUuid = yield* effect.Effect.sync(() => crypto.randomUUID());
4543
+ const turnId = require_src.TurnId.make(promptUuid);
4544
+ const startedAt = yield* nowIso;
4545
+ while (context.turnState !== void 0) yield* completeTurn(context, "completed");
4546
+ context.turnState = makeClaudeTurnState({
3568
4547
  turnId,
3569
- startedAt: yield* nowIso,
3570
- items: [],
3571
- assistantTextBlocks: /* @__PURE__ */ new Map(),
3572
- assistantTextBlockOrder: [],
3573
- capturedProposedPlanKeys: /* @__PURE__ */ new Set(),
3574
- nextSyntheticAssistantBlockIndex: -1
3575
- };
3576
- const updatedAt = yield* nowIso;
3577
- context.turnState = turnState;
4548
+ promptUuid,
4549
+ startedAt,
4550
+ openedBy: "prompt"
4551
+ });
3578
4552
  context.session = {
3579
4553
  ...context.session,
3580
4554
  status: "running",
3581
4555
  activeTurnId: turnId,
3582
- updatedAt
4556
+ updatedAt: startedAt
3583
4557
  };
4558
+ context.promptSent = true;
3584
4559
  const turnStartedStamp = yield* makeEventStamp();
3585
4560
  yield* offerRuntimeEventForContext(context, {
3586
4561
  type: "turn.started",
@@ -3604,7 +4579,10 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
3604
4579
  });
3605
4580
  yield* effect.Queue.offer(context.promptQueue, {
3606
4581
  type: "message",
3607
- message
4582
+ message: {
4583
+ ...message,
4584
+ uuid: promptUuid
4585
+ }
3608
4586
  }).pipe(effect.Effect.mapError((cause) => toRequestError(input.threadId, "turn/start", cause)));
3609
4587
  if (context.agentControl) yield* context.agentControl.bindTurn(turnId).pipe(effect.Effect.catchCause((cause) => effect.Effect.logWarning("failed to bind Agent Control turn authority", {
3610
4588
  threadId: input.threadId,
@@ -3617,9 +4595,73 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
3617
4595
  ...context.session.resumeCursor !== void 0 ? { resumeCursor: context.session.resumeCursor } : {}
3618
4596
  };
3619
4597
  });
3620
- const interruptTurn = effect.Effect.fn("interruptTurn")(function* (threadId, _turnId) {
4598
+ const sendTurn = effect.Effect.fn("sendTurn")(function* (input) {
4599
+ const context = yield* requireSession(input.threadId);
4600
+ return yield* effect.Effect.acquireUseRelease(effect.Effect.sync(() => {
4601
+ context.turnInstallsInFlight += 1;
4602
+ }), () => sendTurnOnContext(context, input), () => effect.Effect.sync(() => {
4603
+ context.turnInstallsInFlight -= 1;
4604
+ }));
4605
+ });
4606
+ /**
4607
+ * Adds a user message to the exact running turn: an SDK user message with `priority: "now"`
4608
+ * and its own uuid. The Ryco turn keeps its id and absorbs the CLI segments the steer starts.
4609
+ * Refusals are `ProviderTurnNotSteerableError`, so the message stays queued as the next turn.
4610
+ */
4611
+ const steerTurn = effect.Effect.fn("steerTurn")(function* (input) {
4612
+ const context = yield* requireSession(input.threadId);
4613
+ const refuse = (reason, detail) => new require_bin.ProviderTurnNotSteerableError({
4614
+ provider: PROVIDER,
4615
+ threadId: input.threadId,
4616
+ turnId: input.expectedTurnId,
4617
+ reason,
4618
+ detail
4619
+ });
4620
+ const turnState = context.turnState;
4621
+ if (!turnState || turnState.turnId !== input.expectedTurnId || context.session.activeTurnId !== input.expectedTurnId || turnState.interruptRequested) return yield* refuse("turn-ended", STEER_TURN_ENDED_DETAIL);
4622
+ 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.");
4623
+ 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.");
4624
+ if (input.input?.trimStart().startsWith("/")) return yield* refuse("unsupported", "Slash commands can't be steered into a running turn. The message stays queued.");
4625
+ const message = yield* buildUserMessageEffect({
4626
+ threadId: input.threadId,
4627
+ ...input.input ? { input: input.input } : {},
4628
+ attachments: input.attachments ?? [],
4629
+ ...context.cacheModelSelection ? { modelSelection: context.cacheModelSelection } : {}
4630
+ }, {
4631
+ fileSystem,
4632
+ attachmentsDir: serverConfig.attachmentsDir,
4633
+ boundInstanceId
4634
+ });
4635
+ const steerUuid = yield* effect.Effect.sync(() => crypto.randomUUID());
4636
+ if (!(yield* context.turnLock.withPermits(1)(effect.Effect.gen(function* () {
4637
+ if (sessions.get(input.threadId) !== context || context.stopped || context.turnState !== turnState || turnState.interruptRequested || turnState.completion !== void 0) return false;
4638
+ turnState.steerPromptUuids.add(steerUuid);
4639
+ const offered = yield* effect.Queue.offer(context.promptQueue, {
4640
+ type: "message",
4641
+ message: {
4642
+ ...message,
4643
+ uuid: steerUuid,
4644
+ priority: "now"
4645
+ }
4646
+ });
4647
+ if (!offered) turnState.steerPromptUuids.delete(steerUuid);
4648
+ return offered;
4649
+ })))) return yield* refuse("turn-ended", STEER_TURN_ENDED_DETAIL);
4650
+ yield* effect.Effect.logInfo("claude.turn.steered", {
4651
+ threadId: input.threadId,
4652
+ turnId: turnState.turnId,
4653
+ awaiting: turnState.awaitingSteerContinuation !== void 0
4654
+ });
4655
+ return {
4656
+ threadId: context.session.threadId,
4657
+ turnId: turnState.turnId
4658
+ };
4659
+ });
4660
+ const interruptTurn = effect.Effect.fn("interruptTurn")(function* (threadId, turnId) {
3621
4661
  const context = yield* requireSession(threadId);
3622
- if (context.agentControl) yield* context.agentControl.retireTurn(_turnId);
4662
+ const target = context.turnState;
4663
+ if (target) target.interruptRequested = true;
4664
+ if (context.agentControl) yield* context.agentControl.retireTurn(turnId);
3623
4665
  if (context.query.stopTask && context.liveTaskIds.size > 0) {
3624
4666
  const liveIds = Array.from(context.liveTaskIds);
3625
4667
  yield* effect.Effect.forEach(liveIds, (taskId) => effect.Effect.gen(function* () {
@@ -3648,10 +4690,47 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
3648
4690
  discard: true
3649
4691
  }).pipe(effect.Effect.timeoutOption("10 seconds"), effect.Effect.ignore);
3650
4692
  }
3651
- yield* effect.Effect.tryPromise({
3652
- try: () => context.query.interrupt(),
4693
+ const cancelQueued = (target ? [...target.steerPromptUuids].filter((uuid) => !target.settledSteerPromptUuids.has(uuid)) : []).length > 0 && context.cliCapabilities?.has("interrupt_cancel_queued_v1") === true;
4694
+ const rawReceipt = yield* effect.Effect.tryPromise({
4695
+ try: () => cancelQueued ? context.query.interrupt({ cancelQueued: true }) : context.query.interrupt(),
3653
4696
  catch: (cause) => toRequestError(threadId, "turn/interrupt", cause)
3654
4697
  });
4698
+ if (target !== void 0 && target.steerPromptUuids.size > 0) {
4699
+ const receipt = readClaudeInterruptReceipt(rawReceipt);
4700
+ yield* effect.Effect.logInfo("claude.turn.interrupt-receipt", {
4701
+ threadId: context.session.threadId,
4702
+ turnId: target.turnId,
4703
+ cancelQueued,
4704
+ hasReceipt: receipt !== void 0,
4705
+ stillQueued: receipt?.stillQueued.length ?? 0,
4706
+ cancelled: receipt?.cancelled?.length ?? 0
4707
+ });
4708
+ yield* context.turnLock.withPermits(1)(effect.Effect.gen(function* () {
4709
+ if (context.stopped) return;
4710
+ const stop = decideClaudeStop({
4711
+ unsettledSteers: [...target.steerPromptUuids].filter((uuid) => !target.settledSteerPromptUuids.has(uuid)),
4712
+ startedSteers: target.startedSteerPromptUuids,
4713
+ promptUuid: target.promptUuid,
4714
+ sealedSegmentCount: target.sealedSegmentCount,
4715
+ awaitingSteerContinuation: target.awaitingSteerContinuation !== void 0,
4716
+ receipt
4717
+ });
4718
+ if (context.turnState === target) for (const uuid of stop.discard) rememberDiscardedSteer(context.discardedSteerPromptUuids, uuid);
4719
+ for (const uuid of stop.release) {
4720
+ context.discardedSteerPromptUuids.delete(uuid);
4721
+ target.settledSteerPromptUuids.add(uuid);
4722
+ }
4723
+ if (stop.forceClose && context.turnState === target) yield* completeTurn(context, "interrupted", "Interrupted by user.", void 0, { expectedTurnState: target });
4724
+ }));
4725
+ }
4726
+ if (target !== void 0 && target.openedBy !== "prompt" && (turnId === void 0 || target.turnId === turnId)) yield* effect.Effect.sleep(effect.Duration.millis(CLAUDE_PROVIDER_TURN_STOP_GRACE_MS)).pipe(effect.Effect.andThen(effect.Effect.suspend(() => {
4727
+ if (context.turnState !== target || target.completion !== void 0 || context.stopped) return effect.Effect.void;
4728
+ return effect.Effect.logInfo("claude.turn.provider-turn-finalized-after-stop", {
4729
+ threadId: context.session.threadId,
4730
+ turnId: target.turnId,
4731
+ openedBy: target.openedBy
4732
+ }).pipe(effect.Effect.andThen(completeTurn(context, "interrupted", PROVIDER_TURN_STOP_REASON)));
4733
+ })), effect.Effect.ignoreCause({ log: true }), effect.Effect.forkDetach);
3655
4734
  });
3656
4735
  const stopBackgroundTask = effect.Effect.fn("stopBackgroundTask")(function* (threadId, taskId, expected) {
3657
4736
  const context = yield* requireSession(threadId);
@@ -3686,12 +4765,109 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
3686
4765
  const context = yield* requireSession(threadId);
3687
4766
  return yield* snapshotThread(context);
3688
4767
  });
3689
- const rollbackThread = effect.Effect.fn("rollbackThread")(function* (threadId, numTurns) {
4768
+ /** The session's main transcript chain, oldest first. Errors and timeouts read as empty. */
4769
+ const readMainTranscriptChain = effect.Effect.fn("readMainTranscriptChain")(function* (sessionId, cwd) {
4770
+ const read = (dir) => effect.Effect.tryPromise(() => readSessionMessages(sessionId, {
4771
+ ...dir !== void 0 ? { dir } : {},
4772
+ includeSystemMessages: true
4773
+ })).pipe(effect.Effect.timeoutOption(CLAUDE_REWIND_TRANSCRIPT_TIMEOUT), effect.Effect.map((entries) => effect.Option.getOrElse(entries, () => [])), effect.Effect.catch(() => effect.Effect.succeed([])), effect.Effect.map((entries) => entries.filter((entry) => typeof entry.uuid === "string" && (entry.parent_tool_use_id === null || entry.parent_tool_use_id === void 0))));
4774
+ const inCwd = yield* read(cwd);
4775
+ return inCwd.length > 0 || cwd === void 0 ? inCwd : yield* read(void 0);
4776
+ });
4777
+ /**
4778
+ * Makes Claude forget the newest turns: close the live query, wait for the
4779
+ * CLI to exit, and reopen the transcript truncated just before the first
4780
+ * dropped prompt (or a fresh session for checkpoint 0). A reopen the CLI
4781
+ * refuses restores the previous conversation and reports the refusal.
4782
+ */
4783
+ const rollbackThread = effect.Effect.fn("rollbackThread")(function* (threadId, input) {
3690
4784
  const context = yield* requireSession(threadId);
3691
- const nextLength = Math.max(0, context.turns.length - numTurns);
3692
- context.turns.splice(nextLength);
3693
- yield* updateResumeCursor(context);
3694
- return yield* snapshotThread(context);
4785
+ const refuse = (detail) => new require_bin.ProviderAdapterRequestError({
4786
+ provider: PROVIDER,
4787
+ method: "thread/rollback",
4788
+ detail
4789
+ });
4790
+ if (context.turnState) return yield* refuse("A Claude turn is still running.");
4791
+ if (context.liveTaskIds.size > 0) return yield* refuse("Claude still has background tasks running. Stop them, then revert again.");
4792
+ if (context.pendingApprovals.size > 0 || context.pendingUserInputs.size > 0) return yield* refuse("Claude is waiting for your answer. Answer it, then revert again.");
4793
+ if (rewindingThreads.has(threadId)) return yield* refuse("Claude is already rewinding this thread.");
4794
+ let plan;
4795
+ if (input.targetTurnId === null) plan = { kind: "fresh" };
4796
+ else {
4797
+ const firstDropped = input.droppedTurnIds[0];
4798
+ const chain = context.resumeSessionId !== void 0 && firstDropped !== void 0 ? yield* readMainTranscriptChain(context.resumeSessionId, context.session.cwd) : [];
4799
+ const index = firstDropped === void 0 ? -1 : chain.findIndex((entry) => entry.uuid === firstDropped);
4800
+ if (index > 0) plan = {
4801
+ kind: "rewind",
4802
+ at: chain[index - 1].uuid,
4803
+ ...input.droppedTurnIds.length === 1 && firstDropped !== void 0 ? { dropsTurn: firstDropped } : {}
4804
+ };
4805
+ else if (index === 0) plan = { kind: "fresh" };
4806
+ else {
4807
+ const head = context.turnHeads.find((entry) => entry.turnId === input.targetTurnId)?.head;
4808
+ if (head !== void 0) plan = {
4809
+ kind: "rewind",
4810
+ at: head
4811
+ };
4812
+ }
4813
+ }
4814
+ 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.");
4815
+ const rewindPlan = plan;
4816
+ rewindingThreads.add(threadId);
4817
+ return yield* effect.Effect.gen(function* () {
4818
+ const previousCursor = context.session.resumeCursor;
4819
+ const dropped = new Set(input.droppedTurnIds);
4820
+ const keptTurnHeads = context.turnHeads.filter((entry) => !dropped.has(entry.turnId));
4821
+ yield* stopSessionInternal(context, {
4822
+ emitExitEvent: false,
4823
+ awaitQueryExitMs: CLAUDE_REWIND_QUERY_EXIT_MS
4824
+ });
4825
+ const previousTurnCount = readClaudeResumeState(previousCursor)?.turnCount ?? context.turns.length;
4826
+ const nextCursor = rewindPlan.kind === "fresh" || context.resumeSessionId === void 0 ? { threadId } : {
4827
+ threadId,
4828
+ resume: context.resumeSessionId,
4829
+ rewind: { at: rewindPlan.at },
4830
+ turnCount: Math.max(0, previousTurnCount - input.numTurns)
4831
+ };
4832
+ const reopenInput = {
4833
+ ...context.startInput,
4834
+ runtimeMode: context.session.runtimeMode,
4835
+ ...context.session.tokenMode !== void 0 ? { tokenMode: context.session.tokenMode } : {},
4836
+ ...context.cacheModelSelection ?? context.startInput.modelSelection ? { modelSelection: context.cacheModelSelection ?? context.startInput.modelSelection } : {},
4837
+ ...context.session.runtimeSessionId !== void 0 ? { runtimeSessionId: context.session.runtimeSessionId } : {}
4838
+ };
4839
+ const reopened = yield* effect.Effect.result(openSessionContext({
4840
+ ...reopenInput,
4841
+ resumeCursor: nextCursor
4842
+ }, {
4843
+ probe: true,
4844
+ turnHeads: keptTurnHeads
4845
+ }));
4846
+ if (reopened._tag === "Success") return yield* snapshotThread(reopened.success);
4847
+ const refusal = adapterFailureDetail(reopened.failure);
4848
+ if ((yield* effect.Effect.result(openSessionContext({
4849
+ ...reopenInput,
4850
+ resumeCursor: previousCursor
4851
+ }, {
4852
+ probe: true,
4853
+ turnHeads: context.turnHeads
4854
+ })))._tag === "Failure") {
4855
+ const stamp = yield* makeEventStamp();
4856
+ yield* offerRuntimeEventForContext(context, {
4857
+ type: "session.exited",
4858
+ eventId: stamp.eventId,
4859
+ provider: PROVIDER,
4860
+ createdAt: stamp.createdAt,
4861
+ threadId,
4862
+ payload: {
4863
+ reason: "Claude could not restart after a failed rewind",
4864
+ exitKind: "error"
4865
+ },
4866
+ providerRefs: {}
4867
+ });
4868
+ }
4869
+ return yield* refuse(`Claude refused to rewind this conversation, so nothing was changed. ${refusal}`);
4870
+ }).pipe(effect.Effect.ensuring(effect.Effect.sync(() => rewindingThreads.delete(threadId))));
3695
4871
  });
3696
4872
  const respondToRequest = effect.Effect.fn("respondToRequest")(function* (threadId, requestId, decision) {
3697
4873
  const context = yield* requireSession(threadId);
@@ -3728,9 +4904,15 @@ const makeClaudeAdapter = effect.Effect.fn("makeClaudeAdapter")(function* (claud
3728
4904
  yield* effect.Effect.addFinalizer(() => effect.Effect.forEach(sessions, ([, context]) => stopSessionInternal(context, { emitExitEvent: false }), { discard: true }).pipe(effect.Effect.tap(() => runtimeEventQueueMetrics.reset), effect.Effect.tap(() => effect.Queue.shutdown(runtimeEventQueue))));
3729
4905
  return {
3730
4906
  provider: PROVIDER,
3731
- capabilities: { sessionModelSwitch: "in-session" },
4907
+ capabilities: {
4908
+ sessionModelSwitch: "in-session",
4909
+ conversationRollback: "native",
4910
+ turnSteering: "native",
4911
+ resumeSurvivesCwdChange: false
4912
+ },
3732
4913
  startSession,
3733
4914
  sendTurn,
4915
+ steerTurn,
3734
4916
  interruptTurn,
3735
4917
  stopBackgroundTask,
3736
4918
  readThread,