@ashlr/hub 3.22.0 → 3.22.1

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 (929) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +5 -5
  3. package/dist/authority-surface.json +16 -11
  4. package/dist/build-identity.json +2 -2
  5. package/dist/cli/verify-safety-sources.d.ts +4 -0
  6. package/dist/cli/verify-safety-sources.js +41 -0
  7. package/dist/cli/verify-safety-sources.js.map +1 -0
  8. package/dist/cli/verify-safety.js +16 -1
  9. package/dist/cli/verify-safety.js.map +1 -1
  10. package/dist/core/decide/needs-you.d.ts +3 -1
  11. package/dist/core/decide/needs-you.js +52 -28
  12. package/dist/core/decide/needs-you.js.map +1 -1
  13. package/dist/core/fleet/fleet-control-model.d.ts +2 -1
  14. package/dist/core/fleet/fleet-control-model.js +5 -0
  15. package/dist/core/fleet/fleet-control-model.js.map +1 -1
  16. package/dist/core/fleet/fleet-control-types.d.ts +11 -1
  17. package/dist/core/fleet/fleet-control.d.ts +4 -0
  18. package/dist/core/fleet/fleet-control.js +23 -1
  19. package/dist/core/fleet/fleet-control.js.map +1 -1
  20. package/dist/core/fleet/quota.js +1 -1
  21. package/dist/core/fleet/quota.js.map +1 -1
  22. package/dist/core/universe/builtins/preparation/manifest.json +1 -1
  23. package/dist/core/universe/builtins/preparation/preparation-bridge.mjs +4 -2
  24. package/dist/core/universe/builtins/preparation/preparation-verification-fixtures.mjs +3 -1
  25. package/dist/core/web/public/next/assets/ActionMenu-Z14OhnFI.js +2 -0
  26. package/dist/core/web/public/next/assets/ActionMenu-Z14OhnFI.js.map +1 -0
  27. package/dist/core/web/public/next/assets/Advanced-fUyq-fpH.js +2 -0
  28. package/dist/core/web/public/next/assets/Advanced-fUyq-fpH.js.map +1 -0
  29. package/dist/core/web/public/next/assets/AgentDetailScreen-C8h--Nah.js +2 -0
  30. package/dist/core/web/public/next/assets/AgentDetailScreen-C8h--Nah.js.map +1 -0
  31. package/dist/core/web/public/next/assets/AgentToolsSheet-BP3h-UbZ.js +2 -0
  32. package/dist/core/web/public/next/assets/AgentToolsSheet-BP3h-UbZ.js.map +1 -0
  33. package/dist/core/web/public/next/assets/AgentToolsStrip--hf18knJ.js +2 -0
  34. package/dist/core/web/public/next/assets/AgentToolsStrip--hf18knJ.js.map +1 -0
  35. package/dist/core/web/public/next/assets/AgentsScreen-BR-j0Fzd.js +2 -0
  36. package/dist/core/web/public/next/assets/AgentsScreen-BR-j0Fzd.js.map +1 -0
  37. package/dist/core/web/public/next/assets/AgentsSection-OKKOuYed.js +3 -0
  38. package/dist/core/web/public/next/assets/AgentsSection-OKKOuYed.js.map +1 -0
  39. package/dist/core/web/public/next/assets/App-ttVrZYp5.js +8 -0
  40. package/dist/core/web/public/next/assets/App-ttVrZYp5.js.map +1 -0
  41. package/dist/core/web/public/next/assets/AppsSection-sqsXqENO.js +2 -0
  42. package/dist/core/web/public/next/assets/AppsSection-sqsXqENO.js.map +1 -0
  43. package/dist/core/web/public/next/assets/AreaTrend-LVgaB49b.js +2 -0
  44. package/dist/core/web/public/next/assets/AreaTrend-LVgaB49b.js.map +1 -0
  45. package/dist/core/web/public/next/assets/AutomationsSection-BITmxjuB.js +2 -0
  46. package/dist/core/web/public/next/assets/AutomationsSection-BITmxjuB.js.map +1 -0
  47. package/dist/core/web/public/next/assets/AutonomyOffState-nO9lIcCv.js +3 -0
  48. package/dist/core/web/public/next/assets/AutonomyOffState-nO9lIcCv.js.map +1 -0
  49. package/dist/core/web/public/next/assets/AutonomySection-DWYUPDP6.js +2 -0
  50. package/dist/core/web/public/next/assets/AutonomySection-DWYUPDP6.js.map +1 -0
  51. package/dist/core/web/public/next/assets/AutonomyStatus-C4Yp1JTY.js +2 -0
  52. package/dist/core/web/public/next/assets/AutonomyStatus-C4Yp1JTY.js.map +1 -0
  53. package/dist/core/web/public/next/assets/BranchBar-CkiZSNqB.js +2 -0
  54. package/dist/core/web/public/next/assets/BranchBar-CkiZSNqB.js.map +1 -0
  55. package/dist/core/web/public/next/assets/BrowserPanel-CECVGJBS.js +7 -0
  56. package/dist/core/web/public/next/assets/BrowserPanel-CECVGJBS.js.map +1 -0
  57. package/dist/core/web/public/next/assets/BudgetControl-De1TPzvX.js +2 -0
  58. package/dist/core/web/public/next/assets/BudgetControl-De1TPzvX.js.map +1 -0
  59. package/dist/core/web/public/next/assets/Button-CstSJwha.js +2 -0
  60. package/dist/core/web/public/next/assets/Button-CstSJwha.js.map +1 -0
  61. package/dist/core/web/public/next/assets/CapacityStrip-nIJcB_lA.js +2 -0
  62. package/dist/core/web/public/next/assets/CapacityStrip-nIJcB_lA.js.map +1 -0
  63. package/dist/core/web/public/next/assets/ChangesPaneHost-Bnj_NcRa.js +16 -0
  64. package/dist/core/web/public/next/assets/ChangesPaneHost-Bnj_NcRa.js.map +1 -0
  65. package/dist/core/web/public/next/assets/ChartFrame-Dljee9y6.js +2 -0
  66. package/dist/core/web/public/next/assets/ChartFrame-Dljee9y6.js.map +1 -0
  67. package/dist/core/web/public/next/assets/ChatPanes-x_ySUIyR.js +2 -0
  68. package/dist/core/web/public/next/assets/ChatPanes-x_ySUIyR.js.map +1 -0
  69. package/dist/core/web/public/next/assets/ChatSection-CXJa8QOi.js +3 -0
  70. package/dist/core/web/public/next/assets/ChatSection-CXJa8QOi.js.map +1 -0
  71. package/dist/core/web/public/next/assets/ChecksPanel-D9r8koxq.js +5 -0
  72. package/dist/core/web/public/next/assets/ChecksPanel-D9r8koxq.js.map +1 -0
  73. package/dist/core/web/public/next/assets/CloudBudgetForm-D5ajpoMe.js +2 -0
  74. package/dist/core/web/public/next/assets/CloudBudgetForm-D5ajpoMe.js.map +1 -0
  75. package/dist/core/web/public/next/assets/CommandPalette-ONyqYZzt.js +3 -0
  76. package/dist/core/web/public/next/assets/CommandPalette-ONyqYZzt.js.map +1 -0
  77. package/dist/core/web/public/next/assets/CommandSection-DxNIibnI.js +3 -0
  78. package/dist/core/web/public/next/assets/CommandSection-DxNIibnI.js.map +1 -0
  79. package/dist/core/web/public/next/assets/CommandWorkflowForm-Bz3PuZXH.js +9 -0
  80. package/dist/core/web/public/next/assets/CommandWorkflowForm-Bz3PuZXH.js.map +1 -0
  81. package/dist/core/web/public/next/assets/CommandWorkflowPicker-COVyeer0.js +3 -0
  82. package/dist/core/web/public/next/assets/CommandWorkflowPicker-COVyeer0.js.map +1 -0
  83. package/dist/core/web/public/next/assets/CompareDialog-PVqv0Tx9.js +4 -0
  84. package/dist/core/web/public/next/assets/CompareDialog-PVqv0Tx9.js.map +1 -0
  85. package/dist/core/web/public/next/assets/ComputerControl-DkSIUrYm.js +2 -0
  86. package/dist/core/web/public/next/assets/ComputerControl-DkSIUrYm.js.map +1 -0
  87. package/dist/core/web/public/next/assets/ConfirmDialog-CdCzzk0I.js +2 -0
  88. package/dist/core/web/public/next/assets/ConfirmDialog-CdCzzk0I.js.map +1 -0
  89. package/dist/core/web/public/next/assets/DeleteChatDialog-BTzOgqho.js +2 -0
  90. package/dist/core/web/public/next/assets/DeleteChatDialog-BTzOgqho.js.map +1 -0
  91. package/dist/core/web/public/next/assets/DevinStopDialog-CGsDqfan.js +2 -0
  92. package/dist/core/web/public/next/assets/DevinStopDialog-CGsDqfan.js.map +1 -0
  93. package/dist/core/web/public/next/assets/Dialog-DDHg9cuT.js +2 -0
  94. package/dist/core/web/public/next/assets/Dialog-DDHg9cuT.js.map +1 -0
  95. package/dist/core/web/public/next/assets/DiffPane-BR3HU7pC.js +2 -0
  96. package/dist/core/web/public/next/assets/DiffPane-BR3HU7pC.js.map +1 -0
  97. package/dist/core/web/public/next/assets/DiffViewer-hJK75qko.js +2 -0
  98. package/dist/core/web/public/next/assets/DiffViewer-hJK75qko.js.map +1 -0
  99. package/dist/core/web/public/next/assets/DockHost-DhOosHbo.js +2 -0
  100. package/dist/core/web/public/next/assets/DockHost-DhOosHbo.js.map +1 -0
  101. package/dist/core/web/public/next/assets/EmptyState-CGVr0VO2.js +2 -0
  102. package/dist/core/web/public/next/assets/EmptyState-CGVr0VO2.js.map +1 -0
  103. package/dist/core/web/public/next/assets/Epistemic-tp0ZNAKZ.js +2 -0
  104. package/dist/core/web/public/next/assets/Epistemic-tp0ZNAKZ.js.map +1 -0
  105. package/dist/core/web/public/next/assets/EvidenceTimeline-YmKIoxNx.js +2 -0
  106. package/dist/core/web/public/next/assets/EvidenceTimeline-YmKIoxNx.js.map +1 -0
  107. package/dist/core/web/public/next/assets/FilesPane-CoNjfkPP.js +2 -0
  108. package/dist/core/web/public/next/assets/FilesPane-CoNjfkPP.js.map +1 -0
  109. package/dist/core/web/public/next/assets/FleetScreen-CstwycnB.js +2 -0
  110. package/dist/core/web/public/next/assets/FleetScreen-CstwycnB.js.map +1 -0
  111. package/dist/core/web/public/next/assets/FleetSection-D0xk0s5J.js +5 -0
  112. package/dist/core/web/public/next/assets/FleetSection-D0xk0s5J.js.map +1 -0
  113. package/dist/core/web/public/next/assets/Funnel-UPrk7fcy.js +2 -0
  114. package/dist/core/web/public/next/assets/Funnel-UPrk7fcy.js.map +1 -0
  115. package/dist/core/web/public/next/assets/GearTray-BSjga1J_.js +2 -0
  116. package/dist/core/web/public/next/assets/GearTray-BSjga1J_.js.map +1 -0
  117. package/dist/core/web/public/next/assets/GitDialogs-ekwzxl76.js +2 -0
  118. package/dist/core/web/public/next/assets/GitDialogs-ekwzxl76.js.map +1 -0
  119. package/dist/core/web/public/next/assets/GrowthSection-Dh-gnkgc.js +3 -0
  120. package/dist/core/web/public/next/assets/GrowthSection-Dh-gnkgc.js.map +1 -0
  121. package/dist/core/web/public/next/assets/HandoffDialog-BDiyA3u-.js +2 -0
  122. package/dist/core/web/public/next/assets/HandoffDialog-BDiyA3u-.js.map +1 -0
  123. package/dist/core/web/public/next/assets/HomeBody-Ce3HBIEb.js +3 -0
  124. package/dist/core/web/public/next/assets/HomeBody-Ce3HBIEb.js.map +1 -0
  125. package/dist/core/web/public/next/assets/HomeSeats-BFLCWCFp.js +2 -0
  126. package/dist/core/web/public/next/assets/HomeSeats-BFLCWCFp.js.map +1 -0
  127. package/dist/core/web/public/next/assets/Input-Cpn9uYj2.js +2 -0
  128. package/dist/core/web/public/next/assets/Input-Cpn9uYj2.js.map +1 -0
  129. package/dist/core/web/public/next/assets/LaunchDialog-CrPEf652.js +9 -0
  130. package/dist/core/web/public/next/assets/LaunchDialog-CrPEf652.js.map +1 -0
  131. package/dist/core/web/public/next/assets/LeaderCard-Dhq-w_Mf.js +2 -0
  132. package/dist/core/web/public/next/assets/LeaderCard-Dhq-w_Mf.js.map +1 -0
  133. package/dist/core/web/public/next/assets/LeaderConversation-CiWqhsoa.js +3 -0
  134. package/dist/core/web/public/next/assets/LeaderConversation-CiWqhsoa.js.map +1 -0
  135. package/dist/core/web/public/next/assets/LeaderScreen-Z5KPjxBV.js +2 -0
  136. package/dist/core/web/public/next/assets/LeaderScreen-Z5KPjxBV.js.map +1 -0
  137. package/dist/core/web/public/next/assets/LessonsPanel-B6XVKAPE.js +2 -0
  138. package/dist/core/web/public/next/assets/LessonsPanel-B6XVKAPE.js.map +1 -0
  139. package/dist/core/web/public/next/assets/LiveTimer-B8t2iX5h.js +2 -0
  140. package/dist/core/web/public/next/assets/LiveTimer-B8t2iX5h.js.map +1 -0
  141. package/dist/core/web/public/next/assets/LocalSeatBadge-HMxIrMiL.js +2 -0
  142. package/dist/core/web/public/next/assets/LocalSeatBadge-HMxIrMiL.js.map +1 -0
  143. package/dist/core/web/public/next/assets/MatrixHeatmap-BlFI5oao.js +2 -0
  144. package/dist/core/web/public/next/assets/MatrixHeatmap-BlFI5oao.js.map +1 -0
  145. package/dist/core/web/public/next/assets/McpSection-snZNKexW.js +2 -0
  146. package/dist/core/web/public/next/assets/McpSection-snZNKexW.js.map +1 -0
  147. package/dist/core/web/public/next/assets/MessageMarkdown-CS0mAtSs.js +3 -0
  148. package/dist/core/web/public/next/assets/MessageMarkdown-CS0mAtSs.js.map +1 -0
  149. package/dist/core/web/public/next/assets/MessageMarkdownRenderer-D5R-zr-W.js +72 -0
  150. package/dist/core/web/public/next/assets/MessageMarkdownRenderer-D5R-zr-W.js.map +1 -0
  151. package/dist/core/web/public/next/assets/Meter-VXI75VNe.js +2 -0
  152. package/dist/core/web/public/next/assets/Meter-VXI75VNe.js.map +1 -0
  153. package/dist/core/web/public/next/assets/MicButton-DORAXsUU.js +2 -0
  154. package/dist/core/web/public/next/assets/MicButton-DORAXsUU.js.map +1 -0
  155. package/dist/core/web/public/next/assets/MindSection-DZLHz29Q.js +3 -0
  156. package/dist/core/web/public/next/assets/MindSection-DZLHz29Q.js.map +1 -0
  157. package/dist/core/web/public/next/assets/MobileComposer-B8nWsIJO.js +2 -0
  158. package/dist/core/web/public/next/assets/MobileComposer-B8nWsIJO.js.map +1 -0
  159. package/dist/core/web/public/next/assets/MobileGuardSheet-BRwOfD9o.js +2 -0
  160. package/dist/core/web/public/next/assets/MobileGuardSheet-BRwOfD9o.js.map +1 -0
  161. package/dist/core/web/public/next/assets/MobileRuntime-kMob_MjB.js +3 -0
  162. package/dist/core/web/public/next/assets/MobileRuntime-kMob_MjB.js.map +1 -0
  163. package/dist/core/web/public/next/assets/MoreScreen-92dC6Bj7.js +2 -0
  164. package/dist/core/web/public/next/assets/MoreScreen-92dC6Bj7.js.map +1 -0
  165. package/dist/core/web/public/next/assets/MultiModelBar-BhAUUQOq.js +7 -0
  166. package/dist/core/web/public/next/assets/MultiModelBar-BhAUUQOq.js.map +1 -0
  167. package/dist/core/web/public/next/assets/MutationTokenDialog-DlY2VLVh.js +2 -0
  168. package/dist/core/web/public/next/assets/MutationTokenDialog-DlY2VLVh.js.map +1 -0
  169. package/dist/core/web/public/next/assets/NeedsYouDrawer-BH0ffbht.js +3 -0
  170. package/dist/core/web/public/next/assets/NeedsYouDrawer-BH0ffbht.js.map +1 -0
  171. package/dist/core/web/public/next/assets/NeedsYouList-CI_Dy-hi.js +2 -0
  172. package/dist/core/web/public/next/assets/NeedsYouList-CI_Dy-hi.js.map +1 -0
  173. package/dist/core/web/public/next/assets/NeedsYouScreen-CvDiEphJ.js +2 -0
  174. package/dist/core/web/public/next/assets/NeedsYouScreen-CvDiEphJ.js.map +1 -0
  175. package/dist/core/web/public/next/assets/NewAgentScreen-BpTRKp9z.js +2 -0
  176. package/dist/core/web/public/next/assets/NewAgentScreen-BpTRKp9z.js.map +1 -0
  177. package/dist/core/web/public/next/assets/NewChatDialog-O1LwwBc4.js +4 -0
  178. package/dist/core/web/public/next/assets/NewChatDialog-O1LwwBc4.js.map +1 -0
  179. package/dist/core/web/public/next/assets/OnboardingFlow-uMNBVHvK.js +3 -0
  180. package/dist/core/web/public/next/assets/OnboardingFlow-uMNBVHvK.js.map +1 -0
  181. package/dist/core/web/public/next/assets/OnboardingGate-sdzxSPZF.js +3 -0
  182. package/dist/core/web/public/next/assets/OnboardingGate-sdzxSPZF.js.map +1 -0
  183. package/dist/core/web/public/next/assets/PlaybooksSection-CnWfwZv8.js +9 -0
  184. package/dist/core/web/public/next/assets/PlaybooksSection-CnWfwZv8.js.map +1 -0
  185. package/dist/core/web/public/next/assets/PreviewPane-D1WaefIG.js +2 -0
  186. package/dist/core/web/public/next/assets/PreviewPane-D1WaefIG.js.map +1 -0
  187. package/dist/core/web/public/next/assets/ProviderLogo-g2YWCmNY.js +2 -0
  188. package/dist/core/web/public/next/assets/ProviderLogo-g2YWCmNY.js.map +1 -0
  189. package/dist/core/web/public/next/assets/RailStatus-OrvAuyzs.js +2 -0
  190. package/dist/core/web/public/next/assets/RailStatus-OrvAuyzs.js.map +1 -0
  191. package/dist/core/web/public/next/assets/ReasoningPane-BARDPl4-.js +2 -0
  192. package/dist/core/web/public/next/assets/ReasoningPane-BARDPl4-.js.map +1 -0
  193. package/dist/core/web/public/next/assets/ReasoningSheet-rPTXyt-b.js +2 -0
  194. package/dist/core/web/public/next/assets/ReasoningSheet-rPTXyt-b.js.map +1 -0
  195. package/dist/core/web/public/next/assets/RefreshIndicator-D96C9qiH.js +2 -0
  196. package/dist/core/web/public/next/assets/RefreshIndicator-D96C9qiH.js.map +1 -0
  197. package/dist/core/web/public/next/assets/RemoteMobileApp-DfDjiBTR.js +2 -0
  198. package/dist/core/web/public/next/assets/RemoteMobileApp-DfDjiBTR.js.map +1 -0
  199. package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-CcfULh_p.js +7 -0
  200. package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-CcfULh_p.js.map +1 -0
  201. package/dist/core/web/public/next/assets/ResourcesChrome-DuEa7WOo.css +1 -0
  202. package/dist/core/web/public/next/assets/ResourcesChrome-e9ifgnWf.js +3 -0
  203. package/dist/core/web/public/next/assets/ResourcesChrome-e9ifgnWf.js.map +1 -0
  204. package/dist/core/web/public/next/assets/ResourcesDrawer-DOv_mxpe.js +3 -0
  205. package/dist/core/web/public/next/assets/ResourcesDrawer-DOv_mxpe.js.map +1 -0
  206. package/dist/core/web/public/next/assets/ReviewMenu-Ba3saQlX.js +2 -0
  207. package/dist/core/web/public/next/assets/ReviewMenu-Ba3saQlX.js.map +1 -0
  208. package/dist/core/web/public/next/assets/RouteErrorBoundary-BaJ1ZePy.js +2 -0
  209. package/dist/core/web/public/next/assets/RouteErrorBoundary-BaJ1ZePy.js.map +1 -0
  210. package/dist/core/web/public/next/assets/RunInCloudAction-DRSX84Jy.js +2 -0
  211. package/dist/core/web/public/next/assets/RunInCloudAction-DRSX84Jy.js.map +1 -0
  212. package/dist/core/web/public/next/assets/RunInDevinAction-BMji-YN2.js +2 -0
  213. package/dist/core/web/public/next/assets/RunInDevinAction-BMji-YN2.js.map +1 -0
  214. package/dist/core/web/public/next/assets/SchedulingEvidence-xxjV6HF_.js +2 -0
  215. package/dist/core/web/public/next/assets/SchedulingEvidence-xxjV6HF_.js.map +1 -0
  216. package/dist/core/web/public/next/assets/ScreenHost-Dv6z76Ta.js +3 -0
  217. package/dist/core/web/public/next/assets/ScreenHost-Dv6z76Ta.js.map +1 -0
  218. package/dist/core/web/public/next/assets/SeatSelector-YRNdNpP8.js +3 -0
  219. package/dist/core/web/public/next/assets/SeatSelector-YRNdNpP8.js.map +1 -0
  220. package/dist/core/web/public/next/assets/Segmented-BA8RmKYq.js +2 -0
  221. package/dist/core/web/public/next/assets/Segmented-BA8RmKYq.js.map +1 -0
  222. package/dist/core/web/public/next/assets/Select-B8GqZOX9.js +2 -0
  223. package/dist/core/web/public/next/assets/Select-B8GqZOX9.js.map +1 -0
  224. package/dist/core/web/public/next/assets/SessionGate-CnASHl7g.js +2 -0
  225. package/dist/core/web/public/next/assets/SessionGate-CnASHl7g.js.map +1 -0
  226. package/dist/core/web/public/next/assets/SessionInsightChip-DIKfih6i.js +2 -0
  227. package/dist/core/web/public/next/assets/SessionInsightChip-DIKfih6i.js.map +1 -0
  228. package/dist/core/web/public/next/assets/SessionSearch-K6lvMlji.js +2 -0
  229. package/dist/core/web/public/next/assets/SessionSearch-K6lvMlji.js.map +1 -0
  230. package/dist/core/web/public/next/assets/SettingsSection-C-c3f_6J.js +2 -0
  231. package/dist/core/web/public/next/assets/SettingsSection-C-c3f_6J.js.map +1 -0
  232. package/dist/core/web/public/next/assets/SetupChecklist-DAbAdrX4.js +2 -0
  233. package/dist/core/web/public/next/assets/SetupChecklist-DAbAdrX4.js.map +1 -0
  234. package/dist/core/web/public/next/assets/ShadowDecisions-C41uRSw4.js +3 -0
  235. package/dist/core/web/public/next/assets/ShadowDecisions-C41uRSw4.js.map +1 -0
  236. package/dist/core/web/public/next/assets/Sheet-Bk64-Hlt.js +2 -0
  237. package/dist/core/web/public/next/assets/Sheet-Bk64-Hlt.js.map +1 -0
  238. package/dist/core/web/public/next/assets/ShortcutsOverlay-CcP96zqy.js +2 -0
  239. package/dist/core/web/public/next/assets/ShortcutsOverlay-CcP96zqy.js.map +1 -0
  240. package/dist/core/web/public/next/assets/Sidebar-sSNKd57n.js +3 -0
  241. package/dist/core/web/public/next/assets/Sidebar-sSNKd57n.js.map +1 -0
  242. package/dist/core/web/public/next/assets/SkipToContent-BynsXs9i.js +2 -0
  243. package/dist/core/web/public/next/assets/SkipToContent-BynsXs9i.js.map +1 -0
  244. package/dist/core/web/public/next/assets/Slider-DS5HrVzl.js +2 -0
  245. package/dist/core/web/public/next/assets/Slider-DS5HrVzl.js.map +1 -0
  246. package/dist/core/web/public/next/assets/SourcesPane-QffcyDfA.js +2 -0
  247. package/dist/core/web/public/next/assets/SourcesPane-QffcyDfA.js.map +1 -0
  248. package/dist/core/web/public/next/assets/SourcesPanel-DlttePk7.js +2 -0
  249. package/dist/core/web/public/next/assets/SourcesPanel-DlttePk7.js.map +1 -0
  250. package/dist/core/web/public/next/assets/StatTile-mYm1GPj7.js +2 -0
  251. package/dist/core/web/public/next/assets/StatTile-mYm1GPj7.js.map +1 -0
  252. package/dist/core/web/public/next/assets/StatusBadge-Yz7S3kZ2.js +2 -0
  253. package/dist/core/web/public/next/assets/StatusBadge-Yz7S3kZ2.js.map +1 -0
  254. package/dist/core/web/public/next/assets/StepBand-Bdkv7iGd.js +2 -0
  255. package/dist/core/web/public/next/assets/StepBand-Bdkv7iGd.js.map +1 -0
  256. package/dist/core/web/public/next/assets/Surface-DVOAKl2g.js +2 -0
  257. package/dist/core/web/public/next/assets/Surface-DVOAKl2g.js.map +1 -0
  258. package/dist/core/web/public/next/assets/Swimlane-CeMBD_FC.js +2 -0
  259. package/dist/core/web/public/next/assets/Swimlane-CeMBD_FC.js.map +1 -0
  260. package/dist/core/web/public/next/assets/Switch-Cqc_bSoh.js +2 -0
  261. package/dist/core/web/public/next/assets/Switch-Cqc_bSoh.js.map +1 -0
  262. package/dist/core/web/public/next/assets/Tag-BvOxSxYi.js +2 -0
  263. package/dist/core/web/public/next/assets/Tag-BvOxSxYi.js.map +1 -0
  264. package/dist/core/web/public/next/assets/TerminalPane-D3f02aI4.js +3 -0
  265. package/dist/core/web/public/next/assets/TerminalPane-D3f02aI4.js.map +1 -0
  266. package/dist/core/web/public/next/assets/TerminalPane-XZ5n3Pns.js +26 -0
  267. package/dist/core/web/public/next/assets/TerminalPane-XZ5n3Pns.js.map +1 -0
  268. package/dist/core/web/public/next/assets/ThinkingBlock-DZNlOGaV.js +2 -0
  269. package/dist/core/web/public/next/assets/ThinkingBlock-DZNlOGaV.js.map +1 -0
  270. package/dist/core/web/public/next/assets/UniverseConsoleApp-CzBI6Upl.js +2 -0
  271. package/dist/core/web/public/next/assets/UniverseConsoleApp-CzBI6Upl.js.map +1 -0
  272. package/dist/core/web/public/next/assets/UniverseView-Dsi3Kk8o.js +9 -0
  273. package/dist/core/web/public/next/assets/UniverseView-Dsi3Kk8o.js.map +1 -0
  274. package/dist/core/web/public/next/assets/UsageSection-rVvLat9z.js +3 -0
  275. package/dist/core/web/public/next/assets/UsageSection-rVvLat9z.js.map +1 -0
  276. package/dist/core/web/public/next/assets/UsePlaybookAction-B4XAzSeI.js +2 -0
  277. package/dist/core/web/public/next/assets/UsePlaybookAction-B4XAzSeI.js.map +1 -0
  278. package/dist/core/web/public/next/assets/VerseConsoleApp-BmckthwC.css +1 -0
  279. package/dist/core/web/public/next/assets/VerseConsoleApp-DjPpZLo1.js +3 -0
  280. package/dist/core/web/public/next/assets/VerseConsoleApp-DjPpZLo1.js.map +1 -0
  281. package/dist/core/web/public/next/assets/VerseMobileApp-ePNuVERe.js +3 -0
  282. package/dist/core/web/public/next/assets/VerseMobileApp-ePNuVERe.js.map +1 -0
  283. package/dist/core/web/public/next/assets/VerseShared-Bf-XTHCh.js +2 -0
  284. package/dist/core/web/public/next/assets/VerseShared-Bf-XTHCh.js.map +1 -0
  285. package/dist/core/web/public/next/assets/VoiceHud-BG5FV2h0.js +2 -0
  286. package/dist/core/web/public/next/assets/VoiceHud-BG5FV2h0.js.map +1 -0
  287. package/dist/core/web/public/next/assets/VoiceInput-k3vB_FxV.js +2 -0
  288. package/dist/core/web/public/next/assets/VoiceInput-k3vB_FxV.js.map +1 -0
  289. package/dist/core/web/public/next/assets/WikiSection-DeBKNqd6.js +2 -0
  290. package/dist/core/web/public/next/assets/WikiSection-DeBKNqd6.js.map +1 -0
  291. package/dist/core/web/public/next/assets/Workspace-CvwS2-RN.js +6 -0
  292. package/dist/core/web/public/next/assets/Workspace-CvwS2-RN.js.map +1 -0
  293. package/dist/core/web/public/next/assets/actions-Dg6UJTLn.js +2 -0
  294. package/dist/core/web/public/next/assets/actions-Dg6UJTLn.js.map +1 -0
  295. package/dist/core/web/public/next/assets/agent-tools-client-DmJq7zlr.js +2 -0
  296. package/dist/core/web/public/next/assets/agent-tools-client-DmJq7zlr.js.map +1 -0
  297. package/dist/core/web/public/next/assets/agents-focus-B1LKhUVg.js +2 -0
  298. package/dist/core/web/public/next/assets/agents-focus-B1LKhUVg.js.map +1 -0
  299. package/dist/core/web/public/next/assets/app-version-Cb1z8iCO.js +2 -0
  300. package/dist/core/web/public/next/assets/app-version-Cb1z8iCO.js.map +1 -0
  301. package/dist/core/web/public/next/assets/apps-model-_chbcQeN.js +2 -0
  302. package/dist/core/web/public/next/assets/apps-model-_chbcQeN.js.map +1 -0
  303. package/dist/core/web/public/next/assets/ask-seat-O60AydbV.js +2 -0
  304. package/dist/core/web/public/next/assets/ask-seat-O60AydbV.js.map +1 -0
  305. package/dist/core/web/public/next/assets/authority-model-BeDDHF22.js +2 -0
  306. package/dist/core/web/public/next/assets/authority-model-BeDDHF22.js.map +1 -0
  307. package/dist/core/web/public/next/assets/automations-focus-BXaRZ8nX.js +2 -0
  308. package/dist/core/web/public/next/assets/automations-focus-BXaRZ8nX.js.map +1 -0
  309. package/dist/core/web/public/next/assets/budget-queries-Nvx0H2XE.js +2 -0
  310. package/dist/core/web/public/next/assets/budget-queries-Nvx0H2XE.js.map +1 -0
  311. package/dist/core/web/public/next/assets/capacity-strip-model-CBMJ2U-w.js +2 -0
  312. package/dist/core/web/public/next/assets/capacity-strip-model-CBMJ2U-w.js.map +1 -0
  313. package/dist/core/web/public/next/assets/charts-DT9PYS49.js +2 -0
  314. package/dist/core/web/public/next/assets/charts-DT9PYS49.js.map +1 -0
  315. package/dist/core/web/public/next/assets/chat-pane-data-CfbpeAYX.js +2 -0
  316. package/dist/core/web/public/next/assets/chat-pane-data-CfbpeAYX.js.map +1 -0
  317. package/dist/core/web/public/next/assets/checkpoint-queries-BKD2evmX.js +2 -0
  318. package/dist/core/web/public/next/assets/checkpoint-queries-BKD2evmX.js.map +1 -0
  319. package/dist/core/web/public/next/assets/cloud-queries-CsU54eNn.js +2 -0
  320. package/dist/core/web/public/next/assets/cloud-queries-CsU54eNn.js.map +1 -0
  321. package/dist/core/web/public/next/assets/command-catalog-B0ApAGD0.js +2 -0
  322. package/dist/core/web/public/next/assets/command-catalog-B0ApAGD0.js.map +1 -0
  323. package/dist/core/web/public/next/assets/composer-queries-D1H4E0Ye.js +2 -0
  324. package/dist/core/web/public/next/assets/composer-queries-D1H4E0Ye.js.map +1 -0
  325. package/dist/core/web/public/next/assets/connectivity-xQ0Nh0j3.js +2 -0
  326. package/dist/core/web/public/next/assets/connectivity-xQ0Nh0j3.js.map +1 -0
  327. package/dist/core/web/public/next/assets/context-queries-bnI3P0Wt.js +2 -0
  328. package/dist/core/web/public/next/assets/context-queries-bnI3P0Wt.js.map +1 -0
  329. package/dist/core/web/public/next/assets/control-queries-BG53otwz.js +2 -0
  330. package/dist/core/web/public/next/assets/control-queries-BG53otwz.js.map +1 -0
  331. package/dist/core/web/public/next/assets/copy-setup-COMDnur3.js +2 -0
  332. package/dist/core/web/public/next/assets/copy-setup-COMDnur3.js.map +1 -0
  333. package/dist/core/web/public/next/assets/deep-link-CqOP-JEm.js +2 -0
  334. package/dist/core/web/public/next/assets/deep-link-CqOP-JEm.js.map +1 -0
  335. package/dist/core/web/public/next/assets/device-permissions-DpsJJcUW.js +2 -0
  336. package/dist/core/web/public/next/assets/device-permissions-DpsJJcUW.js.map +1 -0
  337. package/dist/core/web/public/next/assets/devin-queries-BSEOfLuZ.js +2 -0
  338. package/dist/core/web/public/next/assets/devin-queries-BSEOfLuZ.js.map +1 -0
  339. package/dist/core/web/public/next/assets/dock-icons-DK7QcBXJ.js +2 -0
  340. package/dist/core/web/public/next/assets/dock-icons-DK7QcBXJ.js.map +1 -0
  341. package/dist/core/web/public/next/assets/dock-panes-DvQ6t4Nl.js +2 -0
  342. package/dist/core/web/public/next/assets/dock-panes-DvQ6t4Nl.js.map +1 -0
  343. package/dist/core/web/public/next/assets/fleet-control-queries-BL-Vlf85.js +2 -0
  344. package/dist/core/web/public/next/assets/fleet-control-queries-BL-Vlf85.js.map +1 -0
  345. package/dist/core/web/public/next/assets/fleet-queries-eacERnLm.js +2 -0
  346. package/dist/core/web/public/next/assets/fleet-queries-eacERnLm.js.map +1 -0
  347. package/dist/core/web/public/next/assets/fleet-state-DfKcuo4A.js +3 -0
  348. package/dist/core/web/public/next/assets/fleet-state-DfKcuo4A.js.map +1 -0
  349. package/dist/core/web/public/next/assets/focus-trap-BZeH0rVB.js +2 -0
  350. package/dist/core/web/public/next/assets/focus-trap-BZeH0rVB.js.map +1 -0
  351. package/dist/core/web/public/next/assets/git-model-C1I4z_iQ.js +5 -0
  352. package/dist/core/web/public/next/assets/git-model-C1I4z_iQ.js.map +1 -0
  353. package/dist/core/web/public/next/assets/global-w7KDTTi0.js +3 -0
  354. package/dist/core/web/public/next/assets/global-w7KDTTi0.js.map +1 -0
  355. package/dist/core/web/public/next/assets/guarded-action-J9umcJgI.js +3 -0
  356. package/dist/core/web/public/next/assets/guarded-action-J9umcJgI.js.map +1 -0
  357. package/dist/core/web/public/next/assets/guarded-runners-Da5yA9Im.js +2 -0
  358. package/dist/core/web/public/next/assets/guarded-runners-Da5yA9Im.js.map +1 -0
  359. package/dist/core/web/public/next/assets/health-queries-D3HgrdU_.js +2 -0
  360. package/dist/core/web/public/next/assets/health-queries-D3HgrdU_.js.map +1 -0
  361. package/dist/core/web/public/next/assets/icons-C3G-y5j2.js +2 -0
  362. package/dist/core/web/public/next/assets/icons-C3G-y5j2.js.map +1 -0
  363. package/dist/core/web/public/next/assets/index-BC5Uslm5.js +11 -0
  364. package/dist/core/web/public/next/assets/index-BC5Uslm5.js.map +1 -0
  365. package/dist/core/web/public/next/assets/jev-queries-D6JNU-s6.js +2 -0
  366. package/dist/core/web/public/next/assets/jev-queries-D6JNU-s6.js.map +1 -0
  367. package/dist/core/web/public/next/assets/ladder-queries-BnYWjJoi.js +2 -0
  368. package/dist/core/web/public/next/assets/ladder-queries-BnYWjJoi.js.map +1 -0
  369. package/dist/core/web/public/next/assets/leader-focus-C6LVWgYI.js +2 -0
  370. package/dist/core/web/public/next/assets/leader-focus-C6LVWgYI.js.map +1 -0
  371. package/dist/core/web/public/next/assets/live-model-BPyZCTr1.js +2 -0
  372. package/dist/core/web/public/next/assets/live-model-BPyZCTr1.js.map +1 -0
  373. package/dist/core/web/public/next/assets/mobile-actions-avKNGddD.js +2 -0
  374. package/dist/core/web/public/next/assets/mobile-actions-avKNGddD.js.map +1 -0
  375. package/dist/core/web/public/next/assets/mobile-toast-BqSzGmw1.js +2 -0
  376. package/dist/core/web/public/next/assets/mobile-toast-BqSzGmw1.js.map +1 -0
  377. package/dist/core/web/public/next/assets/multimodel-flows-DOHsEKUG.js +7 -0
  378. package/dist/core/web/public/next/assets/multimodel-flows-DOHsEKUG.js.map +1 -0
  379. package/dist/core/web/public/next/assets/multimodel-queries-xmBBUT6n.js +2 -0
  380. package/dist/core/web/public/next/assets/multimodel-queries-xmBBUT6n.js.map +1 -0
  381. package/dist/core/web/public/next/assets/mutations-CdLi0erM.js +2 -0
  382. package/dist/core/web/public/next/assets/mutations-CdLi0erM.js.map +1 -0
  383. package/dist/core/web/public/next/assets/nav-CUXtg-Iw.js +2 -0
  384. package/dist/core/web/public/next/assets/nav-CUXtg-Iw.js.map +1 -0
  385. package/dist/core/web/public/next/assets/needs-you-actions-B2tjWO-0.js +2 -0
  386. package/dist/core/web/public/next/assets/needs-you-actions-B2tjWO-0.js.map +1 -0
  387. package/dist/core/web/public/next/assets/needs-you-model-DL9EEd2L.js +2 -0
  388. package/dist/core/web/public/next/assets/needs-you-model-DL9EEd2L.js.map +1 -0
  389. package/dist/core/web/public/next/assets/open-terminal-BfbxGoYQ.js +2 -0
  390. package/dist/core/web/public/next/assets/open-terminal-BfbxGoYQ.js.map +1 -0
  391. package/dist/core/web/public/next/assets/open-terminal-request-BT1UE0fz.js +2 -0
  392. package/dist/core/web/public/next/assets/open-terminal-request-BT1UE0fz.js.map +1 -0
  393. package/dist/core/web/public/next/assets/overnight-queries-cjjogTzn.js +2 -0
  394. package/dist/core/web/public/next/assets/overnight-queries-cjjogTzn.js.map +1 -0
  395. package/dist/core/web/public/next/assets/palette-handoff-XL2WWc9I.js +2 -0
  396. package/dist/core/web/public/next/assets/palette-handoff-XL2WWc9I.js.map +1 -0
  397. package/dist/core/web/public/next/assets/panes-5GU8cuI9.js +3 -0
  398. package/dist/core/web/public/next/assets/panes-5GU8cuI9.js.map +1 -0
  399. package/dist/core/web/public/next/assets/path-display-ZSzKoo8T.js +2 -0
  400. package/dist/core/web/public/next/assets/path-display-ZSzKoo8T.js.map +1 -0
  401. package/dist/core/web/public/next/assets/playbook-composer-D04tqOmU.js +2 -0
  402. package/dist/core/web/public/next/assets/playbook-composer-D04tqOmU.js.map +1 -0
  403. package/dist/core/web/public/next/assets/playbook-focus-DD1VIfkd.js +2 -0
  404. package/dist/core/web/public/next/assets/playbook-focus-DD1VIfkd.js.map +1 -0
  405. package/dist/core/web/public/next/assets/playbooks-queries-X7NGzpIn.js +2 -0
  406. package/dist/core/web/public/next/assets/playbooks-queries-X7NGzpIn.js.map +1 -0
  407. package/dist/core/web/public/next/assets/preloaded-6hKNGuRp.js +2 -0
  408. package/dist/core/web/public/next/assets/preloaded-6hKNGuRp.js.map +1 -0
  409. package/dist/core/web/public/next/assets/primitives-6nAFZkcg.js +1 -0
  410. package/dist/core/web/public/next/assets/pwa-BzXJXtDt.js +2 -0
  411. package/dist/core/web/public/next/assets/pwa-BzXJXtDt.js.map +1 -0
  412. package/dist/core/web/public/next/assets/queries-PgZlvFqO.js +2 -0
  413. package/dist/core/web/public/next/assets/queries-PgZlvFqO.js.map +1 -0
  414. package/dist/core/web/public/next/assets/reasoning-pref-BS0PSZ8d.js +2 -0
  415. package/dist/core/web/public/next/assets/reasoning-pref-BS0PSZ8d.js.map +1 -0
  416. package/dist/core/web/public/next/assets/remote-session-Bu-dtRcS.js +3 -0
  417. package/dist/core/web/public/next/assets/remote-session-Bu-dtRcS.js.map +1 -0
  418. package/dist/core/web/public/next/assets/resolved-store-UYN2k9My.js +2 -0
  419. package/dist/core/web/public/next/assets/resolved-store-UYN2k9My.js.map +1 -0
  420. package/dist/core/web/public/next/assets/resources-queries-XfQ8w9In.js +2 -0
  421. package/dist/core/web/public/next/assets/resources-queries-XfQ8w9In.js.map +1 -0
  422. package/dist/core/web/public/next/assets/reveal-anchor-3ZUTtB8Q.js +2 -0
  423. package/dist/core/web/public/next/assets/reveal-anchor-3ZUTtB8Q.js.map +1 -0
  424. package/dist/core/web/public/next/assets/sheet-DP8ByDWU.js +2 -0
  425. package/dist/core/web/public/next/assets/sheet-DP8ByDWU.js.map +1 -0
  426. package/dist/core/web/public/next/assets/slots-DWlj_c7i.js +3 -0
  427. package/dist/core/web/public/next/assets/slots-DWlj_c7i.js.map +1 -0
  428. package/dist/core/web/public/next/assets/sources-queries-Cjk1rpDU.js +4 -0
  429. package/dist/core/web/public/next/assets/sources-queries-Cjk1rpDU.js.map +1 -0
  430. package/dist/core/web/public/next/assets/sse-Z3U8XhDI.js +2 -0
  431. package/dist/core/web/public/next/assets/sse-Z3U8XhDI.js.map +1 -0
  432. package/dist/core/web/public/next/assets/surface-data-hufdOfpz.js +2 -0
  433. package/dist/core/web/public/next/assets/surface-data-hufdOfpz.js.map +1 -0
  434. package/dist/core/web/public/next/assets/surface-prefetch-CFtP8imB.js +2 -0
  435. package/dist/core/web/public/next/assets/surface-prefetch-CFtP8imB.js.map +1 -0
  436. package/dist/core/web/public/next/assets/terminal-client-CCSvMeEv.js +2 -0
  437. package/dist/core/web/public/next/assets/terminal-client-CCSvMeEv.js.map +1 -0
  438. package/dist/core/web/public/next/assets/terminal-icons-Dx6neM-J.js +2 -0
  439. package/dist/core/web/public/next/assets/terminal-icons-Dx6neM-J.js.map +1 -0
  440. package/dist/core/web/public/next/assets/terminal-view-BSieiQvi.js +6 -0
  441. package/dist/core/web/public/next/assets/terminal-view-BSieiQvi.js.map +1 -0
  442. package/dist/core/web/public/next/assets/thread-data-Cd2DZffn.js +2 -0
  443. package/dist/core/web/public/next/assets/thread-data-Cd2DZffn.js.map +1 -0
  444. package/dist/core/web/public/next/assets/ui-parts-wvov2ktB.js +2 -0
  445. package/dist/core/web/public/next/assets/ui-parts-wvov2ktB.js.map +1 -0
  446. package/dist/core/web/public/next/assets/usage-queries-nZjJ1aky.js +2 -0
  447. package/dist/core/web/public/next/assets/usage-queries-nZjJ1aky.js.map +1 -0
  448. package/dist/core/web/public/next/assets/use-chat-activity-_tBmEPPN.js +2 -0
  449. package/dist/core/web/public/next/assets/use-chat-activity-_tBmEPPN.js.map +1 -0
  450. package/dist/core/web/public/next/assets/use-guarded-action-DKKjhPKG.js +2 -0
  451. package/dist/core/web/public/next/assets/use-guarded-action-DKKjhPKG.js.map +1 -0
  452. package/dist/core/web/public/next/assets/use-ticker-w1c3SOqK.js +2 -0
  453. package/dist/core/web/public/next/assets/use-ticker-w1c3SOqK.js.map +1 -0
  454. package/dist/core/web/public/next/assets/use-token-gate-h5QAERLT.js +2 -0
  455. package/dist/core/web/public/next/assets/use-token-gate-h5QAERLT.js.map +1 -0
  456. package/dist/core/web/public/next/assets/useAutoSeat-Dpbn0XUv.js +2 -0
  457. package/dist/core/web/public/next/assets/useAutoSeat-Dpbn0XUv.js.map +1 -0
  458. package/dist/core/web/public/next/assets/useOnboarding-VoV1LcuJ.js +2 -0
  459. package/dist/core/web/public/next/assets/useOnboarding-VoV1LcuJ.js.map +1 -0
  460. package/dist/core/web/public/next/assets/useSeatHealth-DuSaKdIs.js +2 -0
  461. package/dist/core/web/public/next/assets/useSeatHealth-DuSaKdIs.js.map +1 -0
  462. package/dist/core/web/public/next/assets/useSeatsRefresh-DFaR1jSz.js +2 -0
  463. package/dist/core/web/public/next/assets/useSeatsRefresh-DFaR1jSz.js.map +1 -0
  464. package/dist/core/web/public/next/assets/useVerseSession-BOsgJzT5.js +2 -0
  465. package/dist/core/web/public/next/assets/useVerseSession-BOsgJzT5.js.map +1 -0
  466. package/dist/core/web/public/next/assets/useVerseTranscript-BN_fMz6x.js +2 -0
  467. package/dist/core/web/public/next/assets/useVerseTranscript-BN_fMz6x.js.map +1 -0
  468. package/dist/core/web/public/next/assets/verse-bootstrap-query-B3vFD9XK.js +2 -0
  469. package/dist/core/web/public/next/assets/verse-bootstrap-query-B3vFD9XK.js.map +1 -0
  470. package/dist/core/web/public/next/assets/verse-icons-vSkflmRB.js +2 -0
  471. package/dist/core/web/public/next/assets/verse-icons-vSkflmRB.js.map +1 -0
  472. package/dist/core/web/public/next/assets/warmup-D9MjYs5S.js +3 -0
  473. package/dist/core/web/public/next/assets/warmup-D9MjYs5S.js.map +1 -0
  474. package/dist/core/web/public/next/assets/wiki-focus-De8-E48Z.js +2 -0
  475. package/dist/core/web/public/next/assets/wiki-focus-De8-E48Z.js.map +1 -0
  476. package/dist/core/web/public/next/index.html +1 -1
  477. package/dist/release-dependency-inventory.json +1 -1
  478. package/package.json +1 -1
  479. package/dist/core/web/public/next/assets/ActionMenu-CebJFKYy.js +0 -2
  480. package/dist/core/web/public/next/assets/ActionMenu-CebJFKYy.js.map +0 -1
  481. package/dist/core/web/public/next/assets/Advanced-Dr9aVbXV.js +0 -2
  482. package/dist/core/web/public/next/assets/Advanced-Dr9aVbXV.js.map +0 -1
  483. package/dist/core/web/public/next/assets/AgentDetailScreen-DCVf81Vo.js +0 -2
  484. package/dist/core/web/public/next/assets/AgentDetailScreen-DCVf81Vo.js.map +0 -1
  485. package/dist/core/web/public/next/assets/AgentToolsSheet-C3SbvEiV.js +0 -2
  486. package/dist/core/web/public/next/assets/AgentToolsSheet-C3SbvEiV.js.map +0 -1
  487. package/dist/core/web/public/next/assets/AgentToolsStrip-CZNxj_Iv.js +0 -2
  488. package/dist/core/web/public/next/assets/AgentToolsStrip-CZNxj_Iv.js.map +0 -1
  489. package/dist/core/web/public/next/assets/AgentsScreen-zLj4gzPR.js +0 -2
  490. package/dist/core/web/public/next/assets/AgentsScreen-zLj4gzPR.js.map +0 -1
  491. package/dist/core/web/public/next/assets/AgentsSection-CIo_nRmi.js +0 -3
  492. package/dist/core/web/public/next/assets/AgentsSection-CIo_nRmi.js.map +0 -1
  493. package/dist/core/web/public/next/assets/App-CPKNuUdC.js +0 -8
  494. package/dist/core/web/public/next/assets/App-CPKNuUdC.js.map +0 -1
  495. package/dist/core/web/public/next/assets/AppsSection-D2F2CM-E.js +0 -2
  496. package/dist/core/web/public/next/assets/AppsSection-D2F2CM-E.js.map +0 -1
  497. package/dist/core/web/public/next/assets/AreaTrend-DiZu8bjc.js +0 -2
  498. package/dist/core/web/public/next/assets/AreaTrend-DiZu8bjc.js.map +0 -1
  499. package/dist/core/web/public/next/assets/AutomationsSection-B4rBNUyo.js +0 -2
  500. package/dist/core/web/public/next/assets/AutomationsSection-B4rBNUyo.js.map +0 -1
  501. package/dist/core/web/public/next/assets/AutonomyOffState-DEznxI-Q.js +0 -3
  502. package/dist/core/web/public/next/assets/AutonomyOffState-DEznxI-Q.js.map +0 -1
  503. package/dist/core/web/public/next/assets/AutonomySection-Dq5n3gs7.js +0 -2
  504. package/dist/core/web/public/next/assets/AutonomySection-Dq5n3gs7.js.map +0 -1
  505. package/dist/core/web/public/next/assets/AutonomyStatus-Uydy6-pZ.js +0 -2
  506. package/dist/core/web/public/next/assets/AutonomyStatus-Uydy6-pZ.js.map +0 -1
  507. package/dist/core/web/public/next/assets/BranchBar-BzUmUM_j.js +0 -2
  508. package/dist/core/web/public/next/assets/BranchBar-BzUmUM_j.js.map +0 -1
  509. package/dist/core/web/public/next/assets/BrowserPanel-C_VI6Awi.js +0 -7
  510. package/dist/core/web/public/next/assets/BrowserPanel-C_VI6Awi.js.map +0 -1
  511. package/dist/core/web/public/next/assets/BudgetControl-B23rNAuC.js +0 -2
  512. package/dist/core/web/public/next/assets/BudgetControl-B23rNAuC.js.map +0 -1
  513. package/dist/core/web/public/next/assets/Button-DJY_Pu5B.js +0 -2
  514. package/dist/core/web/public/next/assets/Button-DJY_Pu5B.js.map +0 -1
  515. package/dist/core/web/public/next/assets/CapacityStrip-B5Yj2PhZ.js +0 -2
  516. package/dist/core/web/public/next/assets/CapacityStrip-B5Yj2PhZ.js.map +0 -1
  517. package/dist/core/web/public/next/assets/ChangesPaneHost-LsUonc7P.js +0 -16
  518. package/dist/core/web/public/next/assets/ChangesPaneHost-LsUonc7P.js.map +0 -1
  519. package/dist/core/web/public/next/assets/ChartFrame-CakjKkPx.js +0 -2
  520. package/dist/core/web/public/next/assets/ChartFrame-CakjKkPx.js.map +0 -1
  521. package/dist/core/web/public/next/assets/ChatPanes-DgKskpXb.js +0 -2
  522. package/dist/core/web/public/next/assets/ChatPanes-DgKskpXb.js.map +0 -1
  523. package/dist/core/web/public/next/assets/ChatSection-DXpzV1NW.js +0 -3
  524. package/dist/core/web/public/next/assets/ChatSection-DXpzV1NW.js.map +0 -1
  525. package/dist/core/web/public/next/assets/ChecksPanel-BeCJVOJC.js +0 -5
  526. package/dist/core/web/public/next/assets/ChecksPanel-BeCJVOJC.js.map +0 -1
  527. package/dist/core/web/public/next/assets/CloudBudgetForm-4SWIGJLs.js +0 -2
  528. package/dist/core/web/public/next/assets/CloudBudgetForm-4SWIGJLs.js.map +0 -1
  529. package/dist/core/web/public/next/assets/CommandPalette-B4QaFGY5.js +0 -3
  530. package/dist/core/web/public/next/assets/CommandPalette-B4QaFGY5.js.map +0 -1
  531. package/dist/core/web/public/next/assets/CommandSection-8TFjYitt.js +0 -3
  532. package/dist/core/web/public/next/assets/CommandSection-8TFjYitt.js.map +0 -1
  533. package/dist/core/web/public/next/assets/CommandWorkflowForm-B2ooVjof.js +0 -9
  534. package/dist/core/web/public/next/assets/CommandWorkflowForm-B2ooVjof.js.map +0 -1
  535. package/dist/core/web/public/next/assets/CommandWorkflowPicker-C09vJiUG.js +0 -3
  536. package/dist/core/web/public/next/assets/CommandWorkflowPicker-C09vJiUG.js.map +0 -1
  537. package/dist/core/web/public/next/assets/CompareDialog-CaopnGI0.js +0 -4
  538. package/dist/core/web/public/next/assets/CompareDialog-CaopnGI0.js.map +0 -1
  539. package/dist/core/web/public/next/assets/ComputerControl-BflC6wd1.js +0 -2
  540. package/dist/core/web/public/next/assets/ComputerControl-BflC6wd1.js.map +0 -1
  541. package/dist/core/web/public/next/assets/ConfirmDialog-CTeMFavv.js +0 -2
  542. package/dist/core/web/public/next/assets/ConfirmDialog-CTeMFavv.js.map +0 -1
  543. package/dist/core/web/public/next/assets/DeleteChatDialog-B2bUTuZ9.js +0 -2
  544. package/dist/core/web/public/next/assets/DeleteChatDialog-B2bUTuZ9.js.map +0 -1
  545. package/dist/core/web/public/next/assets/DevinStopDialog-DPP34cna.js +0 -2
  546. package/dist/core/web/public/next/assets/DevinStopDialog-DPP34cna.js.map +0 -1
  547. package/dist/core/web/public/next/assets/Dialog-r4j4R4b6.js +0 -2
  548. package/dist/core/web/public/next/assets/Dialog-r4j4R4b6.js.map +0 -1
  549. package/dist/core/web/public/next/assets/DiffPane-CKnpzqaU.js +0 -2
  550. package/dist/core/web/public/next/assets/DiffPane-CKnpzqaU.js.map +0 -1
  551. package/dist/core/web/public/next/assets/DiffViewer-BzQ7245p.js +0 -2
  552. package/dist/core/web/public/next/assets/DiffViewer-BzQ7245p.js.map +0 -1
  553. package/dist/core/web/public/next/assets/DockHost-BCZtC_lm.js +0 -2
  554. package/dist/core/web/public/next/assets/DockHost-BCZtC_lm.js.map +0 -1
  555. package/dist/core/web/public/next/assets/EmptyState-Cwpga8L9.js +0 -2
  556. package/dist/core/web/public/next/assets/EmptyState-Cwpga8L9.js.map +0 -1
  557. package/dist/core/web/public/next/assets/Epistemic-BBwXv-C1.js +0 -2
  558. package/dist/core/web/public/next/assets/Epistemic-BBwXv-C1.js.map +0 -1
  559. package/dist/core/web/public/next/assets/EvidenceTimeline-hAENJQCa.js +0 -2
  560. package/dist/core/web/public/next/assets/EvidenceTimeline-hAENJQCa.js.map +0 -1
  561. package/dist/core/web/public/next/assets/FilesPane-CrPN5zlx.js +0 -2
  562. package/dist/core/web/public/next/assets/FilesPane-CrPN5zlx.js.map +0 -1
  563. package/dist/core/web/public/next/assets/FleetScreen-Cz9HQ-st.js +0 -2
  564. package/dist/core/web/public/next/assets/FleetScreen-Cz9HQ-st.js.map +0 -1
  565. package/dist/core/web/public/next/assets/FleetSection-CmZKQ1rr.js +0 -5
  566. package/dist/core/web/public/next/assets/FleetSection-CmZKQ1rr.js.map +0 -1
  567. package/dist/core/web/public/next/assets/Funnel-Cfg55EZp.js +0 -2
  568. package/dist/core/web/public/next/assets/Funnel-Cfg55EZp.js.map +0 -1
  569. package/dist/core/web/public/next/assets/GearTray-D-Mhc8TJ.js +0 -2
  570. package/dist/core/web/public/next/assets/GearTray-D-Mhc8TJ.js.map +0 -1
  571. package/dist/core/web/public/next/assets/GitDialogs-e-7RQEGv.js +0 -2
  572. package/dist/core/web/public/next/assets/GitDialogs-e-7RQEGv.js.map +0 -1
  573. package/dist/core/web/public/next/assets/GrowthSection-DsIrdTDd.js +0 -3
  574. package/dist/core/web/public/next/assets/GrowthSection-DsIrdTDd.js.map +0 -1
  575. package/dist/core/web/public/next/assets/HandoffDialog-1MB2fmT1.js +0 -2
  576. package/dist/core/web/public/next/assets/HandoffDialog-1MB2fmT1.js.map +0 -1
  577. package/dist/core/web/public/next/assets/HomeBody-n_t3A58_.js +0 -3
  578. package/dist/core/web/public/next/assets/HomeBody-n_t3A58_.js.map +0 -1
  579. package/dist/core/web/public/next/assets/HomeSeats-DA66aOWC.js +0 -2
  580. package/dist/core/web/public/next/assets/HomeSeats-DA66aOWC.js.map +0 -1
  581. package/dist/core/web/public/next/assets/Input-Bt6fp051.js +0 -2
  582. package/dist/core/web/public/next/assets/Input-Bt6fp051.js.map +0 -1
  583. package/dist/core/web/public/next/assets/LaunchDialog-BCd7XqCv.js +0 -9
  584. package/dist/core/web/public/next/assets/LaunchDialog-BCd7XqCv.js.map +0 -1
  585. package/dist/core/web/public/next/assets/LeaderCard-DFAFcyfZ.js +0 -2
  586. package/dist/core/web/public/next/assets/LeaderCard-DFAFcyfZ.js.map +0 -1
  587. package/dist/core/web/public/next/assets/LeaderConversation-LSenfZzT.js +0 -3
  588. package/dist/core/web/public/next/assets/LeaderConversation-LSenfZzT.js.map +0 -1
  589. package/dist/core/web/public/next/assets/LeaderScreen-B2UxRWUm.js +0 -2
  590. package/dist/core/web/public/next/assets/LeaderScreen-B2UxRWUm.js.map +0 -1
  591. package/dist/core/web/public/next/assets/LessonsPanel-D86ZT0we.js +0 -2
  592. package/dist/core/web/public/next/assets/LessonsPanel-D86ZT0we.js.map +0 -1
  593. package/dist/core/web/public/next/assets/LiveTimer-AtG5hPwV.js +0 -2
  594. package/dist/core/web/public/next/assets/LiveTimer-AtG5hPwV.js.map +0 -1
  595. package/dist/core/web/public/next/assets/LocalSeatBadge-XfGRZCA3.js +0 -2
  596. package/dist/core/web/public/next/assets/LocalSeatBadge-XfGRZCA3.js.map +0 -1
  597. package/dist/core/web/public/next/assets/MatrixHeatmap-PSnyMJ2h.js +0 -2
  598. package/dist/core/web/public/next/assets/MatrixHeatmap-PSnyMJ2h.js.map +0 -1
  599. package/dist/core/web/public/next/assets/McpSection-BG2FSkgH.js +0 -2
  600. package/dist/core/web/public/next/assets/McpSection-BG2FSkgH.js.map +0 -1
  601. package/dist/core/web/public/next/assets/MessageMarkdown-CQEqoMvf.js +0 -3
  602. package/dist/core/web/public/next/assets/MessageMarkdown-CQEqoMvf.js.map +0 -1
  603. package/dist/core/web/public/next/assets/MessageMarkdownRenderer-DU-VLDhb.js +0 -72
  604. package/dist/core/web/public/next/assets/MessageMarkdownRenderer-DU-VLDhb.js.map +0 -1
  605. package/dist/core/web/public/next/assets/Meter-BfaE-BjY.js +0 -2
  606. package/dist/core/web/public/next/assets/Meter-BfaE-BjY.js.map +0 -1
  607. package/dist/core/web/public/next/assets/MicButton-BbGB7y_9.js +0 -2
  608. package/dist/core/web/public/next/assets/MicButton-BbGB7y_9.js.map +0 -1
  609. package/dist/core/web/public/next/assets/MindSection-CX0VaHo1.js +0 -3
  610. package/dist/core/web/public/next/assets/MindSection-CX0VaHo1.js.map +0 -1
  611. package/dist/core/web/public/next/assets/MobileComposer-CFeLWUCz.js +0 -2
  612. package/dist/core/web/public/next/assets/MobileComposer-CFeLWUCz.js.map +0 -1
  613. package/dist/core/web/public/next/assets/MobileGuardSheet-cGW9RCTr.js +0 -2
  614. package/dist/core/web/public/next/assets/MobileGuardSheet-cGW9RCTr.js.map +0 -1
  615. package/dist/core/web/public/next/assets/MobileRuntime-BWTZ_QLr.js +0 -3
  616. package/dist/core/web/public/next/assets/MobileRuntime-BWTZ_QLr.js.map +0 -1
  617. package/dist/core/web/public/next/assets/MoreScreen-BcHZhVrR.js +0 -2
  618. package/dist/core/web/public/next/assets/MoreScreen-BcHZhVrR.js.map +0 -1
  619. package/dist/core/web/public/next/assets/MultiModelBar-COxIRv7m.js +0 -7
  620. package/dist/core/web/public/next/assets/MultiModelBar-COxIRv7m.js.map +0 -1
  621. package/dist/core/web/public/next/assets/MutationTokenDialog-Dnf_rcnc.js +0 -2
  622. package/dist/core/web/public/next/assets/MutationTokenDialog-Dnf_rcnc.js.map +0 -1
  623. package/dist/core/web/public/next/assets/NeedsYouDrawer-COrUlnd0.js +0 -3
  624. package/dist/core/web/public/next/assets/NeedsYouDrawer-COrUlnd0.js.map +0 -1
  625. package/dist/core/web/public/next/assets/NeedsYouList-AXzOe4EL.js +0 -2
  626. package/dist/core/web/public/next/assets/NeedsYouList-AXzOe4EL.js.map +0 -1
  627. package/dist/core/web/public/next/assets/NeedsYouScreen-HSXybHgd.js +0 -2
  628. package/dist/core/web/public/next/assets/NeedsYouScreen-HSXybHgd.js.map +0 -1
  629. package/dist/core/web/public/next/assets/NewAgentScreen-BI849ZsG.js +0 -2
  630. package/dist/core/web/public/next/assets/NewAgentScreen-BI849ZsG.js.map +0 -1
  631. package/dist/core/web/public/next/assets/NewChatDialog-BHoCnP6Q.js +0 -4
  632. package/dist/core/web/public/next/assets/NewChatDialog-BHoCnP6Q.js.map +0 -1
  633. package/dist/core/web/public/next/assets/OnboardingFlow-BVljU2uy.js +0 -3
  634. package/dist/core/web/public/next/assets/OnboardingFlow-BVljU2uy.js.map +0 -1
  635. package/dist/core/web/public/next/assets/OnboardingGate-DlI4L7Ki.js +0 -3
  636. package/dist/core/web/public/next/assets/OnboardingGate-DlI4L7Ki.js.map +0 -1
  637. package/dist/core/web/public/next/assets/PlaybooksSection-hhNpXnsR.js +0 -9
  638. package/dist/core/web/public/next/assets/PlaybooksSection-hhNpXnsR.js.map +0 -1
  639. package/dist/core/web/public/next/assets/PreviewPane-BbXr63u2.js +0 -2
  640. package/dist/core/web/public/next/assets/PreviewPane-BbXr63u2.js.map +0 -1
  641. package/dist/core/web/public/next/assets/ProviderLogo-BliSWEMw.js +0 -2
  642. package/dist/core/web/public/next/assets/ProviderLogo-BliSWEMw.js.map +0 -1
  643. package/dist/core/web/public/next/assets/RailStatus-SnrVxLnp.js +0 -2
  644. package/dist/core/web/public/next/assets/RailStatus-SnrVxLnp.js.map +0 -1
  645. package/dist/core/web/public/next/assets/ReasoningPane-C04_bOAi.js +0 -2
  646. package/dist/core/web/public/next/assets/ReasoningPane-C04_bOAi.js.map +0 -1
  647. package/dist/core/web/public/next/assets/ReasoningSheet-BvNFwtuX.js +0 -2
  648. package/dist/core/web/public/next/assets/ReasoningSheet-BvNFwtuX.js.map +0 -1
  649. package/dist/core/web/public/next/assets/RefreshIndicator-BNptNJiV.js +0 -2
  650. package/dist/core/web/public/next/assets/RefreshIndicator-BNptNJiV.js.map +0 -1
  651. package/dist/core/web/public/next/assets/RemoteMobileApp-osaSEvnm.js +0 -2
  652. package/dist/core/web/public/next/assets/RemoteMobileApp-osaSEvnm.js.map +0 -1
  653. package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-LO31zjUR.js +0 -7
  654. package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-LO31zjUR.js.map +0 -1
  655. package/dist/core/web/public/next/assets/ResourcesChrome-ByZE532G.js +0 -3
  656. package/dist/core/web/public/next/assets/ResourcesChrome-ByZE532G.js.map +0 -1
  657. package/dist/core/web/public/next/assets/ResourcesChrome-p_VCkMZH.css +0 -1
  658. package/dist/core/web/public/next/assets/ResourcesDrawer-BH9uwNE8.js +0 -3
  659. package/dist/core/web/public/next/assets/ResourcesDrawer-BH9uwNE8.js.map +0 -1
  660. package/dist/core/web/public/next/assets/ReviewMenu-B2A_YDPi.js +0 -2
  661. package/dist/core/web/public/next/assets/ReviewMenu-B2A_YDPi.js.map +0 -1
  662. package/dist/core/web/public/next/assets/RouteErrorBoundary-CVabFM97.js +0 -2
  663. package/dist/core/web/public/next/assets/RouteErrorBoundary-CVabFM97.js.map +0 -1
  664. package/dist/core/web/public/next/assets/RunInCloudAction-BpNHE7m8.js +0 -2
  665. package/dist/core/web/public/next/assets/RunInCloudAction-BpNHE7m8.js.map +0 -1
  666. package/dist/core/web/public/next/assets/RunInDevinAction-Bkf5Gb3a.js +0 -2
  667. package/dist/core/web/public/next/assets/RunInDevinAction-Bkf5Gb3a.js.map +0 -1
  668. package/dist/core/web/public/next/assets/SchedulingEvidence-B08-qhhm.js +0 -2
  669. package/dist/core/web/public/next/assets/SchedulingEvidence-B08-qhhm.js.map +0 -1
  670. package/dist/core/web/public/next/assets/ScreenHost-BGSxFyWK.js +0 -3
  671. package/dist/core/web/public/next/assets/ScreenHost-BGSxFyWK.js.map +0 -1
  672. package/dist/core/web/public/next/assets/SeatSelector-B4lRZl0K.js +0 -3
  673. package/dist/core/web/public/next/assets/SeatSelector-B4lRZl0K.js.map +0 -1
  674. package/dist/core/web/public/next/assets/Segmented-Dokzywy8.js +0 -2
  675. package/dist/core/web/public/next/assets/Segmented-Dokzywy8.js.map +0 -1
  676. package/dist/core/web/public/next/assets/Select-tf4lNvWD.js +0 -2
  677. package/dist/core/web/public/next/assets/Select-tf4lNvWD.js.map +0 -1
  678. package/dist/core/web/public/next/assets/SessionGate-Bab2qO29.js +0 -2
  679. package/dist/core/web/public/next/assets/SessionGate-Bab2qO29.js.map +0 -1
  680. package/dist/core/web/public/next/assets/SessionInsightChip-C-fj8h4A.js +0 -2
  681. package/dist/core/web/public/next/assets/SessionInsightChip-C-fj8h4A.js.map +0 -1
  682. package/dist/core/web/public/next/assets/SessionSearch-CqjjwOW2.js +0 -2
  683. package/dist/core/web/public/next/assets/SessionSearch-CqjjwOW2.js.map +0 -1
  684. package/dist/core/web/public/next/assets/SettingsSection-DfOsHzl6.js +0 -2
  685. package/dist/core/web/public/next/assets/SettingsSection-DfOsHzl6.js.map +0 -1
  686. package/dist/core/web/public/next/assets/SetupChecklist-BsxCTcYY.js +0 -2
  687. package/dist/core/web/public/next/assets/SetupChecklist-BsxCTcYY.js.map +0 -1
  688. package/dist/core/web/public/next/assets/ShadowDecisions-B1ZPv7K-.js +0 -3
  689. package/dist/core/web/public/next/assets/ShadowDecisions-B1ZPv7K-.js.map +0 -1
  690. package/dist/core/web/public/next/assets/Sheet-DLlZ00Lu.js +0 -2
  691. package/dist/core/web/public/next/assets/Sheet-DLlZ00Lu.js.map +0 -1
  692. package/dist/core/web/public/next/assets/ShortcutsOverlay-CDwQdpGV.js +0 -2
  693. package/dist/core/web/public/next/assets/ShortcutsOverlay-CDwQdpGV.js.map +0 -1
  694. package/dist/core/web/public/next/assets/Sidebar-H5WNri2S.js +0 -3
  695. package/dist/core/web/public/next/assets/Sidebar-H5WNri2S.js.map +0 -1
  696. package/dist/core/web/public/next/assets/SkipToContent-BjJE6yOo.js +0 -2
  697. package/dist/core/web/public/next/assets/SkipToContent-BjJE6yOo.js.map +0 -1
  698. package/dist/core/web/public/next/assets/Slider-C68TumXj.js +0 -2
  699. package/dist/core/web/public/next/assets/Slider-C68TumXj.js.map +0 -1
  700. package/dist/core/web/public/next/assets/SourcesPane-DHYs4YIg.js +0 -2
  701. package/dist/core/web/public/next/assets/SourcesPane-DHYs4YIg.js.map +0 -1
  702. package/dist/core/web/public/next/assets/SourcesPanel-DFyLfYBO.js +0 -2
  703. package/dist/core/web/public/next/assets/SourcesPanel-DFyLfYBO.js.map +0 -1
  704. package/dist/core/web/public/next/assets/StatTile-CTUuhOLS.js +0 -2
  705. package/dist/core/web/public/next/assets/StatTile-CTUuhOLS.js.map +0 -1
  706. package/dist/core/web/public/next/assets/StatusBadge-DrVbi5dF.js +0 -2
  707. package/dist/core/web/public/next/assets/StatusBadge-DrVbi5dF.js.map +0 -1
  708. package/dist/core/web/public/next/assets/StepBand-CXDpnu2R.js +0 -2
  709. package/dist/core/web/public/next/assets/StepBand-CXDpnu2R.js.map +0 -1
  710. package/dist/core/web/public/next/assets/Surface-DCL7uORg.js +0 -2
  711. package/dist/core/web/public/next/assets/Surface-DCL7uORg.js.map +0 -1
  712. package/dist/core/web/public/next/assets/Swimlane-BAEjfoVU.js +0 -2
  713. package/dist/core/web/public/next/assets/Swimlane-BAEjfoVU.js.map +0 -1
  714. package/dist/core/web/public/next/assets/Switch-Z7RmRjWE.js +0 -2
  715. package/dist/core/web/public/next/assets/Switch-Z7RmRjWE.js.map +0 -1
  716. package/dist/core/web/public/next/assets/Tag-Ciht3C94.js +0 -2
  717. package/dist/core/web/public/next/assets/Tag-Ciht3C94.js.map +0 -1
  718. package/dist/core/web/public/next/assets/TerminalPane-BdIyhtzJ.js +0 -26
  719. package/dist/core/web/public/next/assets/TerminalPane-BdIyhtzJ.js.map +0 -1
  720. package/dist/core/web/public/next/assets/TerminalPane-DJKT600N.js +0 -3
  721. package/dist/core/web/public/next/assets/TerminalPane-DJKT600N.js.map +0 -1
  722. package/dist/core/web/public/next/assets/ThinkingBlock-CHRZX_fJ.js +0 -2
  723. package/dist/core/web/public/next/assets/ThinkingBlock-CHRZX_fJ.js.map +0 -1
  724. package/dist/core/web/public/next/assets/UniverseConsoleApp-QSoaY_Fk.js +0 -2
  725. package/dist/core/web/public/next/assets/UniverseConsoleApp-QSoaY_Fk.js.map +0 -1
  726. package/dist/core/web/public/next/assets/UniverseView-ZXAOJ0Rq.js +0 -9
  727. package/dist/core/web/public/next/assets/UniverseView-ZXAOJ0Rq.js.map +0 -1
  728. package/dist/core/web/public/next/assets/UsageSection-BEAa-W_q.js +0 -3
  729. package/dist/core/web/public/next/assets/UsageSection-BEAa-W_q.js.map +0 -1
  730. package/dist/core/web/public/next/assets/UsePlaybookAction-S7Yky_M8.js +0 -2
  731. package/dist/core/web/public/next/assets/UsePlaybookAction-S7Yky_M8.js.map +0 -1
  732. package/dist/core/web/public/next/assets/VerseConsoleApp-Cj6yPJo3.js +0 -3
  733. package/dist/core/web/public/next/assets/VerseConsoleApp-Cj6yPJo3.js.map +0 -1
  734. package/dist/core/web/public/next/assets/VerseConsoleApp-n6qr3lCF.css +0 -1
  735. package/dist/core/web/public/next/assets/VerseMobileApp-BRayqF_2.js +0 -3
  736. package/dist/core/web/public/next/assets/VerseMobileApp-BRayqF_2.js.map +0 -1
  737. package/dist/core/web/public/next/assets/VerseShared-CH8mV5ew.js +0 -2
  738. package/dist/core/web/public/next/assets/VerseShared-CH8mV5ew.js.map +0 -1
  739. package/dist/core/web/public/next/assets/VoiceHud-CO4yGRlr.js +0 -2
  740. package/dist/core/web/public/next/assets/VoiceHud-CO4yGRlr.js.map +0 -1
  741. package/dist/core/web/public/next/assets/VoiceInput-fSLnbGJ4.js +0 -2
  742. package/dist/core/web/public/next/assets/VoiceInput-fSLnbGJ4.js.map +0 -1
  743. package/dist/core/web/public/next/assets/WikiSection-CN-HansV.js +0 -2
  744. package/dist/core/web/public/next/assets/WikiSection-CN-HansV.js.map +0 -1
  745. package/dist/core/web/public/next/assets/Workspace-dufi6DmW.js +0 -6
  746. package/dist/core/web/public/next/assets/Workspace-dufi6DmW.js.map +0 -1
  747. package/dist/core/web/public/next/assets/actions-gBplqbpY.js +0 -2
  748. package/dist/core/web/public/next/assets/actions-gBplqbpY.js.map +0 -1
  749. package/dist/core/web/public/next/assets/agent-tools-client-ClFut2J1.js +0 -2
  750. package/dist/core/web/public/next/assets/agent-tools-client-ClFut2J1.js.map +0 -1
  751. package/dist/core/web/public/next/assets/agents-focus-DjBz83BQ.js +0 -2
  752. package/dist/core/web/public/next/assets/agents-focus-DjBz83BQ.js.map +0 -1
  753. package/dist/core/web/public/next/assets/app-version-B0FcXqqB.js +0 -2
  754. package/dist/core/web/public/next/assets/app-version-B0FcXqqB.js.map +0 -1
  755. package/dist/core/web/public/next/assets/apps-model-C-SdWY0N.js +0 -2
  756. package/dist/core/web/public/next/assets/apps-model-C-SdWY0N.js.map +0 -1
  757. package/dist/core/web/public/next/assets/ask-seat-DhGxiGSd.js +0 -2
  758. package/dist/core/web/public/next/assets/ask-seat-DhGxiGSd.js.map +0 -1
  759. package/dist/core/web/public/next/assets/authority-model-CoXAS-Z6.js +0 -2
  760. package/dist/core/web/public/next/assets/authority-model-CoXAS-Z6.js.map +0 -1
  761. package/dist/core/web/public/next/assets/automations-focus-CeneF7lP.js +0 -2
  762. package/dist/core/web/public/next/assets/automations-focus-CeneF7lP.js.map +0 -1
  763. package/dist/core/web/public/next/assets/budget-queries-DCZevH2S.js +0 -2
  764. package/dist/core/web/public/next/assets/budget-queries-DCZevH2S.js.map +0 -1
  765. package/dist/core/web/public/next/assets/capacity-strip-model-Wna9o0dS.js +0 -2
  766. package/dist/core/web/public/next/assets/capacity-strip-model-Wna9o0dS.js.map +0 -1
  767. package/dist/core/web/public/next/assets/charts-CzqC55eL.js +0 -2
  768. package/dist/core/web/public/next/assets/charts-CzqC55eL.js.map +0 -1
  769. package/dist/core/web/public/next/assets/chat-pane-data-BBA55Pw-.js +0 -2
  770. package/dist/core/web/public/next/assets/chat-pane-data-BBA55Pw-.js.map +0 -1
  771. package/dist/core/web/public/next/assets/checkpoint-queries-gP6Vh70H.js +0 -2
  772. package/dist/core/web/public/next/assets/checkpoint-queries-gP6Vh70H.js.map +0 -1
  773. package/dist/core/web/public/next/assets/cloud-queries-Bsqo7wye.js +0 -2
  774. package/dist/core/web/public/next/assets/cloud-queries-Bsqo7wye.js.map +0 -1
  775. package/dist/core/web/public/next/assets/command-catalog-Dnx-iMLX.js +0 -2
  776. package/dist/core/web/public/next/assets/command-catalog-Dnx-iMLX.js.map +0 -1
  777. package/dist/core/web/public/next/assets/composer-queries-DHGJlnFJ.js +0 -2
  778. package/dist/core/web/public/next/assets/composer-queries-DHGJlnFJ.js.map +0 -1
  779. package/dist/core/web/public/next/assets/connectivity-BViMMNcD.js +0 -2
  780. package/dist/core/web/public/next/assets/connectivity-BViMMNcD.js.map +0 -1
  781. package/dist/core/web/public/next/assets/context-queries-Bsl-w0q-.js +0 -2
  782. package/dist/core/web/public/next/assets/context-queries-Bsl-w0q-.js.map +0 -1
  783. package/dist/core/web/public/next/assets/control-queries-CUNa6TAx.js +0 -2
  784. package/dist/core/web/public/next/assets/control-queries-CUNa6TAx.js.map +0 -1
  785. package/dist/core/web/public/next/assets/copy-setup-C2goNcTZ.js +0 -2
  786. package/dist/core/web/public/next/assets/copy-setup-C2goNcTZ.js.map +0 -1
  787. package/dist/core/web/public/next/assets/deep-link-Dg_zaqAl.js +0 -2
  788. package/dist/core/web/public/next/assets/deep-link-Dg_zaqAl.js.map +0 -1
  789. package/dist/core/web/public/next/assets/device-permissions-CEXY0Vor.js +0 -2
  790. package/dist/core/web/public/next/assets/device-permissions-CEXY0Vor.js.map +0 -1
  791. package/dist/core/web/public/next/assets/devin-queries-Cu_YYhw2.js +0 -2
  792. package/dist/core/web/public/next/assets/devin-queries-Cu_YYhw2.js.map +0 -1
  793. package/dist/core/web/public/next/assets/dock-icons-DGZoDN6N.js +0 -2
  794. package/dist/core/web/public/next/assets/dock-icons-DGZoDN6N.js.map +0 -1
  795. package/dist/core/web/public/next/assets/dock-panes-BgSO9q_f.js +0 -2
  796. package/dist/core/web/public/next/assets/dock-panes-BgSO9q_f.js.map +0 -1
  797. package/dist/core/web/public/next/assets/fleet-control-queries-clsJWanE.js +0 -2
  798. package/dist/core/web/public/next/assets/fleet-control-queries-clsJWanE.js.map +0 -1
  799. package/dist/core/web/public/next/assets/fleet-queries-DX1AwHEt.js +0 -2
  800. package/dist/core/web/public/next/assets/fleet-queries-DX1AwHEt.js.map +0 -1
  801. package/dist/core/web/public/next/assets/fleet-state-EgNiSDxu.js +0 -3
  802. package/dist/core/web/public/next/assets/fleet-state-EgNiSDxu.js.map +0 -1
  803. package/dist/core/web/public/next/assets/focus-trap-B1vuEhZX.js +0 -2
  804. package/dist/core/web/public/next/assets/focus-trap-B1vuEhZX.js.map +0 -1
  805. package/dist/core/web/public/next/assets/git-model-Bu59fz1m.js +0 -5
  806. package/dist/core/web/public/next/assets/git-model-Bu59fz1m.js.map +0 -1
  807. package/dist/core/web/public/next/assets/global-BJ_kVFpD.js +0 -3
  808. package/dist/core/web/public/next/assets/global-BJ_kVFpD.js.map +0 -1
  809. package/dist/core/web/public/next/assets/guarded-action-CzvG7Qgc.js +0 -3
  810. package/dist/core/web/public/next/assets/guarded-action-CzvG7Qgc.js.map +0 -1
  811. package/dist/core/web/public/next/assets/guarded-runners-BPM0KdoQ.js +0 -2
  812. package/dist/core/web/public/next/assets/guarded-runners-BPM0KdoQ.js.map +0 -1
  813. package/dist/core/web/public/next/assets/health-queries-CMxSsJKS.js +0 -2
  814. package/dist/core/web/public/next/assets/health-queries-CMxSsJKS.js.map +0 -1
  815. package/dist/core/web/public/next/assets/icons-MYfI6vZr.js +0 -2
  816. package/dist/core/web/public/next/assets/icons-MYfI6vZr.js.map +0 -1
  817. package/dist/core/web/public/next/assets/index-DOAOxiKl.js +0 -11
  818. package/dist/core/web/public/next/assets/index-DOAOxiKl.js.map +0 -1
  819. package/dist/core/web/public/next/assets/jev-queries-CS2A5uWe.js +0 -2
  820. package/dist/core/web/public/next/assets/jev-queries-CS2A5uWe.js.map +0 -1
  821. package/dist/core/web/public/next/assets/ladder-queries-CBoG3heV.js +0 -2
  822. package/dist/core/web/public/next/assets/ladder-queries-CBoG3heV.js.map +0 -1
  823. package/dist/core/web/public/next/assets/leader-focus-DDQlv0TB.js +0 -2
  824. package/dist/core/web/public/next/assets/leader-focus-DDQlv0TB.js.map +0 -1
  825. package/dist/core/web/public/next/assets/live-model-CCjYFk48.js +0 -2
  826. package/dist/core/web/public/next/assets/live-model-CCjYFk48.js.map +0 -1
  827. package/dist/core/web/public/next/assets/mobile-actions-XqB_h7a8.js +0 -2
  828. package/dist/core/web/public/next/assets/mobile-actions-XqB_h7a8.js.map +0 -1
  829. package/dist/core/web/public/next/assets/mobile-toast-eIrghd9o.js +0 -2
  830. package/dist/core/web/public/next/assets/mobile-toast-eIrghd9o.js.map +0 -1
  831. package/dist/core/web/public/next/assets/multimodel-flows-CzI-yHg5.js +0 -7
  832. package/dist/core/web/public/next/assets/multimodel-flows-CzI-yHg5.js.map +0 -1
  833. package/dist/core/web/public/next/assets/multimodel-queries-DxIT9AZY.js +0 -2
  834. package/dist/core/web/public/next/assets/multimodel-queries-DxIT9AZY.js.map +0 -1
  835. package/dist/core/web/public/next/assets/mutations-BlGALvmG.js +0 -2
  836. package/dist/core/web/public/next/assets/mutations-BlGALvmG.js.map +0 -1
  837. package/dist/core/web/public/next/assets/nav-ByibvQW1.js +0 -2
  838. package/dist/core/web/public/next/assets/nav-ByibvQW1.js.map +0 -1
  839. package/dist/core/web/public/next/assets/needs-you-actions-Dp5UxM3X.js +0 -2
  840. package/dist/core/web/public/next/assets/needs-you-actions-Dp5UxM3X.js.map +0 -1
  841. package/dist/core/web/public/next/assets/needs-you-model-DYsqHMqy.js +0 -2
  842. package/dist/core/web/public/next/assets/needs-you-model-DYsqHMqy.js.map +0 -1
  843. package/dist/core/web/public/next/assets/open-terminal-dOVyLFvn.js +0 -2
  844. package/dist/core/web/public/next/assets/open-terminal-dOVyLFvn.js.map +0 -1
  845. package/dist/core/web/public/next/assets/open-terminal-request-BIhvirIl.js +0 -2
  846. package/dist/core/web/public/next/assets/open-terminal-request-BIhvirIl.js.map +0 -1
  847. package/dist/core/web/public/next/assets/overnight-queries-KxqH6BRN.js +0 -2
  848. package/dist/core/web/public/next/assets/overnight-queries-KxqH6BRN.js.map +0 -1
  849. package/dist/core/web/public/next/assets/palette-handoff-69pw9oBv.js +0 -2
  850. package/dist/core/web/public/next/assets/palette-handoff-69pw9oBv.js.map +0 -1
  851. package/dist/core/web/public/next/assets/panes-CHt3427X.js +0 -3
  852. package/dist/core/web/public/next/assets/panes-CHt3427X.js.map +0 -1
  853. package/dist/core/web/public/next/assets/path-display-DuIZF5G3.js +0 -2
  854. package/dist/core/web/public/next/assets/path-display-DuIZF5G3.js.map +0 -1
  855. package/dist/core/web/public/next/assets/playbook-composer-DipWgX7t.js +0 -2
  856. package/dist/core/web/public/next/assets/playbook-composer-DipWgX7t.js.map +0 -1
  857. package/dist/core/web/public/next/assets/playbook-focus-EXJPMBBI.js +0 -2
  858. package/dist/core/web/public/next/assets/playbook-focus-EXJPMBBI.js.map +0 -1
  859. package/dist/core/web/public/next/assets/playbooks-queries-BlpGBpOV.js +0 -2
  860. package/dist/core/web/public/next/assets/playbooks-queries-BlpGBpOV.js.map +0 -1
  861. package/dist/core/web/public/next/assets/preloaded-TmpzuCEi.js +0 -2
  862. package/dist/core/web/public/next/assets/preloaded-TmpzuCEi.js.map +0 -1
  863. package/dist/core/web/public/next/assets/primitives-CDKCUR2v.js +0 -1
  864. package/dist/core/web/public/next/assets/pwa-CTGMm-wR.js +0 -2
  865. package/dist/core/web/public/next/assets/pwa-CTGMm-wR.js.map +0 -1
  866. package/dist/core/web/public/next/assets/queries--mGK10fL.js +0 -2
  867. package/dist/core/web/public/next/assets/queries--mGK10fL.js.map +0 -1
  868. package/dist/core/web/public/next/assets/reasoning-pref-CWGL9MD2.js +0 -2
  869. package/dist/core/web/public/next/assets/reasoning-pref-CWGL9MD2.js.map +0 -1
  870. package/dist/core/web/public/next/assets/remote-session-I4RXlsas.js +0 -3
  871. package/dist/core/web/public/next/assets/remote-session-I4RXlsas.js.map +0 -1
  872. package/dist/core/web/public/next/assets/resolved-store-DwGn9hb_.js +0 -2
  873. package/dist/core/web/public/next/assets/resolved-store-DwGn9hb_.js.map +0 -1
  874. package/dist/core/web/public/next/assets/resources-queries-T6ER_hPN.js +0 -2
  875. package/dist/core/web/public/next/assets/resources-queries-T6ER_hPN.js.map +0 -1
  876. package/dist/core/web/public/next/assets/reveal-anchor-CHtvhrYm.js +0 -2
  877. package/dist/core/web/public/next/assets/reveal-anchor-CHtvhrYm.js.map +0 -1
  878. package/dist/core/web/public/next/assets/sheet-BlzGO1wo.js +0 -2
  879. package/dist/core/web/public/next/assets/sheet-BlzGO1wo.js.map +0 -1
  880. package/dist/core/web/public/next/assets/slots-40edgV7X.js +0 -3
  881. package/dist/core/web/public/next/assets/slots-40edgV7X.js.map +0 -1
  882. package/dist/core/web/public/next/assets/sources-queries-BrM41X16.js +0 -4
  883. package/dist/core/web/public/next/assets/sources-queries-BrM41X16.js.map +0 -1
  884. package/dist/core/web/public/next/assets/sse-CAFwslNC.js +0 -2
  885. package/dist/core/web/public/next/assets/sse-CAFwslNC.js.map +0 -1
  886. package/dist/core/web/public/next/assets/surface-data-D_oFOgkh.js +0 -2
  887. package/dist/core/web/public/next/assets/surface-data-D_oFOgkh.js.map +0 -1
  888. package/dist/core/web/public/next/assets/surface-prefetch-wqfiATYQ.js +0 -2
  889. package/dist/core/web/public/next/assets/surface-prefetch-wqfiATYQ.js.map +0 -1
  890. package/dist/core/web/public/next/assets/terminal-client-iL4DagCN.js +0 -2
  891. package/dist/core/web/public/next/assets/terminal-client-iL4DagCN.js.map +0 -1
  892. package/dist/core/web/public/next/assets/terminal-icons-BakeOpKV.js +0 -2
  893. package/dist/core/web/public/next/assets/terminal-icons-BakeOpKV.js.map +0 -1
  894. package/dist/core/web/public/next/assets/terminal-view-D6AAh08q.js +0 -6
  895. package/dist/core/web/public/next/assets/terminal-view-D6AAh08q.js.map +0 -1
  896. package/dist/core/web/public/next/assets/thread-data-CSDZ514s.js +0 -2
  897. package/dist/core/web/public/next/assets/thread-data-CSDZ514s.js.map +0 -1
  898. package/dist/core/web/public/next/assets/ui-parts-DubQJIoq.js +0 -2
  899. package/dist/core/web/public/next/assets/ui-parts-DubQJIoq.js.map +0 -1
  900. package/dist/core/web/public/next/assets/usage-queries-BONqdout.js +0 -2
  901. package/dist/core/web/public/next/assets/usage-queries-BONqdout.js.map +0 -1
  902. package/dist/core/web/public/next/assets/use-chat-activity-BZjdPPNP.js +0 -2
  903. package/dist/core/web/public/next/assets/use-chat-activity-BZjdPPNP.js.map +0 -1
  904. package/dist/core/web/public/next/assets/use-guarded-action-xJ4rxyVo.js +0 -2
  905. package/dist/core/web/public/next/assets/use-guarded-action-xJ4rxyVo.js.map +0 -1
  906. package/dist/core/web/public/next/assets/use-ticker-Bsu0cMvl.js +0 -2
  907. package/dist/core/web/public/next/assets/use-ticker-Bsu0cMvl.js.map +0 -1
  908. package/dist/core/web/public/next/assets/use-token-gate-E-xzEAu6.js +0 -2
  909. package/dist/core/web/public/next/assets/use-token-gate-E-xzEAu6.js.map +0 -1
  910. package/dist/core/web/public/next/assets/useAutoSeat-CXC9e4vx.js +0 -2
  911. package/dist/core/web/public/next/assets/useAutoSeat-CXC9e4vx.js.map +0 -1
  912. package/dist/core/web/public/next/assets/useOnboarding-Csw_AXrj.js +0 -2
  913. package/dist/core/web/public/next/assets/useOnboarding-Csw_AXrj.js.map +0 -1
  914. package/dist/core/web/public/next/assets/useSeatHealth-B6AXxre9.js +0 -2
  915. package/dist/core/web/public/next/assets/useSeatHealth-B6AXxre9.js.map +0 -1
  916. package/dist/core/web/public/next/assets/useSeatsRefresh-BIAa7Exn.js +0 -2
  917. package/dist/core/web/public/next/assets/useSeatsRefresh-BIAa7Exn.js.map +0 -1
  918. package/dist/core/web/public/next/assets/useVerseSession-BOyvOEDi.js +0 -2
  919. package/dist/core/web/public/next/assets/useVerseSession-BOyvOEDi.js.map +0 -1
  920. package/dist/core/web/public/next/assets/useVerseTranscript-BOhcfdp7.js +0 -2
  921. package/dist/core/web/public/next/assets/useVerseTranscript-BOhcfdp7.js.map +0 -1
  922. package/dist/core/web/public/next/assets/verse-bootstrap-query-D-fU89IT.js +0 -2
  923. package/dist/core/web/public/next/assets/verse-bootstrap-query-D-fU89IT.js.map +0 -1
  924. package/dist/core/web/public/next/assets/verse-icons-UKbUG3gv.js +0 -2
  925. package/dist/core/web/public/next/assets/verse-icons-UKbUG3gv.js.map +0 -1
  926. package/dist/core/web/public/next/assets/warmup-CZ-IBU5L.js +0 -3
  927. package/dist/core/web/public/next/assets/warmup-CZ-IBU5L.js.map +0 -1
  928. package/dist/core/web/public/next/assets/wiki-focus-DhAvbMnX.js +0 -2
  929. package/dist/core/web/public/next/assets/wiki-focus-DhAvbMnX.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"mappings":"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","names":[],"ignoreList":[],"sources":["../../../../../../src/web-ui/routes/verse/terminal/panel-stream.ts","../../../../../../src/web-ui/routes/verse/terminal/ansi-spans.ts","../../../../../../src/web-ui/routes/verse/terminal/blocks-model.ts","../../../../../../src/web-ui/routes/verse/terminal/block-tools.ts","../../../../../../src/web-ui/routes/verse/terminal/extra-glyphs.tsx","../../../../../../src/web-ui/routes/verse/terminal/FixChips.tsx","../../../../../../src/web-ui/routes/verse/terminal/BlockList.tsx","../../../../../../src/web-ui/routes/verse/terminal/AgentTerminal.tsx","../../../../../../src/web-ui/routes/verse/terminal/layout-model.ts","../../../../../../src/web-ui/routes/verse/terminal/assist-disclosure.ts","../../../../../../src/web-ui/routes/verse/terminal/input-model.ts","../../../../../../src/web-ui/routes/verse/terminal/CommandInput.tsx","../../../../../../src/web-ui/routes/verse/terminal/HistoryPalette.tsx","../../../../../../src/web-ui/routes/verse/terminal/input-editor.ts","../../../../../../src/web-ui/routes/verse/terminal/panel-client.ts","../../../../../../src/web-ui/routes/verse/terminal/panel-keys.ts","../../../../../../src/web-ui/routes/verse/terminal/file-links.ts","../../../../../../src/web-ui/routes/verse/terminal/ligatures.ts","../../../../../../src/web-ui/routes/verse/terminal/xterm-view.ts","../../../../../../src/web-ui/routes/verse/terminal/TerminalLeaf.tsx","../../../../../../src/web-ui/routes/verse/terminal/TerminalPanel.tsx","../../../../../../src/web-ui/routes/verse/terminal/TerminalPane.tsx"],"sourcesContent":["/**\n * terminal/panel-stream.ts — the 3.15 panel's live frames.\n *\n * ONE CONNECTION FOR EVERY PANE. A browser allows about six connections per\n * origin and Verse already holds two (app events, the open chat), so a\n * stream per pane capped the panel at two panes. `createTerminalStreamMux`\n * keeps a single fetch() to `GET /api/verse/terminal/stream?tabs=id:seq,…`\n * whose frames are tagged with their tab, and hands each pane its own:\n *\n * - subscribe/unsubscribe are batched (a group switch is many of each in\n * one React commit) into ONE reconnect with the new set; every tab\n * resumes past its own last seq, so nothing is lost or drawn twice;\n * - a drop reconnects with backoff, a 401 renews the read session once,\n * a `gone` frame ends that one tab's subscription;\n * - a server without the multiplexed route (404 / 400: an older sidecar)\n * falls back to the per-tab stream below, pane by pane.\n *\n * The per-tab stream is the dock's 3.10 connection — fetch() with the\n * read-client header (not EventSource: the read boundary accepts the client\n * proof as a query parameter only on the EventSource paths it knows), resume\n * with `?after=<last seq>` — with a parser that also reads the shell\n * integration's frames (`block`, `cwd`, `integration`).\n */\nimport type { VerseTerminalBlock, VerseTerminalShellIntegration, VerseTerminalStreamFrame } from '../../../data/api-types.js';\nimport { VERSE_TERMINAL_STREAM_PATH } from '../../../../core/verse/workbench-types.js';\nimport { getReadClientProof, renewReadSession } from '../../../data/auth-store.js';\nimport { terminalStreamPath } from '../dock/terminal/terminal-client.js';\nimport { parseTerminalSseBlock, type TerminalStreamDeps, type TerminalStreamHandlers as BaseHandlers, type TerminalStreamState } from '../dock/terminal/terminal-stream.js';\n\nexport type { TerminalStreamState };\n\nexport interface PanelStreamHandlers {\n onFrame: (frame: VerseTerminalStreamFrame) => void;\n onState?: BaseHandlers['onState'];\n}\n\nexport interface PanelStream {\n close(): void;\n}\n\nexport type PanelStreamOpener = (tabId: string, after: () => number, handlers: PanelStreamHandlers, deps?: TerminalStreamDeps) => PanelStream;\n\nconst INTEGRATION_STATES: readonly VerseTerminalShellIntegration[] = ['active', 'injected', 'off'];\n\nfunction isBlock(value: unknown): value is VerseTerminalBlock {\n const b = value as VerseTerminalBlock | null;\n return !!b && typeof b === 'object'\n && typeof b.id === 'string' && /^b-\\d+$/.test(b.id)\n && typeof b.command === 'string'\n && (b.state === 'running' || b.state === 'done')\n && typeof b.startSeq === 'number' && typeof b.ordinal === 'number'\n && typeof b.startedAt === 'string';\n}\n\nfunction sseData(block: string): string {\n let data = '';\n for (const line of block.split('\\n')) {\n if (line.startsWith('data:')) data += line.slice(line.startsWith('data: ') ? 6 : 5);\n }\n return data;\n}\n\n/** Parse one SSE block into a frame (3.10 frames and the 3.15 ones); null for comments and junk. */\nexport function parsePanelSseBlock(block: string): VerseTerminalStreamFrame | null {\n const base = parseTerminalSseBlock(block);\n if (base) return base;\n const data = sseData(block);\n if (!data) return null;\n let parsed: unknown;\n try {\n parsed = JSON.parse(data);\n } catch {\n return null;\n }\n return shellFrameFromObject(parsed);\n}\n\n/** The 3.15-only frames (block, cwd, integration) from a parsed object. */\nfunction shellFrameFromObject(parsed: unknown): VerseTerminalStreamFrame | null {\n const frame = parsed as Record<string, unknown> | null;\n if (!frame || typeof frame !== 'object') return null;\n if (frame['type'] === 'block' && isBlock(frame['block'])) return { type: 'block', block: frame['block'] };\n if (frame['type'] === 'cwd' && typeof frame['cwd'] === 'string') return { type: 'cwd', cwd: frame['cwd'] };\n if (frame['type'] === 'integration' && INTEGRATION_STATES.includes(frame['state'] as VerseTerminalShellIntegration)) {\n return { type: 'integration', state: frame['state'] as VerseTerminalShellIntegration };\n }\n return null;\n}\n\nfunction defaultBackoff(attempt: number): number {\n return Math.min(250 * 2 ** attempt, 8_000);\n}\n\nexport const openPanelStream: PanelStreamOpener = (tabId, after, handlers, deps = {}) => {\n const doFetch = deps.fetch ?? ((input: RequestInfo | URL, init?: RequestInit) => fetch(input, init));\n const renew = deps.renew ?? renewReadSession;\n const proof = deps.proof ?? getReadClientProof;\n const backoff = deps.backoffMs ?? defaultBackoff;\n let closed = false;\n let controller: AbortController | null = null;\n let timer: ReturnType<typeof setTimeout> | null = null;\n let attempt = 0;\n let renewedOnce = false;\n\n const setState = (state: TerminalStreamState): void => {\n if (!closed || state === 'closed') handlers.onState?.(state);\n };\n\n const schedule = (): void => {\n if (closed) return;\n setState('reconnecting');\n timer = setTimeout(() => {\n timer = null;\n void connect();\n }, backoff(attempt++));\n };\n\n async function connect(): Promise<void> {\n if (closed) return;\n controller = new AbortController();\n let res: Response;\n try {\n res = await doFetch(terminalStreamPath(tabId, after()), {\n method: 'GET',\n credentials: 'same-origin',\n headers: { 'x-ashlr-read-client': proof(), Accept: 'text/event-stream' },\n signal: controller.signal,\n cache: 'no-store',\n });\n } catch {\n schedule();\n return;\n }\n if (closed) return;\n if (res.status === 404) {\n setState('gone');\n closed = true;\n return;\n }\n if (res.status === 401) {\n if (!renewedOnce && (await renew().catch(() => false))) {\n renewedOnce = true;\n void connect();\n return;\n }\n setState('expired');\n closed = true;\n return;\n }\n if (!res.ok || !res.body) {\n schedule();\n return;\n }\n renewedOnce = false;\n setState('open');\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n try {\n for (;;) {\n const { value, done } = await reader.read();\n if (done) break;\n attempt = 0;\n buffer += decoder.decode(value, { stream: true });\n let idx: number;\n while ((idx = buffer.indexOf('\\n\\n')) !== -1) {\n const block = buffer.slice(0, idx);\n buffer = buffer.slice(idx + 2);\n const frame = parsePanelSseBlock(block);\n if (frame && !closed) handlers.onFrame(frame);\n }\n }\n } catch {\n /* aborted, or the connection dropped: reconnect below unless closed */\n }\n schedule();\n }\n\n setState('connecting');\n void connect();\n\n return {\n close() {\n if (closed) return;\n closed = true;\n if (timer) clearTimeout(timer);\n controller?.abort();\n handlers.onState?.('closed');\n },\n };\n};\n\n// ===========================================================================\n// The multiplexer\n// ===========================================================================\n\ntype MuxParsed = { tab: string; frame: VerseTerminalStreamFrame | { type: 'gone' } };\n\n/** One multiplexed frame: which tab, and its frame (or `gone`). Null for comments and junk. */\nexport function parseMuxSseBlock(block: string): MuxParsed | null {\n const data = sseData(block);\n if (!data) return null;\n let parsed: unknown;\n try {\n parsed = JSON.parse(data);\n } catch {\n return null;\n }\n const obj = parsed as Record<string, unknown> | null;\n if (!obj || typeof obj !== 'object' || typeof obj['tab'] !== 'string' || !/^t-[a-z0-9]{1,32}$/.test(obj['tab'])) return null;\n const tab = obj['tab'];\n if (obj['type'] === 'gone') return { tab, frame: { type: 'gone' } };\n // The 3.10 parser reads an SSE block: hand it this one's data back.\n const base = parseTerminalSseBlock(`data: ${data}`);\n if (base) return { tab, frame: base };\n const shell = shellFrameFromObject(obj);\n return shell ? { tab, frame: shell } : null;\n}\n\nexport interface TerminalStreamMux {\n /** Same contract as a per-tab stream: frames for `tabId`, resumed past `after()` on every (re)connect. */\n subscribe(tabId: string, after: () => number, handlers: PanelStreamHandlers): PanelStream;\n /** Tabs currently subscribed. */\n tabs(): string[];\n /** Stop everything. */\n close(): void;\n}\n\nexport interface TerminalStreamMuxDeps extends TerminalStreamDeps {\n /** How subscription changes are batched into one reconnect (default: a 0 ms timer). */\n batch?: (run: () => void) => void;\n /** The per-tab stream a server without the multiplexed route falls back to. */\n openSingle?: PanelStreamOpener;\n}\n\ninterface MuxSub {\n after: () => number;\n handlers: PanelStreamHandlers;\n /** The per-tab stream, in fallback mode. */\n single: PanelStream | null;\n state: TerminalStreamState | null;\n}\n\nexport function muxStreamPath(cursors: ReadonlyArray<readonly [string, number]>): string {\n const list = cursors.map(([id, seq]) => (Number.isSafeInteger(seq) && seq > 0 ? `${id}:${seq}` : id)).join(',');\n return `${VERSE_TERMINAL_STREAM_PATH}?tabs=${encodeURIComponent(list)}`;\n}\n\nexport function createTerminalStreamMux(deps: TerminalStreamMuxDeps = {}): TerminalStreamMux {\n const doFetch = deps.fetch ?? ((input: RequestInfo | URL, init?: RequestInit) => fetch(input, init));\n const renew = deps.renew ?? renewReadSession;\n const proof = deps.proof ?? getReadClientProof;\n const backoff = deps.backoffMs ?? defaultBackoff;\n const batch = deps.batch ?? ((run: () => void) => { setTimeout(run, 0); });\n const openSingle = deps.openSingle ?? ((tabId, after, handlers) => openPanelStream(tabId, after, handlers, deps));\n\n const subs = new Map<string, MuxSub>();\n let closed = false;\n /** An older server: every pane gets its own per-tab stream. */\n let fallback = false;\n let controller: AbortController | null = null;\n /** Bumped on every (re)connect: frames of an older connection are dropped. */\n let generation = 0;\n /** The set the current connection carries (sorted ids joined), or null when none is open. */\n let carrying: string | null = null;\n let retryTimer: ReturnType<typeof setTimeout> | null = null;\n let batched = false;\n let attempt = 0;\n let renewedOnce = false;\n\n const setState = (sub: MuxSub, state: TerminalStreamState): void => {\n if (sub.state === state) return;\n sub.state = state;\n try { sub.handlers.onState?.(state); } catch { /* one pane never breaks the others */ }\n };\n\n const wanted = (): string => [...subs.keys()].sort().join(',');\n\n function disconnect(): void {\n generation += 1;\n carrying = null;\n controller?.abort();\n controller = null;\n if (retryTimer) {\n clearTimeout(retryTimer);\n retryTimer = null;\n }\n }\n\n function enterFallback(): void {\n fallback = true;\n disconnect();\n for (const [id, sub] of subs) {\n if (!sub.single) sub.single = openSingle(id, sub.after, sub.handlers);\n }\n }\n\n function scheduleRetry(gen: number): void {\n if (closed || gen !== generation) return;\n carrying = null;\n for (const sub of subs.values()) setState(sub, 'reconnecting');\n retryTimer = setTimeout(() => {\n retryTimer = null;\n if (gen === generation) void connect();\n }, backoff(attempt++));\n }\n\n function sync(): void {\n batched = false;\n if (closed || fallback) return;\n const key = wanted();\n if (key === '') {\n disconnect();\n return;\n }\n if (key === carrying) return;\n void connect();\n }\n\n function requestSync(): void {\n if (batched || closed) return;\n batched = true;\n batch(sync);\n }\n\n function dispatch(parsed: MuxParsed): void {\n const sub = subs.get(parsed.tab);\n if (!sub) return;\n if (parsed.frame.type === 'gone') {\n subs.delete(parsed.tab);\n setState(sub, 'gone');\n return;\n }\n try { sub.handlers.onFrame(parsed.frame); } catch { /* a pane's error never stops the stream */ }\n }\n\n async function connect(): Promise<void> {\n disconnect();\n if (closed || fallback || subs.size === 0) return;\n const gen = generation;\n const ids = [...subs.keys()].sort();\n carrying = ids.join(',');\n const ctrl = new AbortController();\n controller = ctrl;\n for (const sub of subs.values()) if (sub.state !== 'open') setState(sub, 'connecting');\n let res: Response;\n try {\n res = await doFetch(muxStreamPath(ids.map((id) => [id, subs.get(id)!.after()] as const)), {\n method: 'GET',\n credentials: 'same-origin',\n headers: { 'x-ashlr-read-client': proof(), Accept: 'text/event-stream' },\n signal: ctrl.signal,\n cache: 'no-store',\n });\n } catch {\n scheduleRetry(gen);\n return;\n }\n if (closed || gen !== generation) {\n try { void res.body?.cancel().catch(() => {}); } catch { /* ignore */ }\n return;\n }\n if (res.status === 404 || res.status === 400) {\n // No multiplexed route on this server (or it cannot read our list): one stream per pane.\n enterFallback();\n return;\n }\n if (res.status === 401) {\n if (!renewedOnce && (await renew().catch(() => false))) {\n renewedOnce = true;\n if (gen === generation) void connect();\n return;\n }\n for (const sub of subs.values()) setState(sub, 'expired');\n disconnect();\n return;\n }\n if (!res.ok || !res.body) {\n scheduleRetry(gen);\n return;\n }\n renewedOnce = false;\n for (const sub of subs.values()) setState(sub, 'open');\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n try {\n for (;;) {\n const { value, done } = await reader.read();\n if (done || gen !== generation) break;\n attempt = 0;\n buffer += decoder.decode(value, { stream: true });\n let idx: number;\n while (gen === generation && (idx = buffer.indexOf('\\n\\n')) !== -1) {\n const block = buffer.slice(0, idx);\n buffer = buffer.slice(idx + 2);\n const parsed = parseMuxSseBlock(block);\n if (parsed) dispatch(parsed);\n }\n }\n } catch {\n /* aborted, or the connection dropped */\n }\n if (gen !== generation || closed) return;\n if (subs.size === 0) {\n carrying = null;\n return;\n }\n scheduleRetry(gen);\n }\n\n return {\n subscribe(tabId, after, handlers) {\n const sub: MuxSub = { after, handlers, single: null, state: null };\n // A pane subscribing again replaces its old entry.\n subs.get(tabId)?.single?.close();\n subs.set(tabId, sub);\n if (closed) {\n setState(sub, 'closed');\n } else if (fallback) {\n sub.single = openSingle(tabId, after, handlers);\n } else {\n setState(sub, 'connecting');\n requestSync();\n }\n let done = false;\n return {\n close() {\n if (done) return;\n done = true;\n if (subs.get(tabId) !== sub) return;\n subs.delete(tabId);\n if (sub.single) sub.single.close();\n else setState(sub, 'closed');\n requestSync();\n },\n };\n },\n tabs: () => [...subs.keys()],\n close() {\n if (closed) return;\n closed = true;\n disconnect();\n for (const sub of subs.values()) {\n if (sub.single) sub.single.close();\n else setState(sub, 'closed');\n }\n subs.clear();\n },\n };\n}\n\nlet sharedMux: TerminalStreamMux | null = null;\n\n/** The panel's default opener: every pane on the page shares one multiplexed connection. */\nexport const openMuxedPanelStream: PanelStreamOpener = (tabId, after, handlers) => {\n sharedMux ??= createTerminalStreamMux();\n return sharedMux.subscribe(tabId, after, handlers);\n};\n\n/** Test hook: forget the shared connection. */\nexport function resetSharedTerminalMuxForTest(): void {\n sharedMux?.close();\n sharedMux = null;\n}\n","/**\n * terminal/ansi-spans.ts — a block's output, in colour, as DOM text (3.15).\n *\n * The block view is not a terminal: it shows what a command printed, the way\n * the terminal showed it, as selectable text. So SGR (colour, bold, dim,\n * italic, underline, inverse, strike — 16, 256 and 24-bit colour) becomes\n * styled runs; cursor motion and erase codes are dropped; OSC strings\n * (titles, hyperlinks, our own block marks) are removed; and a line redrawn\n * with `\\r` (a progress bar) shows its last drawing.\n *\n * The 16 ANSI colours are the terminal's own palette custom properties\n * (`var(--term-red)` …, declared on the panel from design tokens), so a\n * block matches the terminal next to it in both themes. 256-colour and RGB\n * values are computed, never literal.\n */\n\nexport interface AnsiStyle {\n fg?: string;\n bg?: string;\n bold?: boolean;\n dim?: boolean;\n italic?: boolean;\n underline?: boolean;\n inverse?: boolean;\n strike?: boolean;\n}\n\nexport interface AnsiRun {\n text: string;\n style: AnsiStyle;\n}\n\nconst NAMED = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'] as const;\n\nfunction named(index: number, bright: boolean): string {\n const name = NAMED[index]!;\n return `var(--term-${bright ? 'bright-' : ''}${name})`;\n}\n\n/** xterm's 256-colour cube and grey ramp. */\nexport function color256(n: number): string {\n if (n < 8) return named(n, false);\n if (n < 16) return named(n - 8, true);\n if (n < 232) {\n const i = n - 16;\n const steps = [0, 95, 135, 175, 215, 255];\n return `rgb(${steps[Math.floor(i / 36)]}, ${steps[Math.floor(i / 6) % 6]}, ${steps[i % 6]})`;\n }\n const level = 8 + (n - 232) * 10;\n return `rgb(${level}, ${level}, ${level})`;\n}\n\nfunction clampByte(v: number | undefined): number {\n return Math.max(0, Math.min(255, Number.isFinite(v) ? Math.round(v!) : 0));\n}\n\n/** Apply one SGR parameter list to `style` (mutates a copy; returns it). */\nexport function applySgr(prev: AnsiStyle, params: number[]): AnsiStyle {\n const style: AnsiStyle = { ...prev };\n const list = params.length === 0 ? [0] : params;\n for (let i = 0; i < list.length; i++) {\n const p = list[i]!;\n if (p === 0) {\n for (const k of Object.keys(style)) delete style[k as keyof AnsiStyle];\n } else if (p === 1) style.bold = true;\n else if (p === 2) style.dim = true;\n else if (p === 3) style.italic = true;\n else if (p === 4) style.underline = true;\n else if (p === 7) style.inverse = true;\n else if (p === 9) style.strike = true;\n else if (p === 22) { delete style.bold; delete style.dim; }\n else if (p === 23) delete style.italic;\n else if (p === 24) delete style.underline;\n else if (p === 27) delete style.inverse;\n else if (p === 29) delete style.strike;\n else if (p >= 30 && p <= 37) style.fg = named(p - 30, false);\n else if (p === 39) delete style.fg;\n else if (p >= 40 && p <= 47) style.bg = named(p - 40, false);\n else if (p === 49) delete style.bg;\n else if (p >= 90 && p <= 97) style.fg = named(p - 90, true);\n else if (p >= 100 && p <= 107) style.bg = named(p - 100, true);\n else if (p === 38 || p === 48) {\n const key = p === 38 ? 'fg' : 'bg';\n if (list[i + 1] === 5 && list[i + 2] !== undefined) {\n style[key] = color256(clampByte(list[i + 2]));\n i += 2;\n } else if (list[i + 1] === 2) {\n style[key] = `rgb(${clampByte(list[i + 2])}, ${clampByte(list[i + 3])}, ${clampByte(list[i + 4])})`;\n i += 4;\n }\n }\n }\n return style;\n}\n\n/**\n * A line redrawn with bare `\\r` shows its final drawing. Escape sequences\n * make an exact overlay impossible without a screen model, and a redraw\n * (a progress bar, a spinner) is nearly always the whole line — so the last\n * segment with visible text wins.\n */\nexport function lastDrawing(line: string): string {\n if (!line.includes('\\r')) return line;\n const parts = line.split('\\r');\n for (let i = parts.length - 1; i >= 0; i--) {\n if (parts[i]!.replace(ESCAPES_FOR_WIDTH, '').trim().length > 0) return parts[i]!;\n }\n return '';\n}\n\n// eslint-disable-next-line no-control-regex\nconst ESCAPES_FOR_WIDTH = /\\x1b\\[[0-?]*[ -/]*[@-~]|\\x1b\\][\\s\\S]*?(?:\\x07|\\x1b\\\\)/g;\n// eslint-disable-next-line no-control-regex\nconst TOKEN_RE = /\\x1b\\[([0-?]*)([ -/]*)([@-~])|\\x1b\\][\\s\\S]*?(?:\\x07|\\x1b\\\\|$)|\\x1b[()][A-Za-z0-9]|\\x1b[^[\\]]/g;\n\nexport const ANSI_RENDER_MAX_CHARS = 200_000;\n\n/** Styled runs for `text` (a block's output as the shell wrote it). */\nexport function parseAnsi(text: string): AnsiRun[] {\n const input = text.length > ANSI_RENDER_MAX_CHARS ? text.slice(-ANSI_RENDER_MAX_CHARS) : text;\n const lines = input.replace(/\\r\\n/g, '\\n').split('\\n').map(lastDrawing).join('\\n');\n const runs: AnsiRun[] = [];\n let style: AnsiStyle = {};\n let last = 0;\n const push = (chunk: string) => {\n // Backspace and other C0 controls (bar \\n and \\t) are not text.\n // eslint-disable-next-line no-control-regex\n const clean = chunk.replace(/[^\\n\\t]\\x08/g, '').replace(/[\\x00-\\x08\\x0b-\\x1f\\x7f]/g, '');\n if (!clean) return;\n const prev = runs[runs.length - 1];\n if (prev && sameStyle(prev.style, style)) prev.text += clean;\n else runs.push({ text: clean, style });\n };\n for (const m of lines.matchAll(TOKEN_RE)) {\n push(lines.slice(last, m.index));\n last = m.index! + m[0].length;\n if (m[3] === 'm' && m[2] === '') {\n const params = (m[1] ?? '').split(/[;:]/).filter((s) => s !== '').map((s) => Number.parseInt(s, 10)).filter((n) => Number.isFinite(n));\n style = applySgr(style, params);\n }\n }\n push(lines.slice(last));\n // Trailing blank lines are the prompt's business, not the command's.\n const tail = runs[runs.length - 1];\n if (tail) {\n tail.text = tail.text.replace(/\\s+$/, '');\n if (!tail.text) runs.pop();\n }\n return runs;\n}\n\nfunction sameStyle(a: AnsiStyle, b: AnsiStyle): boolean {\n const ka = Object.keys(a);\n const kb = Object.keys(b);\n return ka.length === kb.length && ka.every((k) => a[k as keyof AnsiStyle] === b[k as keyof AnsiStyle]);\n}\n\n/** Inline CSS for a run (inverse swaps fg/bg against the terminal's own colours). */\nexport function runCss(style: AnsiStyle): Record<string, string> {\n const css: Record<string, string> = {};\n let fg = style.fg;\n let bg = style.bg;\n if (style.inverse) {\n [fg, bg] = [bg ?? 'var(--term-bg)', fg ?? 'var(--term-fg)'];\n }\n if (fg) css['color'] = fg;\n if (bg) css['backgroundColor'] = bg;\n if (style.bold) css['fontWeight'] = '600';\n if (style.dim) css['opacity'] = '0.7';\n if (style.italic) css['fontStyle'] = 'italic';\n const deco = [style.underline ? 'underline' : '', style.strike ? 'line-through' : ''].filter(Boolean).join(' ');\n if (deco) css['textDecoration'] = deco;\n return css;\n}\n","/**\n * terminal/blocks-model.ts — command blocks on the page (3.15): the\n * operator's own (from the server's `block` frames) and the agents' (from\n * the chat transcript's tool events), in one shape, plus the text a block\n * becomes when it is sent to a chat.\n *\n * AGENT BLOCKS ARE A READING, NEVER A RUN. They are derived from tool-use /\n * tool-result events the chat already holds (useVerseTranscript) — the\n * command the agent's CLI reported and the output it got back. Nothing here\n * executes anything; \"Paste in terminal\" types the command at a prompt and\n * stops, exactly like the transcript's own \"Run in terminal\".\n */\nimport type { VerseTerminalBlock } from '../../../data/api-types.js';\nimport type { TranscriptItem } from '../verse-transcript.js';\nimport { readToolFacts } from '../chat/tool-semantics.js';\n\n/** One block as the list renders it. */\nexport interface BlockView {\n /** Terminal: the server's `b-<n>`. Agent: the tool call id. */\n id: string;\n source: 'terminal' | 'agent';\n command: string;\n cwd: string | null;\n startedAt: string;\n durationMs: number | null;\n exitCode: number | null;\n /** Agent calls often report failure without a code. */\n failed: boolean;\n running: boolean;\n /** Terminal blocks: output is fetched on demand. Agent blocks: already here. */\n output: string | null;\n truncated: boolean;\n fullscreen: boolean;\n /** Agent blocks: the tool that ran it (Bash, command_execution…). */\n tool?: string;\n /** 3.15, terminal blocks: loopback URLs the command printed (\"Open in Browser pane\"). */\n localUrls?: readonly string[];\n}\n\n// ---------------------------------------------------------------------------\n// Terminal blocks\n// ---------------------------------------------------------------------------\n\n/** Merge a `block` frame into the ordered list (a block arrives when it starts and again when it finishes). */\nexport function upsertBlock(list: readonly VerseTerminalBlock[], block: VerseTerminalBlock, max = 500): VerseTerminalBlock[] {\n const i = list.findIndex((b) => b.id === block.id);\n if (i >= 0) {\n const next = list.slice();\n next[i] = block;\n return next;\n }\n const next = [...list, block];\n // Server ids are b-<n> in order; keep them sorted even if a replay interleaves.\n next.sort((a, b) => blockNumber(a.id) - blockNumber(b.id));\n return next.length > max ? next.slice(next.length - max) : next;\n}\n\nfunction blockNumber(id: string): number {\n const n = Number.parseInt(id.slice(2), 10);\n return Number.isFinite(n) ? n : 0;\n}\n\nexport function terminalBlockView(block: VerseTerminalBlock): BlockView {\n return {\n id: block.id,\n source: 'terminal',\n command: block.command,\n cwd: block.cwd,\n startedAt: block.startedAt,\n durationMs: block.durationMs,\n exitCode: block.exitCode,\n failed: block.exitCode !== null && block.exitCode !== 0,\n running: block.state === 'running',\n output: null,\n truncated: block.truncated || block.evicted,\n fullscreen: block.fullscreen,\n ...(block.localUrls && block.localUrls.length > 0 ? { localUrls: block.localUrls } : {}),\n };\n}\n\n/** The key a block's xterm marker is filed under: its C mark's frame and position in that frame. */\nexport function markerKey(seq: number, ordinal: number): string {\n return `${seq}:${ordinal}`;\n}\n\n// ---------------------------------------------------------------------------\n// Agent blocks\n// ---------------------------------------------------------------------------\n\nfunction record(value: unknown): Record<string, unknown> | null {\n return value !== null && typeof value === 'object' && !Array.isArray(value) ? (value as Record<string, unknown>) : null;\n}\n\n/**\n * Every shell command the chat's agents ran, oldest first: a tool call whose\n * input carries a command line (Claude Code's Bash, Codex's\n * command_execution, a local seat's run_command…), paired with its result.\n */\nexport function agentBlocksFromTranscript(items: readonly TranscriptItem[]): BlockView[] {\n const out: BlockView[] = [];\n for (const item of items) {\n if (item.kind !== 'tool') continue;\n const facts = readToolFacts({ name: item.name, input: item.input, result: item.result });\n if (!facts.command) continue;\n const input = record(item.input);\n const cwd = typeof input?.['cwd'] === 'string' ? (input['cwd'] as string)\n : typeof input?.['workdir'] === 'string' ? (input['workdir'] as string) : null;\n const pending = item.result === null;\n const exitCode = facts.command.exitCode;\n out.push({\n id: item.toolUseId,\n source: 'agent',\n command: facts.command.command,\n cwd,\n startedAt: item.at,\n durationMs: item.durationMs,\n exitCode,\n failed: item.result?.isError === true || (exitCode !== null && exitCode !== 0),\n running: pending,\n output: item.result?.output ?? null,\n truncated: false,\n fullscreen: false,\n tool: item.name,\n });\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// Presentation\n// ---------------------------------------------------------------------------\n\nexport function formatDuration(ms: number | null): string {\n if (ms === null || !Number.isFinite(ms)) return '';\n if (ms < 1_000) return `${Math.max(0, Math.round(ms))} ms`;\n if (ms < 60_000) return `${(ms / 1_000).toFixed(ms < 10_000 ? 1 : 0)} s`;\n const m = Math.floor(ms / 60_000);\n const s = Math.round((ms % 60_000) / 1_000);\n if (m < 60) return s > 0 ? `${m} m ${s} s` : `${m} m`;\n const h = Math.floor(m / 60);\n return `${h} h ${m % 60} m`;\n}\n\n/** What the status chip says: an honest exit (no code invented). */\nexport function blockStatus(block: Pick<BlockView, 'running' | 'exitCode' | 'failed'>): { tone: 'running' | 'ok' | 'error' | 'unknown'; label: string } {\n if (block.running) return { tone: 'running', label: 'Running' };\n if (block.exitCode === 0) return { tone: 'ok', label: 'Exit 0' };\n if (block.exitCode !== null) return { tone: 'error', label: `Exit ${block.exitCode}` };\n if (block.failed) return { tone: 'error', label: 'Failed' };\n return { tone: 'unknown', label: 'Done' };\n}\n\n// ---------------------------------------------------------------------------\n// Chat text\n// ---------------------------------------------------------------------------\n\n/** Output past this is cut to its tail for a chat message (the error is at the end). */\nexport const CHAT_OUTPUT_MAX_CHARS = 12_000;\nexport const CHAT_OUTPUT_MAX_LINES = 200;\n\n/** A fence one backtick longer than any run inside (≥ 3), so the text cannot close it early. */\nexport function fenceFor(text: string): string {\n const longest = Math.max(0, ...Array.from(text.matchAll(/`+/g), (m) => m[0].length));\n return '`'.repeat(Math.max(3, longest + 1));\n}\n\nexport function tailForChat(output: string): { text: string; cut: boolean } {\n let text = output.replace(/\\s+$/, '');\n let cut = false;\n const lines = text.split('\\n');\n if (lines.length > CHAT_OUTPUT_MAX_LINES) {\n text = lines.slice(-CHAT_OUTPUT_MAX_LINES).join('\\n');\n cut = true;\n }\n if (text.length > CHAT_OUTPUT_MAX_CHARS) {\n text = text.slice(-CHAT_OUTPUT_MAX_CHARS);\n const nl = text.indexOf('\\n');\n if (nl >= 0 && nl < 200) text = text.slice(nl + 1);\n cut = true;\n }\n return { text, cut };\n}\n\nexport type ChatIntent = 'send' | 'explain';\n\n/**\n * The message a block becomes. `command` and `output` must ALREADY be the\n * server's `format=chat` text (plain, secrets scrubbed) — or, for an agent\n * block, the transcript's own (scrubbed on the way to the page).\n */\nexport function blockChatText(\n block: Pick<BlockView, 'exitCode' | 'failed' | 'cwd' | 'source' | 'running'>,\n command: string,\n output: string,\n intent: ChatIntent,\n): string {\n const { text, cut } = tailForChat(output);\n const body = `$ ${command}${text ? `\\n${text}` : ''}`;\n const fence = fenceFor(body);\n const status = block.running ? 'still running'\n : block.exitCode !== null ? `exit ${block.exitCode}`\n : block.failed ? 'failed' : 'finished';\n const where = block.cwd ? ` in \\`${block.cwd}\\`` : '';\n const whose = block.source === 'agent' ? 'An agent ran this command' : 'I ran this in my terminal';\n const lines: string[] = [];\n if (intent === 'explain') {\n lines.push(`${whose}${where} (${status}). Explain what went wrong and how to fix it — propose the fix, don't run anything yet.`);\n } else {\n lines.push(`${whose}${where} (${status}):`);\n }\n lines.push('', `${fence}console`, body, fence);\n if (cut) lines.push('', '_(output cut to its last lines)_');\n return lines.join('\\n');\n}\n","/**\n * terminal/block-tools.ts — what the 3.15 block actions compute, pure (so it\n * is tested without a terminal):\n *\n * - filter-in-block: an output's lines kept (or dropped, inverted) by a\n * substring or a regular expression, colour codes kept on the lines shown;\n * - multi-select: shift-click ranges and ⌘/Ctrl-click toggles;\n * - bookmarks: per tab, remembered on this device;\n * - the message a SET of blocks becomes (Send / Ask with several selected);\n * - `verse://terminal/<tab>/<block>` links;\n * - how long a running block has been running (\"1m 12s\").\n */\nimport { blockChatText, fenceFor, tailForChat, type BlockView, type ChatIntent } from './blocks-model.js';\n\n// ---------------------------------------------------------------------------\n// Filter in block\n// ---------------------------------------------------------------------------\n\nexport interface OutputFilter {\n pattern: string;\n regex: boolean;\n invert: boolean;\n caseSensitive: boolean;\n}\n\nexport const EMPTY_FILTER: OutputFilter = { pattern: '', regex: false, invert: false, caseSensitive: false };\n\n// eslint-disable-next-line no-control-regex\nconst SGR_RE = /\\x1b\\[[0-9;:]*m/g;\n\n/**\n * The lines of `text` (ANSI kept) whose PLAIN text matches — or, inverted,\n * does not. `error` is set (and every line kept) for an invalid regex, so the\n * view never goes blank while one is being typed.\n */\nexport function filterOutputLines(text: string, filter: OutputFilter): { text: string; shown: number; total: number; error: string | null } {\n const lines = text.split('\\n');\n if (!filter.pattern) return { text, shown: lines.length, total: lines.length, error: null };\n let test: (line: string) => boolean;\n if (filter.regex) {\n let re: RegExp;\n try {\n re = new RegExp(filter.pattern, filter.caseSensitive ? '' : 'i');\n } catch (err) {\n return { text, shown: lines.length, total: lines.length, error: err instanceof Error ? err.message : 'invalid regular expression' };\n }\n test = (line) => re.test(line);\n } else {\n const needle = filter.caseSensitive ? filter.pattern : filter.pattern.toLowerCase();\n test = (line) => (filter.caseSensitive ? line : line.toLowerCase()).includes(needle);\n }\n const kept = lines.filter((line) => test(line.replace(SGR_RE, '')) !== filter.invert);\n return { text: kept.join('\\n'), shown: kept.length, total: lines.length, error: null };\n}\n\n// ---------------------------------------------------------------------------\n// Multi-select\n// ---------------------------------------------------------------------------\n\nexport interface BlockSelection {\n ids: ReadonlySet<string>;\n /** Where the next shift-click range starts. */\n anchor: string | null;\n}\n\nexport const EMPTY_SELECTION: BlockSelection = { ids: new Set(), anchor: null };\n\n/**\n * A click on a block with modifiers. `range` (shift) selects from the anchor\n * to this block, `toggle` (⌘/Ctrl) adds or removes this one; a plain click is\n * not a selection gesture (null = \"not handled\", the card folds instead).\n */\nexport function selectBlock(\n selection: BlockSelection,\n order: readonly string[],\n id: string,\n gesture: { range: boolean; toggle: boolean },\n): BlockSelection | null {\n if (gesture.range) {\n const from = selection.anchor !== null ? order.indexOf(selection.anchor) : -1;\n const to = order.indexOf(id);\n if (to < 0) return selection;\n if (from < 0) return { ids: new Set([id]), anchor: id };\n const [a, b] = from <= to ? [from, to] : [to, from];\n const ids = new Set(gesture.toggle ? selection.ids : []);\n for (const x of order.slice(a, b + 1)) ids.add(x);\n return { ids, anchor: selection.anchor };\n }\n if (gesture.toggle) {\n const ids = new Set(selection.ids);\n if (ids.has(id)) ids.delete(id);\n else ids.add(id);\n return { ids, anchor: id };\n }\n return null;\n}\n\n/** Drop ids that no longer exist (a block evicted from the tab). */\nexport function pruneSelection(selection: BlockSelection, order: readonly string[]): BlockSelection {\n const present = new Set(order);\n if ([...selection.ids].every((id) => present.has(id)) && (selection.anchor === null || present.has(selection.anchor))) return selection;\n return {\n ids: new Set([...selection.ids].filter((id) => present.has(id))),\n anchor: selection.anchor !== null && present.has(selection.anchor) ? selection.anchor : null,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Several blocks → one message\n// ---------------------------------------------------------------------------\n\n/** One message for several blocks, oldest first. `texts` are the server's `format=chat` (scrubbed) command + output. */\nexport function blocksChatText(\n items: ReadonlyArray<{ block: Pick<BlockView, 'exitCode' | 'failed' | 'cwd' | 'source' | 'running'>; command: string; output: string }>,\n intent: ChatIntent,\n): string {\n if (items.length === 1) return blockChatText(items[0]!.block, items[0]!.command, items[0]!.output, intent);\n const failed = items.some(({ block }) => block.failed || (block.exitCode !== null && block.exitCode !== 0));\n const head = intent === 'explain'\n ? `I ran these ${items.length} commands in my terminal${failed ? ' and something failed' : ''}. Explain what went wrong and how to fix it — propose the fix, don't run anything yet.`\n : `I ran these ${items.length} commands in my terminal:`;\n const parts = [head];\n for (const { block, command, output } of items) {\n // Each block gets a share of the budget, so one long log cannot crowd the others out.\n const { text, cut } = tailForChat(output.length > 4_000 ? output.slice(-4_000) : output);\n const status = block.running ? 'still running' : block.exitCode !== null ? `exit ${block.exitCode}` : block.failed ? 'failed' : 'finished';\n const body = `$ ${command}${text ? `\\n${text}` : ''}`;\n const fence = fenceFor(body);\n parts.push('', `${block.cwd ? `In \\`${block.cwd}\\`` : 'Command'} (${status})${cut || output.length > 4_000 ? ' — last lines only' : ''}:`, `${fence}console`, body, fence);\n }\n return parts.join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// Links, time\n// ---------------------------------------------------------------------------\n\nconst TAB_RE = /^t-[a-z0-9]{1,32}$/;\nconst BLOCK_RE = /^b-\\d{1,9}$/;\n\n/** `verse://terminal/<tab>/<block>` — pasted into a chat or a note, it opens that block. */\nexport function terminalBlockLink(tabId: string, blockId?: string | null): string | null {\n if (!TAB_RE.test(tabId) || (blockId && !BLOCK_RE.test(blockId))) return null;\n return `verse://terminal/${tabId}${blockId ? `/${blockId}` : ''}`;\n}\n\n/** \"12s\", \"1m 12s\", \"1h 03m\": the sticky header's elapsed time. */\nexport function elapsedLabel(ms: number): string {\n const s = Math.max(0, Math.floor(ms / 1000));\n if (s < 60) return `${s}s`;\n const m = Math.floor(s / 60);\n if (m < 60) return `${m}m ${String(s % 60).padStart(2, '0')}s`;\n return `${Math.floor(m / 60)}h ${String(m % 60).padStart(2, '0')}m`;\n}\n\n/** `http://localhost:5173/` → `localhost:5173` for a button label. */\nexport function urlLabel(url: string): string {\n return url.replace(/^https?:\\/\\//i, '').replace(/\\/$/, '');\n}\n\n// ---------------------------------------------------------------------------\n// Per-device stores: bookmarks, the fix-chip setting\n// ---------------------------------------------------------------------------\n\ntype Store = Pick<Storage, 'getItem' | 'setItem' | 'removeItem'> | null;\n\nconst BOOKMARKS_KEY = 'ashlr.verse.terminal.bookmarks.v1';\n/** Tabs are few and short-lived; the oldest are dropped past this. */\nconst BOOKMARK_TABS_MAX = 64;\n\nexport function loadBookmarks(storage: Store): Record<string, string[]> {\n try {\n const raw = storage?.getItem(BOOKMARKS_KEY);\n if (!raw) return {};\n const parsed = JSON.parse(raw) as unknown;\n if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) return {};\n const out: Record<string, string[]> = {};\n for (const [tab, ids] of Object.entries(parsed as Record<string, unknown>)) {\n if (TAB_RE.test(tab) && Array.isArray(ids)) out[tab] = ids.filter((id): id is string => typeof id === 'string' && BLOCK_RE.test(id));\n }\n return out;\n } catch {\n return {};\n }\n}\n\nexport function toggleBookmark(storage: Store, tabId: string, blockId: string): Record<string, string[]> {\n const all = loadBookmarks(storage);\n const list = all[tabId] ?? [];\n const next = list.includes(blockId) ? list.filter((id) => id !== blockId) : [...list, blockId];\n if (next.length > 0) {\n delete all[tabId];\n all[tabId] = next;\n } else {\n delete all[tabId];\n }\n const tabs = Object.keys(all);\n for (const old of tabs.slice(0, Math.max(0, tabs.length - BOOKMARK_TABS_MAX))) delete all[old];\n try {\n storage?.setItem(BOOKMARKS_KEY, JSON.stringify(all));\n } catch {\n /* this page only */\n }\n return all;\n}\n\nconst FIX_CHIPS_KEY = 'ashlr.verse.terminal.fixChips.v1';\n\n/** \"Suggest fixes with the local model\": ON unless turned off (it is free and never leaves this Mac). */\nexport function loadFixChipsEnabled(storage: Store): boolean {\n try {\n return storage?.getItem(FIX_CHIPS_KEY) !== '0';\n } catch {\n return true;\n }\n}\n\nexport function saveFixChipsEnabled(storage: Store, on: boolean): void {\n try {\n storage?.setItem(FIX_CHIPS_KEY, on ? '1' : '0');\n } catch {\n /* this page only */\n }\n}\n","/**\n * terminal/extra-glyphs.tsx — the few 3.15 block-action glyphs the shared\n * icon set does not have (same 16px grammar: 1.5 stroke, round caps).\n */\nimport type { ReactNode } from 'react';\n\nfunction Svg({ size = 14, children }: { size?: number; children: ReactNode }) {\n return (\n <svg width={size} height={size} viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" strokeWidth={1.5}\n strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\" focusable=\"false\">\n {children}\n </svg>\n );\n}\n\n/** Bookmark: a star, filled when set. */\nexport function StarGlyph({ filled = false, size }: { filled?: boolean; size?: number }) {\n return (\n <Svg {...(size ? { size } : {})}>\n <path d=\"M8 2.2l1.75 3.55 3.9.57-2.82 2.75.67 3.88L8 11.12l-3.5 1.83.67-3.88L2.35 6.32l3.9-.57z\" fill={filled ? 'currentColor' : 'none'} />\n </Svg>\n );\n}\n\n/** Ask a seat: a speech bubble with a question mark. */\nexport function AskGlyph({ size }: { size?: number }) {\n return (\n <Svg {...(size ? { size } : {})}>\n <path d=\"M2.75 3.75h10.5v7h-5.5l-3 2.5v-2.5h-2z\" />\n <path d=\"M6.6 5.9a1.45 1.45 0 1 1 1.9 1.38c-.35.12-.5.36-.5.72\" /><path d=\"M8 9.35v.05\" />\n </Svg>\n );\n}\n\n/** A link (copy the block's verse:// link). */\nexport function LinkGlyph({ size }: { size?: number }) {\n return (\n <Svg {...(size ? { size } : {})}>\n <path d=\"M6.75 9.25l2.5-2.5\" />\n <path d=\"M7.5 4.75l1-1a2.47 2.47 0 0 1 3.5 3.5l-1 1\" />\n <path d=\"M8.5 11.25l-1 1a2.47 2.47 0 0 1-3.5-3.5l1-1\" />\n </Svg>\n );\n}\n\n/** Filter the output's lines. */\nexport function FilterGlyph({ size }: { size?: number }) {\n return (\n <Svg {...(size ? { size } : {})}>\n <path d=\"M2.5 3.5h11l-4.25 5v4l-2.5-1.25V8.5z\" />\n </Svg>\n );\n}\n\n/** Re-run the command. */\nexport function RerunGlyph({ size }: { size?: number }) {\n return (\n <Svg {...(size ? { size } : {})}>\n <path d=\"M12.75 8a4.75 4.75 0 1 1-1.4-3.36\" /><path d=\"M12.25 2.5v2.5h-2.5\" />\n </Svg>\n );\n}\n\n/** Open in the Browser pane. */\nexport function BrowserGlyph({ size }: { size?: number }) {\n return (\n <Svg {...(size ? { size } : {})}>\n <rect x=\"1.75\" y=\"2.75\" width=\"12.5\" height=\"10.5\" rx=\"1.5\" /><path d=\"M1.75 5.75h12.5\" />\n </Svg>\n );\n}\n","/**\n * terminal/FixChips.tsx — error-fix chips for a command that exited non-zero\n * (3.15). The LOCAL model proposes at most three commands (server:\n * terminal-assist.ts, over the block's scrubbed text); each is a chip whose\n * [Paste] types it at a prompt and stops — nothing here ever runs a command.\n * Beside them, \"Ask Claude Code / Codex / Devin…\" hands the failed block to\n * that seat's chat.\n *\n * Opt-in per device (\"Suggest fixes with the local model\", default on — it is\n * free and the text never leaves this Mac). When the local model does not\n * answer, the suggestions are simply absent; the Ask chips stay.\n */\nimport { useEffect, useState } from 'react';\nimport type { VerseTerminalFixResponse, VerseTerminalFixSuggestion } from '../../../data/api-types.js';\nimport { IconX } from '../../../components/primitives/icons.js';\nimport styles from './TerminalExtras.module.css';\n\nexport interface AskTarget {\n seatId: string;\n label: string;\n}\n\nexport interface FixChipsProps {\n /** Null = suggestions are off (the Ask chips still show). */\n load: (() => Promise<VerseTerminalFixResponse>) | null;\n onPaste: (command: string) => void;\n askTargets: readonly AskTarget[];\n onAsk: (seatId: string) => void;\n /** \"Ask…\": every seat (a menu anchored here). */\n onAskMore?: (anchor: HTMLElement) => void;\n variant: 'card' | 'bar';\n onDismiss?: () => void;\n}\n\ntype LoadState = { kind: 'off' } | { kind: 'loading' } | { kind: 'done'; suggestions: VerseTerminalFixSuggestion[] } | { kind: 'failed' };\n\nexport function FixChips({ load, onPaste, askTargets, onAsk, onAskMore, variant, onDismiss }: FixChipsProps) {\n const [state, setState] = useState<LoadState>(load ? { kind: 'loading' } : { kind: 'off' });\n\n useEffect(() => {\n if (!load) {\n setState({ kind: 'off' });\n return undefined;\n }\n let cancelled = false;\n setState({ kind: 'loading' });\n load().then(\n (res) => { if (!cancelled) setState({ kind: 'done', suggestions: res.suggestions }); },\n () => { if (!cancelled) setState({ kind: 'failed' }); },\n );\n return () => { cancelled = true; };\n }, [load]);\n\n const suggestions = state.kind === 'done' ? state.suggestions : [];\n if (askTargets.length === 0 && !onAskMore && (state.kind === 'off' || state.kind === 'failed' || (state.kind === 'done' && suggestions.length === 0))) {\n return null;\n }\n\n const asks = (\n <>\n {askTargets.map((t) => (\n <button key={t.seatId} type=\"button\" className={styles.chip} data-kind=\"ask\" onClick={() => onAsk(t.seatId)}\n title={`Send this failed command and its output (secrets removed) to ${t.label}`}>\n Ask {t.label}\n </button>\n ))}\n {onAskMore ? (\n <button type=\"button\" className={styles.chip} data-kind=\"ask\" aria-haspopup=\"menu\" onClick={(e) => onAskMore(e.currentTarget)}\n title=\"Ask another seat, or every ready seat side by side\">\n Ask…\n </button>\n ) : null}\n </>\n );\n\n const chips = suggestions.map((s) => (\n <button key={s.command} type=\"button\" className={styles.chip} onClick={() => onPaste(s.command)}\n title={`${s.why ? `${s.why} — ` : ''}Paste at the prompt (it does not run until you press Enter)`}\n aria-label={`Paste ${s.command}`}>\n <span className={styles.chipCode}>{s.command}</span>\n <span className={styles.chipVerb} aria-hidden=\"true\">Paste</span>\n </button>\n ));\n\n if (variant === 'bar') {\n return (\n <div className={styles.bar} role=\"group\" aria-label=\"Fix this error\">\n <span className={styles.barLabel}>{state.kind === 'loading' ? 'Looking for a fix…' : suggestions.length > 0 ? 'Try:' : 'Fix it:'}</span>\n {chips}\n {asks}\n <span className={styles.barSpacer} />\n {onDismiss ? (\n <button type=\"button\" className={styles.chip} aria-label=\"Dismiss fix suggestions\" title=\"Dismiss\" onClick={onDismiss}>\n <IconX size={10} />\n </button>\n ) : null}\n </div>\n );\n }\n\n return (\n <div className={styles.fixes} role=\"group\" aria-label=\"Fix this error\">\n {state.kind === 'loading' ? <span role=\"status\">Looking for a fix with the local model…</span> : null}\n {suggestions.map((s, i) => (\n <div key={s.command} className={styles.fixRow}>\n {chips[i]}\n {s.why ? <span className={styles.fixWhy}>{s.why}</span> : null}\n </div>\n ))}\n {askTargets.length > 0 || onAskMore ? <div className={styles.fixRow}>{asks}</div> : null}\n </div>\n );\n}\n","/**\n * terminal/BlockList.tsx — command blocks as cards (3.15, Warp-style).\n *\n * One card per command: the command line, where it ran, how long it took,\n * how it ended; the output folds away and unfolds (in colour, as selectable\n * text). Actions per card: copy output, send to chat, and — for a command\n * that failed — \"Explain / fix\", which hands the block to the chat seat.\n * The same list shows the operator's own terminal blocks and, read-only,\n * the commands the chat's agents ran (the Agent tab).\n *\n * 3.15 \"many agents\" additions (terminal blocks only — `extras`):\n * - ⇧-click / ⌘-click a card's head to select several; the selection bar\n * copies, sends or asks a seat about all of them at once;\n * - the RUNNING block's head sticks to the top while its output scrolls;\n * - Filter-in-block: keep (or, inverted, drop) the lines matching a text\n * or a regular expression;\n * - bookmarks (★, per tab, this device) and \"Bookmarked only\";\n * - Ask… (any seat), Re-run, Copy link (verse://terminal/<tab>/<block>);\n * - a loopback URL the command printed → \"Open in Browser pane\";\n * - a failed command: the local model's fix chips (Paste, never run).\n *\n * Output of a terminal block is fetched when the card opens (the server\n * keeps it; the stream only carries metadata) and refetched while the\n * command is still running.\n */\nimport { memo, useCallback, useEffect, useMemo, useRef, useState, type CSSProperties, type MouseEvent as ReactMouseEvent } from 'react';\nimport type { VerseTerminalFixResponse } from '../../../data/api-types.js';\nimport { EmptyState } from '../../../components/primitives/EmptyState.js';\nimport { IconChevronRight, IconCopy, IconSend, IconX } from '../../../components/primitives/icons.js';\nimport { parseAnsi, runCss } from './ansi-spans.js';\nimport { EMPTY_FILTER, filterOutputLines, urlLabel, type BlockSelection, type OutputFilter } from './block-tools.js';\nimport { blockStatus, formatDuration, type BlockView } from './blocks-model.js';\nimport { AskGlyph, BrowserGlyph, FilterGlyph, LinkGlyph, RerunGlyph, StarGlyph } from './extra-glyphs.js';\nimport { FixChips, type AskTarget } from './FixChips.js';\nimport styles from './TerminalPanel.module.css';\nimport extra from './TerminalExtras.module.css';\n\nexport type BlockAction =\n | 'copy-output' | 'copy-command' | 'send' | 'explain' | 'paste' | 'jump'\n // 3.15 many-agents actions\n | 'ask' | 'ask-seat' | 'rerun' | 'bookmark' | 'copy-link' | 'open-url' | 'paste-text';\n\n/** What some actions need besides the block: where to anchor a menu, which URL, which text, which seat. */\nexport interface BlockActionExtra {\n anchor?: HTMLElement;\n url?: string;\n text?: string;\n seatId?: string;\n}\n\n/** The terminal-only additions (the Agent tab's list has none). */\nexport interface BlockListExtras {\n selection: BlockSelection;\n /** A modifier-click on a card's head. */\n onSelect: (id: string, gesture: { range: boolean; toggle: boolean }) => void;\n onClearSelection: () => void;\n onSelectionAction: (action: 'copy-output' | 'send' | 'ask', anchor?: HTMLElement) => void;\n bookmarks: ReadonlySet<string>;\n /** Null = fix suggestions are off. */\n loadFix: ((block: BlockView) => Promise<VerseTerminalFixResponse>) | null;\n askTargets: readonly AskTarget[];\n /** Re-run is offered (a live, plain shell with no command running). */\n canRerun: boolean;\n}\n\nexport interface BlockListProps {\n blocks: readonly BlockView[];\n /** Terminal blocks: the output as the shell wrote it. Agent blocks carry theirs. */\n loadOutput?: (block: BlockView) => Promise<string>;\n onAction: (action: BlockAction, block: BlockView, extra?: BlockActionExtra) => void;\n /** Which actions this list offers (the Agent tab has no \"Jump to\"). */\n actions: readonly BlockAction[];\n emptyTitle: string;\n emptyBody: string;\n /** Scroll to and ring this block (⌘↑/⌘↓ from the terminal, a gutter dot). */\n highlightId?: string | null;\n label: string;\n extras?: BlockListExtras;\n}\n\n/** Cards open at first: the latest few, and any that failed. */\nconst OPEN_LATEST = 3;\nconst RUNNING_REFRESH_MS = 1_500;\n\nfunction relativeTime(iso: string, now: number): string {\n const t = Date.parse(iso);\n if (!Number.isFinite(t)) return '';\n const s = Math.max(0, Math.round((now - t) / 1000));\n if (s < 60) return `${s}s ago`;\n const m = Math.round(s / 60);\n if (m < 60) return `${m}m ago`;\n const h = Math.round(m / 60);\n if (h < 24) return `${h}h ago`;\n return new Date(t).toLocaleDateString();\n}\n\nfunction folderName(cwd: string | null): string | null {\n if (!cwd) return null;\n const trimmed = cwd.replace(/\\/+$/, '');\n return trimmed.split('/').pop() || trimmed;\n}\n\nconst AnsiOutput = memo(function AnsiOutput({ text }: { text: string }) {\n const runs = useMemo(() => parseAnsi(text), [text]);\n return (\n <>\n {runs.map((run, i) => {\n const css = runCss(run.style);\n return Object.keys(css).length === 0\n ? <span key={i}>{run.text}</span>\n : <span key={i} style={css as CSSProperties}>{run.text}</span>;\n })}\n </>\n );\n});\n\ninterface CardProps {\n block: BlockView;\n open: boolean;\n onToggle: (id: string) => void;\n loadOutput?: (block: BlockView) => Promise<string>;\n onAction: (action: BlockAction, block: BlockView, extra?: BlockActionExtra) => void;\n actions: readonly BlockAction[];\n highlighted: boolean;\n now: number;\n extras?: BlockListExtras;\n selected: boolean;\n bookmarked: boolean;\n}\n\nconst BlockCard = memo(function BlockCard({ block, open, onToggle, loadOutput, onAction, actions, highlighted, now, extras, selected, bookmarked }: CardProps) {\n const [fetched, setFetched] = useState<{ text: string; at: string } | null>(null);\n const [error, setError] = useState(false);\n const [filterOpen, setFilterOpen] = useState(false);\n const [filter, setFilter] = useState<OutputFilter>(EMPTY_FILTER);\n const ref = useRef<HTMLLIElement>(null);\n const status = blockStatus(block);\n const output = block.output ?? fetched?.text ?? null;\n\n // Terminal blocks fetch their output when opened, again when they finish,\n // and every so often while running.\n const version = `${block.running ? 'run' : 'done'}:${block.durationMs ?? ''}`;\n useEffect(() => {\n if (!open || block.output !== null || !loadOutput || block.fullscreen) return undefined;\n let cancelled = false;\n const load = () => {\n loadOutput(block).then(\n (text) => { if (!cancelled) { setFetched({ text, at: version }); setError(false); } },\n () => { if (!cancelled) setError(true); },\n );\n };\n if (fetched?.at !== version) load();\n const timer = block.running ? setInterval(load, RUNNING_REFRESH_MS) : null;\n return () => {\n cancelled = true;\n if (timer) clearInterval(timer);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- `fetched` is read, not a trigger\n }, [open, version, block.id, loadOutput]);\n\n useEffect(() => {\n if (highlighted) ref.current?.scrollIntoView({ block: 'nearest' });\n }, [highlighted]);\n\n const filtered = useMemo(() => (output !== null && filter.pattern ? filterOutputLines(output, filter) : null), [output, filter]);\n const loadFix = extras?.loadFix ?? null;\n // Keyed on the block's id and exit: re-renders of the same finished block never ask the model again.\n const blockRef = useRef(block);\n blockRef.current = block;\n // eslint-disable-next-line react-hooks/exhaustive-deps -- keyed on the block's identity; the block is read through the ref\n const fixLoader = useMemo(() => (loadFix ? () => loadFix(blockRef.current) : null), [loadFix, block.id, block.exitCode]);\n\n const cwdName = folderName(block.cwd);\n const offerExplain = actions.includes('explain') && (status.tone === 'error');\n const terminal = block.source === 'terminal' && extras !== undefined;\n const onHead = (event: ReactMouseEvent<HTMLButtonElement>) => {\n if (extras && (event.shiftKey || event.metaKey || event.ctrlKey)) {\n event.preventDefault();\n extras.onSelect(block.id, { range: event.shiftKey, toggle: event.metaKey || event.ctrlKey });\n return;\n }\n onToggle(block.id);\n };\n const urls = block.localUrls ?? [];\n return (\n <li ref={ref} className={`${styles.block}${selected ? ` ${extra.selected}` : ''}`} data-tone={status.tone} data-highlight={highlighted || undefined}\n data-selected={selected || undefined} data-testid={`block-${block.id}`} aria-selected={extras ? selected : undefined}>\n <div className={`${styles.blockTop}${block.running && terminal ? ` ${extra.runningTop}` : ''}`}>\n <button type=\"button\" className={styles.blockHead} aria-expanded={open} onClick={onHead}\n title={extras ? `${block.command || 'Command'} — ⇧-click or ⌘-click to select several` : block.command || 'Command'}>\n <span className={styles.chevron} aria-hidden=\"true\"><IconChevronRight size={12} /></span>\n <span className={styles.prompt} aria-hidden=\"true\">$</span>\n <span className={styles.command} data-empty={block.command ? undefined : true}>{block.command || 'command'}</span>\n <span className={styles.meta}>\n {bookmarked ? <span className={extra.bookmarked} aria-label=\"Bookmarked\"><StarGlyph filled size={12} /></span> : null}\n {cwdName ? <span title={block.cwd ?? undefined}>{cwdName}</span> : null}\n {block.durationMs !== null ? <span>{formatDuration(block.durationMs)}</span> : null}\n <span>{relativeTime(block.startedAt, now)}</span>\n <span className={styles.status} data-tone={status.tone}>{status.label}</span>\n </span>\n </button>\n <div className={styles.blockActions}>\n {actions.includes('copy-output') ? (\n <button type=\"button\" className={styles.iconBtn} aria-label=\"Copy output\" title=\"Copy output\"\n disabled={block.fullscreen} onClick={() => onAction('copy-output', block)}>\n <IconCopy size={14} />\n </button>\n ) : null}\n {actions.includes('copy-command') && block.command ? (\n <button type=\"button\" className={styles.iconBtn} aria-label=\"Copy command\" title=\"Copy the command\"\n onClick={() => onAction('copy-command', block)}>\n <span aria-hidden=\"true\" className={styles.prompt}>$</span>\n </button>\n ) : null}\n {actions.includes('send') ? (\n <button type=\"button\" className={styles.iconBtn} aria-label=\"Send to chat\" title=\"Send this block to the chat\"\n onClick={() => onAction('send', block)}>\n <IconSend size={14} />\n </button>\n ) : null}\n {actions.includes('ask') ? (\n <button type=\"button\" className={styles.iconBtn} aria-label=\"Ask a seat about this command\" aria-haspopup=\"menu\"\n title=\"Ask… — Claude Code, Codex, Devin, Grok, a local model, or all of them side by side\"\n onClick={(e) => onAction('ask', block, { anchor: e.currentTarget })}>\n <AskGlyph />\n </button>\n ) : null}\n {offerExplain ? (\n <button type=\"button\" className={styles.iconBtn} aria-label=\"Explain and fix this error\" title=\"Ask the chat to explain and fix this error\"\n onClick={() => onAction('explain', block)}>\n <span aria-hidden=\"true\" style={{ fontSize: 'var(--text-2xs-size)', fontWeight: 600 }}>Fix</span>\n </button>\n ) : null}\n {actions.includes('rerun') && extras?.canRerun && block.command && !block.running ? (\n <button type=\"button\" className={styles.iconBtn} aria-label=\"Re-run this command\" title=\"Re-run: type it at the prompt and press Enter\"\n onClick={() => onAction('rerun', block)}>\n <RerunGlyph />\n </button>\n ) : null}\n {actions.includes('bookmark') ? (\n <button type=\"button\" className={styles.iconBtn} aria-pressed={bookmarked} aria-label={bookmarked ? 'Remove bookmark' : 'Bookmark this block'}\n title={bookmarked ? 'Remove bookmark' : 'Bookmark'} onClick={() => onAction('bookmark', block)}>\n <StarGlyph filled={bookmarked} />\n </button>\n ) : null}\n {actions.includes('copy-link') ? (\n <button type=\"button\" className={styles.iconBtn} aria-label=\"Copy link to this block\" title=\"Copy a verse://terminal link to this block\"\n onClick={() => onAction('copy-link', block)}>\n <LinkGlyph />\n </button>\n ) : null}\n {actions.includes('jump') ? (\n <button type=\"button\" className={styles.iconBtn} aria-label=\"Show in terminal\" title=\"Show in terminal\"\n onClick={() => onAction('jump', block)}>\n <span aria-hidden=\"true\">↗</span>\n </button>\n ) : null}\n {actions.includes('paste') && block.command ? (\n <button type=\"button\" className={styles.iconBtn} aria-label=\"Paste command in terminal\" title=\"Paste the command at a terminal prompt (it does not run)\"\n onClick={() => onAction('paste', block)}>\n <PasteGlyph />\n </button>\n ) : null}\n {terminal && open && output !== null && output.trim().length > 0 ? (\n <button type=\"button\" className={styles.iconBtn} aria-pressed={filterOpen} aria-label=\"Filter output lines\" title=\"Filter the output's lines\"\n onClick={() => { setFilterOpen((o) => !o); if (filterOpen) setFilter(EMPTY_FILTER); }}>\n <FilterGlyph />\n </button>\n ) : null}\n </div>\n </div>\n {terminal && urls.length > 0 ? (\n <div className={extra.bar}>\n {urls.map((url) => (\n <button key={url} type=\"button\" className={extra.chip} onClick={() => onAction('open-url', block, { url })}\n title={`Open ${url} in the Browser pane`}>\n <BrowserGlyph size={12} /><span className={extra.chipCode}>{urlLabel(url)}</span><span className={extra.chipVerb}>Open in Browser</span>\n </button>\n ))}\n </div>\n ) : null}\n {open && filterOpen ? (\n <div className={extra.filterRow} role=\"search\" aria-label=\"Filter output\">\n <input className={extra.filterInput} aria-label=\"Filter lines\" placeholder={filter.regex ? 'Regular expression' : 'Text to match'}\n value={filter.pattern} autoFocus aria-invalid={filtered?.error ? true : undefined}\n onChange={(e) => setFilter((f) => ({ ...f, pattern: e.target.value }))}\n onKeyDown={(e) => { if (e.key === 'Escape') { e.preventDefault(); setFilter(EMPTY_FILTER); setFilterOpen(false); } }} />\n <button type=\"button\" className={styles.toggle} aria-pressed={filter.regex} aria-label=\"Regular expression\" title=\"Regular expression\"\n onClick={() => setFilter((f) => ({ ...f, regex: !f.regex }))}>.*</button>\n <button type=\"button\" className={styles.toggle} aria-pressed={filter.caseSensitive} aria-label=\"Match case\" title=\"Match case\"\n onClick={() => setFilter((f) => ({ ...f, caseSensitive: !f.caseSensitive }))}>Aa</button>\n <button type=\"button\" className={styles.toggle} aria-pressed={filter.invert} aria-label=\"Invert: hide matching lines\" title=\"Invert: show the lines that do NOT match\"\n onClick={() => setFilter((f) => ({ ...f, invert: !f.invert }))}>!</button>\n <span className={extra.filterCount} aria-live=\"polite\">\n {filtered?.error ? 'Invalid pattern' : filtered ? `${filtered.shown} of ${filtered.total} lines` : ''}\n </span>\n </div>\n ) : null}\n {open ? (\n block.fullscreen ? (\n <p className={styles.outputNote}>A full-screen program (an editor, a pager): its screen is not kept as output.</p>\n ) : output === null ? (\n <p className={styles.outputNote} role={error ? 'alert' : 'status'}>{error ? 'The output could not be loaded.' : 'Loading output…'}</p>\n ) : output.trim().length === 0 ? (\n <p className={styles.outputNote}>{block.running ? 'No output yet.' : 'No output.'}</p>\n ) : (\n <>\n <pre className={styles.output} tabIndex={0} aria-label={`Output of ${block.command || 'the command'}`}>\n <AnsiOutput text={filtered && !filtered.error ? filtered.text : output} />\n </pre>\n {block.truncated ? <p className={styles.outputNote}>Only the last part of this output is kept.</p> : null}\n </>\n )\n ) : null}\n {terminal && status.tone === 'error' && block.exitCode !== null && open ? (\n <FixChips\n variant=\"card\"\n load={fixLoader}\n askTargets={extras!.askTargets}\n onPaste={(text) => onAction('paste-text', block, { text })}\n onAsk={(seatId) => onAction('ask-seat', block, { seatId })}\n onAskMore={(anchor) => onAction('ask', block, { anchor })}\n />\n ) : null}\n </li>\n );\n});\n\nexport function BlockList({ blocks, loadOutput, onAction, actions, emptyTitle, emptyBody, highlightId = null, label, extras }: BlockListProps) {\n const [toggled, setToggled] = useState<ReadonlyMap<string, boolean>>(() => new Map());\n const [bookmarkedOnly, setBookmarkedOnly] = useState(false);\n const scroller = useRef<HTMLDivElement>(null);\n const pinned = useRef(true);\n const [now, setNow] = useState(() => Date.now());\n\n useEffect(() => {\n const timer = setInterval(() => setNow(Date.now()), 30_000);\n return () => clearInterval(timer);\n }, []);\n\n const shown = useMemo(\n () => (bookmarkedOnly && extras ? blocks.filter((b) => extras.bookmarks.has(b.id)) : blocks),\n [blocks, bookmarkedOnly, extras],\n );\n\n const onToggle = useCallback((id: string) => {\n setToggled((prev) => {\n const next = new Map(prev);\n const index = blocks.findIndex((b) => b.id === id);\n const current = prev.get(id) ?? defaultOpen(blocks, index);\n next.set(id, !current);\n return next;\n });\n }, [blocks]);\n\n // Follow new blocks while the list is scrolled to the bottom (like a terminal).\n useEffect(() => {\n const el = scroller.current;\n if (!el || !pinned.current || highlightId) return;\n el.scrollTop = el.scrollHeight;\n }, [blocks, highlightId]);\n\n if (blocks.length === 0) {\n return (\n <div className={styles.blocksEmpty}>\n <EmptyState compact title={emptyTitle} body={emptyBody} />\n </div>\n );\n }\n\n const selectedCount = extras ? extras.selection.ids.size : 0;\n const bookmarkCount = extras ? blocks.filter((b) => extras.bookmarks.has(b.id)).length : 0;\n\n return (\n <div className={styles.blocks} ref={scroller} onScroll={(e) => {\n const el = e.currentTarget;\n pinned.current = el.scrollHeight - el.scrollTop - el.clientHeight < 24;\n }}>\n {extras && (selectedCount > 0 || bookmarkCount > 0) ? (\n <div className={extra.listTools} role=\"toolbar\" aria-label={selectedCount > 0 ? 'Selected blocks' : 'Blocks'}>\n {selectedCount > 0 ? (\n <>\n <span aria-live=\"polite\">{selectedCount} selected</span>\n <button type=\"button\" className={extra.chip} onClick={() => extras.onSelectionAction('copy-output')}>Copy outputs</button>\n <button type=\"button\" className={extra.chip} onClick={() => extras.onSelectionAction('send')}>Send to chat</button>\n <button type=\"button\" className={extra.chip} aria-haspopup=\"menu\" onClick={(e) => extras.onSelectionAction('ask', e.currentTarget)}>Ask…</button>\n <button type=\"button\" className={extra.chip} aria-label=\"Clear selection\" title=\"Clear selection\" onClick={extras.onClearSelection}>\n <IconX size={10} />\n </button>\n </>\n ) : <span>⇧/⌘-click blocks to select several</span>}\n <span className={extra.barSpacer} />\n {bookmarkCount > 0 ? (\n <button type=\"button\" className={styles.toggle} aria-pressed={bookmarkedOnly} title=\"Show only bookmarked blocks\"\n onClick={() => setBookmarkedOnly((v) => !v)}>\n <StarGlyph filled={bookmarkedOnly} size={12} /> {bookmarkCount}\n </button>\n ) : null}\n </div>\n ) : null}\n <ol className={styles.blockList} aria-label={label} aria-multiselectable={extras ? true : undefined}>\n {shown.map((block) => {\n const index = blocks.indexOf(block);\n return (\n <BlockCard\n key={block.id}\n block={block}\n open={toggled.get(block.id) ?? defaultOpen(blocks, index)}\n onToggle={onToggle}\n {...(loadOutput ? { loadOutput } : {})}\n onAction={onAction}\n actions={actions}\n highlighted={highlightId === block.id}\n now={now}\n {...(extras ? { extras } : {})}\n selected={extras?.selection.ids.has(block.id) ?? false}\n bookmarked={extras?.bookmarks.has(block.id) ?? false}\n />\n );\n })}\n </ol>\n </div>\n );\n}\n\n/** \"Type at a prompt\": a return arrow into a line (same grammar as the shared 16px icons). */\nfunction PasteGlyph() {\n return (\n <svg width={14} height={14} viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" strokeWidth={1.5}\n strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\" focusable=\"false\">\n <path d=\"M13 3.5v4.25a1.5 1.5 0 0 1-1.5 1.5H3.5\" /><path d=\"m6 6.5-2.5 2.75L6 12\" />\n </svg>\n );\n}\n\nfunction defaultOpen(blocks: readonly BlockView[], index: number): boolean {\n const block = blocks[index];\n if (!block) return false;\n return index >= blocks.length - OPEN_LATEST || block.running || blockStatus(block).tone === 'error';\n}\n","/**\n * terminal/AgentTerminal.tsx — the per-chat \"Agent\" tab (3.15): every shell\n * command this chat's agents ran, as read-only blocks, so the operator can\n * watch exactly what ran.\n *\n * READ-ONLY, AND NOTHING RE-RUNS. The blocks are the chat transcript's own\n * tool events (useVerseTranscript reads the chat store the Chat section\n * already streams; it opens no connection of its own). \"Paste in terminal\"\n * types a command at one of YOUR prompts and stops there, like the\n * transcript's \"Run in terminal\". Commands a seat runs where Verse cannot\n * see them (a CLI's own sandboxed sub-shells it does not report) are not\n * here — only what the seat reported as a tool call.\n */\nimport { useMemo } from 'react';\nimport { useVerseTranscript } from '../useVerseTranscript.js';\nimport { BlockList, type BlockAction } from './BlockList.js';\nimport { agentBlocksFromTranscript, type BlockView } from './blocks-model.js';\nimport styles from './TerminalPanel.module.css';\n\nexport interface AgentTerminalProps {\n sessionId: string;\n onAction: (action: BlockAction, block: BlockView) => void;\n /** Ring this block (from the panel). */\n highlightId?: string | null;\n}\n\nexport const AGENT_BLOCK_ACTIONS: readonly BlockAction[] = ['copy-output', 'copy-command', 'send', 'explain', 'paste'];\n\nexport function AgentTerminal({ sessionId, onAction, highlightId = null }: AgentTerminalProps) {\n const transcript = useVerseTranscript(sessionId);\n const blocks = useMemo(() => agentBlocksFromTranscript(transcript.items), [transcript.items]);\n const running = blocks.some((b) => b.running);\n return (\n <div className={styles.leaf} data-testid=\"agent-terminal\">\n <div className={styles.header}>\n <span className={styles.cwd}>What the agents ran in this chat</span>\n <span className={styles.headerStatus} role=\"status\" aria-live=\"polite\">\n {running ? 'A command is running…' : blocks.length > 0 ? `${blocks.length} ${blocks.length === 1 ? 'command' : 'commands'}` : ''}\n </span>\n </div>\n <BlockList\n blocks={blocks}\n onAction={onAction}\n actions={AGENT_BLOCK_ACTIONS}\n highlightId={highlightId}\n label=\"Commands the agents ran\"\n emptyTitle=\"No agent commands yet\"\n emptyBody=\"When an agent in this chat runs a shell command, it appears here as a read-only block: the command, its output and how it ended.\"\n />\n </div>\n );\n}\n","/**\n * terminal/layout-model.ts — tabs and splits (3.15).\n *\n * The SERVER owns shells (tabs, PTYs, scrollback); the PAGE owns how they are\n * laid out. A strip tab is a GROUP of up to six shells: side by side (row),\n * stacked (column), or tiled (grid — ⌈√n⌉ columns). One pane can be ZOOMED\n * to fill the group for a moment. The layout is kept per chat in\n * localStorage, so a reload reattaches to the same shells in the same\n * arrangement; shells the layout does not know yet (opened elsewhere) get a\n * group of their own, and groups whose shells are gone disappear.\n *\n * WHY SIX NOW. Until 3.15 every visible shell held its own streaming\n * connection and a browser allows ~6 per origin, so a group stopped at two.\n * The panel now reads every visible shell over ONE multiplexed connection\n * (panel-stream.ts `createTerminalStreamMux`), so a group's size is a\n * question of screen space, not connections.\n */\n\n/** Where a split puts the new pane, relative to the focused one. */\nexport type SplitDirection = 'row' | 'column';\n/** How a group lays its panes out. */\nexport type GroupArrangement = 'row' | 'column' | 'grid';\nexport type LeafMode = 'terminal' | 'blocks';\nexport type PaneDirection = 'left' | 'right' | 'up' | 'down';\n\nexport interface TerminalGroup {\n id: string;\n /** Shell ids, 1 to MAX_PANES_PER_GROUP. */\n panes: string[];\n direction: GroupArrangement;\n /** The pane keystrokes go to. */\n focused: string;\n /** A pane shown alone, filling the group; absent = every pane. */\n zoomed?: string | null;\n}\n\nexport const AGENT_GROUP_ID = 'agent';\nexport const MAX_PANES_PER_GROUP = 6;\nconst ARRANGEMENTS: readonly GroupArrangement[] = ['row', 'column', 'grid'];\n\nexport interface TerminalLayout {\n groups: TerminalGroup[];\n /** A group id, AGENT_GROUP_ID, or null (nothing chosen yet). */\n active: string | null;\n /** Per shell: the raw terminal or its block list. */\n modes: Record<string, LeafMode>;\n}\n\nexport const EMPTY_LAYOUT: TerminalLayout = { groups: [], active: null, modes: {} };\n\nlet groupCounter = 0;\nexport function newGroupId(): string {\n groupCounter += 1;\n return `g-${Date.now().toString(36)}-${groupCounter}`;\n}\n\n/**\n * Fit a (possibly stale, possibly hand-edited) layout to the shells that\n * exist: unknown shells pruned, empty groups dropped, duplicates removed,\n * new shells appended as their own groups, the active group kept valid.\n */\nexport function reconcileLayout(layout: TerminalLayout, liveTabIds: readonly string[]): TerminalLayout {\n const live = new Set(liveTabIds);\n const seen = new Set<string>();\n const groups: TerminalGroup[] = [];\n for (const g of layout.groups) {\n const panes = g.panes.filter((id) => live.has(id) && !seen.has(id)).slice(0, MAX_PANES_PER_GROUP);\n for (const id of panes) seen.add(id);\n if (panes.length === 0) continue;\n const focused = panes.includes(g.focused) ? g.focused : panes[0]!;\n const direction: GroupArrangement = ARRANGEMENTS.includes(g.direction) ? g.direction : 'row';\n const zoomed = g.zoomed && panes.length > 1 && panes.includes(g.zoomed) ? g.zoomed : null;\n groups.push({ id: g.id, panes, direction, focused, ...(zoomed ? { zoomed } : {}) });\n }\n for (const id of liveTabIds) {\n if (seen.has(id)) continue;\n seen.add(id);\n groups.push({ id: newGroupId(), panes: [id], direction: 'row', focused: id });\n }\n const modes: Record<string, LeafMode> = {};\n for (const [id, mode] of Object.entries(layout.modes)) {\n if (live.has(id) && (mode === 'terminal' || mode === 'blocks')) modes[id] = mode;\n }\n let active = layout.active;\n if (active !== AGENT_GROUP_ID && !groups.some((g) => g.id === active)) active = groups.at(-1)?.id ?? null;\n const unchanged = active === layout.active\n && groups.length === layout.groups.length\n && groups.every((g, i) => {\n const o = layout.groups[i]!;\n return o.id === g.id && o.focused === g.focused && o.direction === g.direction && o.panes.join() === g.panes.join()\n && (o.zoomed ?? null) === (g.zoomed ?? null);\n })\n && Object.keys(modes).length === Object.keys(layout.modes).length;\n return unchanged ? layout : { groups, active, modes };\n}\n\n/** A new shell in its own group, made active. */\nexport function addGroup(layout: TerminalLayout, tabId: string): TerminalLayout {\n const group: TerminalGroup = { id: newGroupId(), panes: [tabId], direction: 'row', focused: tabId };\n return { ...layout, groups: [...layout.groups.filter((g) => !g.panes.includes(tabId)), group], active: group.id };\n}\n\n/**\n * The arrangement after a split: the first split picks it; splitting again\n * the same way keeps it; splitting the OTHER way (a row split down) tiles.\n */\nexport function arrangementAfterSplit(current: GroupArrangement, panes: number, direction: SplitDirection): GroupArrangement {\n if (panes <= 1) return direction;\n if (current === 'grid' || current === direction) return current;\n return 'grid';\n}\n\n/** Put `tabId` beside the group's focused pane (un-zooming it). Null when the group is full. */\nexport function splitGroup(layout: TerminalLayout, groupId: string, tabId: string, direction: SplitDirection): TerminalLayout | null {\n const group = layout.groups.find((g) => g.id === groupId);\n if (!group || group.panes.length >= MAX_PANES_PER_GROUP) return null;\n const at = group.panes.indexOf(group.focused);\n const panes = [...group.panes];\n panes.splice(at + 1, 0, tabId);\n const next: TerminalGroup = { id: group.id, panes, direction: arrangementAfterSplit(group.direction, group.panes.length, direction), focused: tabId };\n return {\n ...layout,\n groups: layout.groups.filter((g) => !g.panes.includes(tabId) || g.id === groupId).map((g) => (g.id === groupId ? next : g)),\n active: groupId,\n };\n}\n\n/** A shell closed: out of its group (the group goes when empty); focus moves to its neighbour. */\nexport function removePane(layout: TerminalLayout, tabId: string): TerminalLayout {\n const groups: TerminalGroup[] = [];\n let removedGroupIndex = -1;\n layout.groups.forEach((g, index) => {\n if (!g.panes.includes(tabId)) {\n groups.push(g);\n return;\n }\n const panes = g.panes.filter((id) => id !== tabId);\n if (panes.length === 0) {\n removedGroupIndex = index;\n return;\n }\n const { zoomed, ...rest } = g;\n const keepZoom = zoomed && zoomed !== tabId && panes.length > 1;\n groups.push({ ...rest, panes, focused: g.focused === tabId ? panes[0]! : g.focused, ...(keepZoom ? { zoomed } : {}) });\n });\n const modes = { ...layout.modes };\n delete modes[tabId];\n let active = layout.active;\n if (removedGroupIndex >= 0 && layout.groups[removedGroupIndex]!.id === active) {\n active = (groups[removedGroupIndex] ?? groups[removedGroupIndex - 1] ?? null)?.id ?? null;\n }\n return { groups, active, modes };\n}\n\nexport function focusPane(layout: TerminalLayout, groupId: string, tabId: string): TerminalLayout {\n const group = layout.groups.find((g) => g.id === groupId);\n if (!group || !group.panes.includes(tabId) || (group.focused === tabId && layout.active === groupId)) return layout;\n return { ...layout, active: groupId, groups: layout.groups.map((g) => (g.id === groupId ? { ...g, focused: tabId } : g)) };\n}\n\n/** Lay a group out as a row, a column or a grid. */\nexport function setArrangement(layout: TerminalLayout, groupId: string, direction: GroupArrangement): TerminalLayout {\n const group = layout.groups.find((g) => g.id === groupId);\n if (!group || group.direction === direction) return layout;\n return { ...layout, groups: layout.groups.map((g) => (g.id === groupId ? { ...g, direction } : g)) };\n}\n\n/** Row → column → grid → row. */\nexport function nextArrangement(direction: GroupArrangement): GroupArrangement {\n return ARRANGEMENTS[(ARRANGEMENTS.indexOf(direction) + 1) % ARRANGEMENTS.length]!;\n}\n\n/** Zoom the focused pane to fill its group, or put it back. A single pane never zooms. */\nexport function toggleZoom(layout: TerminalLayout, groupId: string): TerminalLayout {\n const group = layout.groups.find((g) => g.id === groupId);\n if (!group) return layout;\n const zoomed = group.zoomed ? null : group.panes.length > 1 ? group.focused : null;\n if ((group.zoomed ?? null) === zoomed) return layout;\n return {\n ...layout,\n groups: layout.groups.map((g) => {\n if (g.id !== groupId) return g;\n const { zoomed: _previous, ...rest } = g;\n return zoomed ? { ...rest, zoomed } : rest;\n }),\n };\n}\n\n/** Columns × rows of a grid of `n` panes: ⌈√n⌉ columns (2 → 2×1, 3–4 → 2×2, 5–6 → 3×2). */\nexport function gridShape(n: number): { cols: number; rows: number } {\n const cols = Math.max(1, Math.ceil(Math.sqrt(n)));\n return { cols, rows: Math.max(1, Math.ceil(n / cols)) };\n}\n\n/** Each pane's cell: its row and column, and how many columns it spans (a short last row's final pane stretches). */\nexport function paneCells(group: Pick<TerminalGroup, 'panes' | 'direction'>): Array<{ id: string; row: number; col: number; span: number }> {\n const n = group.panes.length;\n if (group.direction === 'row') return group.panes.map((id, i) => ({ id, row: 0, col: i, span: 1 }));\n if (group.direction === 'column') return group.panes.map((id, i) => ({ id, row: i, col: 0, span: 1 }));\n const { cols } = gridShape(n);\n return group.panes.map((id, i) => {\n const row = Math.floor(i / cols);\n const col = i % cols;\n // Three panes: two on top, the third full-width below — no hole in the grid.\n const span = i === n - 1 ? cols - col : 1;\n return { id, row, col, span };\n });\n}\n\n/**\n * The pane beside `from` in a direction (⌥⌘←→↑↓), or null at the edge. Up and\n * down pick the nearest row, then the pane most in line with this one.\n */\nexport function neighborPane(group: Pick<TerminalGroup, 'panes' | 'direction'>, from: string, direction: PaneDirection): string | null {\n const cells = paneCells(group);\n const here = cells.find((c) => c.id === from);\n if (!here) return null;\n const center = (c: { col: number; span: number }) => c.col + c.span / 2;\n let best: { id: string; primary: number; secondary: number } | null = null;\n for (const c of cells) {\n if (c.id === from) continue;\n let primary: number;\n let secondary = 0;\n if (direction === 'left' || direction === 'right') {\n if (c.row !== here.row) continue;\n primary = direction === 'left' ? here.col - c.col : c.col - here.col;\n } else {\n primary = direction === 'up' ? here.row - c.row : c.row - here.row;\n secondary = Math.abs(center(c) - center(here));\n }\n if (primary <= 0) continue;\n if (!best || primary < best.primary || (primary === best.primary && secondary < best.secondary)) best = { id: c.id, primary, secondary };\n }\n return best?.id ?? null;\n}\n\n/** The next / previous pane in order, wrapping. */\nexport function cyclePane(group: Pick<TerminalGroup, 'panes'>, from: string, delta: 1 | -1): string {\n const i = group.panes.indexOf(from);\n if (i < 0) return group.panes[0] ?? from;\n return group.panes[(i + delta + group.panes.length) % group.panes.length]!;\n}\n\nexport function setMode(layout: TerminalLayout, tabId: string, mode: LeafMode): TerminalLayout {\n if ((layout.modes[tabId] ?? 'terminal') === mode) return layout;\n return { ...layout, modes: { ...layout.modes, [tabId]: mode } };\n}\n\n// ---------------------------------------------------------------------------\n// Persistence (per chat; storage failures are harmless)\n// ---------------------------------------------------------------------------\n\nconst KEY_PREFIX = 'ashlr.verse.terminal.layout.v1:';\n\nexport function layoutStorageKey(sessionId: string): string {\n return `${KEY_PREFIX}${sessionId}`;\n}\n\nfunction isGroup(value: unknown): value is TerminalGroup {\n const g = value as TerminalGroup | null;\n return !!g && typeof g.id === 'string' && Array.isArray(g.panes) && g.panes.every((p) => typeof p === 'string')\n && typeof g.focused === 'string' && ARRANGEMENTS.includes(g.direction)\n && (g.zoomed === undefined || g.zoomed === null || typeof g.zoomed === 'string');\n}\n\nexport function parseLayout(raw: string | null): TerminalLayout {\n if (!raw) return EMPTY_LAYOUT;\n try {\n const parsed = JSON.parse(raw) as Partial<TerminalLayout> | null;\n if (!parsed || typeof parsed !== 'object') return EMPTY_LAYOUT;\n const groups = Array.isArray(parsed.groups) ? parsed.groups.filter(isGroup).slice(0, 32) : [];\n const active = typeof parsed.active === 'string' ? parsed.active : null;\n const modes = parsed.modes && typeof parsed.modes === 'object' ? (parsed.modes as Record<string, LeafMode>) : {};\n return { groups, active, modes };\n } catch {\n return EMPTY_LAYOUT;\n }\n}\n\nexport function loadLayout(sessionId: string, storage: Pick<Storage, 'getItem'> | null = safeStorage()): TerminalLayout {\n try {\n return parseLayout(storage?.getItem(layoutStorageKey(sessionId)) ?? null);\n } catch {\n return EMPTY_LAYOUT;\n }\n}\n\nexport function saveLayout(sessionId: string, layout: TerminalLayout, storage: Pick<Storage, 'setItem' | 'removeItem'> | null = safeStorage()): void {\n try {\n if (layout.groups.length === 0) storage?.removeItem(layoutStorageKey(sessionId));\n else storage?.setItem(layoutStorageKey(sessionId), JSON.stringify(layout));\n } catch {\n /* private mode / quota: the layout lasts for this page only */\n }\n}\n\nfunction safeStorage(): Storage | null {\n try {\n return typeof localStorage === 'undefined' ? null : localStorage;\n } catch {\n return null;\n }\n}\n","import type { VerseTerminalAssistMode } from '../../../data/api-types.js';\n\n/** Shown before the request is sent from either terminal command entry point. */\nexport function assistDisclosure(mode: VerseTerminalAssistMode): string {\n if (mode === 'auto') {\n return 'Local model first. If it is unavailable, your request, current folder, and recent command/output may be sent to Grok.';\n }\n if (mode === 'off') return 'Plain-English commands are off.';\n return 'Your request, current folder, and recent command/output go only to the configured local model.';\n}\n\nexport function assistLoadingLabel(mode: VerseTerminalAssistMode): string {\n return mode === 'auto' ? 'Asking the local model; Grok may answer if it is unavailable…' : 'Asking the local model…';\n}\n","/**\n * terminal/input-model.ts — the input editor's pure rules (3.15): when it is\n * shown, what Enter sends, the ghost text, ↑/↓ through history, which word is\n * a path to complete, and `#` → plain language. No DOM, no CodeMirror\n * (command-editor.ts is the lazily loaded editor; CommandInput.tsx the glue).\n */\n\n/**\n * Where the shell is, from its OSC 133 marks as xterm parsed them:\n * A → drawing a prompt, B → waiting for input, C → running, D → done.\n * The editor is offered only at `input` — after B, before C.\n */\nexport type PromptPhase = 'unknown' | 'prompt' | 'input' | 'running' | 'done';\n\nexport function nextPromptPhase(phase: PromptPhase, markPayload: string): PromptPhase {\n const code = markPayload.split(';', 1)[0];\n switch (code) {\n case 'A': return 'prompt';\n case 'B': return 'input';\n case 'C': return 'running';\n case 'D': return 'done';\n default: return phase;\n }\n}\n\nexport interface InputVisibility {\n phase: PromptPhase;\n /** The integration is live: without marks there is no telling where a prompt is. */\n integration: boolean;\n alternateScreen: boolean;\n exited: boolean;\n /** Raw input for this shell (the operator's own line editor, untouched). */\n raw: boolean;\n /** The operator typed into the terminal itself at this prompt: it is theirs until the next one. */\n handedOff: boolean;\n /** The terminal view is showing (not the Blocks view). */\n terminalMode: boolean;\n}\n\nexport function inputVisible(v: InputVisibility): boolean {\n return v.integration && v.phase === 'input' && !v.alternateScreen && !v.exited && !v.raw && !v.handedOff && v.terminalMode;\n}\n\n/**\n * Terminal replies xterm sends through onData on the program's behalf\n * (cursor position, device attributes, focus in/out) — not the operator\n * typing, so they never hand the prompt over to the raw terminal.\n */\n// eslint-disable-next-line no-control-regex\nconst TERMINAL_REPLY_RE = /^(?:\\x1b\\[\\??[\\d;]*[Rcn]|\\x1b\\[[IO]|\\x1b\\][\\s\\S]*(?:\\x07|\\x1b\\\\)|\\x1bP[\\s\\S]*\\x1b\\\\)+$/;\n\nexport function isOperatorKeystroke(data: string): boolean {\n return data.length > 0 && !TERMINAL_REPLY_RE.test(data);\n}\n\n// eslint-disable-next-line no-control-regex\nconst UNSAFE_IN_PASTE_RE = /[\\u0000-\\u0008\\u000b\\u000c\\u000e-\\u001f\\u007f]/g;\n\n/**\n * What Enter sends to the PTY. One line: the text and a CR, exactly as if\n * typed. Several lines: as ONE bracketed paste then CR when the shell asked\n * for bracketed paste (zsh, bash ≥ 5.1, fish do) — so the shell sees one\n * command, not a line-by-line run — else line by line (each line a CR,\n * which is what typing it would do). Control characters other than tab and\n * newline are dropped: a stray ESC must not end the paste early.\n */\nexport function submitBytes(text: string, bracketedPaste: boolean): string {\n const clean = text.replace(/\\r\\n?/g, '\\n').replace(UNSAFE_IN_PASTE_RE, '').replace(/\\n+$/, '');\n if (!clean.includes('\\n')) return `${clean}\\r`;\n if (bracketedPaste) return `\\x1b[200~${clean}\\x1b[201~\\r`;\n return `${clean.replace(/\\n/g, '\\r')}\\r`;\n}\n\n/** Hand the line to the shell's own editor (no Enter): what Esc / Tab / ⌃R-again do. */\nexport function handOffBytes(text: string, key: string): string {\n const clean = text.replace(/\\r\\n?/g, '\\n').replace(UNSAFE_IN_PASTE_RE, '');\n if (!clean) return key;\n // Several lines can only arrive whole as a bracketed paste; otherwise send the first.\n const line = clean.includes('\\n') ? `\\x1b[200~${clean}\\x1b[201~` : clean;\n return `${line}${key}`;\n}\n\n/**\n * Ghost text: the best history command that starts with what is typed (the\n * list comes ranked from the server: cwd, repo, success, recency), shown\n * after the cursor. Only for one line with something typed.\n */\nexport function ghostFor(text: string, ranked: readonly string[]): string | null {\n if (text.trim().length === 0 || text.includes('\\n')) return null;\n for (const cmd of ranked) {\n if (cmd.length > text.length && cmd.startsWith(text)) return cmd;\n }\n return null;\n}\n\n/**\n * ↑ / ↓ through history, like a shell: ↑ from the draft goes to the most\n * recent command (optionally only those starting with the draft), ↓ past the\n * newest returns to the draft.\n */\nexport class HistoryWalker {\n private index = -1;\n private draft = '';\n private matches: string[] = [];\n\n constructor(private readonly source: () => readonly string[]) {}\n\n get active(): boolean {\n return this.index >= 0;\n }\n\n reset(): void {\n this.index = -1;\n this.draft = '';\n this.matches = [];\n }\n\n /** The text to show after ↑, or null to stay (nothing older). */\n prev(current: string): string | null {\n if (this.index < 0) {\n this.draft = current;\n const prefix = current.trim();\n const all = this.source();\n this.matches = prefix ? all.filter((c) => c.startsWith(prefix) && c !== current) : [...all];\n }\n if (this.index + 1 >= this.matches.length) return null;\n this.index += 1;\n return this.matches[this.index]!;\n }\n\n /** The text to show after ↓, or null when not walking. */\n next(): string | null {\n if (this.index < 0) return null;\n this.index -= 1;\n return this.index < 0 ? this.draft : this.matches[this.index]!;\n }\n}\n\n/** `#…` (or `# …`) is a request in plain language, not a command; null when it is not one. */\nexport function assistRequest(text: string): string | null {\n const m = /^\\s*#\\s*([\\s\\S]*)$/.exec(text);\n if (!m) return null;\n const request = m[1]!.trim();\n return request.length > 0 ? request : null;\n}\n\n// ---------------------------------------------------------------------------\n// Path completion\n// ---------------------------------------------------------------------------\n\n/** The word being typed at `cursor`, when it looks like a path (has a `/`, or starts with `.` or `~`). */\nexport function pathToken(text: string, cursor: number): { from: number; token: string } | null {\n const before = text.slice(0, cursor);\n // A word starts after unescaped whitespace or a shell operator.\n let from = before.length;\n while (from > 0) {\n const ch = before[from - 1]!;\n if (/[\\s;|&<>()`'\"=]/.test(ch) && before[from - 2] !== '\\\\') break;\n from -= 1;\n }\n const token = before.slice(from);\n if (!token || !(token.includes('/') || token.startsWith('.') || token.startsWith('~'))) return null;\n return { from, token };\n}\n\nfunction splitSegments(path: string): string[] {\n return path.split('/').filter((s) => s.length > 0 && s !== '.');\n}\n\n/** POSIX `relative(from, to)` for absolute (or `~/`) paths, without node:path. */\nexport function relativePath(from: string, to: string): string {\n const a = splitSegments(from);\n const b = splitSegments(to);\n let i = 0;\n while (i < a.length && i < b.length && a[i] === b[i]) i += 1;\n const ups = a.length - i;\n const rest = b.slice(i);\n const parts = [...Array.from({ length: ups }, () => '..'), ...rest];\n return parts.join('/') || '.';\n}\n\nfunction joinPath(root: string, rel: string): string {\n return `${root.replace(/\\/+$/, '')}/${rel.replace(/^\\/+/, '')}`;\n}\n\n/**\n * The composer's file index lists files relative to a chat root. For the\n * word being typed in `cwd`, the candidates it names — files, and the\n * directories on the way to them — spelled relative to `cwd` (or as typed,\n * for `~/` and absolute words). Ranked: the next path segment first.\n */\nexport function pathCompletions(token: string, cwd: string | null, files: ReadonlyArray<{ path: string; root: string }>, limit = 30): string[] {\n const out = new Set<string>();\n const typedAbsolute = token.startsWith('/') || token.startsWith('~');\n for (const f of files) {\n const abs = joinPath(f.root, f.path);\n let spelled: string;\n if (typedAbsolute) {\n spelled = token.startsWith('~') && abs.startsWith('~') ? abs : token.startsWith('/') && abs.startsWith('/') ? abs : '';\n if (!spelled) continue;\n } else {\n if (!cwd) continue;\n spelled = relativePath(cwd, abs);\n if (token.startsWith('./') && !spelled.startsWith('.')) spelled = `./${spelled}`;\n }\n if (!spelled.startsWith(token)) continue;\n // Offer the next segment: a directory (with its slash) or the file itself.\n const rest = spelled.slice(token.length);\n const slash = rest.indexOf('/');\n out.add(slash >= 0 ? spelled.slice(0, token.length + slash + 1) : spelled);\n if (out.size >= limit) break;\n }\n return [...out].sort((x, y) => Number(y.endsWith('/')) - Number(x.endsWith('/')) || x.length - y.length || x.localeCompare(y));\n}\n\n/** The search the file index is asked for a word: its last segment (the index matches names and paths). */\nexport function fileIndexQuery(token: string): string {\n const segments = token.split('/').filter((s) => s && s !== '.' && s !== '..' && s !== '~');\n return segments.join('/');\n}\n","/**\n * terminal/CommandInput.tsx — the input editor docked under a shell (3.15).\n *\n * WHEN. Only at a shell prompt: after the integration's OSC 133 B and before\n * C, never in the alternate screen, never for a shell marked Raw, and not\n * again at a prompt where the operator typed into the terminal itself (that\n * prompt is theirs). TerminalLeaf decides (input-model.ts `inputVisible`);\n * this component keeps its editor mounted between prompts so a draft\n * survives a command that is still running.\n *\n * WHAT IT DOES\n * ↩ runs the text: it is written to the PTY followed by CR, exactly\n * what typing it would send (several lines go as ONE bracketed paste);\n * #… ⌘I plain words → a command from the configured model (terminal-assist),\n * put back HERE for review. Nothing runs until the next ↩ — and a\n * command flagged as destructive needs a second one;\n * ghost the best history match, dim, after the cursor (→ / ⇥ take it);\n * ↑ ↓ history, most recent first (starting with what is typed);\n * paths completions from the composer's file index as a path is typed;\n * Ctrl+R the history palette (Ctrl+R again there: the shell's own Ctrl+R);\n * Esc / ⇥ hand the line to the shell's own editor (vi mode, fzf-tab …);\n * ⌃C ⌃D ⌃L as a shell would: clear/interrupt, EOF, clear screen.\n *\n * The operator's dotfiles are never touched: Raw simply turns this off.\n */\nimport { forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState } from 'react';\nimport type { VerseTerminalAssistMode, VerseTerminalAssistResponse } from '../../../data/api-types.js';\nimport { assistDisclosure, assistLoadingLabel } from './assist-disclosure.js';\nimport { ApiError } from '../../../data/client.js';\nimport type { KeyPlatform } from '../shell/command-keys.js';\nimport type { InputEditor, InputEditorFactory, InputKeyIntent } from './input-editor.js';\nimport {\n assistRequest,\n fileIndexQuery,\n ghostFor,\n handOffBytes,\n HistoryWalker,\n pathCompletions,\n pathToken,\n submitBytes,\n} from './input-model.js';\nimport type { PanelTerminalApi } from './panel-client.js';\nimport styles from './TerminalPanel.module.css';\n\nexport interface CommandInputHandle {\n focus(): void;\n getText(): string;\n /** Put a command in the editor (from the palette, a block's \"paste\") — never run. */\n insert(text: string): void;\n /** ⌘I / \"Generate command…\": turn the typed text (or a new request) into a command. */\n openAssist(): void;\n}\n\nexport interface CommandInputProps {\n tabId: string;\n sessionId: string | null;\n cwd: string | null;\n /** At a prompt, and the editor is wanted there. */\n visible: boolean;\n /** Its pane has the keyboard: take focus when a prompt appears. */\n focusWanted: boolean;\n api: PanelTerminalApi;\n assistMode: VerseTerminalAssistMode;\n createEditor: InputEditorFactory;\n platform: KeyPlatform;\n /** Does the shell accept bracketed paste right now (it turns it on at its prompt)? */\n bracketedPaste: () => boolean;\n /** Bytes to the PTY, in order with everything else typed in this pane. */\n send: (text: string) => void;\n /** The line went to the shell's own editor: the terminal gets the keyboard until the next prompt. */\n onHandOff: () => void;\n /** Ctrl+R, with what was typed. */\n onHistorySearch: (draft: string) => void;\n onError: (text: string) => void;\n /** The panel's own keys (⌘D, ⌘F, ⌥⌘arrows, ⇧⌘Return …) reach it from the editor too; true = taken. */\n onPanelKey?: (event: KeyboardEvent) => boolean;\n}\n\n/** Recent history per cwd, shared by every pane: one request per prompt, not per keystroke. */\nconst historyCache = new Map<string, { at: number; ranked: string[]; recent: string[] }>();\nconst HISTORY_TTL_MS = 15_000;\nconst HISTORY_FETCH_LIMIT = 300;\n\n/** Forget cached history (after a clear, or in tests). */\nexport function resetCommandInputHistoryCache(): void {\n historyCache.clear();\n}\n\nexport const CommandInput = forwardRef<CommandInputHandle, CommandInputProps>(function CommandInput(props, ref) {\n const { visible, focusWanted, cwd } = props;\n const hostRef = useRef<HTMLDivElement>(null);\n const editorRef = useRef<InputEditor | null>(null);\n const propsRef = useRef(props);\n propsRef.current = props;\n const [ready, setReady] = useState(false);\n const [failed, setFailed] = useState(false);\n const [assistMode, setAssistMode] = useState(false);\n const [assist, setAssist] = useState<{ state: 'idle' | 'loading' | 'done' | 'error'; result: VerseTerminalAssistResponse | null; error: string | null }>({ state: 'idle', result: null, error: null });\n /** A generated command flagged risky, not yet confirmed with a second ↩. */\n const riskyPending = useRef<string | null>(null);\n const [riskyWarn, setRiskyWarn] = useState(false);\n const history = useRef<{ ranked: string[]; recent: string[] }>({ ranked: [], recent: [] });\n const walker = useRef(new HistoryWalker(() => history.current.recent));\n const cwdKey = cwd ?? '';\n\n // -------------------------------------------------------------------------\n // History for this prompt\n // -------------------------------------------------------------------------\n\n const loadHistory = useCallback(async (force = false) => {\n const api = propsRef.current.api;\n if (!api.history) return;\n const hit = historyCache.get(cwdKey);\n if (hit && !force && Date.now() - hit.at < HISTORY_TTL_MS) {\n history.current = hit;\n return;\n }\n try {\n const res = await api.history({ cwd: cwdKey || null, limit: HISTORY_FETCH_LIMIT });\n const ranked = res.entries.map((e) => e.cmd);\n const recent = [...res.entries].sort((a, b) => Date.parse(b.ts) - Date.parse(a.ts)).map((e) => e.cmd);\n const next = { at: Date.now(), ranked, recent };\n historyCache.set(cwdKey, next);\n history.current = next;\n } catch {\n /* no history (locked, offline, off): the editor still works */\n }\n }, [cwdKey]);\n\n /** What was just run goes to the front at once (the server's copy lands when the command ends). */\n const remember = useCallback((cmd: string) => {\n const trimmed = cmd.trim();\n if (!trimmed) return;\n const front = (list: string[]) => [trimmed, ...list.filter((c) => c !== trimmed)];\n const next = { at: historyCache.get(cwdKey)?.at ?? 0, ranked: front(history.current.ranked), recent: front(history.current.recent) };\n history.current = next;\n // Stale on purpose: the next prompt refetches (exit codes, other panes).\n historyCache.set(cwdKey, { ...next, at: 0 });\n }, [cwdKey]);\n\n const updateGhost = useCallback((text: string) => {\n const editor = editorRef.current;\n if (!editor) return;\n editor.setGhost(assistRequest(text) !== null ? null : ghostFor(text, history.current.ranked));\n }, []);\n\n // -------------------------------------------------------------------------\n // Assist\n // -------------------------------------------------------------------------\n\n const runAssist = useCallback(async (request: string) => {\n const p = propsRef.current;\n if (!p.api.assist) {\n p.onError('This server cannot generate commands.');\n return;\n }\n setAssistMode(true);\n setAssist({ state: 'loading', result: null, error: null });\n try {\n const result = await p.api.assist({ request, tabId: p.tabId, ...(p.cwd ? { cwd: p.cwd } : {}), ...(p.assistMode === 'auto' ? { cloudAllowed: true } : {}) });\n setAssist({ state: 'done', result, error: null });\n riskyPending.current = result.risky ? result.command : null;\n setRiskyWarn(false);\n editorRef.current?.setText(result.command);\n editorRef.current?.focus();\n } catch (err) {\n const text = err instanceof ApiError && err.status === 401\n ? 'Unlock actions with the mutation token to generate commands.'\n : err instanceof ApiError && err.detail ? err.detail : 'The command could not be generated.';\n setAssist({ state: 'error', result: null, error: text });\n }\n }, []);\n\n const resetAssist = useCallback(() => {\n setAssistMode(false);\n setAssist({ state: 'idle', result: null, error: null });\n riskyPending.current = null;\n setRiskyWarn(false);\n }, []);\n\n // -------------------------------------------------------------------------\n // Keys\n // -------------------------------------------------------------------------\n\n const onKey = useCallback((intent: InputKeyIntent): boolean => {\n const editor = editorRef.current;\n const p = propsRef.current;\n if (!editor) return false;\n const text = editor.getText();\n switch (intent) {\n case 'submit': {\n const request = assistRequest(text);\n if (request !== null) {\n void runAssist(request);\n return true;\n }\n if (text.trim().length > 0 && riskyPending.current !== null && riskyPending.current === text) {\n // A generated command that changes or deletes things: one more ↩ to mean it.\n riskyPending.current = null;\n setRiskyWarn(true);\n return true;\n }\n p.send(submitBytes(text, p.bracketedPaste()));\n remember(text);\n walker.current.reset();\n editor.setText('');\n resetAssist();\n return true;\n }\n case 'history-prev': {\n const prev = walker.current.prev(text);\n if (prev !== null) editor.setText(prev);\n return true;\n }\n case 'history-next': {\n const next = walker.current.next();\n if (next === null) return false;\n editor.setText(next);\n return true;\n }\n case 'history-search':\n p.onHistorySearch(text);\n return true;\n case 'assist': {\n const request = assistRequest(text) ?? (text.trim() ? text.trim() : null);\n if (request) void runAssist(request);\n else {\n setAssistMode(true);\n editor.setText('# ');\n }\n return true;\n }\n case 'interrupt':\n if (text.length > 0) {\n editor.setText('');\n walker.current.reset();\n resetAssist();\n } else {\n p.send('\\x03');\n }\n return true;\n case 'eof':\n p.send('\\x04');\n return true;\n case 'clear-screen':\n p.send('\\x0c');\n return true;\n case 'hand-off':\n if (assistMode && assist.state !== 'idle') {\n resetAssist();\n return true;\n }\n if (text.length > 0) p.send(handOffBytes(text, ''));\n editor.setText('');\n p.onHandOff();\n return true;\n case 'tab':\n p.send(handOffBytes(text, '\\t'));\n editor.setText('');\n p.onHandOff();\n return true;\n }\n }, [assist.state, assistMode, remember, resetAssist, runAssist]);\n\n const onKeyRef = useRef(onKey);\n onKeyRef.current = onKey;\n\n // -------------------------------------------------------------------------\n // The editor: created the first time a prompt shows it, kept afterwards\n // -------------------------------------------------------------------------\n\n useEffect(() => {\n if (!visible || editorRef.current || failed) return;\n const host = hostRef.current;\n if (!host) return;\n let cancelled = false;\n propsRef.current.createEditor({\n host,\n initial: '',\n label: 'Command',\n placeholder: placeholderFor(propsRef.current.platform),\n onChange: (text) => {\n updateGhost(text);\n setAssistMode(assistRequest(text) !== null || text.trimStart().startsWith('#'));\n if (riskyPending.current !== null && text !== riskyPending.current) riskyPending.current = null;\n setRiskyWarn(false);\n },\n onKey: (intent) => onKeyRef.current(intent),\n completePaths: async (text, cursor) => {\n const p = propsRef.current;\n const tok = pathToken(text, cursor);\n if (!tok || !p.sessionId || !p.api.files) return null;\n const files = await p.api.files(p.sessionId, fileIndexQuery(tok.token));\n return { from: tok.from, options: pathCompletions(tok.token, p.cwd, files) };\n },\n }).then((editor) => {\n if (cancelled) {\n editor.dispose();\n return;\n }\n editorRef.current = editor;\n setReady(true);\n }, (err) => {\n console.error('[verse] the command editor failed to load', err);\n if (!cancelled) setFailed(true);\n });\n return () => { cancelled = true; };\n }, [visible, failed, updateGhost]);\n\n useEffect(() => () => {\n editorRef.current?.dispose();\n editorRef.current = null;\n }, []);\n\n // Each new prompt: fresh history for where the shell is now, and the keyboard.\n useEffect(() => {\n if (!visible || !ready) return;\n walker.current.reset();\n void loadHistory().then(() => updateGhost(editorRef.current?.getText() ?? ''));\n if (focusWanted) editorRef.current?.focus();\n }, [visible, ready, focusWanted, loadHistory, updateGhost]);\n\n useImperativeHandle(ref, () => ({\n focus: () => editorRef.current?.focus(),\n getText: () => editorRef.current?.getText() ?? '',\n insert: (text) => {\n const editor = editorRef.current;\n if (!editor) return;\n editor.setText(text.replace(/[\\r\\n]+$/, ''));\n editor.focus();\n },\n openAssist: () => { onKeyRef.current('assist'); },\n }), []);\n\n if (failed) return null;\n const hint = assist.state === 'loading' ? assistLoadingLabel(props.assistMode)\n : assist.state === 'error' ? assist.error\n : riskyWarn ? 'This command changes or deletes things. Press Return again to run it.'\n : assist.state === 'done' && assist.result\n ? [assist.result.explanation, `Review, then Return to run · from ${assist.result.provider}`].filter(Boolean).join(' · ')\n : assistMode ? `Describe what you want, then Return. ${assistDisclosure(props.assistMode)} The command comes back to review; nothing runs on its own.`\n : null;\n\n return (\n <div\n className={styles.inputDock}\n hidden={!visible}\n data-testid={`command-input-${props.tabId}`}\n data-assist={assistMode || undefined}\n // Capture: the panel's chords are taken before the editor sees them.\n onKeyDownCapture={(event) => { if (props.onPanelKey?.(event.nativeEvent)) event.stopPropagation(); }}\n >\n {hint ? (\n <div className={styles.inputHint} role={assist.state === 'error' || riskyWarn ? 'alert' : 'status'} data-tone={assist.state === 'error' || riskyWarn || (assist.result?.risky && assist.state === 'done') ? 'warn' : undefined}>\n {hint}\n </div>\n ) : null}\n <div className={styles.inputRow}>\n <span className={styles.inputPrompt} aria-hidden=\"true\">{assistMode ? '#' : '$'}</span>\n <div ref={hostRef} className={styles.inputEditor} />\n </div>\n </div>\n );\n});\n\nfunction placeholderFor(platform: KeyPlatform): string {\n const assist = platform === 'mac' ? '⌘I' : 'Ctrl+Shift+Alt+I';\n return `Type a command · # or ${assist} to describe it in words · Ctrl+R history · Esc hands off to the shell`;\n}\n","/**\n * terminal/HistoryPalette.tsx — Ctrl+R for the Verse terminal (3.15), and the\n * \"Generate command…\" prompt. Built from the ⌘K palette's primitives (its\n * stylesheet, the focus trap, the combobox + listbox pattern), so it looks\n * and moves exactly like it.\n *\n * history every command the operator's shells finished (the server's\n * history, ranked for this shell's cwd: prefix → here → repo →\n * succeeded → recent). ↩ puts the command in the input editor —\n * it does NOT run it. Ctrl+R again gives the search to the shell's\n * own Ctrl+R (fzf, atuin …) with what was typed.\n * assist a request in plain words → the configured model → ONE command, shown\n * for review. ↩ inserts it for editing; nothing runs.\n */\nimport { useCallback, useEffect, useId, useRef, useState, type KeyboardEvent as ReactKeyboardEvent } from 'react';\nimport { createPortal } from 'react-dom';\nimport type { VerseTerminalAssistMode, VerseTerminalAssistResponse, VerseTerminalHistoryEntry } from '../../../data/api-types.js';\nimport { assistDisclosure, assistLoadingLabel } from './assist-disclosure.js';\nimport { ApiError } from '../../../data/client.js';\nimport { useFocusTrap } from '../../../components/primitives/focus-trap.js';\nimport { ReturnKeyIcon } from '../verse-icons.js';\nimport type { PanelTerminalApi } from './panel-client.js';\nimport { Button } from '../../../components/primitives/Button.js';\nimport styles from '../shell/CommandPalette.module.css';\nimport own from './HistoryPalette.module.css';\n\nexport type TerminalPaletteMode = 'history' | 'assist';\n\nexport interface HistoryPaletteProps {\n mode: TerminalPaletteMode;\n assistMode: VerseTerminalAssistMode;\n api: PanelTerminalApi;\n tabId: string | null;\n cwd: string | null;\n /** What was typed in the editor when it opened (the first query). */\n initialQuery: string;\n /** A command to put in the editor (or paste at the prompt). Never run. */\n onPick: (command: string) => void;\n /** Ctrl+R again: hand the search to the shell's own Ctrl+R, with this text. */\n onPassThrough?: (query: string) => void;\n onClose: () => void;\n /** Turn history on (shown when it is off). */\n onEnableHistory?: () => void;\n}\n\nconst QUERY_DEBOUNCE_MS = 70;\n\nfunction ago(iso: string, now = Date.now()): string {\n const ms = now - Date.parse(iso);\n if (!Number.isFinite(ms) || ms < 0) return '';\n const min = Math.round(ms / 60_000);\n if (min < 1) return 'just now';\n if (min < 60) return `${min} min ago`;\n const h = Math.round(min / 60);\n if (h < 24) return `${h} h ago`;\n const d = Math.round(h / 24);\n return d < 30 ? `${d} d ago` : new Date(iso).toLocaleDateString();\n}\n\nfunction historySubtitle(e: VerseTerminalHistoryEntry): string {\n const parts: string[] = [];\n if (e.here) parts.push('here');\n else if (e.sameRepo) parts.push('this repo');\n if (e.exit !== null && e.exit !== 0) parts.push(`exit ${e.exit}`);\n if (e.count > 1) parts.push(`${e.count}×`);\n const when = ago(e.ts);\n if (when) parts.push(when);\n return parts.join(' · ');\n}\n\nfunction assistError(err: unknown): string {\n if (err instanceof ApiError) {\n if (err.status === 401) return 'Unlock actions with the mutation token to generate commands.';\n if (err.detail) return err.detail;\n }\n return 'The command could not be generated.';\n}\n\nexport function HistoryPalette({ mode, assistMode, api, tabId, cwd, initialQuery, onPick, onPassThrough, onClose, onEnableHistory }: HistoryPaletteProps) {\n const [query, setQuery] = useState(initialQuery);\n const [entries, setEntries] = useState<VerseTerminalHistoryEntry[]>([]);\n const [enabled, setEnabled] = useState(true);\n const [loading, setLoading] = useState(false);\n const [active, setActive] = useState(0);\n const [assist, setAssist] = useState<{ state: 'idle' | 'loading' | 'done' | 'error'; result: VerseTerminalAssistResponse | null; error: string | null }>({ state: 'idle', result: null, error: null });\n const panelRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const listRef = useRef<HTMLDivElement>(null);\n const listId = useId();\n const labelId = useId();\n const mounted = useRef(true);\n useEffect(() => () => { mounted.current = false; }, []);\n\n useFocusTrap({ open: true, containerRef: panelRef, onClose, initialFocusRef: inputRef });\n\n // History: ask the server as the query changes (debounced; the latest answer wins).\n useEffect(() => {\n if (mode !== 'history' || !api.history) return undefined;\n const controller = new AbortController();\n const timer = setTimeout(() => {\n setLoading(true);\n api.history!({ q: query, cwd, limit: 100 }, controller.signal).then((res) => {\n if (!mounted.current || controller.signal.aborted) return;\n setEntries(res.entries);\n setEnabled(res.enabled);\n setActive(0);\n }, () => { /* offline / locked: keep what is shown */ }).finally(() => {\n if (mounted.current && !controller.signal.aborted) setLoading(false);\n });\n }, QUERY_DEBOUNCE_MS);\n return () => {\n clearTimeout(timer);\n controller.abort();\n };\n }, [api, cwd, mode, query]);\n\n useEffect(() => {\n listRef.current?.querySelector<HTMLElement>(`[data-index=\"${active}\"]`)?.scrollIntoView?.({ block: 'nearest' });\n }, [active]);\n\n const generate = useCallback(async (request: string) => {\n if (!api.assist || !request.trim()) return;\n setAssist({ state: 'loading', result: null, error: null });\n try {\n const result = await api.assist({ request: request.trim(), ...(tabId ? { tabId } : {}), ...(cwd ? { cwd } : {}), ...(assistMode === 'auto' ? { cloudAllowed: true } : {}) });\n if (mounted.current) setAssist({ state: 'done', result, error: null });\n } catch (err) {\n if (mounted.current) setAssist({ state: 'error', result: null, error: assistError(err) });\n }\n }, [api, assistMode, cwd, tabId]);\n\n const pick = (command: string) => {\n onClose();\n onPick(command);\n };\n\n const onKeyDown = (event: ReactKeyboardEvent<HTMLInputElement>) => {\n const count = mode === 'history' ? entries.length : assist.result ? 1 : 0;\n if (event.ctrlKey && !event.metaKey && event.key.toLowerCase() === 'r') {\n event.preventDefault();\n if (mode === 'history' && onPassThrough) {\n onClose();\n onPassThrough(query);\n }\n return;\n }\n switch (event.key) {\n case 'ArrowDown':\n event.preventDefault();\n if (count > 0) setActive((i) => (i + 1) % count);\n return;\n case 'ArrowUp':\n event.preventDefault();\n if (count > 0) setActive((i) => (i - 1 + count) % count);\n return;\n case 'Enter': {\n event.preventDefault();\n if (mode === 'history') {\n const entry = entries[active];\n if (entry) pick(entry.cmd);\n return;\n }\n // Assist: the first ↩ asks, the next inserts what came back (for review).\n if (assist.state === 'done' && assist.result && !event.shiftKey) pick(assist.result.command);\n else if (assist.state !== 'loading') void generate(query);\n return;\n }\n case 'Escape':\n event.preventDefault();\n event.stopPropagation();\n onClose();\n return;\n default:\n return;\n }\n };\n\n const title = mode === 'history' ? 'Command history' : 'Generate a command';\n const placeholder = mode === 'history' ? 'Search commands you ran' : 'Describe what you want to do, in plain words';\n const activeId = (mode === 'history' ? entries[active] : assist.result) ? `${listId}-${active}` : undefined;\n\n return createPortal(\n <div className={styles.backdrop} onMouseDown={(e) => e.target === e.currentTarget && onClose()}>\n <div ref={panelRef} className={styles.panel} role=\"dialog\" aria-modal=\"true\" aria-labelledby={labelId} data-verse-overlay={`terminal-${mode}`}>\n <h2 id={labelId} className=\"visually-hidden\">{title}</h2>\n <div className={styles.field}>\n <span className={styles.crumb}>{mode === 'history' ? 'History' : 'Command'}<span aria-hidden=\"true\"> ›</span></span>\n <input\n ref={inputRef}\n className={styles.input}\n value={query}\n placeholder={placeholder}\n aria-label={placeholder}\n role=\"combobox\"\n aria-expanded=\"true\"\n aria-controls={listId}\n aria-autocomplete=\"list\"\n aria-activedescendant={activeId}\n autoComplete=\"off\"\n autoCorrect=\"off\"\n spellCheck={false}\n onChange={(e) => {\n setQuery(e.target.value);\n if (mode === 'assist' && assist.state !== 'loading') setAssist({ state: 'idle', result: null, error: null });\n }}\n onKeyDown={onKeyDown}\n />\n </div>\n <div ref={listRef} id={listId} className={styles.list} role=\"listbox\" aria-label={title} aria-busy={loading || assist.state === 'loading' || undefined}>\n {mode === 'history' ? (\n !enabled ? (\n <p className={styles.empty}>\n Command history is off.{' '}\n {onEnableHistory ? <Button size=\"sm\" variant=\"subtle\" onClick={onEnableHistory}>Turn it on</Button> : null}\n </p>\n ) : entries.length === 0 ? (\n <p className={styles.empty}>{loading ? 'Searching…' : query ? `No command matches “${query}”.` : 'Commands you run in the terminal appear here.'}</p>\n ) : (\n <div role=\"group\" aria-label=\"Commands\" className={styles.group}>\n {entries.map((entry, i) => (\n <div\n key={entry.cmd}\n id={`${listId}-${i}`}\n data-index={i}\n role=\"option\"\n aria-selected={i === active}\n className={styles.item}\n data-tone={entry.exit !== null && entry.exit !== 0 ? 'warn' : undefined}\n onMouseMove={() => i !== active && setActive(i)}\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => pick(entry.cmd)}\n >\n <span className={styles.lead} aria-hidden=\"true\"><span className={styles.bullet} data-kind={entry.here ? 'running' : 'command'} /></span>\n <span className={styles.text}>\n <span className={`${styles.title} ${own.command}`}>{entry.cmd}</span>\n <span className={styles.subtitle}>{historySubtitle(entry)}</span>\n </span>\n </div>\n ))}\n </div>\n )\n ) : assist.state === 'loading' ? (\n <p className={styles.empty} role=\"status\">{assistLoadingLabel(assistMode)}</p>\n ) : assist.state === 'error' ? (\n <p className={styles.empty} role=\"alert\">{assist.error}</p>\n ) : assist.result ? (\n <div role=\"group\" aria-label=\"Suggested command\" className={styles.group}>\n <div\n id={`${listId}-0`}\n data-index={0}\n role=\"option\"\n aria-selected=\"true\"\n className={styles.item}\n data-tone={assist.result.risky ? 'danger' : undefined}\n onMouseDown={(e) => e.preventDefault()}\n onClick={() => pick(assist.result!.command)}\n >\n <span className={styles.lead} aria-hidden=\"true\"><span className={styles.bullet} data-kind=\"command\" /></span>\n <span className={styles.text}>\n <span className={`${styles.title} ${own.command} ${own.wrap}`}>{assist.result.command}</span>\n <span className={styles.subtitle}>\n {[assist.result.risky ? 'Changes or deletes things — read it before running' : null, assist.result.explanation, `from ${assist.result.provider}`].filter(Boolean).join(' · ')}\n </span>\n </span>\n </div>\n </div>\n ) : (\n <p className={styles.empty}>\n {api.assist ? `Press Return to ask. ${assistDisclosure(assistMode)} The command comes back for you to review; nothing runs until you run it.` : 'This server cannot generate commands.'}\n </p>\n )}\n </div>\n <div className={styles.foot} aria-hidden=\"true\">\n <span><kbd className={styles.key}>↑↓</kbd> move</span>\n {mode === 'history'\n ? <span><kbd className={styles.key}><ReturnKeyIcon /></kbd> insert (does not run)</span>\n : <span><kbd className={styles.key}><ReturnKeyIcon /></kbd> {assist.state === 'done' ? 'insert for review' : 'generate'}</span>}\n {mode === 'history' && onPassThrough ? <span><kbd className={styles.key}>Ctrl+R</kbd> shell’s own search</span> : null}\n <span><kbd className={styles.key}>esc</kbd> close</span>\n </div>\n <p className=\"visually-hidden\" role=\"status\" aria-live=\"polite\">\n {mode === 'history' ? (entries.length === 1 ? '1 command' : `${entries.length} commands`) : assist.state === 'done' ? 'Command ready' : ''}\n </p>\n </div>\n </div>,\n document.body,\n );\n}\n","/**\n * terminal/input-editor.ts — the seam between the input editor (the React\n * glue, CommandInput.tsx) and the text editor under it.\n *\n * The real one is CodeMirror 6 (command-editor.ts), loaded in its OWN chunk\n * the first time a shell reaches a prompt with the editor on: nothing on the\n * chat's first paint — nor the terminal's own first paint — pays for it\n * (terminal-lazy.test.ts pins that no file but command-editor.ts imports\n * @codemirror). Tests inject a fake editor: the seam is small on purpose.\n */\n\n/** What a key in the editor asks the terminal to do. The editor handles plain editing itself. */\nexport type InputKeyIntent =\n /** ↩ — run it (or, for `#…`, turn it into a command). */\n | 'submit'\n /** ↑ on the first line / ↓ on the last. */\n | 'history-prev'\n | 'history-next'\n /** ⌃R — search history (again, from the palette: the shell's own ⌃R). */\n | 'history-search'\n /** ⌘I — describe a command in plain words. */\n | 'assist'\n /** ⌃C — clear the line; on an empty line, interrupt (sent to the shell). */\n | 'interrupt'\n /** ⌃D on an empty line — the shell's EOF. */\n | 'eof'\n /** ⌃L — the shell clears its screen. */\n | 'clear-screen'\n /** Esc — give the line to the shell's own editor (vi users: a second Esc is theirs). */\n | 'hand-off'\n /** ⇥ with no suggestion to accept — the shell's own completion gets the line and the Tab. */\n | 'tab';\n\nexport interface InputEditorOptions {\n host: HTMLElement;\n initial: string;\n placeholder: string;\n /** Every change of the text (typing, completion, setText). */\n onChange: (text: string) => void;\n /** A terminal key. Return true when it was handled (the editor then does nothing else with it). */\n onKey: (intent: InputKeyIntent) => boolean;\n onFocusChange?: (focused: boolean) => void;\n /** Path candidates for the word being typed (files from the composer's index); [] = none. */\n completePaths?: (text: string, cursor: number) => Promise<{ from: number; options: string[] } | null>;\n /** Accessible name. */\n label: string;\n}\n\nexport interface InputEditor {\n getText(): string;\n /** Replace the text, cursor at the end. */\n setText(text: string): void;\n focus(): void;\n hasFocus(): boolean;\n /** The full command to suggest after what is typed (shown past the cursor), or null. */\n setGhost(suggestion: string | null): void;\n setPlaceholder(text: string): void;\n dispose(): void;\n}\n\nexport type InputEditorFactory = (opts: InputEditorOptions) => Promise<InputEditor>;\n\nlet editorModule: Promise<typeof import('./command-editor.js')> | null = null;\n\n/** CodeMirror, fetched on first use (and retried after a failed chunk load). */\nexport const createLazyInputEditor: InputEditorFactory = async (opts) => {\n if (!editorModule) {\n editorModule = import('./command-editor.js');\n editorModule.catch(() => { editorModule = null; });\n }\n const mod = await editorModule;\n return mod.createCommandEditor(opts);\n};\n\n/** Start fetching the editor's chunk without creating one (a shell that just came up). */\nexport function preloadInputEditor(): void {\n if (editorModule) return;\n editorModule = import('./command-editor.js');\n editorModule.catch(() => { editorModule = null; });\n}\n","/**\n * terminal/panel-client.ts — the Terminal panel's HTTP calls (3.15): the\n * 3.10 tab calls (list, create, input, resize, kill, open-external — reused\n * from the dock's client) plus blocks, block output, redaction and file links,\n * and — for the input editor — history, settings, plain-language assist and\n * path candidates from the composer's file index.\n *\n * REUSE. `panelTerminalApi.history` / `.assist` are the hooks other units\n * (block menus, \"Ask any seat\", workflows) call; both are server-scrubbed.\n */\nimport type {\n VerseTerminalAssistRequest,\n VerseTerminalAssistResponse,\n VerseTerminalBlockOutputFormat,\n VerseTerminalBlockOutputResponse,\n VerseTerminalBlocksResponse,\n VerseTerminalCreateRequest,\n VerseTerminalHistoryResponse,\n VerseTerminalFixResponse,\n VerseTerminalLaunchListResponse,\n VerseTerminalLaunchRequest,\n VerseTerminalLaunchResponse,\n VerseTerminalOpenFileRequest,\n VerseTerminalSettings,\n VerseTerminalTab,\n} from '../../../data/api-types.js';\nimport { getMutationToken, touchMutationHold } from '../../../data/auth-store.js';\nimport { apiGet, apiPost } from '../../../data/client.js';\nimport {\n VERSE_TERMINAL_ASSIST_PATH,\n VERSE_TERMINAL_HISTORY_CLEAR_PATH,\n VERSE_TERMINAL_HISTORY_PATH,\n VERSE_TERMINAL_LAUNCH_PATH,\n VERSE_TERMINAL_PATH,\n VERSE_TERMINAL_REDACT_PATH,\n VERSE_TERMINAL_SETTINGS_PATH,\n} from '../../../../core/verse/workbench-types.js';\nimport { searchSessionFiles } from '../composer/composer-queries.js';\nimport { TerminalLockedError, terminalApi, type TerminalApi } from '../dock/terminal/terminal-client.js';\n\nexport interface TerminalHistoryQuery {\n q?: string;\n cwd?: string | null;\n limit?: number;\n}\n\nexport interface PanelTerminalApi extends TerminalApi {\n create(req: VerseTerminalCreateRequest): Promise<VerseTerminalTab>;\n blocks(tabId: string): Promise<VerseTerminalBlocksResponse>;\n blockOutput(tabId: string, blockId: string, format: VerseTerminalBlockOutputFormat): Promise<VerseTerminalBlockOutputResponse>;\n /** Text → the same secret scrub a block gets on its way to a chat. */\n redact(text: string): Promise<string>;\n openFile(tabId: string, req: VerseTerminalOpenFileRequest): Promise<void>;\n /** 3.15: ranked command history (optional so older fakes still type-check; the panel treats absent as empty). */\n history?(query: TerminalHistoryQuery, signal?: AbortSignal): Promise<VerseTerminalHistoryResponse>;\n clearHistory?(): Promise<void>;\n settings?(): Promise<VerseTerminalSettings>;\n updateSettings?(patch: Partial<VerseTerminalSettings>): Promise<VerseTerminalSettings>;\n /** Plain words → a command, as TEXT. Never typed, never run. */\n assist?(req: VerseTerminalAssistRequest): Promise<VerseTerminalAssistResponse>;\n /** Files in the chat's folders matching `query` (the composer's `@` index). */\n files?(sessionId: string, query: string, signal?: AbortSignal): Promise<Array<{ path: string; root: string }>>;\n /** 3.15: the local model's candidate commands for a failed block (optional: older fakes). */\n fix?(tabId: string, blockId: string): Promise<VerseTerminalFixResponse>;\n /** 3.15: the chat's launch configurations. */\n launchList?(sessionId: string): Promise<VerseTerminalLaunchListResponse>;\n /** 3.15: open a launch configuration's tabs (its commands come from the file on the server). */\n launch?(req: VerseTerminalLaunchRequest): Promise<VerseTerminalLaunchResponse>;\n}\n\nasync function post<T>(path: string, body: unknown): Promise<T> {\n const token = getMutationToken();\n if (!token) throw new TerminalLockedError();\n const result = await apiPost<T>(path, body, token);\n touchMutationHold();\n return result;\n}\n\nconst tabBase = (id: string) => `${VERSE_TERMINAL_PATH}/${encodeURIComponent(id)}`;\n\nexport function historyPath(query: TerminalHistoryQuery): string {\n const params = new URLSearchParams();\n if (query.q) params.set('q', query.q);\n if (query.cwd) params.set('cwd', query.cwd);\n if (query.limit !== undefined) params.set('limit', String(query.limit));\n const qs = params.toString();\n return qs ? `${VERSE_TERMINAL_HISTORY_PATH}?${qs}` : VERSE_TERMINAL_HISTORY_PATH;\n}\n\nexport const panelTerminalApi: PanelTerminalApi = {\n ...terminalApi,\n blocks: (tabId) => apiGet<VerseTerminalBlocksResponse>(`${tabBase(tabId)}/blocks`),\n blockOutput: (tabId, blockId, format) =>\n apiGet<VerseTerminalBlockOutputResponse>(`${tabBase(tabId)}/blocks/${encodeURIComponent(blockId)}?format=${format}`),\n redact: async (text) => (await post<{ text: string }>(VERSE_TERMINAL_REDACT_PATH, { text })).text,\n openFile: async (tabId, req) => { await post<unknown>(`${tabBase(tabId)}/open-file`, req); },\n history: (query, signal) => apiGet<VerseTerminalHistoryResponse>(historyPath(query), signal),\n clearHistory: async () => { await post<unknown>(VERSE_TERMINAL_HISTORY_CLEAR_PATH, {}); },\n settings: () => apiGet<VerseTerminalSettings>(VERSE_TERMINAL_SETTINGS_PATH),\n updateSettings: (patch) => post<VerseTerminalSettings>(VERSE_TERMINAL_SETTINGS_PATH, patch),\n assist: (req) => post<VerseTerminalAssistResponse>(VERSE_TERMINAL_ASSIST_PATH, req),\n files: async (sessionId, query, signal) => (await searchSessionFiles(sessionId, query, signal)).files,\n fix: (tabId, blockId) => post<VerseTerminalFixResponse>(`${tabBase(tabId)}/blocks/${encodeURIComponent(blockId)}/fix`, {}),\n launchList: (sessionId) => apiGet<VerseTerminalLaunchListResponse>(`${VERSE_TERMINAL_LAUNCH_PATH}?sessionId=${encodeURIComponent(sessionId)}`),\n launch: (req) => post<VerseTerminalLaunchResponse>(VERSE_TERMINAL_LAUNCH_PATH, req),\n};\n","/**\n * terminal/panel-keys.ts — the Terminal panel's own keys (3.15), and which\n * keys leave the terminal for the page.\n *\n * While a terminal has focus it owns the keyboard (⌃C, Ctrl+R, Esc, ⌥-word\n * motion are the shell's). Three groups of keys are taken out of it:\n *\n * 1. the panel's own — ⌘F find, ⌘D split right, ⌥⌘D split down,\n * ⌥⌘←→↑↓ focus the pane that way, ⇧⌘Return zoom the pane (and back),\n * ⌘↑ / ⌘↓ previous / next command block, ⇧⌘K blocks view,\n * ⌘I describe a command in plain words;\n * 2. the app's catalog chords that use ⌘ (⌘K, ⌘J, ⌘1–5 …) or ⌃` / ⌃Tab\n * (keyPassesToPage, as the 3.10 pane);\n * 3. nothing else.\n *\n * Off macOS, `mod` is Ctrl — and Ctrl+F / Ctrl+D belong to the shell there\n * (forward-char, EOF), so the panel's keys need Ctrl+SHIFT on those\n * platforms (pane focus: Ctrl+Shift+Alt+arrows, which no shell binds). The\n * page-level listeners skip default-prevented events, so a key the panel\n * takes is prevented and runs nothing else.\n */\nimport { eventKeyName, matchKey, type KeyPlatform } from '../shell/command-keys.js';\n\n/**\n * Keys the PAGE handles even while a terminal has focus: an app chord that\n * uses ⌘ (macOS), or ⌃` / ⌃Tab; off macOS only Ctrl+Shift chords and\n * ⌃` / ⌃Tab (Ctrl+K must still kill a line). Same rule as the 3.10 pane.\n */\nexport function keyPassesToPage(event: KeyboardEvent, platform: KeyPlatform): boolean {\n if (event.type !== 'keydown') return false;\n if (!matchKey(event, ['chat', 'global'], platform)) return false;\n const key = eventKeyName(event);\n const shellChord = event.ctrlKey && (key === '`' || key === 'tab');\n if (platform === 'mac') return event.metaKey || shellChord;\n return shellChord || (event.ctrlKey && event.shiftKey);\n}\n\nexport type PanelKeyAction =\n | 'find'\n | 'split-right'\n | 'split-down'\n | 'prev-block'\n | 'next-block'\n | 'toggle-blocks'\n | 'focus-left'\n | 'focus-right'\n | 'focus-up'\n | 'focus-down'\n | 'zoom-pane'\n | 'assist';\n\nconst FOCUS_BY_ARROW: Readonly<Record<string, PanelKeyAction>> = {\n arrowleft: 'focus-left',\n arrowright: 'focus-right',\n arrowup: 'focus-up',\n arrowdown: 'focus-down',\n};\n\nexport function panelKeyAction(event: KeyboardEvent, platform: KeyPlatform): PanelKeyAction | null {\n if (event.type !== 'keydown') return null;\n const key = eventKeyName(event);\n if (platform === 'mac') {\n if (!event.metaKey || event.ctrlKey) return null;\n if (event.altKey && !event.shiftKey && FOCUS_BY_ARROW[key]) return FOCUS_BY_ARROW[key]!;\n if (key === 'f' && !event.shiftKey && !event.altKey) return 'find';\n if (key === 'd' && !event.shiftKey) return event.altKey ? 'split-down' : 'split-right';\n if (key === 'arrowup' && !event.shiftKey && !event.altKey) return 'prev-block';\n if (key === 'arrowdown' && !event.shiftKey && !event.altKey) return 'next-block';\n if (key === 'k' && event.shiftKey && !event.altKey) return 'toggle-blocks';\n if (key === 'enter' && event.shiftKey && !event.altKey) return 'zoom-pane';\n if (key === 'i' && !event.shiftKey && !event.altKey) return 'assist';\n return null;\n }\n if (!event.ctrlKey || !event.shiftKey || event.metaKey) return null;\n if (event.altKey && FOCUS_BY_ARROW[key]) return FOCUS_BY_ARROW[key]!;\n if (key === 'f' && !event.altKey) return 'find';\n // Ctrl+Shift+D is the dock's Review here: splits are the toolbar's off macOS.\n if (key === 'arrowup' && !event.altKey) return 'prev-block';\n if (key === 'arrowdown' && !event.altKey) return 'next-block';\n if (key === 'k' && event.altKey) return 'toggle-blocks';\n if (key === 'enter' && !event.altKey) return 'zoom-pane';\n if (key === 'i' && event.altKey) return 'assist';\n return null;\n}\n\n/** How the panel's keys read in tooltips. */\nexport function panelKeyLabel(action: PanelKeyAction, platform: KeyPlatform): string {\n const mac = platform === 'mac';\n switch (action) {\n case 'find': return mac ? '⌘F' : 'Ctrl+Shift+F';\n case 'split-right': return mac ? '⌘D' : '';\n case 'split-down': return mac ? '⌥⌘D' : '';\n case 'prev-block': return mac ? '⌘↑' : 'Ctrl+Shift+↑';\n case 'next-block': return mac ? '⌘↓' : 'Ctrl+Shift+↓';\n case 'toggle-blocks': return mac ? '⇧⌘K' : 'Ctrl+Shift+Alt+K';\n case 'focus-left': return mac ? '⌥⌘←' : 'Ctrl+Shift+Alt+←';\n case 'focus-right': return mac ? '⌥⌘→' : 'Ctrl+Shift+Alt+→';\n case 'focus-up': return mac ? '⌥⌘↑' : 'Ctrl+Shift+Alt+↑';\n case 'focus-down': return mac ? '⌥⌘↓' : 'Ctrl+Shift+Alt+↓';\n case 'zoom-pane': return mac ? '⇧⌘Return' : 'Ctrl+Shift+Enter';\n case 'assist': return mac ? '⌘I' : 'Ctrl+Shift+Alt+I';\n }\n}\n","/**\n * terminal/file-links.ts — `file:line[:col]` references in terminal output\n * (3.15). Clicking one opens the file in the operator's editor; the SERVER\n * decides whether it may (POST …/open-file: inside the chat's roots only).\n *\n * Recognised, as compilers, test runners and stack traces print them:\n * src/app.ts:12:5 ./a.js:3 /abs/x.py:10 ~/p/y.rs:4:2\n * src/app.ts(12,5) (tsc, MSBuild)\n * at fn (/path/file.js:10:15) (node stack; the parens are not the link)\n * File \"/path/x.py\", line 12 (Python traceback)\n * src/app.ts (a bare path — only with a `/`)\n *\n * NOT recognised: a bare `name.ext` with no line and no directory (every\n * \"node.js\" or \"v1.2\" in prose would light up), and anything that is part of\n * a URL (`https://host/a.js` is the web-links addon's).\n */\n\nexport interface FileLink {\n /** As printed (`~/…` and relative paths are resolved by the server). */\n path: string;\n line: number | null;\n column: number | null;\n /** [start, end) in the line's text. */\n start: number;\n end: number;\n}\n\nconst PATH = String.raw`(?:~|\\.{1,2})?\\/?(?:[\\w.@+\\-]+\\/)*[\\w.@+\\-]*[\\w@+\\-]\\.[A-Za-z0-9]{1,12}`;\n// `path:line[:col]` or `path(line,col)`. The look-behind keeps URL tails and\n// longer words out; the look-ahead stops `a.ts:12abc` from counting.\nconst FILE_RE = new RegExp(String.raw`(?<![\\w/.~:\\-@])(${PATH})(?::(\\d{1,7})(?::(\\d{1,5}))?|\\((\\d{1,7}),(\\d{1,5})\\))?(?![\\w/])`, 'g');\nconst PYTHON_RE = /File \"([^\"\\n]{1,1024})\", line (\\d{1,7})/g;\n\nfunction inUrl(text: string, index: number): boolean {\n // The token this match sits in, back to the previous whitespace or quote.\n let i = index;\n while (i > 0 && !/[\\s\"'`(<[]/.test(text[i - 1]!)) i--;\n return /^[a-z][a-z0-9+.-]*:\\/\\//i.test(text.slice(i, index + 1)) || /^[a-z][a-z0-9+.-]*:\\/\\//i.test(text.slice(i));\n}\n\n/** Every file reference in one line of terminal text, left to right, non-overlapping. */\nexport function findFileLinks(text: string): FileLink[] {\n const out: FileLink[] = [];\n if (text.length === 0 || text.length > 4096) return out;\n\n for (const m of text.matchAll(PYTHON_RE)) {\n out.push({ path: m[1]!, line: Number(m[2]), column: null, start: m.index!, end: m.index! + m[0].length });\n }\n\n for (const m of text.matchAll(FILE_RE)) {\n const start = m.index!;\n const end = start + m[0].length;\n if (out.some((l) => start < l.end && end > l.start)) continue;\n const path = m[1]!;\n const line = m[2] ?? m[4];\n const col = m[3] ?? m[5];\n // A bare name with no line and no directory is prose, not a path.\n if (line === undefined && !path.includes('/')) continue;\n // A version string (v1.2.3) or a number (3.14) is not a file.\n if (/^v?\\d+(?:\\.\\d+)+$/.test(path)) continue;\n if (inUrl(text, start)) continue;\n out.push({\n path,\n line: line === undefined ? null : Number(line),\n column: col === undefined ? null : Number(col),\n start,\n end,\n });\n }\n return out.sort((a, b) => a.start - b.start);\n}\n","/**\n * terminal/ligatures.ts — programming ligatures under the WebGL renderer (3.15).\n *\n * xterm draws each cell on its own, so `=>` in a ligature font (Fira Code,\n * JetBrains Mono, Cascadia Code, Monaspace…) shows as two glyphs. A\n * CHARACTER JOINER tells the WebGL renderer which runs to rasterise as one\n * unit; the font's own shaping then draws its ligature across those cells.\n *\n * Why a list and not the font's GSUB table: @xterm/addon-ligatures reads the\n * font file from disk (Node/Electron only) or the Local Font Access API,\n * neither of which WKWebView offers. The sequences below are the ones every\n * common coding font ligates. A font WITHOUT ligatures loses nothing: the run\n * is drawn as the same characters, in the same cells.\n */\n\n/** Longest first, so `===` wins over `==`. */\nexport const LIGATURE_SEQUENCES: readonly string[] = [\n '<!--', '===', '!==', '<=>', '>>=', '<<=', '||=', '&&=', '??=', '...', '-->', '->>', '<<-', '|||', '::=',\n '=>', '->', '<-', '==', '!=', '<=', '>=', '::', ':=', '&&', '||', '??', '++', '//', '/*', '*/',\n '</', '/>', '<>', '|>', '<|', '..', '=~', '!~', '>>', '<<', '#{', '#[', '0x',\n].sort((a, b) => b.length - a.length);\n\nfunction escapeRe(s: string): string {\n return s.replace(/[.*+?^${}()|[\\]\\\\/]/g, '\\\\$&');\n}\n\nconst LIGATURE_RE = new RegExp(LIGATURE_SEQUENCES.map(escapeRe).join('|'), 'g');\n\n/** The joiner: [start, end) ranges of `text` to draw as single units. */\nexport function ligatureRanges(text: string): [number, number][] {\n const ranges: [number, number][] = [];\n if (text.length < 2) return ranges;\n for (const m of text.matchAll(LIGATURE_RE)) {\n // `0x` is only a ligature before a hex digit (0xFF), never in prose.\n if (m[0] === '0x' && !/[0-9a-fA-F]/.test(text[m.index! + 2] ?? '')) continue;\n ranges.push([m.index!, m.index! + m[0].length]);\n }\n return ranges;\n}\n","/**\n * terminal/xterm-view.ts — the Terminal panel's one seam to xterm.js (3.15).\n *\n * Builds on the dock's 3.10 view (terminal-view.ts: lazy chunk, theme from\n * design tokens) with what a Warp-grade terminal needs:\n *\n * - WebGL rendering where the GPU allows it (falls back to xterm's DOM\n * renderer on a lost context or no WebGL2), true colour, Unicode 11\n * widths (emoji, CJK), and programming ligatures (ligatures.ts);\n * - ⌘F search (@xterm/addon-search, loaded on first use);\n * - links: URLs and `file:line` references, followed on ⌘-click (Ctrl off\n * macOS) — a plain click still selects, as in every terminal;\n * - the shell's OSC 133 marks as they are PARSED (so a block's marker\n * lands on the exact line), line markers and decorations for blocks.\n *\n * LAZY. Everything here — xterm and every addon — loads in its own chunk\n * the first time a terminal is shown; nothing on the chat's first paint\n * imports this file (terminal-lazy.test.ts pins that). Tests inject a fake\n * view: jsdom has no canvas, WebGL or layout for xterm.\n */\nimport type { ITheme, Terminal as XtermTerminal, IDisposable, IMarker } from '@xterm/xterm';\nimport { resolveTerminalTheme, type TerminalTheme } from '../dock/terminal/terminal-view.js';\nimport { findFileLinks, type FileLink } from './file-links.js';\nimport { ligatureRanges } from './ligatures.js';\n\nexport interface ViewDisposable {\n dispose(): void;\n}\n\n/** A line in the terminal's buffer that moves with it as output scrolls. */\nexport interface LineMark {\n readonly line: number;\n readonly isDisposed: boolean;\n dispose(): void;\n}\n\nexport interface FindOptions {\n caseSensitive?: boolean;\n regex?: boolean;\n wholeWord?: boolean;\n backwards?: boolean;\n}\n\nexport interface LinkHandlers {\n openUrl(url: string): void;\n /** `bufferLine`: the buffer row the link is on (to resolve it against the directory its command ran in). */\n openFile(link: FileLink, bufferLine: number): void;\n}\n\nexport interface PanelView {\n readonly cols: number;\n readonly rows: number;\n readonly renderer: 'webgl' | 'dom';\n open(host: HTMLElement): Promise<void>;\n write(data: Uint8Array, done?: () => void): void;\n reset(): void;\n /** Clear the screen and scrollback (⌘K in other terminals). */\n clear(): void;\n focus(): void;\n fit(): { cols: number; rows: number } | null;\n /** Redraw every row (after being hidden: a renderer drawn at zero size shows nothing until told). */\n refresh(): void;\n onData(cb: (data: string) => void): ViewDisposable;\n onBinary(cb: (data: string) => void): ViewDisposable;\n onSelectionChange(cb: () => void): ViewDisposable;\n hasSelection(): boolean;\n getSelection(): string;\n paste(text: string): void;\n bracketedPaste(): boolean;\n setTheme(theme: TerminalTheme): void;\n setScreenReaderMode(on: boolean): void;\n setKeyFilter(filter: (event: KeyboardEvent) => boolean): void;\n setLigatures(on: boolean): void;\n setLinkHandlers(handlers: LinkHandlers): void;\n /** Payloads of OSC 133 (`A`, `C`, `D;0`…) in stream order, as they are parsed. */\n onShellMark(cb: (payload: string) => void): ViewDisposable;\n /** A mark on the cursor's line now; null in the alternate screen. */\n markCursorLine(): LineMark | null;\n decorate(mark: LineMark, opts: { overviewColor?: string; render: (el: HTMLElement) => void }): ViewDisposable | null;\n scrollToLine(line: number): void;\n scrollToBottom(): void;\n /** The buffer line at the top of the viewport. */\n viewportY(): number;\n selectLines(start: number, end: number): void;\n find(term: string, opts?: FindOptions): Promise<boolean>;\n clearFind(): void;\n onFindResults(cb: (r: { index: number; count: number }) => void): ViewDisposable;\n /** 3.15: the alternate screen (vim, less, htop) came or went. Optional: older fakes omit it. */\n onBufferChange?(cb: (alternate: boolean) => void): ViewDisposable;\n isAlternateScreen?(): boolean;\n dispose(): void;\n}\n\nexport interface PanelViewOptions {\n fontFamily: string;\n fontSize: number;\n theme: TerminalTheme;\n screenReaderMode: boolean;\n ligatures: boolean;\n /** false = never try WebGL (the DOM renderer). */\n gpu: boolean;\n /** Colours for search highlights (#RRGGBB — the addon requires that form). */\n findColors?: { match: string; active: string };\n}\n\nexport type PanelViewFactory = (opts: PanelViewOptions) => Promise<PanelView>;\n\n/** Scrollback lines the VIEW keeps (the server keeps its own 256 KB for reattach). */\nexport const PANEL_SCROLLBACK_LINES = 10_000;\n\ntype XtermModule = typeof import('@xterm/xterm');\ntype FitModule = typeof import('@xterm/addon-fit');\ntype Unicode11Module = typeof import('@xterm/addon-unicode11');\ntype WebLinksModule = typeof import('@xterm/addon-web-links');\n\nlet core: Promise<[XtermModule, FitModule, Unicode11Module, WebLinksModule]> | null = null;\n\nfunction loadCore() {\n if (!core) {\n core = Promise.all([\n import('@xterm/xterm'),\n import('@xterm/addon-fit'),\n import('@xterm/addon-unicode11'),\n import('@xterm/addon-web-links'),\n import('@xterm/xterm/css/xterm.css'),\n ]).then(([xterm, fit, unicode, links]) => [xterm, fit, unicode, links] as [XtermModule, FitModule, Unicode11Module, WebLinksModule]);\n // A failed chunk load must be retryable (the panel offers \"Try again\").\n core.catch(() => { core = null; });\n }\n return core;\n}\n\n/** ⌘ on macOS, Ctrl elsewhere: the modifier that follows a link. */\nexport function isLinkModifier(event: MouseEvent, mac: boolean): boolean {\n return mac ? event.metaKey : event.ctrlKey;\n}\n\nfunction webglAvailable(): boolean {\n try {\n if (typeof document === 'undefined' || typeof window === 'undefined' || !('WebGL2RenderingContext' in window)) return false;\n const canvas = document.createElement('canvas');\n return canvas.getContext('webgl2') !== null;\n } catch {\n return false;\n }\n}\n\n/** The real xterm.js view. */\nexport const createPanelXtermView: PanelViewFactory = async (opts) => {\n const [{ Terminal }, { FitAddon }, { Unicode11Addon }, { WebLinksAddon }] = await loadCore();\n const mac = typeof navigator !== 'undefined' && /Mac|iPhone|iPad/.test(navigator.platform || navigator.userAgent || '');\n const term: XtermTerminal = new Terminal({\n fontFamily: opts.fontFamily,\n fontSize: opts.fontSize,\n lineHeight: 1.2,\n cursorBlink: true,\n cursorStyle: 'bar',\n scrollback: PANEL_SCROLLBACK_LINES,\n theme: opts.theme as ITheme,\n screenReaderMode: opts.screenReaderMode,\n macOptionIsMeta: true,\n minimumContrastRatio: 3,\n // Unicode 11 widths and decorations are \"proposed\" API in xterm 6.\n allowProposedApi: true,\n // Room for block markers and search hits beside the scrollbar.\n overviewRuler: { width: 8 },\n // Wide glyphs (emoji, CJK) drawn at their real width.\n rescaleOverlappingGlyphs: true,\n });\n const fit = new FitAddon();\n term.loadAddon(fit);\n term.loadAddon(new Unicode11Addon());\n term.unicode.activeVersion = '11';\n\n let renderer: 'webgl' | 'dom' = 'dom';\n let webgl: IDisposable | null = null;\n let joiner: number | null = null;\n let links: LinkHandlers | null = null;\n let search: import('@xterm/addon-search').SearchAddon | null = null;\n let searchLoading: Promise<import('@xterm/addon-search').SearchAddon> | null = null;\n const findListeners = new Set<(r: { index: number; count: number }) => void>();\n let opened = false;\n\n const setLigatures = (on: boolean) => {\n if (on && joiner === null) joiner = term.registerCharacterJoiner(ligatureRanges);\n else if (!on && joiner !== null) {\n term.deregisterCharacterJoiner(joiner);\n joiner = null;\n }\n };\n\n async function enableWebgl(): Promise<void> {\n if (!opts.gpu || !webglAvailable()) return;\n try {\n const { WebglAddon } = await import('@xterm/addon-webgl');\n const addon = new WebglAddon();\n // A lost GPU context (sleep, driver reset, too many contexts) drops\n // back to the DOM renderer instead of a blank terminal.\n addon.onContextLoss(() => {\n addon.dispose();\n webgl = null;\n renderer = 'dom';\n });\n term.loadAddon(addon);\n webgl = addon;\n renderer = 'webgl';\n } catch {\n renderer = 'dom';\n }\n }\n\n async function ensureSearch() {\n if (search) return search;\n if (!searchLoading) {\n searchLoading = import('@xterm/addon-search').then(({ SearchAddon }) => {\n const addon = new SearchAddon();\n term.loadAddon(addon);\n addon.onDidChangeResults((r) => {\n for (const cb of findListeners) cb({ index: r.resultIndex, count: r.resultCount });\n });\n search = addon;\n return addon;\n });\n searchLoading.catch(() => { searchLoading = null; });\n }\n return searchLoading;\n }\n\n return {\n get cols() { return term.cols; },\n get rows() { return term.rows; },\n get renderer() { return renderer; },\n async open(host) {\n if (opened) return;\n opened = true;\n term.open(host);\n await enableWebgl();\n setLigatures(opts.ligatures);\n term.loadAddon(new WebLinksAddon((event, uri) => {\n if (links && isLinkModifier(event, mac)) links.openUrl(uri);\n }));\n term.registerLinkProvider({\n provideLinks(y, callback) {\n const line = term.buffer.active.getLine(y - 1);\n if (!line) return callback(undefined);\n const found = findFileLinks(line.translateToString(true));\n if (found.length === 0) return callback(undefined);\n callback(found.map((link) => ({\n range: { start: { x: link.start + 1, y }, end: { x: link.end, y } },\n text: line.translateToString(true).slice(link.start, link.end),\n decorations: { underline: true, pointerCursor: true },\n activate: (event: MouseEvent) => {\n if (links && isLinkModifier(event, mac)) links.openFile(link, y - 1);\n },\n })));\n },\n });\n },\n write(data, done) { term.write(data, done); },\n reset() { term.reset(); },\n clear() { term.clear(); },\n focus() { term.focus(); },\n fit() {\n const dims = fit.proposeDimensions();\n if (!dims || !Number.isFinite(dims.cols) || !Number.isFinite(dims.rows) || dims.cols < 2 || dims.rows < 2) return null;\n const changed = dims.cols !== term.cols || dims.rows !== term.rows;\n fit.fit();\n // A resized WebGL canvas is blank until the next write: draw it now.\n if (changed) term.refresh(0, term.rows - 1);\n return { cols: term.cols, rows: term.rows };\n },\n refresh() {\n term.clearTextureAtlas();\n term.refresh(0, term.rows - 1);\n },\n onData: (cb) => term.onData(cb),\n onBinary: (cb) => term.onBinary(cb),\n onSelectionChange: (cb) => term.onSelectionChange(cb),\n hasSelection: () => term.hasSelection(),\n getSelection: () => term.getSelection(),\n paste(text) { term.paste(text); },\n bracketedPaste: () => term.modes.bracketedPasteMode,\n setTheme(theme) { term.options.theme = theme as ITheme; },\n setScreenReaderMode(on) { term.options.screenReaderMode = on; },\n setKeyFilter(filter) { term.attachCustomKeyEventHandler(filter); },\n setLigatures,\n setLinkHandlers(handlers) { links = handlers; },\n onShellMark(cb) {\n return term.parser.registerOscHandler(133, (data) => {\n try { cb(data); } catch { /* a broken listener never breaks parsing */ }\n // Not \"handled\": xterm has no 133 handler of its own, and another may want it.\n return false;\n });\n },\n markCursorLine() {\n if (term.buffer.active.type !== 'normal') return null;\n const marker = term.registerMarker(0) as IMarker | undefined;\n return marker ?? null;\n },\n decorate(mark, o) {\n const deco = term.registerDecoration({\n marker: mark as IMarker,\n anchor: 'right',\n x: 0,\n width: 2,\n ...(o.overviewColor ? { overviewRulerOptions: { color: o.overviewColor, position: 'right' as const } } : {}),\n });\n if (!deco) return null;\n deco.onRender((el) => o.render(el));\n return deco;\n },\n scrollToLine(line) { term.scrollToLine(Math.max(0, line)); },\n scrollToBottom() { term.scrollToBottom(); },\n viewportY: () => term.buffer.active.viewportY,\n selectLines(start, end) { term.selectLines(start, end); },\n async find(text, o = {}) {\n const addon = await ensureSearch();\n const options = {\n caseSensitive: o.caseSensitive ?? false,\n regex: o.regex ?? false,\n wholeWord: o.wholeWord ?? false,\n ...(opts.findColors ? {\n decorations: {\n matchBackground: opts.findColors.match,\n activeMatchBackground: opts.findColors.active,\n matchOverviewRuler: opts.findColors.match,\n activeMatchColorOverviewRuler: opts.findColors.active,\n },\n } : {}),\n };\n return o.backwards ? addon.findPrevious(text, options) : addon.findNext(text, { ...options, incremental: true });\n },\n clearFind() {\n search?.clearDecorations();\n term.clearSelection();\n },\n onFindResults(cb) {\n findListeners.add(cb);\n return { dispose: () => { findListeners.delete(cb); } };\n },\n onBufferChange: (cb) => term.buffer.onBufferChange((buffer) => cb(buffer.type === 'alternate')),\n isAlternateScreen: () => term.buffer.active.type === 'alternate',\n dispose() {\n findListeners.clear();\n try { webgl?.dispose(); } catch { /* already gone */ }\n term.dispose();\n },\n };\n};\n\n// ---------------------------------------------------------------------------\n// Colours from tokens\n// ---------------------------------------------------------------------------\n\n/** `rgb(…)` / `rgba(…)` → `#rrggbb` (the search addon's required form); null when unparseable. */\nexport function rgbToHex(value: string): string | null {\n const m = /^rgba?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})/.exec(value.trim());\n if (!m) return null;\n return `#${[m[1], m[2], m[3]].map((v) => Math.min(255, Number(v)).toString(16).padStart(2, '0')).join('')}`;\n}\n\n/** Concrete colours for the panel's non-palette needs, resolved from its `--term-*` properties. */\nexport function resolvePanelColors(host: HTMLElement): { ok: string; error: string; running: string; match: string | null; active: string | null } {\n const theme = resolveTerminalTheme(host);\n return {\n ok: theme.green ?? 'green',\n error: theme.red ?? 'red',\n running: theme.yellow ?? 'orange',\n match: theme.selectionBackground ? rgbToHex(theme.selectionBackground) : null,\n active: theme.yellow ? rgbToHex(theme.yellow) : null,\n };\n}\n","/**\n * terminal/TerminalLeaf.tsx — one shell on screen (3.15): its xterm view, its\n * live stream, its keystrokes, its command blocks and their markers, find.\n *\n * STREAM. Only a leaf that is on screen streams (one fetch() connection; see\n * layout-model.ts for why that matters); a hidden one catches up from its\n * last seq when shown. A reload replays the server's scrollback and then its\n * blocks (terminal.ts subscribe), so markers and blocks come back too.\n *\n * MARKERS. xterm parses the shell's OSC 133 marks as it writes; on each `A`\n * (a prompt) the leaf marks that line, and on each `C` (a command started)\n * it files the prompt's mark under (frame seq, ordinal) — exactly the key the\n * server gives the block. When the block's frame arrives it finds its line:\n * a status dot beside it (click for its actions), a tick in the scrollbar's\n * overview ruler, ⌘↑/⌘↓ to walk them, and \"Show in terminal\" from the list.\n *\n * INPUT EDITOR (3.15). The same marks say where the shell is (input-model.ts\n * PromptPhase): at a prompt — after B, before C, not in the alternate screen\n * — the leaf docks CommandInput under the terminal and gives it the keyboard.\n * Typing into the terminal itself at that prompt hands the prompt to the\n * shell's own line editor until the next one; a Raw shell never shows it.\n * 3.15 MANY AGENTS. Over the terminal view: the RUNNING command's sticky\n * header (once its prompt line has scrolled away), a bar offering to open a\n * loopback URL the command printed in the Browser pane, and — after a command\n * fails — the local model's fix chips. Selection of several blocks lives\n * here (its blocks are here); what to do with them is the panel's.\n\n */\nimport { forwardRef, lazy, Suspense, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';\nimport type { VerseTerminalBlock, VerseTerminalFixResponse, VerseTerminalStreamFrame, VerseTerminalTab } from '../../../data/api-types.js';\nimport { Button } from '../../../components/primitives/Button.js';\nimport { SkeletonLine } from '../../../components/primitives/Skeleton.js';\nimport { IconChevronDown, IconChevronUp, IconX } from '../../../components/primitives/icons.js';\nimport type { KeyPlatform } from '../shell/command-keys.js';\nimport { createInputQueue, type InputQueue } from '../dock/terminal/input-queue.js';\nimport { base64ToBytes } from '../dock/terminal/terminal-client.js';\nimport type { PanelStreamOpener, TerminalStreamState } from './panel-stream.js';\nimport { resolveTerminalFont, resolveTerminalTheme, watchThemeChanges } from '../dock/terminal/terminal-view.js';\nimport { BlockList, type BlockAction, type BlockActionExtra, type BlockListExtras } from './BlockList.js';\nimport { blockStatus, markerKey, terminalBlockView, upsertBlock, type BlockView } from './blocks-model.js';\nimport { elapsedLabel, EMPTY_SELECTION, pruneSelection, selectBlock, urlLabel, type BlockSelection } from './block-tools.js';\nimport { BrowserGlyph } from './extra-glyphs.js';\nimport { FixChips, type AskTarget } from './FixChips.js';\nimport extra from './TerminalExtras.module.css';\nimport type { FileLink } from './file-links.js';\nimport type { LeafMode } from './layout-model.js';\nimport type { PanelTerminalApi } from './panel-client.js';\nimport { keyPassesToPage, panelKeyAction, panelKeyLabel, type PanelKeyAction } from './panel-keys.js';\nimport { resolvePanelColors, type LineMark, type PanelView, type PanelViewFactory, type ViewDisposable } from './xterm-view.js';\nimport { CommandInput, type CommandInputHandle } from './CommandInput.js';\nimport type { VerseTerminalAssistMode } from '../../../data/api-types.js';\nimport type { InputEditorFactory } from './input-editor.js';\nimport { inputVisible, isOperatorKeystroke, nextPromptPhase, type PromptPhase } from './input-model.js';\nimport styles from './TerminalPanel.module.css';\n\n// Dictation (voice/): lazy. The terminal is the `verbatim` surface — the\n// words go in exactly as heard, and are NEVER followed by Enter.\nconst VoiceInput = lazy(() => import('../voice/VoiceInput.js'));\n\nexport interface LeafDeps {\n api: PanelTerminalApi;\n createView: PanelViewFactory;\n openStream: PanelStreamOpener;\n platform: KeyPlatform;\n writeClipboard: (text: string) => Promise<void>;\n openUrl: (url: string) => void;\n /** 3.15: the input editor (CodeMirror, lazily). Absent = no input editor (raw terminal only). */\n createInputEditor?: InputEditorFactory;\n /** Start fetching the editor's chunk (a shell whose integration just came up). */\n preloadInputEditor?: () => void;\n}\n\nexport interface LeafPrefs {\n screenReader: boolean;\n ligatures: boolean;\n gpu: boolean;\n /** 3.15: the input editor at shell prompts (default on; Raw per shell overrides). */\n inputEditor: boolean;\n}\n\nexport type LeafNotice = { tone: 'error' | 'info'; text: string };\n\n/** 3.15: what the panel lends every leaf for the many-agents block actions. */\nexport interface LeafExtras {\n /** This tab's bookmarked block ids. */\n bookmarks: ReadonlySet<string>;\n /** Null = fix suggestions are off. */\n loadFix: ((tabId: string, block: BlockView) => Promise<VerseTerminalFixResponse>) | null;\n askTargets: readonly AskTarget[];\n onOpenUrl: (url: string) => void;\n /** Several selected blocks: copy / send / ask about them together. */\n onSelectionAction: (tabId: string, action: 'copy-output' | 'send' | 'ask', blocks: BlockView[], anchor?: HTMLElement) => void;\n}\n\n/** What the panel can ask of a leaf. */\nexport interface LeafHandle {\n focus(): void;\n getSelection(): string;\n clear(): void;\n openFind(): void;\n jumpTo(blockId: string): void;\n size(): { cols: number; rows: number } | null;\n paste(text: string): void;\n /** The shell has printed something (its prompt): a paste will land at a prompt. */\n hasOutput(): boolean;\n /** 3.15: the input editor is showing (at a prompt). */\n inputActive(): boolean;\n /** Put a command where the operator will type next: the input editor, else pasted at the prompt. Never run. */\n insertCommand(text: string): void;\n /** ⌘I: plain words → a command, in the input editor. False when the editor is not showing. */\n openAssist(): boolean;\n /** Write bytes to the shell as if typed (in order with the rest), e.g. a ⌃R handed to the shell. */\n sendText(text: string): void;\n /** 3.15: this tab's blocks as the list shows them (for a link or a request naming one). */\n blocks(): BlockView[];\n\n}\n\nexport interface TerminalLeafProps {\n tab: VerseTerminalTab;\n deps: LeafDeps;\n /** On screen (its group is active and the panel is visible). */\n shown: boolean;\n /** The pane keystrokes go to, in its group. */\n focused: boolean;\n mode: LeafMode;\n prefs: LeafPrefs;\n assistMode: VerseTerminalAssistMode;\n onFocus: () => void;\n /** Title, exit, cwd, integration: the panel keeps the tab list. */\n onMeta: (tabId: string, frame: Exclude<VerseTerminalStreamFrame, { type: 'output' } | { type: 'block' }>) => void;\n onBlockAction: (tabId: string, action: BlockAction, block: BlockView, extra?: BlockActionExtra) => void;\n /** A block's dot in the terminal was clicked: its actions, anchored there. */\n onBlockMenu: (tabId: string, block: BlockView, anchor: HTMLElement) => void;\n onKeyAction: (tabId: string, action: PanelKeyAction) => void;\n onSelection: (tabId: string, has: boolean, text: string) => void;\n onNotice: (notice: LeafNotice) => void;\n onStreamState: (tabId: string, state: TerminalStreamState | null) => void;\n onRestart: (tab: VerseTerminalTab) => void;\n onClose: (tab: VerseTerminalTab) => void;\n onError: (err: unknown, fallback: string) => string;\n /** 3.15: this shell uses its own line editor only (no input editor). */\n raw?: boolean;\n /** 3.15: another pane of its group is zoomed: this one is kept (and its view) but not shown. */\n concealed?: boolean;\n /** 3.15: in a grid, how many columns this pane spans (a short last row stretches). */\n gridSpan?: number;\n /** 3.15: ⌃R in the input editor — the panel opens the history palette. */\n onHistorySearch?: (tabId: string, draft: string) => void;\n /** 3.15: the many-agents block actions; absent = the 3.15.0 list. */\n extras?: LeafExtras;\n\n}\n\ninterface MarkRecord {\n mark: LineMark;\n deco: ViewDisposable | null;\n tone: string | null;\n}\n\nexport const TerminalLeaf = forwardRef<LeafHandle, TerminalLeafProps>(function TerminalLeaf(props, ref) {\n const { tab, deps, shown, focused, mode, prefs } = props;\n const hostRef = useRef<HTMLDivElement>(null);\n const leafRef = useRef<HTMLDivElement>(null);\n const viewRef = useRef<PanelView | null>(null);\n const queueRef = useRef<InputQueue | null>(null);\n const lastSeq = useRef(0);\n const disposers = useRef<ViewDisposable[]>([]);\n const [ready, setReady] = useState(false);\n const [failed, setFailed] = useState(false);\n const [blocks, setBlocks] = useState<readonly VerseTerminalBlock[]>([]);\n const [highlight, setHighlight] = useState<string | null>(null);\n /** The server's replay has started arriving (it always opens with the title): \"no commands\" is true now. */\n const [replayed, setReplayed] = useState(false);\n const [find, setFind] = useState<{ open: boolean; term: string; caseSensitive: boolean; regex: boolean; index: number; count: number }>({\n open: false, term: '', caseSensitive: false, regex: false, index: -1, count: 0,\n });\n const findInput = useRef<HTMLInputElement>(null);\n const findOpenRef = useRef(false);\n findOpenRef.current = find.open;\n const exitedRef = useRef(tab.exited !== null);\n exitedRef.current = tab.exited !== null;\n const propsRef = useRef(props);\n propsRef.current = props;\n const [selection, setSelection] = useState<BlockSelection>(EMPTY_SELECTION);\n /** Fix chips / URL bar dismissed for these blocks (terminal view). */\n const [dismissed, setDismissed] = useState<ReadonlySet<string>>(() => new Set());\n const [clock, setClock] = useState(() => Date.now());\n\n // Where the shell is (its OSC 133 marks), for the input editor.\n const [phase, setPhase] = useState<PromptPhase>('unknown');\n const [alternate, setAlternate] = useState(false);\n const [handedOff, setHandedOff] = useState(false);\n const inputRef = useRef<CommandInputHandle>(null);\n const showInput = Boolean(deps.createInputEditor) && prefs.inputEditor && inputVisible({\n phase,\n integration: tab.shellIntegration === 'active',\n alternateScreen: alternate,\n exited: tab.exited !== null,\n raw: props.raw === true,\n handedOff,\n terminalMode: mode === 'terminal',\n });\n const showInputRef = useRef(showInput);\n showInputRef.current = showInput;\n\n // Seq bookkeeping for markers: frames queued into xterm, C marks seen per frame.\n const writing = useRef<number[]>([]);\n const ordinals = useRef(new Map<number, number>());\n const promptMark = useRef<LineMark | null>(null);\n /** The newest frame xterm has finished parsing. */\n const writtenSeq = useRef(0);\n /** Blocks whose C mark is in a frame not parsed yet. */\n const pendingDecorations = useRef(new Map<string, VerseTerminalBlock>());\n const marks = useRef(new Map<string, MarkRecord>());\n const blocksRef = useRef<readonly VerseTerminalBlock[]>([]);\n blocksRef.current = blocks;\n\n // -------------------------------------------------------------------------\n // Markers and decorations\n // -------------------------------------------------------------------------\n\n const decorate = useCallback((block: VerseTerminalBlock) => {\n const view = viewRef.current;\n const host = hostRef.current;\n if (!view || !host) return;\n const rec = marks.current.get(markerKey(block.startSeq, block.ordinal));\n if (!rec || rec.mark.isDisposed) return;\n const status = blockStatus(terminalBlockView(block));\n if (rec.tone === status.tone) return;\n rec.deco?.dispose();\n const colors = resolvePanelColors(host);\n const overviewColor = status.tone === 'ok' ? colors.ok : status.tone === 'error' ? colors.error : status.tone === 'running' ? colors.running : undefined;\n rec.tone = status.tone;\n rec.deco = view.decorate(rec.mark, {\n ...(overviewColor ? { overviewColor } : {}),\n render: (el) => {\n // Added, not assigned: xterm positions the element through its own class.\n el.classList.add(styles.blockDot!);\n // At the line's right end, clear of the prompt (xterm leaves `right` unset for x = 0).\n el.style.left = 'auto';\n el.style.right = '0px';\n el.dataset['tone'] = status.tone;\n el.title = `${block.command || 'command'} — ${status.label}`;\n el.setAttribute('role', 'button');\n el.setAttribute('aria-label', `Command block: ${block.command || 'command'}, ${status.label}`);\n el.onclick = (event) => {\n event.preventDefault();\n event.stopPropagation();\n const current = blocksRef.current.find((b) => b.id === block.id) ?? block;\n propsRef.current.onBlockMenu(tab.id, terminalBlockView(current), el);\n };\n el.oncontextmenu = el.onclick;\n },\n });\n }, [tab.id]);\n\n const disposeMarks = useCallback(() => {\n for (const rec of marks.current.values()) {\n rec.deco?.dispose();\n rec.mark.dispose();\n }\n marks.current.clear();\n promptMark.current?.dispose();\n promptMark.current = null;\n ordinals.current.clear();\n pendingDecorations.current.clear();\n writing.current = [];\n }, []);\n\n /** ⌘↑ / ⌘↓: scroll to the previous / next command's prompt line. */\n const walkRef = useRef((direction: -1 | 1) => {\n const view = viewRef.current;\n if (!view) return;\n const lines = [...marks.current.values()].filter((r) => !r.mark.isDisposed).map((r) => r.mark.line).sort((a, b) => a - b);\n const top = view.viewportY();\n const target = direction < 0 ? [...lines].reverse().find((l) => l < top) : lines.find((l) => l > top);\n if (target !== undefined) view.scrollToLine(target);\n else if (direction > 0) view.scrollToBottom();\n });\n\n /**\n * The panel's own keys, from the terminal or from its input editor. From\n * the editor, ⌘I stays the editor's (\"describe it\" in place).\n */\n const panelKeyRef = useRef((event: KeyboardEvent, fromTerminal: boolean): boolean => {\n const action = panelKeyAction(event, propsRef.current.deps.platform);\n if (!action || (!fromTerminal && action === 'assist')) return false;\n event.preventDefault();\n if (action === 'prev-block' || action === 'next-block') walkRef.current(action === 'prev-block' ? -1 : 1);\n else propsRef.current.onKeyAction(propsRef.current.tab.id, action);\n return true;\n });\n\n // -------------------------------------------------------------------------\n // The view\n // -------------------------------------------------------------------------\n\n const attach = useCallback(async () => {\n const host = hostRef.current;\n if (!host || viewRef.current) return;\n try {\n const colors = resolvePanelColors(host);\n const view = await deps.createView({\n ...resolveTerminalFont(host),\n theme: resolveTerminalTheme(host),\n screenReaderMode: prefs.screenReader,\n ligatures: prefs.ligatures,\n gpu: prefs.gpu,\n ...(colors.match && colors.active ? { findColors: { match: colors.match, active: colors.active } } : {}),\n });\n if (!hostRef.current) {\n view.dispose();\n return;\n }\n await view.open(host);\n viewRef.current = view;\n const queue = createInputQueue((b64) => deps.api.input(tab.id, b64), {\n onError: (err) => propsRef.current.onNotice({ tone: 'error', text: propsRef.current.onError(err, 'That input did not reach the shell.') }),\n });\n queueRef.current = queue;\n const d = disposers.current;\n d.push(view.onData((data) => {\n if (exitedRef.current) return;\n // Typed into the terminal itself at a prompt the editor was showing: this prompt is the shell's.\n if (showInputRef.current && isOperatorKeystroke(data)) setHandedOff(true);\n queue.pushText(data);\n }));\n if (view.onBufferChange) d.push(view.onBufferChange((alt) => setAlternate(alt)));\n d.push(view.onBinary((data) => { if (!exitedRef.current) queue.pushBinary(data); }));\n d.push(view.onSelectionChange(() => {\n const has = view.hasSelection();\n // A find match selects its text: that is not the operator copying, so no copy-on-select.\n propsRef.current.onSelection(tab.id, has, has && !findOpenRef.current ? view.getSelection() : '');\n }));\n d.push(view.onShellMark((payload) => {\n const seq = writing.current[0];\n const code = payload.split(';', 1)[0];\n setPhase((prev) => nextPromptPhase(prev, payload));\n // A new prompt: whoever had the last one, the editor is offered again.\n if (code === 'A') setHandedOff(false);\n if (code === 'A') {\n promptMark.current?.dispose();\n promptMark.current = view.markCursorLine();\n } else if (code === 'C' && seq !== undefined) {\n const ordinal = ordinals.current.get(seq) ?? 0;\n ordinals.current.set(seq, ordinal + 1);\n const mark = promptMark.current && !promptMark.current.isDisposed ? promptMark.current : view.markCursorLine();\n promptMark.current = null;\n if (!mark) return;\n const key = markerKey(seq, ordinal);\n marks.current.get(key)?.mark.dispose();\n marks.current.set(key, { mark, deco: null, tone: null });\n // The block may already be known (a replay sends blocks after output).\n const block = blocksRef.current.find((b) => b.startSeq === seq && b.ordinal === ordinal);\n if (block) decorate(block);\n }\n }));\n d.push(view.onFindResults((r) => setFind((f) => ({ ...f, index: r.index, count: r.count }))));\n view.setLinkHandlers({\n openUrl: (url) => deps.openUrl(url),\n openFile: (link: FileLink, bufferLine: number) => {\n // A relative path is relative to where the command that PRINTED it\n // ran — the block whose prompt line is the last one above the link —\n // not to wherever the shell has since `cd`-ed.\n let cwd = propsRef.current.tab.cwd ?? null;\n let best = -1;\n for (const block of blocksRef.current) {\n const rec = marks.current.get(markerKey(block.startSeq, block.ordinal));\n if (!rec || rec.mark.isDisposed || rec.mark.line > bufferLine || rec.mark.line < best) continue;\n best = rec.mark.line;\n cwd = block.cwd ?? cwd;\n }\n deps.api.openFile(tab.id, {\n path: link.path,\n ...(link.line !== null ? { line: link.line } : {}),\n ...(link.column !== null ? { column: link.column } : {}),\n ...(cwd ? { cwd } : {}),\n }).catch((err) => propsRef.current.onNotice({ tone: 'error', text: propsRef.current.onError(err, 'That file could not be opened.') }));\n },\n });\n view.setKeyFilter((event) => {\n if (panelKeyRef.current(event, true)) return false;\n return !keyPassesToPage(event, deps.platform);\n });\n setFailed(false);\n setReady(true);\n } catch (err) {\n console.error('[verse] terminal view failed to load', err);\n setFailed(true);\n }\n }, [deps, prefs.gpu, prefs.ligatures, prefs.screenReader, tab.id, decorate]);\n\n // Mount: the view is created once per leaf; the SERVER keeps the shell when it unmounts.\n useEffect(() => {\n void attach();\n return () => {\n queueRef.current?.dispose();\n queueRef.current = null;\n for (const d of disposers.current) {\n try { d.dispose(); } catch { /* already gone */ }\n }\n disposers.current = [];\n disposeMarks();\n try { viewRef.current?.dispose(); } catch { /* already gone */ }\n viewRef.current = null;\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- once per leaf\n }, []);\n\n useEffect(() => { viewRef.current?.setScreenReaderMode(prefs.screenReader); }, [prefs.screenReader]);\n useEffect(() => { viewRef.current?.setLigatures(prefs.ligatures); }, [prefs.ligatures]);\n\n // Theme follows the app.\n useEffect(() => watchThemeChanges(() => {\n const host = hostRef.current;\n if (!host) return;\n viewRef.current?.setTheme(resolveTerminalTheme(host));\n for (const rec of marks.current.values()) rec.tone = null;\n for (const block of blocksRef.current) decorate(block);\n }), [decorate]);\n\n // -------------------------------------------------------------------------\n // Fit + resize\n // -------------------------------------------------------------------------\n\n const resizeTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const fitNow = useCallback(() => {\n const view = viewRef.current;\n if (!view) return;\n const before = { cols: view.cols, rows: view.rows };\n const size = view.fit();\n if (!size) return;\n if (size.cols === before.cols && size.rows === before.rows && size.cols === tab.cols && size.rows === tab.rows) return;\n if (resizeTimer.current) clearTimeout(resizeTimer.current);\n resizeTimer.current = setTimeout(() => {\n deps.api.resize(tab.id, size.cols, size.rows).catch(() => { /* the next fit retries */ });\n }, 80);\n }, [deps.api, tab.id, tab.cols, tab.rows]);\n\n useEffect(() => {\n if (!shown || !ready || mode !== 'terminal') return undefined;\n fitNow();\n // Shown again (another tab, the Blocks view): a renderer that last drew\n // while hidden has nothing on screen until it redraws.\n viewRef.current?.refresh();\n const host = hostRef.current?.parentElement;\n if (!host || typeof ResizeObserver === 'undefined') return undefined;\n let frame = 0;\n const observer = new ResizeObserver(() => {\n cancelAnimationFrame(frame);\n frame = requestAnimationFrame(fitNow);\n });\n observer.observe(host);\n // Web fonts change the cell size once they load.\n const fonts = typeof document !== 'undefined' ? (document as Document & { fonts?: FontFaceSet }).fonts : undefined;\n void fonts?.ready?.then(() => requestAnimationFrame(fitNow));\n // A move to another display changes the pixel ratio (and the cell size).\n const dpr = typeof window !== 'undefined' && typeof window.matchMedia === 'function'\n ? window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`) : null;\n const onDpr = () => requestAnimationFrame(fitNow);\n dpr?.addEventListener?.('change', onDpr);\n return () => {\n cancelAnimationFrame(frame);\n observer.disconnect();\n dpr?.removeEventListener?.('change', onDpr);\n };\n }, [shown, ready, mode, fitNow]);\n\n useEffect(() => () => { if (resizeTimer.current) clearTimeout(resizeTimer.current); }, []);\n\n // -------------------------------------------------------------------------\n // The live stream (on screen only)\n // -------------------------------------------------------------------------\n\n useEffect(() => {\n if (!shown || !ready) {\n propsRef.current.onStreamState(tab.id, null);\n return undefined;\n }\n const view = viewRef.current;\n if (!view) return undefined;\n const tabId = tab.id;\n const onFrame = (frame: VerseTerminalStreamFrame) => {\n if (frame.type !== 'output') setReplayed(true);\n switch (frame.type) {\n case 'output': {\n if (frame.seq <= lastSeq.current) return;\n // A gap: the server's ring dropped frames this view never got —\n // start over from what it still has rather than draw a torn screen.\n if (lastSeq.current > 0 && frame.seq > lastSeq.current + 1) {\n view.reset();\n disposeMarks();\n }\n const seq = frame.seq;\n writing.current.push(seq);\n view.write(base64ToBytes(frame.dataBase64), () => {\n if (writing.current[0] === seq) writing.current.shift();\n ordinals.current.delete(seq);\n writtenSeq.current = Math.max(writtenSeq.current, seq);\n for (const [id, block] of pendingDecorations.current) {\n if (block.startSeq > writtenSeq.current) continue;\n pendingDecorations.current.delete(id);\n decorate(block);\n }\n });\n lastSeq.current = seq;\n return;\n }\n case 'block': {\n // The ref too: a decoration's click reads the latest record before React re-renders.\n blocksRef.current = upsertBlock(blocksRef.current, frame.block);\n setBlocks(blocksRef.current);\n // Only once xterm has PARSED the frame holding its C mark (writes are async).\n if (frame.block.startSeq <= writtenSeq.current) decorate(frame.block);\n else pendingDecorations.current.set(frame.block.id, frame.block);\n return;\n }\n default:\n propsRef.current.onMeta(tabId, frame);\n }\n };\n const stream = deps.openStream(tabId, () => lastSeq.current, {\n onFrame,\n onState: (state) => propsRef.current.onStreamState(tabId, state),\n });\n return () => stream.close();\n }, [shown, ready, tab.id, deps, decorate, disposeMarks]);\n\n // Focus follows the pane that should have the keyboard: its input editor at a prompt, else the terminal.\n useEffect(() => {\n if (!(shown && focused && ready && mode === 'terminal')) return;\n if (showInput) inputRef.current?.focus();\n else viewRef.current?.focus();\n }, [shown, focused, ready, mode, showInput]);\n\n // Fetch the editor's chunk once a shell's integration is up (it will be needed at its first prompt).\n useEffect(() => {\n if (tab.shellIntegration === 'active' && prefs.inputEditor && !props.raw) deps.preloadInputEditor?.();\n }, [tab.shellIntegration, prefs.inputEditor, props.raw, deps]);\n\n // -------------------------------------------------------------------------\n // Find\n // -------------------------------------------------------------------------\n\n const runFind = useCallback((term: string, opts: { backwards?: boolean; caseSensitive: boolean; regex: boolean }) => {\n const view = viewRef.current;\n if (!view) return;\n if (!term) {\n view.clearFind();\n setFind((f) => ({ ...f, index: -1, count: 0 }));\n return;\n }\n void view.find(term, { caseSensitive: opts.caseSensitive, regex: opts.regex, ...(opts.backwards ? { backwards: true } : {}) }).catch(() => {\n /* an invalid regex while typing */\n });\n }, []);\n\n const closeFind = useCallback(() => {\n viewRef.current?.clearFind();\n setFind((f) => ({ ...f, open: false, index: -1, count: 0 }));\n viewRef.current?.focus();\n }, []);\n\n // -------------------------------------------------------------------------\n // Blocks: jump, walk\n // -------------------------------------------------------------------------\n\n const jumpTo = useCallback((blockId: string) => {\n const block = blocksRef.current.find((b) => b.id === blockId);\n const view = viewRef.current;\n if (!block || !view) return;\n const rec = marks.current.get(markerKey(block.startSeq, block.ordinal));\n if (rec && !rec.mark.isDisposed) {\n view.scrollToLine(Math.max(0, rec.mark.line - 1));\n view.selectLines(rec.mark.line, rec.mark.line);\n }\n setHighlight(blockId);\n }, []);\n\n const sendText = useCallback((text: string) => {\n if (exitedRef.current) return;\n queueRef.current?.pushText(text);\n }, []);\n\n /** Insert text at the shell's own prompt — never a trailing newline, so nothing runs. */\n const pasteAtPrompt = useCallback((text: string) => {\n const view = viewRef.current;\n if (!view) return;\n const clean = text.replace(/[\\r\\n]+$/, '');\n if (clean.includes('\\n') && !view.bracketedPaste()) {\n // Without bracketed paste a shell would RUN each line as it arrives.\n deps.writeClipboard(clean).then(\n () => propsRef.current.onNotice({ tone: 'info', text: 'That command has several lines, so it was copied instead: paste it with ⌘V.' }),\n () => propsRef.current.onNotice({ tone: 'error', text: 'That command has several lines and could not be pasted safely.' }),\n );\n } else {\n view.paste(clean);\n }\n view.focus();\n }, [deps]);\n\n /**\n * Text for where the operator types next — the input editor at a prompt,\n * else the shell's own prompt. Never run: no Enter is added.\n */\n const pasteText = useCallback((text: string) => {\n if (showInputRef.current && inputRef.current) inputRef.current.insert(text);\n else pasteAtPrompt(text);\n }, [pasteAtPrompt]);\n // Dictated words: one line, verbatim, where the operator types next (no Enter).\n const insertDictated = useCallback((text: string) => pasteText(text.replace(/\\s*[\\r\\n]+\\s*/g, ' ').trim()), [pasteText]);\n\n useImperativeHandle(ref, () => ({\n focus: () => {\n if (showInputRef.current) inputRef.current?.focus();\n else viewRef.current?.focus();\n },\n getSelection: () => viewRef.current?.getSelection() ?? '',\n clear: () => {\n viewRef.current?.clear();\n },\n openFind: () => {\n setFind((f) => ({ ...f, open: true }));\n setTimeout(() => findInput.current?.select(), 0);\n },\n jumpTo,\n size: () => (viewRef.current && viewRef.current.cols > 1 ? { cols: viewRef.current.cols, rows: viewRef.current.rows } : null),\n hasOutput: () => writtenSeq.current > 0,\n blocks: () => blocksRef.current.map(terminalBlockView),\n // At a prompt with the editor showing, a paste lands in the editor (still not run).\n\n paste: pasteText,\n inputActive: () => showInputRef.current,\n insertCommand: pasteText,\n openAssist: () => {\n if (!showInputRef.current || !inputRef.current) return false;\n inputRef.current.openAssist();\n return true;\n },\n sendText,\n }), [jumpTo, pasteText, sendText]);\n\n const blockViews = useMemo(() => blocks.map(terminalBlockView), [blocks]);\n const loadOutput = useCallback(async (block: BlockView) =>\n (await deps.api.blockOutput(tab.id, block.id, 'ansi')).output, [deps.api, tab.id]);\n const onListAction = useCallback((action: BlockAction, block: BlockView, more?: BlockActionExtra) => {\n propsRef.current.onBlockAction(tab.id, action, block, more);\n }, [tab.id]);\n\n // -------------------------------------------------------------------------\n // 3.15: selection, sticky header, URL bar, fix chips\n // -------------------------------------------------------------------------\n\n const order = useMemo(() => blockViews.map((b) => b.id), [blockViews]);\n useEffect(() => { setSelection((sel) => pruneSelection(sel, order)); }, [order]);\n const extrasProp = props.extras;\n const listExtras = useMemo<BlockListExtras | undefined>(() => {\n if (!extrasProp) return undefined;\n const loadFix = extrasProp.loadFix;\n return {\n selection,\n onSelect: (id, gesture) => setSelection((sel) => selectBlock(sel, order, id, gesture) ?? sel),\n onClearSelection: () => setSelection(EMPTY_SELECTION),\n onSelectionAction: (action, anchor) => {\n const picked = blockViews.filter((b) => selection.ids.has(b.id));\n if (picked.length > 0) extrasProp.onSelectionAction(tab.id, action, picked, anchor);\n },\n bookmarks: extrasProp.bookmarks,\n loadFix: loadFix ? (block) => loadFix(tab.id, block) : null,\n askTargets: extrasProp.askTargets,\n canRerun: !tab.exited && !tab.agent && !blockViews.some((b) => b.running),\n };\n }, [extrasProp, selection, order, blockViews, tab.id, tab.exited, tab.agent]);\n\n const latest = blockViews.at(-1) ?? null;\n const running = latest && latest.running && !latest.fullscreen && !tab.agent ? latest : null;\n // The sticky header and its clock tick only while a command runs on screen.\n useEffect(() => {\n if (!running || !shown || mode !== 'terminal') return undefined;\n setClock(Date.now());\n const timer = setInterval(() => setClock(Date.now()), 1_000);\n return () => clearInterval(timer);\n }, [running, shown, mode]);\n let stickyVisible = false;\n if (running && ready) {\n const block = blocksRef.current.find((b) => b.id === running.id);\n const rec = block ? marks.current.get(markerKey(block.startSeq, block.ordinal)) : undefined;\n const view = viewRef.current;\n // Shown once the command's own prompt line has scrolled out of view (clock re-evaluates it).\n stickyVisible = Boolean(rec && !rec.mark.isDisposed && view && rec.mark.line < view.viewportY());\n }\n const urlBlock = extrasProp && latest && (latest.localUrls?.length ?? 0) > 0 && !dismissed.has(`url:${latest.id}`) ? latest : null;\n const fixBlock = extrasProp && latest && !latest.running && latest.exitCode !== null && latest.exitCode !== 0 && !tab.agent && !dismissed.has(`fix:${latest.id}`) ? latest : null;\n const fixLoadFn = extrasProp?.loadFix ?? null;\n // Keyed on the block's id: a later frame for another block must not ask the model again.\n const fixBlockRef = useRef(fixBlock);\n fixBlockRef.current = fixBlock;\n const fixBlockId = fixBlock?.id ?? null;\n const fixLoad = useMemo(\n () => (fixLoadFn && fixBlockId ? () => fixLoadFn(tab.id, fixBlockRef.current!) : null),\n [fixLoadFn, fixBlockId, tab.id],\n );\n const dismiss = (key: string) => setDismissed((prev) => new Set(prev).add(key));\n\n const findKey = panelKeyLabel('find', deps.platform);\n const exited = tab.exited;\n\n return (\n <div\n ref={leafRef}\n className={styles.leaf}\n hidden={props.concealed || undefined}\n data-span={props.gridSpan && props.gridSpan > 1 ? props.gridSpan : undefined}\n data-focused={focused || undefined}\n data-testid={`terminal-leaf-${tab.id}`}\n onMouseDown={() => { if (!focused) props.onFocus(); }}\n onFocusCapture={() => { if (!focused) props.onFocus(); }}\n >\n {find.open ? (\n <div className={styles.find} role=\"search\" aria-label=\"Find in terminal\">\n <input\n ref={findInput}\n className={styles.findInput}\n aria-label=\"Find\"\n placeholder=\"Find\"\n value={find.term}\n autoFocus\n onChange={(e) => {\n const term = e.target.value;\n setFind((f) => ({ ...f, term }));\n runFind(term, { caseSensitive: find.caseSensitive, regex: find.regex });\n }}\n onKeyDown={(e) => {\n if (e.key === 'Escape') { e.preventDefault(); e.stopPropagation(); closeFind(); }\n if (e.key === 'Enter') { e.preventDefault(); runFind(find.term, { caseSensitive: find.caseSensitive, regex: find.regex, backwards: e.shiftKey }); }\n }}\n />\n <span className={styles.findCount} aria-live=\"polite\">\n {find.term ? (find.count === 0 ? 'No results' : find.index >= 0 ? `${find.index + 1} of ${find.count}` : `${find.count}+`) : ''}\n </span>\n <button type=\"button\" className={styles.toggle} aria-pressed={find.caseSensitive} title=\"Match case\" aria-label=\"Match case\"\n onClick={() => { const next = !find.caseSensitive; setFind((f) => ({ ...f, caseSensitive: next })); runFind(find.term, { caseSensitive: next, regex: find.regex }); }}>Aa</button>\n <button type=\"button\" className={styles.toggle} aria-pressed={find.regex} title=\"Regular expression\" aria-label=\"Regular expression\"\n onClick={() => { const next = !find.regex; setFind((f) => ({ ...f, regex: next })); runFind(find.term, { caseSensitive: find.caseSensitive, regex: next }); }}>.*</button>\n <button type=\"button\" className={styles.iconBtn} aria-label=\"Previous match\" title=\"Previous match (⇧Enter)\"\n onClick={() => runFind(find.term, { caseSensitive: find.caseSensitive, regex: find.regex, backwards: true })}><IconChevronUp size={14} /></button>\n <button type=\"button\" className={styles.iconBtn} aria-label=\"Next match\" title=\"Next match (Enter)\"\n onClick={() => runFind(find.term, { caseSensitive: find.caseSensitive, regex: find.regex })}><IconChevronDown size={14} /></button>\n <button type=\"button\" className={styles.iconBtn} aria-label=\"Close find\" title={`Close (Esc) — open with ${findKey}`} onClick={closeFind}><IconX size={12} /></button>\n </div>\n ) : null}\n\n <div\n className={styles.viewport}\n hidden={mode !== 'terminal'}\n onMouseUp={(event) => {\n // A click in the terminal at a prompt (not a selection, not a control like the mic) keeps typing in the editor, as in Warp.\n if ((event.target as HTMLElement | null)?.closest?.('button, a, input, [role=\"button\"]')) return;\n if (showInputRef.current && !viewRef.current?.hasSelection()) setTimeout(() => inputRef.current?.focus(), 0);\n }}\n >\n {running && stickyVisible ? (\n <div className={extra.stickyRun} role=\"status\" aria-label={`Running: ${running.command || 'command'}`}>\n <span className={styles.prompt} aria-hidden=\"true\">$</span>\n <span className={extra.stickyCommand}>{running.command || 'command'}</span>\n <span className={extra.stickyMeta}>{elapsedLabel(clock - Date.parse(running.startedAt))}</span>\n <button type=\"button\" className={styles.iconBtn} aria-label=\"Jump to the running command\" title=\"Jump to where it started\"\n onClick={() => jumpTo(running.id)}>↑</button>\n </div>\n ) : null}\n\n <div className={styles.host} ref={hostRef} data-testid={`terminal-host-${tab.id}`} />\n {ready && !exited ? (\n <span className={styles.voiceSlot}>\n <Suspense fallback={null}>\n <VoiceInput surface=\"terminal\" mode=\"verbatim\" targetRef={leafRef} onInsert={insertDictated} />\n </Suspense>\n </span>\n ) : null}\n {!ready && !failed ? <div className={styles.viewLoading} aria-hidden=\"true\"><SkeletonLine width=\"30%\" /></div> : null}\n {failed ? (\n <div className={styles.viewLoading} role=\"alert\">\n <p>The terminal could not load. The rest of the chat still works.</p>\n <Button size=\"sm\" variant=\"subtle\" onClick={() => { setFailed(false); void attach(); }}>Try again</Button>\n </div>\n ) : null}\n </div>\n\n {deps.createInputEditor && prefs.inputEditor && !props.raw && tab.shellIntegration === 'active' ? (\n <CommandInput\n ref={inputRef}\n tabId={tab.id}\n sessionId={tab.sessionId}\n cwd={tab.cwd ?? tab.root}\n visible={showInput}\n focusWanted={shown && focused}\n api={deps.api}\n assistMode={props.assistMode}\n createEditor={deps.createInputEditor}\n platform={deps.platform}\n bracketedPaste={() => viewRef.current?.bracketedPaste() ?? false}\n send={sendText}\n onHandOff={() => {\n setHandedOff(true);\n viewRef.current?.focus();\n }}\n onHistorySearch={(draft) => propsRef.current.onHistorySearch?.(tab.id, draft)}\n onError={(text) => propsRef.current.onNotice({ tone: 'error', text })}\n onPanelKey={(event) => panelKeyRef.current(event, false)}\n />\n ) : null}\n {mode === 'terminal' && urlBlock ? (\n <div className={extra.bar} role=\"group\" aria-label=\"A local server is up\">\n <span className={extra.barLabel}>Serving</span>\n {(urlBlock.localUrls ?? []).map((url) => (\n <button key={url} type=\"button\" className={extra.chip} onClick={() => extrasProp!.onOpenUrl(url)} title={`Open ${url} in the Browser pane`}>\n <BrowserGlyph size={12} /><span className={extra.chipCode}>{urlLabel(url)}</span><span className={extra.chipVerb}>Open in Browser</span>\n </button>\n ))}\n <span className={extra.barSpacer} />\n <button type=\"button\" className={extra.chip} aria-label=\"Dismiss\" title=\"Dismiss\" onClick={() => dismiss(`url:${urlBlock.id}`)}>\n <IconX size={10} />\n </button>\n </div>\n ) : null}\n {mode === 'terminal' && fixBlock ? (\n <FixChips\n key={fixBlock.id}\n variant=\"bar\"\n load={fixLoad}\n askTargets={extrasProp!.askTargets}\n onPaste={(text) => props.onBlockAction(tab.id, 'paste-text', fixBlock, { text })}\n onAsk={(seatId) => props.onBlockAction(tab.id, 'ask-seat', fixBlock, { seatId })}\n onAskMore={(anchor) => props.onBlockAction(tab.id, 'ask', fixBlock, { anchor })}\n onDismiss={() => dismiss(`fix:${fixBlock.id}`)}\n\n />\n ) : null}\n\n {mode === 'blocks' && !replayed && blockViews.length === 0 ? (\n <div className={styles.loading} role=\"status\" aria-label=\"Loading commands\"><SkeletonLine width=\"60%\" /><SkeletonLine width=\"40%\" /></div>\n ) : mode === 'blocks' ? (\n <BlockList\n blocks={blockViews}\n loadOutput={loadOutput}\n onAction={onListAction}\n actions={extrasProp\n ? ['copy-output', 'send', 'ask', 'explain', 'rerun', 'bookmark', 'copy-link', 'jump', 'paste']\n : ['copy-output', 'send', 'explain', 'jump', 'paste']}\n {...(listExtras ? { extras: listExtras } : {})}\n highlightId={highlight}\n label={`Commands in ${tab.title}`}\n emptyTitle={tab.shellIntegration === 'off' ? 'No command blocks for this shell' : 'No commands yet'}\n emptyBody={tab.shellIntegration === 'off'\n ? 'Blocks need zsh, bash or fish. This shell still works as a plain terminal.'\n : 'Each command you run here appears as a block: its output, how long it took and how it ended.'}\n />\n ) : null}\n\n {exited ? (\n <div className={styles.exitBar} role=\"status\">\n <span>\n {exited.signal && exited.code === null\n ? `Shell ended (${exited.signal}).`\n : `Shell exited${exited.code === null ? '' : ` with code ${exited.code}`}.`}\n </span>\n <Button size=\"sm\" variant=\"subtle\" onClick={() => props.onRestart(tab)}>Restart</Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={() => props.onClose(tab)}>Close</Button>\n </div>\n ) : null}\n </div>\n );\n});\n","/**\n * terminal/TerminalPanel.tsx — the Verse terminal (3.15): a Warp-grade\n * terminal the operator and the agents share.\n *\n * WHAT IT IS\n * - Tabs, each one shell or a SPLIT of up to six (⌘D right, ⌥⌘D down; side\n * by side, stacked or tiled; ⌥⌘←→↑↓ between them, ⇧⌘Return zooms one), laid\n * out per chat and restored after a reload — the shells themselves live\n * on the server (core/verse/terminal.ts) and are reattached, scrollback\n * and command blocks included. Every visible shell streams over ONE\n * connection (panel-stream.ts, the multiplexer).\n * - An INPUT EDITOR at each prompt (CommandInput.tsx): multi-line, bash\n * highlighting, ghost text and ↑/↓ from the persistent history, path\n * completion, Ctrl+R history palette, `#`/⌘I plain words → a command (local\n * model, never run on its own). Raw per shell turns it off.\n * - Each shell: xterm.js on WebGL (DOM fallback), true colour, Unicode 11,\n * ligatures, ⌘F find, ⌘-click links (URLs, and `file:line` into the\n * editor), copy on select, 10k lines of scrollback.\n * - COMMAND BLOCKS (shell integration, OSC 133): every command is a block —\n * command, duration, exit code, output that folds. A dot beside each\n * command in the terminal, ⌘↑/⌘↓ between them, and a Blocks view (⇧⌘K)\n * with Copy output / Send to chat / Explain & fix.\n * - The AGENT tab: the commands this chat's agents ran, read-only, from the\n * transcript's own tool events. Nothing is re-run.\n * - Everything sent to a chat — a block, a selection — goes through the\n * server's secret scrub first (format=chat, /redact).\n *\n * 3.15 — THE TERMINAL FOR MANY AGENTS\n * - Ask any seat: a block's \"Ask…\" lists every seat (Claude Code, both\n * Codex accounts, Grok, Devin CLI / cloud, local models) and sends the\n * scrubbed block to that seat's chat — this chat when it is on that seat,\n * otherwise a new chat on the same folders (multimodel/ask-seat.ts).\n * \"Ask all ready seats\" opens Compare with every ready seat side by side.\n * - Error-fix chips: a failed command gets the LOCAL model's ≤ 3 candidate\n * commands ([Paste] types one; nothing runs), opt-out in More.\n * - Agent tabs (Claude Code, Codex, Devin, Grok launched here) show live\n * status — running / idle / needs you — from per-launch hooks or their\n * output (server: terminal-agent-hooks.ts); \"needs you\" also reaches the\n * Needs-you drawer and the desktop notifier.\n * - Blocks: multi-select, sticky running header, re-run, filter-in-block,\n * bookmarks, verse://terminal links, \"Open in Browser pane\" for a local URL.\n * - Launch configurations (.ashlr/verse/launch.json), typed only on Launch.\n *\n * CONTRACT. `TerminalPanelProps` below is the whole interface; it is a\n * superset of the dock's 3.10 `TerminalPaneProps`, so the adapter\n * (./TerminalPane.tsx) maps one onto the other and the pane registry (or the\n * dock's slot) mounts it lazily. This file is never imported statically from\n * the chat's first-paint path (terminal-lazy.test.ts).\n */\nimport { lazy, Suspense, useCallback, useEffect, useMemo, useRef, useState, type KeyboardEvent as ReactKeyboardEvent } from 'react';\nimport type {\n VerseSeat,\n VerseSession,\n VerseTerminalAgentState,\n VerseTerminalLaunchConfig,\n VerseTerminalStreamFrame,\n VerseTerminalListResponse,\n VerseTerminalTab,\n} from '../../../data/api-types.js';\nimport { ApiError } from '../../../data/client.js';\nimport { Button, IconButton } from '../../../components/primitives/Button.js';\nimport { Dialog } from '../../../components/primitives/Dialog.js';\nimport { EmptyState } from '../../../components/primitives/EmptyState.js';\nimport { SkeletonLine } from '../../../components/primitives/Skeleton.js';\nimport { IconExternalLink, IconPlus, IconSearch, IconSend, IconX } from '../../../components/primitives/icons.js';\nimport { asSentence } from '../autonomy/format.js';\nimport { ActionMenu, anchorBelow, type ActionMenuItem, type MenuAnchor } from '../chat/ActionMenu.js';\nimport { cleanTerminalOutput } from '../chat/ansi.js';\nimport { detectKeyPlatform } from '../shell/command-keys.js';\nimport { usePollWhileVisible, useSectionVisible } from '../shell/section-visibility.js';\nimport { useCommandHandler } from '../shell/command-bus.js';\nimport { useViewport } from '../shell/viewport.js';\nimport { projectName } from '../verse-model.js';\nimport type { VerseTerminalLaunchVia } from '../../../../core/verse/workbench-types.js';\nimport { TerminalLockedError } from '../dock/terminal/terminal-client.js';\nimport { openMuxedPanelStream, type TerminalStreamState } from './panel-stream.js';\nimport { ChevronDownGlyph, TerminalGlyph } from '../dock/terminal/terminal-icons.js';\nimport { AgentTerminal } from './AgentTerminal.js';\nimport type { BlockAction, BlockActionExtra } from './BlockList.js';\nimport { blockChatText, fenceFor, type BlockView, type ChatIntent } from './blocks-model.js';\nimport {\n blocksChatText,\n loadBookmarks,\n loadFixChipsEnabled,\n saveFixChipsEnabled,\n terminalBlockLink,\n toggleBookmark,\n} from './block-tools.js';\nimport { askableSeats, askSeat, firstSeatPerEngine } from '../multimodel/ask-seat.js';\nimport { DEFAULT_FLOW_API, type FlowTarget } from '../multimodel/multimodel-flows.js';\nimport { toAdvisorSeats } from '../multimodel/useAutoSeat.js';\nimport { requestPreview } from '../dock/dock-store.js';\nimport { getVerseSessionHead } from '../verse-store.js';\nimport extra from './TerminalExtras.module.css';\nimport {\n addGroup,\n AGENT_GROUP_ID,\n focusPane,\n gridShape,\n loadLayout,\n MAX_PANES_PER_GROUP,\n neighborPane,\n paneCells,\n reconcileLayout,\n removePane,\n saveLayout,\n setArrangement,\n setMode,\n splitGroup,\n toggleZoom,\n type GroupArrangement,\n type LeafMode,\n type PaneDirection,\n type SplitDirection,\n type TerminalGroup,\n type TerminalLayout,\n} from './layout-model.js';\nimport { resetCommandInputHistoryCache } from './CommandInput.js';\nimport { HistoryPalette, type TerminalPaletteMode } from './HistoryPalette.js';\nimport { createLazyInputEditor, preloadInputEditor } from './input-editor.js';\nimport type { VerseTerminalAssistMode, VerseTerminalSettings } from '../../../data/api-types.js';\nimport { panelTerminalApi, type PanelTerminalApi } from './panel-client.js';\nimport { agentToolsApi, type AgentToolsApi } from '../agent-tools/agent-tools-client.js';\nimport type { VerseAgentTabInfo } from '../../../../core/verse/verse-mcp-types.js';\nimport { panelKeyLabel, type PanelKeyAction } from './panel-keys.js';\nimport { TerminalLeaf, type LeafDeps, type LeafExtras, type LeafHandle, type LeafNotice, type LeafPrefs } from './TerminalLeaf.js';\nimport { createPanelXtermView, type PanelViewFactory } from './xterm-view.js';\nimport styles from './TerminalPanel.module.css';\n\nconst CompareDialog = lazy(async () => ({ default: (await import('../multimodel/CompareDialog.js')).CompareDialog }));\nconst LaunchDialog = lazy(async () => ({ default: (await import('./LaunchDialog.js')).LaunchDialog }));\nconst CommandWorkflowPicker = lazy(async () => ({ default: (await import('../playbooks/CommandWorkflowPicker.js')).CommandWorkflowPicker }));\n\n// ===========================================================================\n// Contract\n// ===========================================================================\n\n/** Open a terminal: focus/open a tab at `root`, optionally pasting (NEVER running) a command. Same shape as the dock's. */\nexport interface TerminalPanelRequest {\n /** Changes on every request, so the same request twice is two opens. */\n nonce: number;\n root?: string;\n /** Force a new tab (⌃⇧`). */\n newTab?: boolean;\n /** Pasted at the prompt — the operator presses Enter. */\n paste?: string;\n /** Apps [Launch ▸]: the catalog agent to start in a new tab (the server builds the command). */\n appId?: string;\n via?: VerseTerminalLaunchVia;\n model?: string;\n /** Preview's dev-server Start. */\n devServerId?: string;\n /** 3.15: show the Agent tab (e.g. from a transcript command's \"Show in terminal\"). */\n agent?: boolean;\n /** 3.15: ⌘K \"Generate command…\" — plain words → a command in the focused shell's editor. */\n assist?: boolean;\n /** 3.15: ⌘K \"Search terminal history…\". */\n history?: boolean;\n /** 3.15: focus this tab (a verse://terminal link, a notification, Needs you) and, with blockId, show that block. */\n tabId?: string;\n blockId?: string;\n /** 3.15: open the launch-configuration dialog. */\n launch?: boolean;\n\n}\n\nexport interface TerminalPanelProps {\n /** The chat this panel belongs to: its tabs, layout and Agent tab. */\n sessionId: string;\n /** The chat's folders, primary first. */\n roots: readonly string[];\n request: TerminalPanelRequest | null;\n /** Draft text into the chat's composer (the operator sends it). Text arrives scrubbed of secrets. */\n onSendToChat: (text: string) => void;\n /**\n * Send text to the chat's seat as a turn (\"Explain / fix this error\").\n * Optional: without it the text is drafted with onSendToChat instead.\n */\n onAskChat?: (text: string) => void;\n /** False while the panel is a background tab — stop timers, skip work. */\n visible: boolean;\n /** 3.15: the chat record (\"Ask…\" routes from it; default: the store's). */\n session?: VerseSession | null;\n /** 3.15: every seat, for \"Ask…\" (the dock's ChatPaneData). */\n seats?: readonly VerseSeat[];\n /** 3.15: switch to another chat (a seat's answer landed in a new chat). */\n onOpenSession?: (sessionId: string) => void;\n /** Test / host seams. */\n deps?: Partial<TerminalPanelDeps>;\n}\n\n/** The fix chips' \"Ask …\" row: one seat per family, the ones that fix code. */\nconst FIX_ASK_ENGINES = ['claude', 'codex', 'devin'] as const;\n\n/** A tab strip badge for an agent tab's live status. */\nfunction agentBadge(state: VerseTerminalAgentState | null | undefined): { state: string; label: string; title: string } | null {\n if (!state) return null;\n const who = state.agent === 'claude-code' ? 'Claude Code' : state.agent === 'codex' ? 'Codex' : state.agent === 'devin' ? 'Devin' : 'Grok';\n const how = state.channel === 'hooks' ? 'from its hooks' : 'read from its output';\n if (state.state === 'needs-you') return { state: 'needs-you', label: 'needs you', title: `${who} needs you${state.message ? `: ${state.message}` : ''} (${how})` };\n if (state.state === 'running') return { state: 'running', label: 'working', title: `${who} is working (${how})` };\n return { state: 'idle', label: 'idle', title: `${who} is idle (${how})` };\n}\n\n/** The most urgent status among a tab's panes. */\nfunction groupAgentState(states: ReadonlyArray<VerseTerminalAgentState | null | undefined>): VerseTerminalAgentState | null {\n const rank = { 'needs-you': 3, running: 2, idle: 1 } as const;\n let best: VerseTerminalAgentState | null = null;\n for (const s of states) if (s && (!best || rank[s.state] > rank[best.state])) best = s;\n return best;\n}\n\ntype AskSource = { tabId: string | null; blocks: BlockView[] };\n\nexport interface TerminalPanelDeps extends LeafDeps {\n api: PanelTerminalApi;\n /** 3.15 agent tools: which tabs an agent drives, sharing and takeover (optional; absent = no agent-tools UI). */\n agentTools?: AgentToolsApi;\n createView: PanelViewFactory;\n storage: Pick<Storage, 'getItem' | 'setItem' | 'removeItem'> | null;\n}\n\nfunction safeLocalStorage(): Storage | null {\n try {\n return typeof localStorage === 'undefined' ? null : localStorage;\n } catch {\n return null;\n }\n}\n\nconst DEFAULT_DEPS: TerminalPanelDeps = {\n api: panelTerminalApi,\n agentTools: agentToolsApi,\n createView: createPanelXtermView,\n // Every pane on one connection (panel-stream.ts): six panes, one of the browser's ~6 slots.\n openStream: openMuxedPanelStream,\n createInputEditor: createLazyInputEditor,\n preloadInputEditor,\n platform: detectKeyPlatform(),\n writeClipboard: async (text) => { await navigator.clipboard.writeText(text); },\n openUrl: (url) => {\n // Only web URLs leave the app; anything else (file:, javascript:) is ignored.\n if (/^https?:\\/\\//i.test(url)) window.open(url, '_blank', 'noopener,noreferrer');\n },\n storage: safeLocalStorage(),\n};\n\nexport const TERMINAL_PANEL_LIST_POLL_MS = 3_000;\nconst PREFS_KEY = 'ashlr.verse.terminal.prefs.v1';\n/** Per chat: the shells set to Raw input (their own line editor only). */\nconst RAW_KEY_PREFIX = 'ashlr.verse.terminal.raw.v1:';\n/** Shared with the 3.10 pane, so the choice carries over. */\nconst SCREEN_READER_KEY = 'ashlr.verse.terminal.screenReader';\n\nlet lastHandledNonce = 0;\nexport function resetTerminalPanelForTest(): void {\n lastHandledNonce = 0;\n}\n\nfunction readPrefs(storage: TerminalPanelDeps['storage']): LeafPrefs {\n const prefs: LeafPrefs = { screenReader: false, ligatures: true, gpu: true, inputEditor: true };\n try {\n const raw = storage?.getItem(PREFS_KEY);\n if (raw) {\n const parsed = JSON.parse(raw) as Partial<LeafPrefs>;\n if (typeof parsed.ligatures === 'boolean') prefs.ligatures = parsed.ligatures;\n if (typeof parsed.gpu === 'boolean') prefs.gpu = parsed.gpu;\n if (typeof parsed.inputEditor === 'boolean') prefs.inputEditor = parsed.inputEditor;\n }\n prefs.screenReader = storage?.getItem(SCREEN_READER_KEY) === '1';\n } catch {\n /* defaults */\n }\n return prefs;\n}\n\nfunction writePrefs(storage: TerminalPanelDeps['storage'], prefs: LeafPrefs): void {\n try {\n storage?.setItem(PREFS_KEY, JSON.stringify({ ligatures: prefs.ligatures, gpu: prefs.gpu, inputEditor: prefs.inputEditor }));\n storage?.setItem(SCREEN_READER_KEY, prefs.screenReader ? '1' : '0');\n } catch {\n /* this page only */\n }\n}\n\nfunction readRaw(storage: TerminalPanelDeps['storage'], sessionId: string): ReadonlySet<string> {\n try {\n const parsed = JSON.parse(storage?.getItem(`${RAW_KEY_PREFIX}${sessionId}`) ?? '[]') as unknown;\n return new Set(Array.isArray(parsed) ? parsed.filter((v): v is string => typeof v === 'string').slice(0, 64) : []);\n } catch {\n return new Set();\n }\n}\n\nfunction writeRaw(storage: TerminalPanelDeps['storage'], sessionId: string, raw: ReadonlySet<string>): void {\n try {\n if (raw.size === 0) storage?.removeItem(`${RAW_KEY_PREFIX}${sessionId}`);\n else storage?.setItem(`${RAW_KEY_PREFIX}${sessionId}`, JSON.stringify([...raw]));\n } catch {\n /* this page only */\n }\n}\n\nconst ASSIST_MODE_LABELS: Readonly<Record<VerseTerminalAssistMode, string>> = {\n auto: 'Local model, then cloud Grok (shares terminal context)',\n local: 'Local model only',\n off: 'Off',\n};\n\nfunction errorText(err: unknown, fallback: string): string {\n if (err instanceof TerminalLockedError) return err.message;\n if (err instanceof ApiError) {\n if (err.status === 401) return 'Unlock actions with the mutation token to use the terminal.';\n if (err.detail) return asSentence(err.detail);\n }\n return fallback;\n}\n\ntype OpenOptions = { root?: string; cwd?: string; appId?: string; via?: VerseTerminalLaunchVia; model?: string; devServerId?: string; size?: { cols: number; rows: number } };\n\n// ===========================================================================\n// Component\n// ===========================================================================\n\nexport function TerminalPanel({ sessionId, roots, request, onSendToChat, onAskChat, visible, session: sessionProp, seats = [], onOpenSession, deps: override }: TerminalPanelProps) {\n const deps = useMemo<TerminalPanelDeps>(() => ({ ...DEFAULT_DEPS, ...override }), [override]);\n const sectionVisible = useSectionVisible();\n const shown = visible && sectionVisible;\n const compact = useViewport().compact;\n\n const [list, setList] = useState<VerseTerminalListResponse | null>(null);\n const [loadError, setLoadError] = useState<string | null>(null);\n const [layout, setLayout] = useState<TerminalLayout>(() => loadLayout(sessionId, deps.storage));\n const [notice, setNotice] = useState<LeafNotice | null>(null);\n // 3.15 agent tools: tabs an agent drives (its own, or a shell you shared), and takeovers.\n const [agentTabs, setAgentTabs] = useState<ReadonlyMap<string, VerseAgentTabInfo>>(new Map());\n const [creating, setCreating] = useState(false);\n const [streamStates, setStreamStates] = useState<ReadonlyMap<string, TerminalStreamState>>(() => new Map());\n const [selection, setSelection] = useState<{ tabId: string; text: string } | null>(null);\n const [copied, setCopied] = useState<string | null>(null);\n const [prefs, setPrefs] = useState<LeafPrefs>(() => readPrefs(deps.storage));\n const [menu, setMenu] = useState<{ kind: 'root' | 'more' | 'block'; anchor: MenuAnchor; from: HTMLElement | null; items: ActionMenuItem[]; label: string } | null>(null);\n const [seen, setSeen] = useState<ReadonlyMap<string, string>>(() => new Map());\n const [agentHighlight, setAgentHighlight] = useState<string | null>(null);\n const [pasteTick, setPasteTick] = useState(0);\n const [rawTabs, setRawTabs] = useState<ReadonlySet<string>>(() => readRaw(deps.storage, sessionId));\n const [palette, setPalette] = useState<{ mode: TerminalPaletteMode; tabId: string | null; draft: string } | null>(null);\n const [settings, setSettings] = useState<VerseTerminalSettings | null>(null);\n const [confirmClear, setConfirmClear] = useState(false);\n // 3.15 many agents\n const [bookmarks, setBookmarks] = useState<Record<string, string[]>>(() => loadBookmarks(deps.storage));\n const [fixChips, setFixChips] = useState(() => loadFixChipsEnabled(deps.storage));\n const [compare, setCompare] = useState<{ prompt: string } | null>(null);\n const [launchOpen, setLaunchOpen] = useState(false);\n const [workflowsOpen, setWorkflowsOpen] = useState(false);\n const [asked, setAsked] = useState<{ text: string; sessionId: string | null } | null>(null);\n\n\n const leaves = useRef(new Map<string, LeafHandle>());\n const leafRefs = useRef(new Map<string, (handle: LeafHandle | null) => void>());\n const mounted = useRef(true);\n const autoCreated = useRef(false);\n const pendingPaste = useRef<{ tabId: string; text: string } | null>(null);\n const tabRefs = useRef(new Map<string, HTMLButtonElement>());\n const copiedTimer = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n mounted.current = true;\n return () => {\n mounted.current = false;\n if (copiedTimer.current) clearTimeout(copiedTimer.current);\n };\n }, []);\n\n // Another chat (the dock keeps the panel mounted across chats): its own layout.\n const layoutFor = useRef(sessionId);\n if (layoutFor.current !== sessionId) {\n layoutFor.current = sessionId;\n autoCreated.current = false;\n }\n useEffect(() => {\n setLayout(loadLayout(sessionId, deps.storage));\n setRawTabs(readRaw(deps.storage, sessionId));\n }, [sessionId, deps.storage]);\n\n const allTabs = useMemo(() => list?.tabs ?? [], [list]);\n const tabs = useMemo(() => allTabs.filter((t) => t.sessionId === sessionId), [allTabs, sessionId]);\n const tabById = useMemo(() => new Map(tabs.map((t) => [t.id, t])), [tabs]);\n const tabIdsKey = tabs.map((t) => t.id).join(',');\n\n // Fit the layout to the shells that exist (and persist it).\n useEffect(() => {\n if (!list) return;\n setLayout((prev) => reconcileLayout(prev, tabIdsKey ? tabIdsKey.split(',') : []));\n }, [list, tabIdsKey]);\n useEffect(() => {\n if (list) saveLayout(sessionId, layout, deps.storage);\n }, [layout, list, sessionId, deps.storage]);\n useEffect(() => {\n if (!list) return;\n const live = new Set(tabIdsKey ? tabIdsKey.split(',') : []);\n setRawTabs((prev) => {\n const next = new Set([...prev].filter((id) => live.has(id)));\n if (next.size === prev.size) return prev;\n writeRaw(deps.storage, sessionId, next);\n return next;\n });\n }, [list, tabIdsKey, sessionId, deps.storage]);\n\n const activeGroup: TerminalGroup | null = layout.active === AGENT_GROUP_ID ? null : layout.groups.find((g) => g.id === layout.active) ?? null;\n const agentActive = layout.active === AGENT_GROUP_ID || (list !== null && !list.available && layout.groups.length === 0);\n const focusedTab = activeGroup ? tabById.get(activeGroup.focused) ?? null : null;\n const focusedMode: LeafMode = focusedTab ? layout.modes[focusedTab.id] ?? 'terminal' : 'terminal';\n\n // -------------------------------------------------------------------------\n // The tab list\n // -------------------------------------------------------------------------\n\n const refresh = useCallback(async () => {\n try {\n const next = await deps.api.list();\n if (!mounted.current) return;\n setList(next);\n setLoadError(null);\n } catch (err) {\n if (mounted.current) setLoadError(errorText(err, 'The terminal list could not be loaded.'));\n }\n if (deps.agentTools) {\n try {\n const { tabs: infos } = await deps.agentTools.tabs();\n if (mounted.current) setAgentTabs(new Map(infos.map((info) => [info.tabId, info])));\n } catch { /* optional: no agent-tools marks this round */ }\n }\n }, [deps.api, deps.agentTools]);\n\n useEffect(() => { void refresh(); }, [refresh]);\n usePollWhileVisible(() => { void refresh(); }, TERMINAL_PANEL_LIST_POLL_MS, { enabled: visible });\n\n // Output seen as it arrives in the visible panes.\n useEffect(() => {\n if (!shown || !activeGroup) return;\n setSeen((prev) => {\n let next: Map<string, string> | null = null;\n for (const id of activeGroup.panes) {\n const t = tabById.get(id);\n if (!t || prev.get(id) === t.lastActivityAt) continue;\n next ??= new Map(prev);\n next.set(id, t.lastActivityAt);\n }\n return next ?? prev;\n });\n }, [shown, activeGroup, tabById]);\n\n const patchTab = useCallback((tabId: string, patch: (t: VerseTerminalTab) => VerseTerminalTab) => {\n setList((prev) => (prev ? { ...prev, tabs: prev.tabs.map((t) => (t.id === tabId ? patch(t) : t)) } : prev));\n }, []);\n\n // -------------------------------------------------------------------------\n // Creating / closing shells\n // -------------------------------------------------------------------------\n\n const sizeHint = useCallback(() => {\n for (const leaf of leaves.current.values()) {\n const size = leaf.size();\n if (size) return size;\n }\n return { cols: 80, rows: 24 };\n }, []);\n\n const createShell = useCallback(async (opts: OpenOptions): Promise<VerseTerminalTab | null> => {\n setCreating(true);\n setNotice(null);\n try {\n const tab = await deps.api.create({\n sessionId,\n ...(opts.root ? { root: opts.root } : {}),\n ...(opts.cwd ? { cwd: opts.cwd } : {}),\n ...(opts.appId ? { appId: opts.appId } : {}),\n ...(opts.appId && opts.via ? { via: opts.via } : {}),\n ...(opts.appId && opts.model ? { model: opts.model } : {}),\n ...(opts.devServerId ? { devServerId: opts.devServerId } : {}),\n ...(opts.size ?? sizeHint()),\n });\n if (mounted.current) setList((prev) => (prev ? { ...prev, tabs: [...prev.tabs.filter((t) => t.id !== tab.id), tab] } : prev));\n return tab;\n } catch (err) {\n if (mounted.current) setNotice({ tone: 'error', text: errorText(err, 'The terminal could not be opened.') });\n return null;\n } finally {\n if (mounted.current) setCreating(false);\n }\n }, [deps.api, sessionId, sizeHint]);\n\n const openInNewGroup = useCallback(async (opts: OpenOptions) => {\n const tab = await createShell(opts);\n if (tab && mounted.current) setLayout((prev) => addGroup(prev, tab.id));\n return tab;\n }, [createShell]);\n\n /** Where a new shell should start: beside the focused one (its root, and its cwd when the shell reported one). */\n const hereOptions = useCallback((): OpenOptions => {\n if (!focusedTab) return {};\n return { root: focusedTab.root, ...(focusedTab.cwd ? { cwd: focusedTab.cwd } : {}) };\n }, [focusedTab]);\n\n const split = useCallback(async (direction: SplitDirection) => {\n if (!activeGroup) return;\n if (activeGroup.panes.length >= MAX_PANES_PER_GROUP) {\n setNotice({ tone: 'info', text: `A tab holds ${MAX_PANES_PER_GROUP} terminals at most. Open a new tab instead.` });\n return;\n }\n const groupId = activeGroup.id;\n // Start the shell at about the size it will have, so its first prompt is\n // not drawn for a wider screen than the one it lands in (the first fit corrects it).\n const here = focusedTab ? leaves.current.get(focusedTab.id)?.size() ?? null : null;\n const size = here\n ? direction === 'row' ? { cols: Math.max(20, Math.floor((here.cols - 1) / 2)), rows: here.rows } : { cols: here.cols, rows: Math.max(5, Math.floor((here.rows - 1) / 2)) }\n : undefined;\n let tab = await createShell({ ...hereOptions(), ...(size ? { size } : {}) });\n // A cwd the server refuses (outside the root): start at the root.\n if (!tab && focusedTab?.cwd) tab = await createShell({ root: focusedTab.root, ...(size ? { size } : {}) });\n if (!tab || !mounted.current) return;\n const created = tab;\n setLayout((prev) => splitGroup(prev, groupId, created.id, direction) ?? addGroup(prev, created.id));\n }, [activeGroup, createShell, hereOptions, focusedTab]);\n\n const closeShell = useCallback(async (tab: VerseTerminalTab) => {\n try {\n await deps.api.kill(tab.id);\n } catch (err) {\n if (!(err instanceof ApiError && err.status === 404)) {\n setNotice({ tone: 'error', text: errorText(err, 'The terminal could not be closed.') });\n return;\n }\n }\n setList((prev) => (prev ? { ...prev, tabs: prev.tabs.filter((t) => t.id !== tab.id) } : prev));\n setLayout((prev) => removePane(prev, tab.id));\n }, [deps.api]);\n\n const closeGroup = useCallback(async (group: TerminalGroup) => {\n for (const id of [...group.panes]) {\n const tab = tabById.get(id);\n if (tab) await closeShell(tab);\n }\n }, [closeShell, tabById]);\n\n const restartShell = useCallback(async (tab: VerseTerminalTab) => {\n const next = await createShell({ root: tab.root });\n if (!next) return;\n setLayout((prev) => {\n const group = prev.groups.find((g) => g.panes.includes(tab.id));\n if (!group) return addGroup(prev, next.id);\n return { ...prev, groups: prev.groups.map((g) => (g.id === group.id ? { ...g, panes: g.panes.map((p) => (p === tab.id ? next.id : p)), focused: g.focused === tab.id ? next.id : g.focused } : g)) };\n });\n try { await deps.api.kill(tab.id); } catch { /* already gone */ }\n setList((prev) => (prev ? { ...prev, tabs: prev.tabs.filter((t) => t.id !== tab.id) } : prev));\n }, [createShell, deps.api]);\n\n // First look at an empty chat: open a shell in its primary folder.\n useEffect(() => {\n if (!list || !list.available || !shown || autoCreated.current || creating) return;\n if (request && request.nonce > lastHandledNonce) return;\n autoCreated.current = true;\n if (tabs.length === 0 && layout.active !== AGENT_GROUP_ID) void openInNewGroup({});\n }, [list, shown, tabs.length, creating, request, layout.active, openInNewGroup]);\n\n // -------------------------------------------------------------------------\n // Requests (from the dock / registry)\n // -------------------------------------------------------------------------\n\n const layoutRef = useRef(layout);\n layoutRef.current = layout;\n\n /** ⌥⌘←→↑↓: the neighbouring pane in its group gets the keyboard. */\n const focusToward = useCallback((tabId: string, direction: PaneDirection) => {\n const group = layoutRef.current.groups.find((g) => g.panes.includes(tabId));\n if (!group || group.zoomed) return;\n const target = neighborPane(group, tabId, direction);\n if (!target) return;\n setLayout((prev) => focusPane(prev, group.id, target));\n leaves.current.get(target)?.focus();\n }, []);\n\n /** ⌘I / \"Generate command…\": in the shell's input editor when it shows, else the palette (its result is pasted, never run). */\n const openAssist = useCallback((tabId: string | null) => {\n const leaf = tabId ? leaves.current.get(tabId) : undefined;\n if (leaf?.openAssist()) return;\n setPalette({ mode: 'assist', tabId, draft: '' });\n }, []);\n\n const openHistory = useCallback((tabId: string | null, draft: string) => {\n setPalette({ mode: 'history', tabId, draft });\n }, []);\n\n const onHistorySearch = useCallback((tabId: string, draft: string) => openHistory(tabId, draft), [openHistory]);\n\n const setRaw = useCallback((tabId: string, on: boolean) => {\n setRawTabs((prev) => {\n if (prev.has(tabId) === on) return prev;\n const next = new Set(prev);\n if (on) next.add(tabId);\n else next.delete(tabId);\n writeRaw(deps.storage, sessionId, next);\n return next;\n });\n setTimeout(() => leaves.current.get(tabId)?.focus(), 0);\n }, [deps.storage, sessionId]);\n\n const loadSettings = useCallback(async () => {\n if (!deps.api.settings) return;\n try {\n const next = await deps.api.settings();\n if (mounted.current) setSettings(next);\n } catch {\n /* the menu shows what it can */\n }\n }, [deps.api]);\n\n const updateSettings = useCallback(async (patch: Partial<VerseTerminalSettings>) => {\n if (!deps.api.updateSettings) return;\n try {\n const next = await deps.api.updateSettings(patch);\n if (!mounted.current) return;\n setSettings(next);\n if (patch.history !== undefined) {\n resetCommandInputHistoryCache();\n setNotice({ tone: 'info', text: next.history ? 'Command history is on: commands you finish are remembered (secrets removed).' : 'Command history is off: nothing new is recorded.' });\n }\n } catch (err) {\n setNotice({ tone: 'error', text: errorText(err, 'That setting could not be changed.') });\n }\n }, [deps.api]);\n\n const clearHistory = useCallback(async () => {\n setConfirmClear(false);\n if (!deps.api.clearHistory) return;\n try {\n await deps.api.clearHistory();\n resetCommandInputHistoryCache();\n setNotice({ tone: 'info', text: 'Command history cleared.' });\n } catch (err) {\n setNotice({ tone: 'error', text: errorText(err, 'The history could not be cleared.') });\n }\n }, [deps.api]);\n\n const pasteInto = useCallback((tabId: string, text: string) => {\n pendingPaste.current = { tabId, text };\n setPasteTick((n) => n + 1);\n }, []);\n\n const handleRequest = useCallback(async (req: TerminalPanelRequest) => {\n if (req.agent) {\n setLayout((prev) => ({ ...prev, active: AGENT_GROUP_ID }));\n return;\n }\n if (req.assist || req.history) {\n const target = focusedTab && !focusedTab.exited ? focusedTab : tabs.find((t) => !t.exited) ?? null;\n if (req.assist) openAssist(target?.id ?? null);\n else openHistory(target?.id ?? null, '');\n return;\n }\n if (req.launch) {\n setLaunchOpen(true);\n return;\n }\n if (req.tabId) {\n // A verse://terminal link, a notification, a Needs-you row: that tab (and block), if it is still open.\n const tabId = req.tabId;\n const group = layout.groups.find((g) => g.panes.includes(tabId));\n if (!group || !tabById.has(tabId)) {\n setNotice({ tone: 'info', text: 'That terminal is no longer open.' });\n return;\n }\n setLayout((prev) => focusPane(prev, group.id, tabId));\n const blockId = req.blockId;\n if (blockId) {\n setLayout((prev) => setMode(prev, tabId, 'blocks'));\n setTimeout(() => leaves.current.get(tabId)?.jumpTo(blockId), 0);\n } else {\n setTimeout(() => leaves.current.get(tabId)?.focus(), 0);\n }\n\n return;\n }\n const wantsNew = req.newTab === true || Boolean(req.appId) || Boolean(req.devServerId);\n let target: VerseTerminalTab | null = null;\n if (!wantsNew) {\n const live = tabs.filter((t) => !t.exited && (!req.root || t.root === req.root));\n target = (focusedTab && live.includes(focusedTab) ? focusedTab : null) ?? live.at(-1) ?? null;\n }\n if (target) {\n const group = layout.groups.find((g) => g.panes.includes(target!.id));\n if (group) setLayout((prev) => ({ ...focusPane(prev, group.id, target!.id), modes: { ...prev.modes, [target!.id]: 'terminal' } }));\n } else {\n target = await openInNewGroup({\n ...(req.root ?? focusedTab?.root ?? roots[0] ? { root: req.root ?? focusedTab?.root ?? roots[0] } : {}),\n ...(req.appId ? { appId: req.appId } : {}),\n ...(req.via ? { via: req.via } : {}),\n ...(req.model ? { model: req.model } : {}),\n ...(req.devServerId ? { devServerId: req.devServerId } : {}),\n });\n }\n if (!target) return;\n if (req.paste) pasteInto(target.id, req.paste);\n else leaves.current.get(target.id)?.focus();\n }, [focusedTab, layout.groups, openAssist, openHistory, openInNewGroup, pasteInto, roots, tabs, tabById]);\n\n\n useEffect(() => {\n if (!request || !list || request.nonce <= lastHandledNonce) return;\n lastHandledNonce = request.nonce;\n autoCreated.current = true;\n if (!list.available && !request.agent) return;\n void handleRequest(request);\n }, [request, list, handleRequest]);\n\n // -------------------------------------------------------------------------\n // Chat hand-off (always scrubbed by the server first)\n // -------------------------------------------------------------------------\n\n const currentSession = useCallback((): VerseSession | null => sessionProp ?? getVerseSessionHead(sessionId).session ?? null, [sessionProp, sessionId]);\n const askTargetsAll = useMemo(() => askableSeats(seats), [seats]);\n\n /** Send `text` to a seat's chat: this chat on that seat, else a new chat on the same folders. */\n const sendToSeat = useCallback(async (target: FlowTarget, text: string, title: string) => {\n const source = currentSession();\n if (!source) {\n onSendToChat(text);\n setNotice({ tone: 'info', text: 'Added to the chat’s message box.' });\n return;\n }\n setAsked({ text: `Asking ${target.label}…`, sessionId: null });\n try {\n const res = await askSeat(DEFAULT_FLOW_API, { source, target, text, title, relation: 'compare' });\n if (!mounted.current) return;\n setAsked({ text: res.created ? `Sent to ${res.label} in a new chat.` : `Sent to ${res.label} in this chat.`, sessionId: res.created ? res.sessionId : null });\n } catch (err) {\n if (!mounted.current) return;\n setAsked(null);\n setNotice({ tone: 'error', text: errorText(err, `${target.label} could not be asked.`) });\n }\n }, [currentSession, onSendToChat]);\n\n const deliver = useCallback((text: string, intent: ChatIntent) => {\n if (intent === 'explain' && onAskChat) {\n onAskChat(text);\n setNotice({ tone: 'info', text: 'Sent to the chat.' });\n return;\n }\n const source = intent === 'explain' ? currentSession() : null;\n if (source) {\n const own = askTargetsAll.find((t) => t.seatId === source.seatId)\n ?? { seatId: source.seatId, model: source.model, label: 'this chat’s seat', engine: source.engine };\n void sendToSeat(own, text, source.title);\n return;\n }\n onSendToChat(text);\n setNotice({ tone: 'info', text: 'Added to the chat’s message box.' });\n }, [askTargetsAll, currentSession, onAskChat, onSendToChat, sendToSeat]);\n\n const flashCopied = useCallback((what: string) => {\n setCopied(what);\n if (copiedTimer.current) clearTimeout(copiedTimer.current);\n copiedTimer.current = setTimeout(() => { if (mounted.current) setCopied(null); }, 1_400);\n }, []);\n\n const terminalBlockText = useCallback(async (tabId: string, block: BlockView, format: 'text' | 'chat') => {\n const res = await deps.api.blockOutput(tabId, block.id, format);\n return { command: res.command, output: res.output };\n }, [deps.api]);\n\n /** Blocks → their scrubbed chat text (agent blocks were scrubbed on the way to the page). */\n const chatTextFor = useCallback(async (source: AskSource, intent: ChatIntent): Promise<string> => {\n const items = await Promise.all(source.blocks.map(async (block) => {\n if (block.source === 'agent' || source.tabId === null) return { block, command: block.command, output: cleanTerminalOutput(block.output ?? '') };\n const { command, output } = await terminalBlockText(source.tabId, block, 'chat');\n return { block, command, output };\n }));\n return blocksChatText(items, intent);\n }, [terminalBlockText]);\n\n const askAbout = useCallback(async (source: AskSource, target: FlowTarget) => {\n try {\n const text = await chatTextFor(source, 'explain');\n const first = source.blocks[0];\n await sendToSeat(target, text, `Terminal · ${(first?.command || 'command').slice(0, 60)}`);\n } catch (err) {\n setNotice({ tone: 'error', text: errorText(err, 'That did not work.') });\n }\n }, [chatTextFor, sendToSeat]);\n\n const askAll = useCallback(async (source: AskSource) => {\n try {\n setCompare({ prompt: await chatTextFor(source, 'explain') });\n } catch (err) {\n setNotice({ tone: 'error', text: errorText(err, 'That did not work.') });\n }\n }, [chatTextFor]);\n\n /** \"Ask…\": every seat, then \"all ready seats side by side\". */\n const openAskMenu = useCallback((anchorEl: HTMLElement, source: AskSource) => {\n const hasSession = currentSession() !== null;\n const ready = askTargetsAll.filter((t) => t.ready);\n const items: ActionMenuItem[] = askTargetsAll.map((t) => ({\n id: `ask:${t.seatId}`,\n label: `Ask ${t.label}`,\n description: t.ready ? (currentSession()?.seatId === t.seatId ? 'In this chat.' : 'In a new chat on the same folders.') : 'May be busy or signed out.',\n onSelect: () => void askAbout(source, t),\n disabled: !hasSession,\n reason: hasSession ? null : 'Open a chat first.',\n }));\n items.push({\n id: 'ask-all',\n label: `Ask all ready seats (${ready.length})`,\n description: 'Their proposed fixes side by side (Compare). Nothing is sent until you confirm.',\n onSelect: () => void askAll(source),\n disabled: !hasSession || ready.length < 2,\n reason: ready.length < 2 ? 'Needs at least two ready seats.' : !hasSession ? 'Open a chat first.' : null,\n separated: true,\n });\n if (askTargetsAll.length === 0) {\n items.unshift({ id: 'none', label: 'No seats are connected', onSelect: () => undefined, disabled: true, reason: 'Connect an account in Apps & Accounts.' });\n }\n setMenu({ kind: 'block', anchor: anchorBelow(anchorEl, 'end'), from: anchorEl, items, label: source.blocks.length > 1 ? `Ask about ${source.blocks.length} commands` : 'Ask a seat' });\n }, [askAbout, askAll, askTargetsAll, currentSession]);\n\n const runBlockAction = useCallback(async (tabId: string | null, action: BlockAction, block: BlockView, more?: BlockActionExtra) => {\n try {\n switch (action) {\n case 'ask':\n if (more?.anchor) openAskMenu(more.anchor, { tabId, blocks: [block] });\n return;\n case 'ask-seat': {\n const target = askTargetsAll.find((t) => t.seatId === more?.seatId);\n if (target) await askAbout({ tabId, blocks: [block] }, target);\n return;\n }\n case 'rerun': {\n const tab = tabId ? tabById.get(tabId) : null;\n if (!tab || tab.exited || !block.command) return;\n // An explicit click on Re-run: the command line, then Enter — exactly as if retyped.\n const bytes = new TextEncoder().encode(`${block.command.replace(/[\\r\\n]+/g, ' ')}\\r`);\n let bin = '';\n for (const b of bytes) bin += String.fromCharCode(b);\n await deps.api.input(tab.id, btoa(bin));\n setLayout((prev) => setMode(prev, tab.id, 'terminal'));\n return;\n }\n case 'bookmark':\n if (tabId) setBookmarks(toggleBookmark(deps.storage, tabId, block.id));\n return;\n case 'copy-link': {\n const link = tabId ? terminalBlockLink(tabId, block.id) : null;\n if (!link) return;\n await deps.writeClipboard(link);\n flashCopied('Link copied');\n return;\n }\n case 'open-url':\n if (more?.url && /^https?:\\/\\/(localhost|127\\.0\\.0\\.1|\\[::1\\])(:\\d+)?(\\/|$)/i.test(more.url)) requestPreview({ url: more.url });\n return;\n case 'paste-text':\n if (tabId && more?.text) {\n const group = layout.groups.find((g) => g.panes.includes(tabId));\n if (group) setLayout((prev) => setMode(focusPane(prev, group.id, tabId), tabId, 'terminal'));\n pasteInto(tabId, more.text);\n }\n return;\n case 'copy-command':\n await deps.writeClipboard(block.command);\n flashCopied('Command copied');\n return;\n case 'copy-output': {\n const text = block.source === 'agent' || tabId === null\n ? cleanTerminalOutput(block.output ?? '')\n : (await terminalBlockText(tabId, block, 'text')).output;\n await deps.writeClipboard(text);\n flashCopied('Output copied');\n return;\n }\n case 'send':\n case 'explain': {\n const intent: ChatIntent = action;\n if (block.source === 'agent' || tabId === null) {\n // The transcript reached the page through the server's public-JSON scrub already.\n deliver(blockChatText(block, block.command, cleanTerminalOutput(block.output ?? ''), intent), intent);\n } else {\n const { command, output } = await terminalBlockText(tabId, block, 'chat');\n deliver(blockChatText(block, command, output, intent), intent);\n }\n return;\n }\n case 'jump':\n if (!tabId) return;\n setLayout((prev) => setMode(prev, tabId, 'terminal'));\n setTimeout(() => leaves.current.get(tabId)?.jumpTo(block.id), 0);\n return;\n case 'paste': {\n const target = focusedTab && !focusedTab.exited ? focusedTab : tabs.find((t) => !t.exited) ?? null;\n if (target) {\n const group = layout.groups.find((g) => g.panes.includes(target.id));\n if (group) setLayout((prev) => setMode(focusPane(prev, group.id, target.id), target.id, 'terminal'));\n pasteInto(target.id, block.command);\n } else {\n const tab = await openInNewGroup({});\n if (tab) pasteInto(tab.id, block.command);\n }\n return;\n }\n }\n } catch (err) {\n setNotice({ tone: 'error', text: errorText(err, 'That did not work.') });\n }\n }, [askAbout, askTargetsAll, deliver, deps, flashCopied, focusedTab, layout.groups, openAskMenu, openInNewGroup, pasteInto, tabById, tabs, terminalBlockText]);\n\n const onSelectionAction = useCallback(async (tabId: string, action: 'copy-output' | 'send' | 'ask', blocks: BlockView[], anchor?: HTMLElement) => {\n const source: AskSource = { tabId, blocks };\n try {\n if (action === 'ask') {\n if (anchor) openAskMenu(anchor, source);\n return;\n }\n if (action === 'send') {\n onSendToChat(await chatTextFor(source, 'send'));\n setNotice({ tone: 'info', text: `${blocks.length} commands added to the chat’s message box.` });\n return;\n }\n const texts = await Promise.all(blocks.map(async (b) => `$ ${b.command}\\n${(await terminalBlockText(tabId, b, 'text')).output}`));\n await deps.writeClipboard(texts.join('\\n\\n'));\n flashCopied(`${blocks.length} outputs copied`);\n } catch (err) {\n setNotice({ tone: 'error', text: errorText(err, 'That did not work.') });\n }\n }, [chatTextFor, deps, flashCopied, onSendToChat, openAskMenu, terminalBlockText]);\n\n const fixTargets = useMemo(() => firstSeatPerEngine(seats, FIX_ASK_ENGINES).map((t) => ({ seatId: t.seatId, label: t.label })), [seats]);\n const bookmarkSets = useMemo(() => new Map(Object.entries(bookmarks).map(([tab, ids]) => [tab, new Set(ids)] as const)), [bookmarks]);\n const emptyBookmarks = useMemo(() => new Set<string>(), []);\n const fixApi = deps.api.fix;\n const loadFix = useMemo(() => (fixChips && fixApi ? (tabId: string, block: BlockView) => fixApi(tabId, block.id) : null), [fixChips, fixApi]);\n const leafExtrasFor = useCallback((tabId: string): LeafExtras => ({\n bookmarks: bookmarkSets.get(tabId) ?? emptyBookmarks,\n loadFix,\n askTargets: fixTargets,\n onOpenUrl: (url) => requestPreview({ url }),\n onSelectionAction: (id, action, blocks, anchor) => void onSelectionAction(id, action, blocks, anchor),\n }), [bookmarkSets, emptyBookmarks, fixTargets, loadFix, onSelectionAction]);\n const leafExtras = useMemo(() => new Map(tabs.map((t) => [t.id, leafExtrasFor(t.id)] as const)), [tabs, leafExtrasFor]);\n\n // -------------------------------------------------------------------------\n // Launch configurations, command workflows (palette + More menu)\n // -------------------------------------------------------------------------\n\n // The palette's entries: served here while the panel is shown (the shell's fallbacks otherwise).\n useCommandHandler('terminal.launch', () => { setLaunchOpen(true); return true; }, shown && Boolean(list?.available));\n useCommandHandler('terminal.workflows', () => { setWorkflowsOpen(true); return true; }, shown);\n\n /** A filled workflow: pasted at the focused (or any live) shell's prompt — never run. */\n const pasteWorkflow = useCallback(async (text: string) => {\n const target = focusedTab && !focusedTab.exited ? focusedTab : tabs.find((t) => !t.exited) ?? null;\n if (target) {\n const group = layout.groups.find((g) => g.panes.includes(target.id));\n if (group) setLayout((prev) => setMode(focusPane(prev, group.id, target.id), target.id, 'terminal'));\n pasteInto(target.id, text);\n return;\n }\n const tab = await openInNewGroup({});\n if (tab) pasteInto(tab.id, text);\n }, [focusedTab, layout.groups, openInNewGroup, pasteInto, tabs]);\n\n const loadLaunchConfigs = useCallback(async () => {\n if (!deps.api.launchList) throw new Error('Launch configurations need a newer server.');\n return deps.api.launchList(sessionId);\n }, [deps.api, sessionId]);\n\n const launchConfig = useCallback(async (config: VerseTerminalLaunchConfig) => {\n if (!deps.api.launch) throw new Error('Launch configurations need a newer server.');\n let res;\n try {\n res = await deps.api.launch({ sessionId, root: config.root, name: config.name, digest: config.digest, ...sizeHint() });\n } catch (err) {\n throw new Error(errorText(err, 'That configuration could not be launched.'));\n }\n if (!mounted.current) return;\n const opened = res.groups.flatMap((g) => g.tabs);\n setList((prev) => (prev ? { ...prev, tabs: [...prev.tabs.filter((t) => !opened.some((o) => o.id === t.id)), ...opened] } : prev));\n setLayout((prev) => {\n let next = prev;\n for (const group of res.groups) {\n const [first, second] = group.tabs;\n if (!first) continue;\n next = addGroup(next, first.id);\n const added = next.groups.find((g) => g.panes.includes(first.id));\n if (second && added) next = splitGroup(next, added.id, second.id, group.split === 'down' ? 'column' : 'row') ?? addGroup(next, second.id);\n }\n return next;\n });\n if (res.errors.length > 0) setNotice({ tone: 'error', text: `Launched with problems: ${res.errors.join('; ')}` });\n else setNotice({ tone: 'info', text: `Launched “${config.name}”.` });\n }, [deps.api, sessionId, sizeHint]);\n\n const sendSelection = useCallback(async () => {\n const tabId = selection?.tabId ?? focusedTab?.id;\n if (!tabId) return;\n const text = (leaves.current.get(tabId)?.getSelection() ?? selection?.text ?? '').replace(/\\s+$/, '');\n if (!text.trim()) return;\n try {\n const clean = await deps.api.redact(text);\n const fence = fenceFor(clean);\n onSendToChat(`${fence}\\n${clean}\\n${fence}`);\n setNotice({ tone: 'info', text: 'Added to the chat’s message box.' });\n } catch (err) {\n setNotice({ tone: 'error', text: errorText(err, 'The selection could not be sent.') });\n }\n }, [deps.api, focusedTab, onSendToChat, selection]);\n\n // -------------------------------------------------------------------------\n // Leaf callbacks\n // -------------------------------------------------------------------------\n\n const onMeta = useCallback((tabId: string, frame: Exclude<VerseTerminalStreamFrame, { type: 'output' } | { type: 'block' }>) => {\n patchTab(tabId, (t) => {\n switch (frame.type) {\n case 'title': return t.title === frame.title ? t : { ...t, title: frame.title };\n case 'exit': return { ...t, exited: { code: frame.code, signal: frame.signal, at: new Date().toISOString() } };\n case 'cwd': return t.cwd === frame.cwd ? t : { ...t, cwd: frame.cwd };\n case 'integration': return t.shellIntegration === frame.state ? t : { ...t, shellIntegration: frame.state };\n case 'agent-state': return { ...t, agentState: frame.agentState };\n default: return t;\n }\n });\n }, [patchTab]);\n\n const onKeyAction = useCallback((tabId: string, action: PanelKeyAction) => {\n switch (action) {\n case 'find':\n leaves.current.get(tabId)?.openFind();\n return;\n case 'split-right':\n void split('row');\n return;\n case 'split-down':\n void split('column');\n return;\n case 'prev-block':\n case 'next-block':\n // The leaf walks its own markers.\n return;\n case 'toggle-blocks':\n setLayout((prev) => setMode(prev, tabId, (prev.modes[tabId] ?? 'terminal') === 'terminal' ? 'blocks' : 'terminal'));\n return;\n case 'focus-left':\n case 'focus-right':\n case 'focus-up':\n case 'focus-down':\n focusToward(tabId, action.slice('focus-'.length) as PaneDirection);\n return;\n case 'zoom-pane': {\n const group = layoutRef.current.groups.find((g) => g.panes.includes(tabId));\n if (group) setLayout((prev) => toggleZoom(focusPane(prev, group.id, tabId), group.id));\n return;\n }\n case 'assist':\n openAssist(tabId);\n return;\n }\n }, [split, focusToward, openAssist]);\n\n const onSelection = useCallback((tabId: string, has: boolean, text: string) => {\n setSelection(has ? { tabId, text } : null);\n if (!has || !text) return;\n // Copy on select (the ⌘C you would type next), once the drag settles.\n deps.writeClipboard(text).then(() => { if (mounted.current) flashCopied('Copied'); }, () => { /* no user gesture: ⌘C still works */ });\n }, [deps, flashCopied]);\n\n const onStreamState = useCallback((tabId: string, state: TerminalStreamState | null) => {\n setStreamStates((prev) => {\n if ((prev.get(tabId) ?? null) === state) return prev;\n const next = new Map(prev);\n if (state === null) next.delete(tabId);\n else next.set(tabId, state);\n return next;\n });\n if (state === 'gone') void refresh();\n }, [refresh]);\n\n const onBlockMenu = useCallback((tabId: string, block: BlockView, anchorEl: HTMLElement) => {\n const failed = block.failed || (block.exitCode !== null && block.exitCode !== 0);\n const items: ActionMenuItem[] = [\n { id: 'copy-output', label: 'Copy output', onSelect: () => void runBlockAction(tabId, 'copy-output', block), disabled: block.fullscreen, reason: block.fullscreen ? 'A full-screen program keeps no output.' : null },\n { id: 'send', label: 'Send to chat', description: 'Adds the command and its output to the message box (secrets removed).', onSelect: () => void runBlockAction(tabId, 'send', block) },\n ...(failed ? [{ id: 'explain', label: 'Explain and fix this error', description: onAskChat ? 'Sends it to this chat’s seat.' : 'Drafts the question in the message box.', onSelect: () => void runBlockAction(tabId, 'explain', block) }] : []),\n { id: 'ask', label: 'Ask…', description: 'Any seat — Claude Code, Codex, Devin, Grok, a local model — or all of them side by side.', onSelect: () => setTimeout(() => openAskMenu(anchorEl, { tabId, blocks: [block] }), 0) },\n { id: 'copy-command', label: 'Copy command', onSelect: () => void runBlockAction(tabId, 'copy-command', block), disabled: !block.command },\n { id: 'copy-link', label: 'Copy link', description: 'A verse://terminal link to this block.', onSelect: () => void runBlockAction(tabId, 'copy-link', block) },\n { id: 'bookmark', label: bookmarkSets.get(tabId)?.has(block.id) ? 'Remove bookmark' : 'Bookmark', onSelect: () => void runBlockAction(tabId, 'bookmark', block) },\n { id: 'blocks', label: 'Show in Blocks', onSelect: () => setLayout((prev) => setMode(prev, tabId, 'blocks')) },\n ];\n setMenu({ kind: 'block', anchor: anchorBelow(anchorEl, 'end'), from: null, items, label: `Command: ${block.command || 'command'}` });\n }, [bookmarkSets, onAskChat, openAskMenu, runBlockAction]);\n\n const leafRef = (tabId: string) => {\n let ref = leafRefs.current.get(tabId);\n if (!ref) {\n ref = (handle) => {\n if (handle) {\n leaves.current.set(tabId, handle);\n } else {\n leaves.current.delete(tabId);\n leafRefs.current.delete(tabId);\n }\n };\n leafRefs.current.set(tabId, ref);\n }\n return ref;\n };\n\n // A paste into a shell that is still starting waits for its first output\n // (the prompt): typeahead before a profile finishes can be eaten by it.\n useEffect(() => {\n if (pasteTick === 0) return undefined;\n const tryPaste = () => {\n const pending = pendingPaste.current;\n if (!pending) return true;\n const leaf = leaves.current.get(pending.tabId);\n if (!leaf?.size() || !leaf.hasOutput()) return false;\n pendingPaste.current = null;\n // A beat after the prompt, so it is not interleaved with its drawing.\n setTimeout(() => leaf.paste(pending.text), 120);\n return true;\n };\n if (tryPaste()) return undefined;\n const timer = setInterval(() => { if (tryPaste()) clearInterval(timer); }, 200);\n const stop = setTimeout(() => clearInterval(timer), 10_000);\n return () => {\n clearInterval(timer);\n clearTimeout(stop);\n };\n }, [pasteTick]);\n\n // -------------------------------------------------------------------------\n // Header actions\n // -------------------------------------------------------------------------\n\n const updatePrefs = (patch: Partial<LeafPrefs>) => {\n setPrefs((prev) => {\n const next = { ...prev, ...patch };\n writePrefs(deps.storage, next);\n return next;\n });\n };\n\n const openExternal = async () => {\n try {\n await deps.api.openExternal(sessionId, focusedTab?.root ?? roots[0]);\n setNotice({ tone: 'info', text: 'Opened in Terminal.' });\n } catch (err) {\n setNotice({ tone: 'error', text: errorText(err, 'Terminal could not be opened.') });\n }\n };\n\n const openMoreMenu = (from: HTMLElement) => {\n void loadSettings();\n const group = activeGroup;\n const layoutItems: ActionMenuItem[] = group && group.panes.length > 1 ? [\n ...(['row', 'column', 'grid'] as GroupArrangement[]).map((arrangement) => ({\n id: `layout-${arrangement}`,\n ...(arrangement === 'row' ? { separated: true } : {}),\n label: `${arrangement === group.direction ? '✓ ' : ''}${arrangement === 'row' ? 'Side by side' : arrangement === 'column' ? 'Stacked' : 'Grid'}`,\n onSelect: () => setLayout((prev) => setArrangement(prev, group.id, arrangement)),\n })),\n { id: 'zoom', label: `${group.zoomed ? 'Show every pane' : 'Zoom this pane'} (${panelKeyLabel('zoom-pane', deps.platform)})`, onSelect: () => setLayout((prev) => toggleZoom(prev, group.id)) },\n ] : [];\n const history = settings?.history ?? true;\n const assistMode = settings?.assist ?? 'local';\n const raw = focusedTab ? rawTabs.has(focusedTab.id) : false;\n const items: ActionMenuItem[] = [\n { id: 'find', label: `Find… (${panelKeyLabel('find', deps.platform)})`, onSelect: () => focusedTab && leaves.current.get(focusedTab.id)?.openFind(), disabled: !focusedTab },\n { id: 'history', label: 'Command history… (Ctrl+R)', description: 'Search what you ran; Return puts it at the prompt without running it.', onSelect: () => openHistory(focusedTab?.id ?? null, '') },\n { id: 'assist', label: `Generate a command… (${panelKeyLabel('assist', deps.platform)})`, description: assistMode === 'auto' ? 'Local model first; Grok may receive the request and recent terminal context.' : 'Describe it in words; the configured local model writes it for you to review.', onSelect: () => openAssist(focusedTab?.id ?? null), disabled: assistMode === 'off', reason: assistMode === 'off' ? 'Plain-English commands are turned off below.' : null },\n ...layoutItems,\n {\n id: 'raw',\n separated: true,\n label: raw ? 'Use the input editor in this shell' : 'Raw input for this shell',\n description: raw ? 'Back to the editor at each prompt: history, completion, plain words.' : 'Keys go straight to the shell: your zsh-autosuggestions, fzf and prompt, untouched.',\n onSelect: () => focusedTab && setRaw(focusedTab.id, !raw),\n disabled: !focusedTab || !prefs.inputEditor,\n },\n { id: 'input-editor', label: prefs.inputEditor ? 'Turn the input editor off' : 'Turn the input editor on', description: 'For every shell: a prompt editor with history, completion and plain words.', onSelect: () => updatePrefs({ inputEditor: !prefs.inputEditor }) },\n { id: 'history-toggle', separated: true, label: history ? 'Stop recording command history' : 'Record command history', description: 'Kept in ~/.ashlr/verse on this Mac, secrets removed.', onSelect: () => void updateSettings({ history: !history }), disabled: !deps.api.updateSettings },\n { id: 'history-clear', label: 'Clear command history…', danger: true, onSelect: () => setConfirmClear(true), disabled: !deps.api.clearHistory },\n ...(['auto', 'local', 'off'] as VerseTerminalAssistMode[]).map((mode) => ({\n id: `assist-${mode}`,\n label: `${mode === assistMode ? '✓ ' : ''}Plain-English commands: ${ASSIST_MODE_LABELS[mode]}`,\n onSelect: () => void updateSettings({ assist: mode }),\n disabled: !deps.api.updateSettings,\n })),\n { id: 'clear', separated: true, label: 'Clear screen and scrollback', onSelect: () => focusedTab && leaves.current.get(focusedTab.id)?.clear(), disabled: !focusedTab },\n { id: 'ligatures', label: prefs.ligatures ? 'Turn ligatures off' : 'Turn ligatures on', description: 'For fonts that have them (Fira Code, JetBrains Mono…), with GPU rendering.', onSelect: () => updatePrefs({ ligatures: !prefs.ligatures }) },\n { id: 'gpu', label: prefs.gpu ? 'Turn GPU rendering off' : 'Turn GPU rendering on', description: 'Applies to terminals opened from now on.', onSelect: () => updatePrefs({ gpu: !prefs.gpu }) },\n { id: 'sr', label: prefs.screenReader ? 'Turn screen reader mode off' : 'Turn screen reader mode on', onSelect: () => updatePrefs({ screenReader: !prefs.screenReader }) },\n ...(deps.platform === 'mac' ? [{ id: 'external', label: 'Open in Terminal.app', onSelect: () => void openExternal() }] : []),\n ...shareMenuItems(),\n {\n id: 'launch', label: 'Launch configuration…', separated: true,\n description: 'Tabs, splits and commands from .ashlr/verse/launch.json — typed only when you launch one.',\n onSelect: () => setLaunchOpen(true), disabled: !list?.available || !deps.api.launchList,\n },\n {\n id: 'workflows', label: 'Command workflow…',\n description: 'Fill a saved command’s parameters and paste it at the prompt (it does not run).',\n onSelect: () => setWorkflowsOpen(true), disabled: !list?.available,\n },\n {\n id: 'fix-chips', label: fixChips ? 'Stop suggesting fixes' : 'Suggest fixes with the local model',\n description: 'When a command fails, the local model offers up to three commands to paste. Free, and nothing leaves this Mac.',\n onSelect: () => { saveFixChipsEnabled(deps.storage, !fixChips); setFixChips(!fixChips); },\n },\n\n ];\n setMenu({ kind: 'more', anchor: anchorBelow(from), from, items, label: 'Terminal' });\n };\n\n // 3.15 agent tools: share one of YOUR shells in this chat with its agent (the\n // chat's Agent tools must be on \"Share my shells\"). Never an agent's own tab\n // or an Apps launch.\n const shareMenuItems = (): ActionMenuItem[] => {\n const api = deps.agentTools;\n if (!api || !focusedTab || focusedTab.agent || focusedTab.appId || focusedTab.sessionId !== sessionId) return [];\n const shared = agentTabs.get(focusedTab.id)?.kind === 'shared';\n return [{\n id: 'share-agent',\n label: shared ? 'Stop sharing this shell with the agent' : 'Share this shell with the agent…',\n description: shared\n ? 'The agent can no longer type here or read this shell.'\n : 'The chat\\'s agent may run commands here and read the output. Typing yourself pauses it.',\n onSelect: () => {\n void api.share(sessionId, focusedTab.id, !shared).then(\n () => { setNotice({ tone: 'info', text: shared ? 'This shell is yours alone again.' : 'Shared with this chat\\'s agent. Type in it to take it back over.' }); void refresh(); },\n (err: unknown) => setNotice({ tone: 'error', text: errorText(err, 'Switch this chat\\'s Agent tools to \"Share my shells\" first (Chat actions → Agent tools).') }),\n );\n },\n }];\n };\n\n const resumeAgent = (tabId: string) => {\n void deps.agentTools?.resume(tabId).then(\n () => { setNotice({ tone: 'info', text: 'Handed back to the agent.' }); void refresh(); },\n (err: unknown) => setNotice({ tone: 'error', text: errorText(err, 'The terminal could not be handed back.') }),\n );\n };\n\n const openRootMenu = (from: HTMLElement) => {\n setMenu({\n kind: 'root',\n anchor: anchorBelow(from),\n from,\n label: 'New terminal in',\n items: roots.map((root) => ({ id: root, label: projectName(root), description: root, onSelect: () => void openInNewGroup({ root }) })),\n });\n };\n\n // Tabs: ←/→ move and activate, Home/End jump (WAI-ARIA tabs, automatic activation).\n const stripIds = [...layout.groups.map((g) => g.id), AGENT_GROUP_ID];\n const onTabKeyDown = (event: ReactKeyboardEvent<HTMLButtonElement>, index: number) => {\n let next = -1;\n if (event.key === 'ArrowRight') next = (index + 1) % stripIds.length;\n else if (event.key === 'ArrowLeft') next = (index - 1 + stripIds.length) % stripIds.length;\n else if (event.key === 'Home') next = 0;\n else if (event.key === 'End') next = stripIds.length - 1;\n if (next < 0) return;\n event.preventDefault();\n const id = stripIds[next]!;\n setLayout((prev) => ({ ...prev, active: id }));\n tabRefs.current.get(id)?.focus();\n };\n\n // -------------------------------------------------------------------------\n // Render\n // -------------------------------------------------------------------------\n\n if (!list) {\n if (loadError) {\n return (\n <div className={styles.panel}>\n <EmptyState compact tone=\"error\" title=\"Terminal is not reachable\" body={loadError}\n action={<Button size=\"sm\" variant=\"subtle\" onClick={() => void refresh()}>Try again</Button>} />\n </div>\n );\n }\n return (\n <div className={styles.panel} aria-busy=\"true\">\n <div className={styles.strip} aria-hidden=\"true\" />\n <div className={styles.loading}><SkeletonLine width=\"40%\" /><SkeletonLine width=\"70%\" /></div>\n </div>\n );\n }\n\n const newTabKey = 'New terminal tab';\n const opening = tabs.length === 0 && !agentActive && (!autoCreated.current || creating);\n const focusedState = focusedTab ? streamStates.get(focusedTab.id) ?? null : null;\n const status = focusedState === 'reconnecting' ? 'Reconnecting…'\n : focusedState === 'expired' ? 'Session expired — reload to reconnect'\n : copied ?? '';\n const agentSelected = agentActive;\n\n return (\n <div className={styles.panel} data-compact={compact || undefined}>\n <div className={styles.strip}>\n <div className={styles.tabs} role=\"tablist\" aria-label=\"Terminals\">\n {layout.groups.map((group, index) => {\n const selected = !agentSelected && group.id === layout.active;\n const first = tabById.get(group.panes[0]!);\n if (!first) return null;\n const title = group.panes.length > 1 ? `${first.title} +${group.panes.length - 1}` : first.title;\n const exited = group.panes.every((id) => tabById.get(id)?.exited);\n const unseen = !selected && group.panes.some((id) => {\n const t = tabById.get(id);\n return t && !t.exited && (seen.get(id) ?? t.createdAt) < t.lastActivityAt;\n });\n return (\n <div key={group.id} className={styles.tab} data-selected={selected || undefined} role=\"presentation\">\n <button\n ref={(node) => { if (node) tabRefs.current.set(group.id, node); else tabRefs.current.delete(group.id); }}\n type=\"button\"\n role=\"tab\"\n id={`terminal-tab-${group.id}`}\n aria-selected={selected}\n aria-controls={`terminal-group-${group.id}`}\n tabIndex={selected ? 0 : -1}\n className={styles.tabButton}\n title={`${title} — ${first.cwd ?? first.root}`}\n onClick={() => setLayout((prev) => ({ ...prev, active: group.id }))}\n onKeyDown={(event) => onTabKeyDown(event, index)}\n >\n <span className={styles.tabTitle}>{title}</span>\n {(() => {\n const badge = agentBadge(groupAgentState(group.panes.map((id) => tabById.get(id)?.agentState)));\n if (badge) return <span className={extra.agentBadge} data-state={badge.state} title={badge.title} aria-label={badge.title}>{badge.label}</span>;\n return first.agent ? <span className={styles.tabMeta}>agent</span> : null;\n })()}\n {agentTabs.get(first.id)?.kind === 'shared' ? <span className={styles.tabMeta}>shared</span> : null}\n {agentTabs.get(first.id)?.takenOverAt ? <span className={styles.tabMeta}>you have it</span> : null}\n\n {exited ? <span className={styles.tabMeta}>exited</span> : null}\n {unseen ? <span className={styles.unseen} aria-label=\"new output\" role=\"img\" /> : null}\n </button>\n <button type=\"button\" className={styles.tabClose} aria-label={`Close terminal ${title}`} title=\"Close terminal\"\n onClick={() => void closeGroup(group)}>\n <IconX size={12} />\n </button>\n </div>\n );\n })}\n <div className={styles.tab} data-selected={agentSelected || undefined} role=\"presentation\">\n <button\n ref={(node) => { if (node) tabRefs.current.set(AGENT_GROUP_ID, node); else tabRefs.current.delete(AGENT_GROUP_ID); }}\n type=\"button\"\n role=\"tab\"\n id=\"terminal-tab-agent\"\n aria-selected={agentSelected}\n aria-controls=\"terminal-group-agent\"\n tabIndex={agentSelected ? 0 : -1}\n className={styles.tabButton}\n title=\"Commands this chat's agents ran (read-only)\"\n onClick={() => setLayout((prev) => ({ ...prev, active: AGENT_GROUP_ID }))}\n onKeyDown={(event) => onTabKeyDown(event, stripIds.length - 1)}\n >\n <span className={styles.tabTitle}>Agent</span>\n <span className={styles.tabMeta}>read-only</span>\n </button>\n </div>\n </div>\n <div className={styles.stripActions}>\n {list.available ? (\n <>\n <IconButton variant=\"ghost\" size=\"sm\" icon={<IconPlus />} aria-label=\"New terminal tab\" title={newTabKey}\n busy={creating} onClick={() => void openInNewGroup(hereOptions())} />\n {roots.length > 1 ? (\n <IconButton variant=\"ghost\" size=\"sm\" icon={<ChevronDownGlyph />} aria-label=\"New terminal in…\" aria-haspopup=\"menu\"\n aria-expanded={menu?.kind === 'root'} title=\"Choose the folder\"\n onClick={(event) => openRootMenu(event.currentTarget)} />\n ) : null}\n </>\n ) : null}\n </div>\n </div>\n\n {!agentSelected && focusedTab ? (\n <div className={styles.header}>\n <span className={styles.cwd} title={focusedTab.cwd ?? focusedTab.root}>{projectName(focusedTab.cwd ?? focusedTab.root)}</span>\n <span className={styles.headerStatus} role=\"status\" aria-live=\"polite\">{status}</span>\n <div className={styles.headerActions}>\n <div className={styles.segmented} role=\"group\" aria-label=\"View\">\n <button type=\"button\" aria-pressed={focusedMode === 'terminal'} onClick={() => setLayout((prev) => setMode(prev, focusedTab.id, 'terminal'))}>Terminal</button>\n <button type=\"button\" aria-pressed={focusedMode === 'blocks'} title={`Commands as blocks (${panelKeyLabel('toggle-blocks', deps.platform)})`}\n onClick={() => setLayout((prev) => setMode(prev, focusedTab.id, 'blocks'))}>Blocks</button>\n </div>\n {!compact ? (\n <>\n <IconButton variant=\"ghost\" size=\"sm\" icon={<SplitGlyph direction=\"row\" />} aria-label=\"Split right\"\n title={`Split right${deps.platform === 'mac' ? ` (${panelKeyLabel('split-right', deps.platform)})` : ''}`}\n disabled={(activeGroup?.panes.length ?? 0) >= MAX_PANES_PER_GROUP} onClick={() => void split('row')} />\n <IconButton variant=\"ghost\" size=\"sm\" icon={<SplitGlyph direction=\"column\" />} aria-label=\"Split down\"\n title={`Split down${deps.platform === 'mac' ? ` (${panelKeyLabel('split-down', deps.platform)})` : ''}`}\n disabled={(activeGroup?.panes.length ?? 0) >= MAX_PANES_PER_GROUP} onClick={() => void split('column')} />\n </>\n ) : null}\n <IconButton variant=\"ghost\" size=\"sm\" icon={<IconSearch />} aria-label=\"Find in terminal\"\n title={`Find (${panelKeyLabel('find', deps.platform)})`} onClick={() => leaves.current.get(focusedTab.id)?.openFind()} />\n <Button variant=\"ghost\" size=\"sm\" icon={<IconSend />} disabled={!selection} aria-label=\"Send selection to chat\"\n title={selection ? 'Send the selected text to the chat as a code block (secrets removed)' : 'Select text in the terminal first'}\n onClick={() => void sendSelection()}>\n {compact ? null : 'Send to chat'}\n </Button>\n <IconButton variant=\"ghost\" size=\"sm\" icon={<MoreGlyph />} aria-label=\"More terminal options\" aria-haspopup=\"menu\"\n aria-expanded={menu?.kind === 'more'} title=\"More\" onClick={(event) => openMoreMenu(event.currentTarget)} />\n </div>\n </div>\n ) : null}\n\n {!agentSelected && focusedTab && agentTabs.get(focusedTab.id)?.takenOverAt ? (\n <div className={styles.notice} data-tone=\"info\" role=\"status\" data-testid=\"terminal-takeover\">\n <span>You took over this terminal, so the agent is paused here.</span>\n <Button size=\"sm\" variant=\"subtle\" onClick={() => resumeAgent(focusedTab.id)}>Resume agent</Button>\n </div>\n ) : null}\n\n {notice ? (\n <div className={styles.notice} data-tone={notice.tone} role={notice.tone === 'error' ? 'alert' : 'status'}>\n <span>{notice.text}</span>\n <button type=\"button\" className={styles.noticeClose} aria-label=\"Dismiss\" title=\"Dismiss\" onClick={() => setNotice(null)}>\n <IconX size={12} />\n </button>\n </div>\n ) : null}\n\n {confirmClear ? (\n <div className={styles.notice} role=\"alertdialog\" aria-label=\"Clear command history\">\n <span>Clear every command in the history? This cannot be undone.</span>\n <Button size=\"sm\" variant=\"subtle\" onClick={() => void clearHistory()}>Clear</Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={() => setConfirmClear(false)}>Cancel</Button>\n\n </div>\n ) : null}\n {asked ? (\n <div className={styles.notice} role=\"status\">\n <span>{asked.text}</span>\n {asked.sessionId && onOpenSession ? (\n <Button size=\"sm\" variant=\"ghost\" onClick={() => { const id = asked.sessionId!; setAsked(null); onOpenSession(id); }}>Open chat</Button>\n ) : null}\n <button type=\"button\" className={styles.noticeClose} aria-label=\"Dismiss\" title=\"Dismiss\" onClick={() => setAsked(null)}>\n <IconX size={12} />\n </button>\n\n </div>\n ) : null}\n\n <div className={styles.body}>\n {!list.available && !agentSelected ? (\n <EmptyState\n compact\n icon={<TerminalGlyph size={20} />}\n title=\"Terminal needs the desktop app\"\n body=\"This Verse server has no built-in terminal. The Agent tab still shows what this chat's agents ran.\"\n action={deps.platform === 'mac' ? (\n <Button size=\"sm\" variant=\"subtle\" icon={<IconExternalLink />} onClick={() => void openExternal()}>Open in Terminal</Button>\n ) : undefined}\n />\n ) : null}\n {opening && list.available ? (\n <div className={styles.loading} role=\"status\" aria-label=\"Opening a shell\"><SkeletonLine width=\"30%\" /></div>\n ) : null}\n {list.available && tabs.length === 0 && !opening && !agentSelected ? (\n <EmptyState compact icon={<TerminalGlyph size={20} />} title=\"No terminal open\"\n body=\"Open a login shell in this chat's folder. Each command you run becomes a block you can copy, send to the chat, or ask it to fix.\"\n action={<Button size=\"sm\" variant=\"subtle\" icon={<IconPlus />} busy={creating} onClick={() => void openInNewGroup({})}>New terminal</Button>} />\n ) : null}\n\n {layout.groups.map((group) => {\n const selected = !agentSelected && group.id === layout.active;\n const cells = new Map(paneCells(group).map((c) => [c.id, c]));\n const zoomed = group.zoomed && group.panes.includes(group.zoomed) ? group.zoomed : null;\n return (\n <div\n key={group.id}\n id={`terminal-group-${group.id}`}\n role=\"tabpanel\"\n aria-labelledby={`terminal-tab-${group.id}`}\n className={styles.group}\n data-direction={zoomed ? 'row' : group.direction}\n data-cols={group.direction === 'grid' && !zoomed ? gridShape(group.panes.length).cols : undefined}\n data-split={(group.panes.length > 1 && !zoomed) || undefined}\n data-zoomed={zoomed ? true : undefined}\n hidden={!selected}\n >\n {group.panes.map((id) => {\n const tab = tabById.get(id);\n if (!tab) return null;\n const concealed = zoomed !== null && zoomed !== id;\n return (\n <TerminalLeaf\n key={id}\n ref={leafRef(id)}\n tab={tab}\n deps={deps}\n shown={shown && selected && !concealed}\n concealed={concealed}\n gridSpan={group.direction === 'grid' && !zoomed ? cells.get(id)?.span ?? 1 : 1}\n raw={rawTabs.has(id)}\n onHistorySearch={onHistorySearch}\n focused={group.focused === id}\n mode={layout.modes[id] ?? 'terminal'}\n prefs={prefs}\n assistMode={settings?.assist ?? 'local'}\n onFocus={() => setLayout((prev) => focusPane(prev, group.id, id))}\n onMeta={onMeta}\n onBlockAction={(tabId, action, block, more) => void runBlockAction(tabId, action, block, more)}\n {...(leafExtras.get(id) ? { extras: leafExtras.get(id)! } : {})}\n onBlockMenu={onBlockMenu}\n onKeyAction={onKeyAction}\n onSelection={onSelection}\n onNotice={setNotice}\n onStreamState={onStreamState}\n onRestart={(t) => void restartShell(t)}\n onClose={(t) => void closeShell(t)}\n onError={errorText}\n />\n );\n })}\n </div>\n );\n })}\n\n <div id=\"terminal-group-agent\" role=\"tabpanel\" aria-labelledby=\"terminal-tab-agent\" className={styles.group} hidden={!agentSelected}>\n {agentSelected ? (\n <AgentTerminal\n sessionId={sessionId}\n highlightId={agentHighlight}\n onAction={(action, block) => {\n setAgentHighlight(block.id);\n void runBlockAction(null, action, block);\n }}\n />\n ) : null}\n </div>\n </div>\n\n {menu ? (\n <ActionMenu label={menu.label} anchor={menu.anchor} returnFocus={menu.from} onClose={() => setMenu(null)} items={menu.items} />\n ) : null}\n\n {palette ? (\n <HistoryPalette\n mode={palette.mode}\n assistMode={settings?.assist ?? 'local'}\n api={deps.api}\n tabId={palette.tabId}\n cwd={(palette.tabId ? tabById.get(palette.tabId)?.cwd ?? tabById.get(palette.tabId)?.root : null) ?? null}\n initialQuery={palette.draft}\n onClose={() => setPalette(null)}\n onPick={(command) => {\n const target = palette.tabId ?? focusedTab?.id ?? null;\n const leaf = target ? leaves.current.get(target) : undefined;\n // Into the editor (or pasted at the prompt) — never run.\n if (leaf) setTimeout(() => leaf.insertCommand(command), 0);\n else void openInNewGroup({}).then((tab) => { if (tab) pasteInto(tab.id, command); });\n }}\n {...(palette.mode === 'history' && palette.tabId ? {\n onPassThrough: (query: string) => {\n const leaf = leaves.current.get(palette.tabId!);\n if (!leaf) return;\n // The shell's own Ctrl+R (fzf, atuin…), searching for what was typed.\n leaf.sendText(`\\x12${query}`);\n setTimeout(() => leaf.focus(), 0);\n },\n } : {})}\n {...(settings?.history === false || deps.api.updateSettings ? { onEnableHistory: () => void updateSettings({ history: true }) } : {})}\n />\n ) : null}\n {compare && currentSession() ? (\n <Suspense fallback={null}>\n <CompareDialog\n mode=\"compare\"\n prompt={compare.prompt}\n selectAll\n maxSeats={askTargetsAll.filter((t) => t.ready).length}\n source={currentSession()!}\n seats={seats}\n advisorSeats={toAdvisorSeats(seats.filter((s) => s.health.state === 'ready'))}\n advice={null}\n onStarted={() => undefined}\n onClose={() => setCompare(null)}\n />\n </Suspense>\n ) : null}\n\n {launchOpen ? (\n <Suspense fallback={null}>\n <LaunchDialog load={loadLaunchConfigs} onLaunch={launchConfig} onClose={() => setLaunchOpen(false)} />\n </Suspense>\n ) : null}\n\n {workflowsOpen ? (\n <Dialog open onClose={() => setWorkflowsOpen(false)} titleId=\"terminal-workflows-title\" title=\"Command workflows\"\n description=\"Fill the parameters; the command is pasted at the prompt and runs only when you press Enter.\">\n <Suspense fallback={<SkeletonLine width=\"50%\" />}>\n <CommandWorkflowPicker onPaste={(text) => void pasteWorkflow(text)} onClose={() => setWorkflowsOpen(false)} />\n </Suspense>\n </Dialog>\n\n ) : null}\n </div>\n );\n}\n\n/** A split glyph: two panes side by side (row) or stacked (column). Same grammar as the shared icons. */\nfunction SplitGlyph({ direction }: { direction: SplitDirection }) {\n return (\n <svg width={16} height={16} viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" strokeWidth={1.5}\n strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\" focusable=\"false\">\n <rect x=\"1.75\" y=\"2.75\" width=\"12.5\" height=\"10.5\" rx=\"1.5\" />\n {direction === 'row' ? <path d=\"M8 2.75v10.5\" /> : <path d=\"M1.75 8h12.5\" />}\n </svg>\n );\n}\n\nfunction MoreGlyph() {\n return (\n <svg width={16} height={16} viewBox=\"0 0 16 16\" fill=\"currentColor\" aria-hidden=\"true\" focusable=\"false\">\n <circle cx=\"3.5\" cy=\"8\" r=\"1.25\" /><circle cx=\"8\" cy=\"8\" r=\"1.25\" /><circle cx=\"12.5\" cy=\"8\" r=\"1.25\" />\n </svg>\n );\n}\n","/**\n * terminal/TerminalPane.tsx — the adapters (3.15): the Terminal panel behind\n * the pane registry's PaneProps (what ./terminal.pane.tsx registers) and\n * behind the dock's 3.10 slot contract (TerminalPaneProps), so either host\n * mounts it with no change to the panel.\n *\n * Loaded lazily (terminal.pane.tsx `lazyPane`), in the panel's own chunk.\n */\nimport { EmptyState } from '../../../components/primitives/EmptyState.js';\nimport type { PaneProps } from '../panes/pane-registry.js';\nimport { useChatPaneData } from '../panes/chat-pane-data.js';\nimport type { TerminalPaneProps } from '../shell/slots.js';\nimport { TerminalGlyph } from '../dock/terminal/terminal-icons.js';\nimport { TerminalPanel, type TerminalPanelProps } from './TerminalPanel.js';\n\n/**\n * The registry's pane body. The registry hands a unit's pane\n * `sessionId: null` when no chat is open: the terminal belongs to a chat\n * (its tabs, layout and Agent tab are the chat's), so it says so instead.\n */\nexport function TerminalRegistryPane({ sessionId, session, roots, requests, host, visible }: PaneProps) {\n // 3.15: every seat, for a block's \"Ask…\" (the dock provides them; empty elsewhere).\n const { seats } = useChatPaneData();\n if (!sessionId) {\n return (\n <EmptyState compact icon={<TerminalGlyph size={20} />} title=\"Open a chat to use the terminal\"\n body=\"Each chat has its own shells, command blocks and a read-only view of what its agents ran.\" />\n );\n }\n return (\n <TerminalPanel\n sessionId={sessionId}\n roots={roots}\n request={requests.terminal}\n onSendToChat={host.sendToChat}\n visible={visible}\n session={session}\n seats={seats}\n onOpenSession={host.openSession}\n />\n );\n}\n\n/** The dock slot's contract (shell/slots.tsx SLOTS['terminal-pane']), plus the optional turn hook. */\nexport function TerminalPane(props: TerminalPaneProps & Pick<TerminalPanelProps, 'onAskChat'>) {\n return <TerminalPanel {...props} />;\n}\n"],"file":"TerminalPane-XZ5n3Pns.js"}