@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,"file":"multimodel-queries-xmBBUT6n.js","names":[],"sources":["../../../../../../src/core/verse/multimodel/types.ts","../../../../../../src/web-ui/routes/verse/multimodel/multimodel-queries.ts"],"sourcesContent":["/**\n * Multi-model chat — the wire and data shapes (3.16 \"every model working\n * together\"): the Auto seat, Compare / cross-family review, cheap-first\n * escalation, one-click handoff, first-class local models and the per-chat\n * meter.\n *\n * WHERE THINGS RUN\n * - Prompt classification and the Auto choice are PURE (classify.ts,\n * advisor.ts) and run in the BROWSER, per keystroke, over the seat list the\n * app already polls. The prompt never leaves the page to be classified.\n * - The server contributes what only it knows, in ONE read\n * (`GET /api/verse/multimodel/context`): what Mason's past choices taught\n * (learning.ts over the outcome log), fleet model ROI per engine (M322/M335\n * `computeModelStats`), whether the repo must stay on this machine, and\n * local model badges.\n * - Every turn — a Compare fan-out, a review, an escalation, an Auto\n * re-route — goes through the EXISTING session routes (POST /sessions,\n * POST /sessions/:id/turns), so the spend chokepoint, the readiness gate,\n * the local-only gate and the mutation token apply exactly as they do to a\n * turn typed by hand. Nothing here opens a second path to a model.\n *\n * INTERACTIVE ONLY. The router is called with `autonomous: false` (Mason's own\n * work: fleet reserves exist FOR him and do not bind him). Fleet dispatch\n * semantics are untouched — no routing file is edited and no fleet caller\n * changes.\n *\n * BROWSER-SAFE: type-only imports and plain consts.\n */\nimport type { RoutingDifficulty, RoutingTask } from '../../routing/types.js';\n\nexport const VERSE_MULTIMODEL_PATH = '/api/verse/multimodel';\nexport const VERSE_MULTIMODEL_CONTEXT_PATH = `${VERSE_MULTIMODEL_PATH}/context`;\nexport const VERSE_MULTIMODEL_OUTCOME_PATH = `${VERSE_MULTIMODEL_PATH}/outcome`;\nexport const VERSE_MULTIMODEL_LINK_PATH = `${VERSE_MULTIMODEL_PATH}/link`;\nexport const VERSE_MULTIMODEL_METER_PATH = `${VERSE_MULTIMODEL_PATH}/meter`;\nexport const VERSE_MULTIMODEL_WARM_PATH = `${VERSE_MULTIMODEL_PATH}/local/warm`;\nexport const VERSE_MULTIMODEL_LABEL_PATH = `${VERSE_MULTIMODEL_PATH}/label`;\n\n// ---------------------------------------------------------------------------\n// Classification\n// ---------------------------------------------------------------------------\n\n/** What a message asks for, in the words a person would use. */\nexport type PromptKind = 'question' | 'explain' | 'code' | 'debug' | 'refactor' | 'review' | 'plan' | 'bulk';\n\nexport const PROMPT_KINDS: readonly PromptKind[] = ['question', 'explain', 'code', 'debug', 'refactor', 'review', 'plan', 'bulk'];\n\nexport type PromptSize = 'small' | 'medium' | 'large';\n\nexport interface PromptClassification {\n kind: PromptKind;\n /** The router's task vocabulary. */\n task: RoutingTask;\n difficulty: RoutingDifficulty;\n size: PromptSize;\n /** chars / 4, rounded up — the estimator the fit badges and handoff stats use. */\n estTokens: number;\n /** Short human noun phrase: \"quick question\", \"hard refactor\". */\n label: string;\n /** What moved the verdict (\"stack trace\", \"3 files named\"), for the tooltip. */\n signals: string[];\n /**\n * Which path produced the label: `rules` (classify.ts, always available,\n * used for the live preview) or `jev` (the decision layer, asked ONCE per\n * sent message and accepted only above its confidence gate). Absent = rules.\n */\n decidedBy?: 'rules' | 'jev';\n /** The decision layer's confidence when it decided; null/absent for rules. */\n confidence?: number | null;\n /**\n * The decision layer's \"needs a frontier model\" probability (0–1), when it\n * was asked and answered above the gate. Drives cheap-first triage.\n */\n needsFrontier?: number | null;\n}\n\n/** POST /api/verse/multimodel/label — the once-per-send labelling call. */\nexport interface PromptLabelRequest {\n text: string;\n /** The chat: EVERY root it reaches is checked — a local-only repo is never sent to the decision layer. */\n sessionId?: string;\n /** A folder, when there is no chat yet. */\n projectPath?: string;\n contextTokens?: number;\n}\n\nexport interface PromptLabelResponse {\n classification: PromptClassification;\n /** Why the rules were used instead of the decision layer (unkeyed, local-only, low confidence…). */\n fallbackReason: string | null;\n}\n\n// ---------------------------------------------------------------------------\n// Auto seat\n// ---------------------------------------------------------------------------\n\n/**\n * `auto` — the best seat for the message (quality where it matters).\n * `cheap-first` — local models draft and triage; a frontier seat only when\n * the message is hard or the draft is weak (escalation.ts).\n */\nexport type AutoMode = 'auto' | 'cheap-first';\n\nexport interface SeatAdviceOption {\n seatId: string;\n label: string;\n engine: string;\n model: string | null;\n /** Runs on this Mac: free and private. */\n local: boolean;\n /** One short clause: \"free · private\", \"5-hour 88% used\". */\n note: string;\n /** 3.15: the tier this seat competes in for this message (routing/tiers.ts); absent on older callers. */\n tier?: 'elite' | 'fast' | 'free';\n}\n\nexport interface SeatAdvice {\n /** Null when no seat can take the message (every one blocked, or none allowed). */\n choice: SeatAdviceOption | null;\n /** True when the choice IS the chat's current seat. */\n stay: boolean;\n /** ONE line, shown under the composer: the choice and its main reason. */\n why: string;\n /** The factors, in order of weight, for the tooltip. */\n factors: string[];\n /** Ranked runners-up the operator can pick instead (never includes `choice`). */\n alternatives: SeatAdviceOption[];\n /** Seats that could not take it, each with its first reason. */\n held: Array<{ seatId: string; label: string; reason: string }>;\n classification: PromptClassification;\n mode: AutoMode;\n /** The repo may not leave this machine: only local seats were considered. */\n localOnly: { on: boolean; reason: string | null };\n /** The router's own sentence, verbatim (for the tooltip / logs). */\n routerWhy: string;\n}\n\n// ---------------------------------------------------------------------------\n// Learning (outcomes)\n// ---------------------------------------------------------------------------\n\n/**\n * What Mason did with an answer or a suggestion. The advisor learns only from\n * these — explicit ratings and the choices he actually made.\n *\n * up / down — thumbs on an answer.\n * retry — asked another seat the same thing (against the first).\n * switch-away / -to — moved a chat off one seat onto another.\n * auto-overridden — Auto suggested this seat and he chose another.\n * auto-followed — he sent where Auto suggested (weak evidence).\n * compare-won/lost — picked / passed over in a side-by-side Compare.\n * escalated — a local draft was not good enough.\n * draft-accepted — a local draft was good enough (cheap-first).\n */\nexport type OutcomeSignal =\n | 'up'\n | 'down'\n | 'retry'\n | 'switch-away'\n | 'switch-to'\n | 'auto-followed'\n | 'auto-overridden'\n | 'compare-won'\n | 'compare-lost'\n | 'escalated'\n | 'draft-accepted';\n\nexport const OUTCOME_SIGNALS: readonly OutcomeSignal[] = [\n 'up', 'down', 'retry', 'switch-away', 'switch-to', 'auto-followed', 'auto-overridden',\n 'compare-won', 'compare-lost', 'escalated', 'draft-accepted',\n];\n\nexport interface SeatOutcome {\n at: string;\n seatId: string;\n engine: string;\n kind: PromptKind;\n signal: OutcomeSignal;\n sessionId?: string;\n model?: string;\n}\n\n/** POST /api/verse/multimodel/outcome */\nexport interface SeatOutcomeRequest {\n seatId: string;\n kind: PromptKind;\n signal: OutcomeSignal;\n sessionId?: string;\n model?: string;\n}\n\n/** Aggregated evidence for one (kind, seat-or-engine) pair. */\nexport interface LearnedStat {\n /** Decayed net score (positive = Mason prefers it for this kind). */\n score: number;\n /** Decayed number of signals behind `score`. */\n n: number;\n up: number;\n down: number;\n}\n\n/** Keyed `${kind}|seat:${seatId}` and `${kind}|engine:${engine}`. */\nexport type LearnedTable = Record<string, LearnedStat>;\n\n// ---------------------------------------------------------------------------\n// Fleet ROI (M322 / M335), per engine\n// ---------------------------------------------------------------------------\n\nexport interface EngineRoi {\n dispatches: number;\n /** Judge ship rate 0–1 over judged proposals; null when never judged. */\n shipRate: number | null;\n avgLatencyMs: number | null;\n}\n\n// ---------------------------------------------------------------------------\n// Local models\n// ---------------------------------------------------------------------------\n\nexport interface LocalModelBadge {\n seatId: string;\n model: string;\n /** Resident right now (warm), installed only, or not reported. */\n state: 'loaded' | 'available' | 'unknown';\n contextWindow: number | null;\n /** Generation speed, tokens per second; null when never measured. */\n tokPerSec: number | null;\n /** `warm` = measured by the warm-up probe (pure generation); `turn` = a chat turn end to end (a floor). */\n tokPerSecSource: 'warm' | 'turn' | null;\n /** The endpoint is loopback: nothing leaves this Mac. */\n private: boolean;\n /** Can drive an agentic session (edit files); null = the runtime did not say. */\n supportsTools: boolean | null;\n}\n\n/** POST /api/verse/multimodel/local/warm */\nexport interface LocalWarmRequest {\n seatId: string;\n}\n\nexport interface LocalWarmResult {\n seatId: string;\n ok: boolean;\n /** Wall time of the warm-up call. */\n ms: number;\n /** Load time the runtime reported (cold start), when it said. */\n loadMs: number | null;\n tokPerSec: number | null;\n error: string | null;\n}\n\n// ---------------------------------------------------------------------------\n// Context (the one read the composer makes)\n// ---------------------------------------------------------------------------\n\n/** GET /api/verse/multimodel/context?sessionId=<id> | ?projectPath=<abs> (every root of the chat is checked) */\nexport interface MultimodelContext {\n learned: LearnedTable;\n /** Keyed by engine (`claude`, `codex`, `grok`, `local`). */\n roi: Record<string, EngineRoi>;\n localOnly: { on: boolean; reason: string | null };\n local: LocalModelBadge[];\n sampledAt: string;\n}\n\n// ---------------------------------------------------------------------------\n// Thread links + the per-chat meter\n// ---------------------------------------------------------------------------\n\n/**\n * How a session joined a chat's thread (beyond `handoffFrom`, which the\n * session record already carries):\n * compare — one answer of a side-by-side fan-out;\n * review — a cross-family reviewer asked about an answer or diff;\n * draft — a local draft in cheap-first mode;\n * escalate — the frontier seat a weak draft escalated to.\n */\nexport type ThreadRelation = 'compare' | 'review' | 'draft' | 'escalate';\n\nexport const THREAD_RELATIONS: readonly ThreadRelation[] = ['compare', 'review', 'draft', 'escalate'];\n\nexport interface ThreadLink {\n parentSessionId: string;\n childSessionId: string;\n relation: ThreadRelation;\n at: string;\n}\n\n/** POST /api/verse/multimodel/link */\nexport interface ThreadLinkRequest {\n parentSessionId: string;\n childSessionId: string;\n relation: ThreadRelation;\n}\n\nexport interface ChatMeterSession {\n sessionId: string;\n title: string;\n seatId: string;\n engine: string;\n model: string;\n /** How it joined the thread: `root`, `handoff`, or a ThreadRelation. */\n relation: 'root' | 'handoff' | ThreadRelation;\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens: number;\n /** What these tokens would cost at the provider's API list price; null for local or unknown prices. */\n listUsd: number | null;\n local: boolean;\n}\n\nexport interface ChatMeterSeat {\n seatId: string;\n label: string;\n engine: string;\n /** \"5-hour 62% used\" — the binding window, or null with no reading (local: null). */\n window: string | null;\n /**\n * What the FLEET may take from this seat under the budget mode; the rest is\n * kept for Mason's chats (which may use all of it). Null for local seats.\n */\n fleetShare: string | null;\n}\n\nexport interface ChatMeter {\n sessionId: string;\n sessions: ChatMeterSession[];\n totals: {\n inputTokens: number;\n outputTokens: number;\n /** Sum of known list prices. Subscription seats are NOT billed this — it is an equivalent. */\n listUsd: number;\n /** Tokens answered on this Mac. */\n localTokens: number;\n /** Local tokens priced at the thread's frontier rate: what cheap-first saved. */\n savedUsd: number;\n };\n seats: ChatMeterSeat[];\n budgetMode: string;\n /** One honest sentence about what the dollars mean. */\n note: string;\n}\n","/**\n * routes/verse/multimodel/multimodel-queries.ts — the reads and writes behind\n * the multi-model composer (core/verse/multimodel-api.ts).\n *\n * GET /api/verse/multimodel/context?projectPath= → MultimodelContext (learned, ROI, local-only, local badges)\n * POST /api/verse/multimodel/label → PromptLabelResponse (once per send)\n * POST /api/verse/multimodel/outcome → {ok}\n * POST /api/verse/multimodel/link → {ok}\n * GET /api/verse/multimodel/meter?sessionId= → ChatMeter\n * POST /api/verse/multimodel/local/warm → LocalWarmResult\n *\n * Reads spend nothing. Writes pull the held mutation token and touch the hold.\n * Outcome and link writes are best-effort by design: a failed \"thumbs up\"\n * must never surface as an error over the answer it rated.\n */\nimport {\n VERSE_MULTIMODEL_CONTEXT_PATH,\n VERSE_MULTIMODEL_LABEL_PATH,\n VERSE_MULTIMODEL_LINK_PATH,\n VERSE_MULTIMODEL_METER_PATH,\n VERSE_MULTIMODEL_OUTCOME_PATH,\n VERSE_MULTIMODEL_WARM_PATH,\n type ChatMeter,\n type LocalWarmResult,\n type MultimodelContext,\n type PromptLabelRequest,\n type PromptLabelResponse,\n type SeatOutcomeRequest,\n type ThreadLinkRequest,\n} from '../../../../core/verse/multimodel/types.js';\nimport { getMutationToken, touchMutationHold } from '../../../data/auth-store.js';\nimport { apiGet, apiPost } from '../../../data/client.js';\nimport { invalidate } from '../../../data/cache.js';\nimport type { QueryDef } from '../../../data/queries.js';\nimport { VerseMutationLockedError } from '../verse-queries.js';\n\nexport const MULTIMODEL_CONTEXT_KEY_PREFIX = 'verse-multimodel-context:';\nexport const MULTIMODEL_METER_KEY_PREFIX = 'verse-multimodel-meter:';\n\n/** A chat (every root it reaches is checked) or a folder about to become one. */\nexport function multimodelContextQuery(scope: { sessionId: string } | { projectPath: string | null }): QueryDef<MultimodelContext> {\n const qs = 'sessionId' in scope\n ? `?sessionId=${encodeURIComponent(scope.sessionId)}`\n : scope.projectPath ? `?projectPath=${encodeURIComponent(scope.projectPath)}` : '';\n return {\n key: `${MULTIMODEL_CONTEXT_KEY_PREFIX}${qs}`,\n fetch: (signal) => apiGet<MultimodelContext>(`${VERSE_MULTIMODEL_CONTEXT_PATH}${qs}`, signal),\n };\n}\n\nexport function chatMeterQuery(sessionId: string): QueryDef<ChatMeter> {\n return {\n key: `${MULTIMODEL_METER_KEY_PREFIX}${sessionId}`,\n fetch: (signal) => apiGet<ChatMeter>(`${VERSE_MULTIMODEL_METER_PATH}?sessionId=${encodeURIComponent(sessionId)}`, signal),\n };\n}\n\nfunction token(): string {\n const t = getMutationToken();\n if (!t) throw new VerseMutationLockedError();\n return t;\n}\n\nexport async function labelPromptRemote(req: PromptLabelRequest): Promise<PromptLabelResponse> {\n const res = await apiPost<PromptLabelResponse>(VERSE_MULTIMODEL_LABEL_PATH, req, token());\n touchMutationHold();\n return res;\n}\n\n/** Best-effort: never throws. */\nexport async function recordOutcome(req: SeatOutcomeRequest): Promise<boolean> {\n try {\n await apiPost<{ ok: true }>(VERSE_MULTIMODEL_OUTCOME_PATH, req, token());\n touchMutationHold();\n return true;\n } catch {\n return false;\n }\n}\n\n/** Best-effort: never throws. Invalidates the parent's meter. */\nexport async function linkThread(req: ThreadLinkRequest): Promise<boolean> {\n try {\n await apiPost<{ ok: true }>(VERSE_MULTIMODEL_LINK_PATH, req, token());\n touchMutationHold();\n invalidate(`${MULTIMODEL_METER_KEY_PREFIX}${req.parentSessionId}`);\n return true;\n } catch {\n return false;\n }\n}\n\nexport async function warmLocalSeat(seatId: string): Promise<LocalWarmResult> {\n const res = await apiPost<LocalWarmResult>(VERSE_MULTIMODEL_WARM_PATH, { seatId }, token());\n touchMutationHold();\n return res;\n}\n\nexport function invalidateChatMeter(sessionId: string): void {\n invalidate(`${MULTIMODEL_METER_KEY_PREFIX}${sessionId}`);\n}\n"],"mappings":"8GA8BA,IAAa,EAAwB,wBACxB,EAAgC,GAAG,EAAsB,UACzD,EAAgC,GAAG,EAAsB,UACzD,EAA6B,GAAG,EAAsB,OACtD,EAA8B,GAAG,EAAsB,QACvD,EAA6B,GAAG,EAAsB,aACtD,EAA8B,GAAG,EAAsB,QCAvD,EAAgC,4BAChC,EAA8B,0BAG3C,SAAgB,EAAuB,EAA4F,CACjI,IAAM,EAAK,cAAe,EACtB,cAAc,mBAAmB,EAAM,SAAS,IAChD,EAAM,YAAc,gBAAgB,mBAAmB,EAAM,WAAW,IAAM,GAClF,MAAO,CACL,IAAK,GAAG,IAAgC,IACxC,MAAQ,GAAW,EAA0B,GAAG,IAAgC,IAAM,CAAM,CAC9F,CACF,CAEA,SAAgB,EAAe,EAAwC,CACrE,MAAO,CACL,IAAK,GAAG,IAA8B,IACtC,MAAQ,GAAW,EAAkB,GAAG,EAA4B,aAAa,mBAAmB,CAAS,IAAK,CAAM,CAC1H,CACF,CAEA,SAAS,GAAgB,CACvB,IAAM,EAAI,EAAiB,EAC3B,GAAI,CAAC,EAAG,MAAM,IAAI,EAClB,OAAO,CACT,CAEA,eAAsB,EAAkB,EAAuD,CAC7F,IAAM,EAAM,MAAM,EAA6B,EAA6B,EAAK,EAAM,CAAC,EAExF,OADA,EAAkB,EACX,CACT,CAGA,eAAsB,EAAc,EAA2C,CAC7E,GAAI,CAGF,OAFA,MAAM,EAAsB,EAA+B,EAAK,EAAM,CAAC,EACvE,EAAkB,EACX,EACT,MAAQ,CACN,MAAO,EACT,CACF,CAGA,eAAsB,EAAW,EAA0C,CACzE,GAAI,CAIF,OAHA,MAAM,EAAsB,EAA4B,EAAK,EAAM,CAAC,EACpE,EAAkB,EAClB,EAAW,GAAG,IAA8B,EAAI,iBAAiB,EAC1D,EACT,MAAQ,CACN,MAAO,EACT,CACF,CAEA,eAAsB,EAAc,EAA0C,CAC5E,IAAM,EAAM,MAAM,EAAyB,EAA4B,CAAE,QAAO,EAAG,EAAM,CAAC,EAE1F,OADA,EAAkB,EACX,CACT,CAEA,SAAgB,EAAoB,EAAyB,CAC3D,EAAW,GAAG,IAA8B,GAAW,CACzD"}
@@ -0,0 +1,2 @@
1
+ import{C as e,H as t,M as n,V as r,a as i}from"./global-w7KDTTi0.js";var a=class extends Error{constructor(){super(`No mutation token held for this session yet.`),this.name=`MissingMutationTokenError`}};async function o(t,r){let o=e();if(!o)throw new a;let s=await i(t,r,o);return n(),s}async function s(){await o(`/api/fleet/pause`,{}),r(`dashboard-snapshot`),r(`control-snapshot`),r(`fleet`),r(`fleet-activity`)}async function c(){await o(`/api/fleet/resume`,{}),r(`dashboard-snapshot`),r(`control-snapshot`),r(`fleet`),r(`fleet-activity`)}async function l(e){await o(`/api/inbox/${encodeURIComponent(e)}/approve`,{}),r(`inbox`),r(`dashboard-snapshot`),r(`proposal-detail-${e}`),t(`inbox-list:`)}async function u(e){await o(`/api/inbox/${encodeURIComponent(e)}/reject`,{}),r(`inbox`),r(`dashboard-snapshot`),r(`proposal-detail-${e}`),t(`inbox-list:`)}export{c as i,s as n,u as r,l as t};
2
+ //# sourceMappingURL=mutations-CdLi0erM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mutations-CdLi0erM.js","names":[],"sources":["../../../../../../src/web-ui/data/mutations.ts"],"sourcesContent":["/**\n * data/mutations.ts — every mutating call the foundation ships with, each\n * wrapped so it (a) pulls the held mutation token from auth-store instead\n * of asking every call site to thread it through, (b) touches the hold on\n * success so a burst of approvals doesn't idle-expire mid-session, and\n * (c) invalidates whatever cache keys the mutation obviously affects so\n * views update without waiting for the next SSE tick.\n *\n * Routes mirror the mutating surface documented at the top of\n * src/core/web/api.ts. Every one of these 404s (not 401/403) when the\n * server was started without --allow-dispatch — apiPost maps that code-less\n * 404 to DispatchDisabledError (a 404 carrying a `code` stays an ApiError).\n */\nimport { apiPost } from './client.js';\nimport { getMutationToken, touchMutationHold } from './auth-store.js';\nimport { invalidate, invalidatePrefix } from './cache.js';\n\nclass MissingMutationTokenError extends Error {\n constructor() {\n super('No mutation token held for this session yet.');\n this.name = 'MissingMutationTokenError';\n }\n}\n\nasync function post<T>(path: string, body: unknown): Promise<T> {\n const token = getMutationToken();\n if (!token) throw new MissingMutationTokenError();\n const result = await apiPost<T>(path, body, token);\n touchMutationHold();\n return result;\n}\n\nexport async function pauseFleet(): Promise<void> {\n await post('/api/fleet/pause', {});\n invalidate('dashboard-snapshot');\n invalidate('control-snapshot');\n invalidate('fleet');\n invalidate('fleet-activity');\n}\n\nexport async function resumeFleet(): Promise<void> {\n await post('/api/fleet/resume', {});\n invalidate('dashboard-snapshot');\n invalidate('control-snapshot');\n invalidate('fleet');\n invalidate('fleet-activity');\n}\n\nexport async function approveProposal(id: string): Promise<void> {\n await post(`/api/inbox/${encodeURIComponent(id)}/approve`, {});\n invalidate('inbox');\n invalidate('dashboard-snapshot');\n invalidate(`proposal-detail-${id}`);\n invalidatePrefix('inbox-list:');\n}\n\nexport async function rejectProposal(id: string): Promise<void> {\n await post(`/api/inbox/${encodeURIComponent(id)}/reject`, {});\n invalidate('inbox');\n invalidate('dashboard-snapshot');\n invalidate(`proposal-detail-${id}`);\n invalidatePrefix('inbox-list:');\n}\n\nexport interface OpenTargetRequest {\n path: string;\n target: 'editor' | 'finder';\n}\n\nexport async function openTarget(req: OpenTargetRequest): Promise<void> {\n await post('/api/open', req);\n}\n"],"mappings":"qEAiBA,IAAM,EAAN,cAAwC,KAAM,CAC5C,aAAc,CACZ,MAAM,8CAA8C,EACpD,KAAK,KAAO,2BACd,CACF,EAEA,eAAe,EAAQ,EAAc,EAA2B,CAC9D,IAAM,EAAQ,EAAiB,EAC/B,GAAI,CAAC,EAAO,MAAM,IAAI,EACtB,IAAM,EAAS,MAAM,EAAW,EAAM,EAAM,CAAK,EAEjD,OADA,EAAkB,EACX,CACT,CAEA,eAAsB,GAA4B,CAChD,MAAM,EAAK,mBAAoB,CAAC,CAAC,EACjC,EAAW,oBAAoB,EAC/B,EAAW,kBAAkB,EAC7B,EAAW,OAAO,EAClB,EAAW,gBAAgB,CAC7B,CAEA,eAAsB,GAA6B,CACjD,MAAM,EAAK,oBAAqB,CAAC,CAAC,EAClC,EAAW,oBAAoB,EAC/B,EAAW,kBAAkB,EAC7B,EAAW,OAAO,EAClB,EAAW,gBAAgB,CAC7B,CAEA,eAAsB,EAAgB,EAA2B,CAC/D,MAAM,EAAK,cAAc,mBAAmB,CAAE,EAAE,UAAW,CAAC,CAAC,EAC7D,EAAW,OAAO,EAClB,EAAW,oBAAoB,EAC/B,EAAW,mBAAmB,GAAI,EAClC,EAAiB,aAAa,CAChC,CAEA,eAAsB,EAAe,EAA2B,CAC9D,MAAM,EAAK,cAAc,mBAAmB,CAAE,EAAE,SAAU,CAAC,CAAC,EAC5D,EAAW,OAAO,EAClB,EAAW,oBAAoB,EAC/B,EAAW,mBAAmB,GAAI,EAClC,EAAiB,aAAa,CAChC"}
@@ -0,0 +1,2 @@
1
+ import{R as e,j as t,k as n}from"./VerseConsoleApp-DjPpZLo1.js";function r(e=null){n(e?{focusId:e}:{})}function i(e){return`c7-anchor-${e.replace(/[^A-Za-z0-9_-]/g,`-`)}`}function a(e){let t=document.getElementById(i(e));t&&typeof t.scrollIntoView==`function`&&t.scrollIntoView({block:`center`,behavior:`smooth`})}function o(t,n=null){e(t),n&&requestAnimationFrame(()=>{document.getElementById(i(n))?a(n):requestAnimationFrame(()=>a(n))})}function s(e){t(e)}export{a,r as i,o as n,s as r,i as t};
2
+ //# sourceMappingURL=nav-CUXtg-Iw.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nav-CUXtg-Iw.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/command/nav.ts"],"sourcesContent":["/**\n * routes/verse/command/nav.ts — how a surface card asks the shell to go\n * somewhere (unit C7). The shell (C1) owns navigation state; these are thin\n * wrappers over its store so every card words navigation the same way:\n *\n * openNeedsYou() ⌘J's drawer, optionally focused on one item;\n * goToSection(s, a) switch surface (keep-alive: the target keeps its\n * state) and, when `anchor` names a card or row on\n * it, scroll that into view once it is on screen;\n * openChat(sessionId) the chat a Needs-you item or insight is about.\n */\nimport type { WorkbenchSectionId } from '../../../../core/verse/workbench-types.js';\nimport { openVerseNeedsYou, openVerseSession, setVerseSection } from '../verse-ui-store.js';\n\nexport function openNeedsYou(focusId: string | null = null): void {\n openVerseNeedsYou(focusId ? { focusId } : {});\n}\n\n/** DOM id for an anchor (\"repo-ashlrai/binshield\" → \"c7-anchor-repo-ashlrai-binshield\"). */\nexport function anchorId(anchor: string): string {\n return `c7-anchor-${anchor.replace(/[^A-Za-z0-9_-]/g, '-')}`;\n}\n\nexport function scrollToAnchor(anchor: string): void {\n const el = document.getElementById(anchorId(anchor));\n if (el && typeof el.scrollIntoView === 'function') el.scrollIntoView({ block: 'center', behavior: 'smooth' });\n}\n\nexport function goToSection(section: WorkbenchSectionId, anchor: string | null = null): void {\n setVerseSection(section);\n if (!anchor) return;\n // The target surface may be mounting (lazy chunk) or un-hiding (keep-alive):\n // try on the next two frames, then give up quietly — a missing anchor is\n // never an error, the operator is already on the right surface.\n requestAnimationFrame(() => {\n if (document.getElementById(anchorId(anchor))) scrollToAnchor(anchor);\n else requestAnimationFrame(() => scrollToAnchor(anchor));\n });\n}\n\nexport function openChat(sessionId: string): void {\n openVerseSession(sessionId);\n}\n"],"mappings":"gEAcA,SAAgB,EAAa,EAAyB,KAAY,CAChE,EAAkB,EAAU,CAAE,SAAQ,EAAI,CAAC,CAAC,CAC9C,CAGA,SAAgB,EAAS,EAAwB,CAC/C,MAAO,aAAa,EAAO,QAAQ,kBAAmB,GAAG,GAC3D,CAEA,SAAgB,EAAe,EAAsB,CACnD,IAAM,EAAK,SAAS,eAAe,EAAS,CAAM,CAAC,EAC/C,GAAM,OAAO,EAAG,gBAAmB,YAAY,EAAG,eAAe,CAAE,MAAO,SAAU,SAAU,QAAS,CAAC,CAC9G,CAEA,SAAgB,EAAY,EAA6B,EAAwB,KAAY,CAC3F,EAAgB,CAAO,EAClB,GAIL,0BAA4B,CACtB,SAAS,eAAe,EAAS,CAAM,CAAC,EAAG,EAAe,CAAM,EAC/D,0BAA4B,EAAe,CAAM,CAAC,CACzD,CAAC,CACH,CAEA,SAAgB,EAAS,EAAyB,CAChD,EAAiB,CAAS,CAC5B"}
@@ -0,0 +1,2 @@
1
+ import{r as e}from"./rolldown-runtime-hePW80VL.js";import{n as t,s as n}from"./index-BC5Uslm5.js";import{C as r,H as i,M as a,V as o,a as s,t as c}from"./global-w7KDTTi0.js";import{O as l,dt as u,z as d}from"./VerseShared-Bf-XTHCh.js";import{t as f}from"./leader-thread-types-CDb-VPPO.js";import{t as p}from"./resolved-store-UYN2k9My.js";import{t as m}from"./Input-Cpn9uYj2.js";import{c as h,i as g,t as _}from"./needs-you-model-DL9EEd2L.js";function v(e){if(!e.startsWith(`leader:leader-question:`))return null;let t=e.slice(f.length);return/^.+:\d+$/.test(t)?t:null}function y(e){return(e.detail??e.title.replace(/^Leader question:\s*/,``)).trim()}var b=e(n(),1),x=t(),S=/^\/api\/verse\/(?:cloud|devin)\/tasks\/[^/]+\/close$/;function C(e){let t=e.request;return e.kind===`reject`&&t!==null&&t.method===`POST`&&S.test(t.path)&&typeof t.body.headSha==`string`}function w(e){let t=e.replace(/[\u0000-\u001f\u007f-\u009f\u2028\u2029]+/g,` `).replace(/\s+/g,` `).trim();return t&&t.slice(0,200).trim()||null}function T(e,t){let n=w(t);return n?{...e,reason:n}:{...e}}function E({holder:e}){let[t,n]=(0,b.useState)(e.value);return(0,x.jsx)(m,{size:`sm`,label:`Why? (optional)`,hint:`Saved on the task and in the GitHub comment, so the next attempt learns from it.`,value:t,maxLength:200,autoComplete:`off`,spellCheck:!0,onChange:t=>{n(t.target.value),e.value=t.target.value}})}function D(e,t){return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(`p`,{style:{margin:`0 0 var(--space-3)`},children:e}),(0,x.jsx)(E,{holder:t})]})}function O(e){p(e.id),e.source===`approvals`&&(o(`inbox`),o(`dashboard-snapshot`),i(`inbox-list:`),e.target.kind===`approval`&&o(`proposal-detail-${e.target.proposalId}`)),l()}function k(e,t,n){let i=t.request;if(!i){n.openTarget(e);return}if(!u(i.path)){n.toast(`That action points outside this app and was not sent.`,`danger`);return}let o=g(e,t),l=h(e).text,f=C(t)?{value:``}:null,p=async()=>{let e=r();if(!e)throw new c(`Mutation token was rejected.`,401,i.path);await s(i.path,f?T(i.body,f.value):i.body,e),a()},m=_.has(t.kind)||o!==null,v=o?.body??l;d({title:o?.title??t.label,body:f?D(v,f):v,confirmLabel:o?.confirmLabel??t.label,destructive:t.destructive,token:!0,tokenReason:`${t.label} changes state on this machine and requires the dispatch token.`,skipConfirm:!m,run:p,onDone:()=>{O(e),n.toast(`${t.label}: ${l}`,`success`)},onError:m?void 0:e=>n.toast(e,`danger`)})}export{y as n,v as r,k as t};
2
+ //# sourceMappingURL=needs-you-actions-B2tjWO-0.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"needs-you-actions-B2tjWO-0.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/leader/question-id.ts","../../../../../../src/web-ui/routes/verse/shell/close-reason.tsx","../../../../../../src/web-ui/routes/verse/shell/needs-you-actions.ts"],"sourcesContent":["/**\n * routes/verse/leader/question-id.ts — from a Needs-you Leader question to\n * the thread's question. Pure and tiny: the Needs-you drawer imports it.\n *\n * item id `leader:leader-question:<memoId>:<index>`\n * questionId `<memoId>:<index>` — the item id minus its prefix, exactly\n * (core/vision/leader-thread-types.ts LEADER_QUESTION_ITEM_PREFIX)\n * title `Leader question: <question>` (clipped); `detail` carries the\n * whole question when the title had to be clipped\n */\nimport { LEADER_QUESTION_ITEM_PREFIX } from './thread-types.js';\n\n/** The thread questionId a Needs-you row is about; null for any other row. */\nexport function questionIdOfNeedsYouItem(itemId: string): string | null {\n if (!itemId.startsWith(LEADER_QUESTION_ITEM_PREFIX)) return null;\n const questionId = itemId.slice(LEADER_QUESTION_ITEM_PREFIX.length);\n return /^.+:\\d+$/.test(questionId) ? questionId : null;\n}\n\n/** The question's own words from a Needs-you row: the full detail when present, else the title without its prefix. */\nexport function needsYouQuestionText(item: { title: string; detail: string | null }): string {\n return (item.detail ?? item.title.replace(/^Leader question:\\s*/, '')).trim();\n}\n","/**\n * routes/verse/shell/close-reason.tsx — the optional \"why\" on a single\n * Needs-you Close (3.15).\n *\n * Closing a cloud or Devin PR from Needs-you used to record only \"Closed in\n * Verse without landing.\", which the retro sweep rightly treats as no lesson.\n * The Close confirmation now carries one short, optional line; the server\n * (core/cloud/cloud-api.ts parseCloudPrCloseBody → pr-actions.ts closeCloudPr)\n * stores it as `Closed in Verse: <reason>`, puts it in the GitHub close\n * comment, and the next retro learns from it.\n *\n * Deliberately small: one labelled field inside the existing confirm dialog\n * (guarded-action.tsx renders `body` as a ReactNode), optional, single line,\n * capped at the server's limit. The confirm button keeps the initial focus,\n * so Close → Enter still closes without a reason; batch Close (cloud-triage.ts\n * runBatch) sends none. The field is uncontrolled from the dialog's point of\n * view: it writes into a holder the action's `run` reads at click time, so a\n * retry after an error re-sends what is typed now.\n */\nimport { useState, type ReactNode } from 'react';\nimport type { NeedsYouAction } from '../../../../core/verse/workbench-types.js';\nimport { Input } from '../../../components/primitives/Input.js';\n\n/** Mirrors core/cloud/pr-actions.ts CLOUD_CLOSE_REASON_MAX (that module is server-only). */\nexport const CLOSE_REASON_MAX = 200;\n\n/** `/api/verse/cloud/tasks/<id>/close` or `/api/verse/devin/tasks/<id>/close` — the only routes that take a reason. */\nconst CLOSE_ROUTE_RE = /^\\/api\\/verse\\/(?:cloud|devin)\\/tasks\\/[^/]+\\/close$/;\n\n/** A cloud or Devin PR's Close (cloud-api.ts triageActions), pinned to a head commit. */\nexport function isCloseTriageAction(action: Pick<NeedsYouAction, 'kind' | 'request'>): boolean {\n const request = action.request;\n return action.kind === 'reject'\n && request !== null\n && request.method === 'POST'\n && CLOSE_ROUTE_RE.test(request.path)\n && typeof request.body['headSha'] === 'string';\n}\n\n/**\n * The reason as the server will accept it: one line, trimmed, at most\n * CLOSE_REASON_MAX characters; null when blank. (The server normalises and\n * secret-scrubs it again — this only keeps the request within its bounds.)\n */\nexport function cleanCloseReason(text: string): string | null {\n // eslint-disable-next-line no-control-regex\n const flat = text.replace(/[\\u0000-\\u001f\\u007f-\\u009f\\u2028\\u2029]+/g, ' ').replace(/\\s+/g, ' ').trim();\n if (!flat) return null;\n return flat.slice(0, CLOSE_REASON_MAX).trim() || null;\n}\n\n/** The close request's body, plus the reason when there is one (never an empty `reason` key). */\nexport function withCloseReason(body: Readonly<Record<string, unknown>>, text: string): Record<string, unknown> {\n const reason = cleanCloseReason(text);\n return reason ? { ...body, reason } : { ...body };\n}\n\nexport interface CloseReasonHolder {\n value: string;\n}\n\nfunction CloseReasonField({ holder }: { holder: CloseReasonHolder }) {\n const [value, setValue] = useState(holder.value);\n return (\n <Input\n size=\"sm\"\n label=\"Why? (optional)\"\n hint=\"Saved on the task and in the GitHub comment, so the next attempt learns from it.\"\n value={value}\n maxLength={CLOSE_REASON_MAX}\n autoComplete=\"off\"\n spellCheck\n onChange={(event) => {\n setValue(event.target.value);\n holder.value = event.target.value;\n }}\n />\n );\n}\n\n/** The confirm body for a Close: the item's own sentence, then the reason field. */\nexport function closeReasonBody(text: ReactNode, holder: CloseReasonHolder): ReactNode {\n return (\n <>\n <p style={{ margin: '0 0 var(--space-3)' }}>{text}</p>\n <CloseReasonField holder={holder} />\n </>\n );\n}\n","/**\n * routes/verse/shell/needs-you-actions.ts — doing what a Needs-you item asks\n * (unit C1). One path for a drawer key (A / R / V / E), a drawer button and\n * the palette:\n *\n * 1. the action's route must be a same-origin `/api/` route\n * (isSafeApiRoute — checked again here, not only at the server's\n * producer boundary, because this is where the mutation token is sent);\n * 2. approve / reject / veto always confirm (the item's own copy, else a\n * generic one); other kinds only when the item carries copy;\n * 3. then the token, then the POST (guarded-action.tsx owns 2–3's order);\n * 4. on success the item is hidden at once (optimistic) and activity is\n * re-polled; it stays hidden until a poll no longer lists it, or 60 s.\n *\n * An action with no route (it needs Touch ID or a terminal) opens the item's\n * target instead — that is where the flow lives.\n *\n * 3.15: a cloud / Devin PR's Close confirms with an optional one-line reason\n * (close-reason.tsx) that rides in the POST body as `reason` — only for that\n * one route, and only when something was typed.\n */\nimport { isSafeApiRoute, type NeedsYouAction, type NeedsYouItem } from '../../../../core/verse/workbench-types.js';\nimport { getMutationToken, touchMutationHold } from '../../../data/auth-store.js';\nimport { invalidate, invalidatePrefix } from '../../../data/cache.js';\nimport { ApiError, apiPost } from '../../../data/client.js';\nimport { closeReasonBody, isCloseTriageAction, withCloseReason, type CloseReasonHolder } from './close-reason.js';\nimport { requestGuarded } from './guard-store.js';\nimport { ALWAYS_CONFIRM, confirmCopy, readableItemTitle } from './needs-you-model.js';\nimport { markResolved } from './resolved-store.js';\nimport { refreshActivity } from './useActivity.js';\n\nexport { markResolved, pruneResolved, resetResolvedForTest, RESOLVED_HIDE_MS, useResolvedIds } from './resolved-store.js';\n\nexport interface ActionContext {\n /** Open the item's target (for an action with no route). */\n openTarget: (item: NeedsYouItem) => void;\n toast: (message: string, tone?: 'neutral' | 'success' | 'danger') => void;\n}\n\nfunction afterSuccess(item: NeedsYouItem): void {\n markResolved(item.id);\n if (item.source === 'approvals') {\n // The approvals list, the inbox badge and the proposal detail all read\n // these keys (data/mutations.ts approveProposal does the same).\n invalidate('inbox');\n invalidate('dashboard-snapshot');\n invalidatePrefix('inbox-list:');\n if (item.target.kind === 'approval') invalidate(`proposal-detail-${item.target.proposalId}`);\n }\n void refreshActivity();\n}\n\n/** Run `action` on `item` through confirm → token → POST. */\nexport function runNeedsYouAction(item: NeedsYouItem, action: NeedsYouAction, ctx: ActionContext): void {\n const request = action.request;\n if (!request) {\n ctx.openTarget(item);\n return;\n }\n if (!isSafeApiRoute(request.path)) {\n ctx.toast('That action points outside this app and was not sent.', 'danger');\n return;\n }\n const copy = confirmCopy(item, action);\n // The operator-facing title (\"fix the flaky snapshot test\"), not the raw\n // producer string (\"PR: fix the flaky snapshot test\") — same text the row shows.\n const title = readableItemTitle(item).text;\n // Read at click time, so a retry after an error sends what is typed now.\n const reason: CloseReasonHolder | null = isCloseTriageAction(action) ? { value: '' } : null;\n const run = async () => {\n const token = getMutationToken();\n if (!token) throw new ApiError('Mutation token was rejected.', 401, request.path);\n await apiPost<unknown>(request.path, reason ? withCloseReason(request.body, reason.value) : request.body, token);\n touchMutationHold();\n };\n const mustConfirm = ALWAYS_CONFIRM.has(action.kind) || copy !== null;\n const bodyText = copy?.body ?? title;\n requestGuarded({\n title: copy?.title ?? action.label,\n body: reason ? closeReasonBody(bodyText, reason) : bodyText,\n confirmLabel: copy?.confirmLabel ?? action.label,\n destructive: action.destructive,\n token: true,\n tokenReason: `${action.label} changes state on this machine and requires the dispatch token.`,\n skipConfirm: !mustConfirm,\n run,\n onDone: () => {\n afterSuccess(item);\n ctx.toast(`${action.label}: ${title}`, 'success');\n },\n onError: mustConfirm ? undefined : (message) => ctx.toast(message, 'danger'),\n });\n}\n"],"mappings":"0bAaA,SAAgB,EAAyB,EAA+B,CACtE,GAAI,CAAC,EAAO,WAAA,yBAAsC,EAAG,OAAO,KAC5D,IAAM,EAAa,EAAO,MAAM,EAA4B,MAAM,EAClE,MAAO,WAAW,KAAK,CAAU,EAAI,EAAa,IACpD,CAGA,SAAgB,EAAqB,EAAwD,CAC3F,OAAQ,EAAK,QAAU,EAAK,MAAM,QAAQ,uBAAwB,EAAE,EAAA,CAAG,KAAK,CAC9E,sBCKM,EAAiB,uDAGvB,SAAgB,EAAoB,EAA2D,CAC7F,IAAM,EAAU,EAAO,QACvB,OAAO,EAAO,OAAS,UAClB,IAAY,MACZ,EAAQ,SAAW,QACnB,EAAe,KAAK,EAAQ,IAAI,GAChC,OAAO,EAAQ,KAAK,SAAe,QAC1C,CAOA,SAAgB,EAAiB,EAA6B,CAE5D,IAAM,EAAO,EAAK,QAAQ,6CAA8C,GAAG,CAAC,CAAC,QAAQ,OAAQ,GAAG,CAAC,CAAC,KAAK,EAEvG,OADK,GACE,EAAK,MAAM,EAAA,GAAmB,CAAC,CAAC,KAAK,GAD1B,IAEpB,CAGA,SAAgB,EAAgB,EAAyC,EAAuC,CAC9G,IAAM,EAAS,EAAiB,CAAI,EACpC,OAAO,EAAS,CAAE,GAAG,EAAM,QAAO,EAAI,CAAE,GAAG,CAAK,CAClD,CAMA,SAAS,EAAiB,CAAE,UAAyC,CACnE,GAAM,CAAC,EAAO,IAAA,EAAY,EAAA,SAAA,CAAS,EAAO,KAAK,EAC/C,OACE,EAAA,EAAA,IAAA,CAAC,EAAD,CACE,KAAK,KACL,MAAM,kBACN,KAAK,mFACE,QACP,UAAA,IACA,aAAa,MACb,WAAA,GACA,SAAW,GAAU,CACnB,EAAS,EAAM,OAAO,KAAK,EAC3B,EAAO,MAAQ,EAAM,OAAO,KAC9B,CACD,CAAA,CAEL,CAGA,SAAgB,EAAgB,EAAiB,EAAsC,CACrF,OACE,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,MAAO,CAAE,OAAQ,oBAAqB,EAAI,SAAA,CAAQ,CAAA,GACrD,EAAA,EAAA,IAAA,CAAC,EAAD,CAA0B,QAAS,CAAA,CACnC,CAAA,CAAA,CAEN,CCjDA,SAAS,EAAa,EAA0B,CAC9C,EAAa,EAAK,EAAE,EAChB,EAAK,SAAW,cAGlB,EAAW,OAAO,EAClB,EAAW,oBAAoB,EAC/B,EAAiB,aAAa,EAC1B,EAAK,OAAO,OAAS,YAAY,EAAW,mBAAmB,EAAK,OAAO,YAAY,GAE7F,EAAqB,CACvB,CAGA,SAAgB,EAAkB,EAAoB,EAAwB,EAA0B,CACtG,IAAM,EAAU,EAAO,QACvB,GAAI,CAAC,EAAS,CACZ,EAAI,WAAW,CAAI,EACnB,MACF,CACA,GAAI,CAAC,EAAe,EAAQ,IAAI,EAAG,CACjC,EAAI,MAAM,wDAAyD,QAAQ,EAC3E,MACF,CACA,IAAM,EAAO,EAAY,EAAM,CAAM,EAG/B,EAAQ,EAAkB,CAAI,CAAC,CAAC,KAEhC,EAAmC,EAAoB,CAAM,EAAI,CAAE,MAAO,EAAG,EAAI,KACjF,EAAM,SAAY,CACtB,IAAM,EAAQ,EAAiB,EAC/B,GAAI,CAAC,EAAO,MAAM,IAAI,EAAS,+BAAgC,IAAK,EAAQ,IAAI,EAChF,MAAM,EAAiB,EAAQ,KAAM,EAAS,EAAgB,EAAQ,KAAM,EAAO,KAAK,EAAI,EAAQ,KAAM,CAAK,EAC/G,EAAkB,CACpB,EACM,EAAc,EAAe,IAAI,EAAO,IAAI,GAAK,IAAS,KAC1D,EAAW,GAAM,MAAQ,EAC/B,EAAe,CACb,MAAO,GAAM,OAAS,EAAO,MAC7B,KAAM,EAAS,EAAgB,EAAU,CAAM,EAAI,EACnD,aAAc,GAAM,cAAgB,EAAO,MAC3C,YAAa,EAAO,YACpB,MAAO,GACP,YAAa,GAAG,EAAO,MAAM,iEAC7B,YAAa,CAAC,EACd,MACA,WAAc,CACZ,EAAa,CAAI,EACjB,EAAI,MAAM,GAAG,EAAO,MAAM,IAAI,IAAS,SAAS,CAClD,EACA,QAAS,EAAc,IAAA,GAAa,GAAY,EAAI,MAAM,EAAS,QAAQ,CAC7E,CAAC,CACH"}
@@ -0,0 +1,2 @@
1
+ import{W as e}from"./VerseShared-Bf-XTHCh.js";import{g as t,m as n,n as r,x as i}from"./verse-model-DAOz9LrY.js";function a(e,t){let n=c(t)??`the target repository`;switch(e){case`pr`:return`Pushes a branch to ${n}'s remote and opens a real pull request. Other people can see it immediately, and this dialog cannot undo it.`;case`patch`:return`Writes the diff to ${n} on disk now. Nothing is pushed, but the working tree changes.`;default:return`Applies this ${String(e)} proposal to ${n} now.`}}function o(e){return e===`pr`}function s(e){return e.engineModel?e.engineModel:e.engineTier?e.engineTier:null}function c(e){if(typeof e!=`string`)return null;let t=e.trim().replace(/\/+$/,``);if(t.length===0)return null;let n=t.slice(t.lastIndexOf(`/`)+1);return n.length>0?n:t}var l={patch:`Patch`,pr:`Pull request`,deploy:`Deploy`,note:`Note`,"desktop-action":`Desktop action`,"browser-action":`Browser action`};function u(e){return l[e]??String(e)}function d(e){return e.length===0?e:e.charAt(0).toUpperCase()+e.slice(1)}function f(e){let t=e.toLowerCase();return Object.prototype.hasOwnProperty.call(r,t)?r[t]:d(t)}function p(e){let t=e;return(t.match(/"/g)??[]).length%2==1&&(t+=`"`),(t.match(/\u201c/g)??[]).length>(t.match(/\u201d/g)??[]).length&&(t+=`”`),t}function m(e){let t=e.replace(/(?:\u2026|\.\.\.)$/,``),n=t.lastIndexOf(` `);return`${(n>0?t.slice(0,n):t).replace(/[\s,;:\-\u2013\u2014]+$/,``)}\u2026`}function h(e){let t=typeof e==`string`?e.trim():``,n=/^(\[partial\]\s*)?(claude|codex|grok|local|ollama|gemini|api[\w-]*) run:\s*(.*)$/is.exec(t),r=n?`${n[1]?`Partial `:``}${f(n[2])} run`:null,i=n?n[3]:t,a=/[\p{L}\p{N}](?:\u2026|\.\.\.)$/u.test(i),o=n!==null&&i.length>=80&&!/[.!?)"'\u201d\u2026]$/.test(i),s=a||o;return s&&(i=m(i)),i=p(i),{eyebrow:r,text:i.length>0?i:t,truncated:s}}var g=/^(Partial )?(.+?) (\S+) run produced (\d+) file\(s\) \(\+(\d+)\/-(\d+)\)\.?\s*([\s\S]*)$/,_=`TITRR — Test, Iterate, Test, Refine, Repeat: after its change the run re-ran the repository’s tests and repaired the change until they passed or it ran out of attempts.`;function v(e){if(/\bTITRR\b/.test(e)){let t=e.replace(/\bTITRR\b\s*/,``).trim();return{label:`Test-and-repair loop${t===`api-model`?` (API model)`:t===`api-model required-diff`?` (API model, retried for a missing diff)`:t===`api-model failed producer`?` (API model, producer failed)`:t.length>0?` (${t})`:``}`,hint:_}}return/^best-of-n/i.test(e)?{label:e,hint:`Several models attempted this change in parallel; a judge compared them.`}:e===`api-model`?{label:`API model run`,hint:null}:e===`Sandboxed`?{label:`Sandboxed run`,hint:`Produced in an isolated sandbox checkout; nothing touched your working tree.`}:{label:e,hint:null}}function y(e){if(typeof e!=`string`)return null;let t=g.exec(e.trim());if(!t)return null;let{label:n,hint:r}=v(t[2]),i=t[7].trim();return{partial:t[1]!==void 0,source:t[2],sourceLabel:n,sourceHint:r,model:t[3],files:Number(t[4]),insertions:Number(t[5]),deletions:Number(t[6]),rest:i.length>0?i:null}}function b(e){let t=e=>e.toLocaleString(`en-US`);return`${t(e.files)} ${e.files===1?`file`:`files`} \u00b7 +${t(e.insertions)} \u2212${t(e.deletions)}`}function x(e){let t=e=>e.toLocaleString(`en-US`);return`${t(e.files)} ${e.files===1?`file`:`files`} changed, ${t(e.insertions)} ${e.insertions===1?`line`:`lines`} added, ${t(e.deletions)} removed`}function S(e,t=Date.now()){if(typeof e!=`string`)return`at an unknown time`;let n=Date.parse(e);if(!Number.isFinite(n))return`at an unknown time`;let r=Math.max(0,Math.round((t-n)/1e3));if(r<45)return`just now`;let i=new Intl.RelativeTimeFormat(`en`,{numeric:`auto`}),a=Math.round(r/60);if(a<60)return i.format(-a,`minute`);let o=Math.round(a/60);if(o<24)return i.format(-o,`hour`);let s=Math.round(o/24);return s<=60?i.format(-s,`day`):`on ${new Date(n).toLocaleDateString(`en-US`,{month:`short`,day:`numeric`,year:`numeric`})}`}function C(e){if(typeof e!=`string`)return;let t=Date.parse(e);if(Number.isFinite(t))return new Date(t).toLocaleString([],{weekday:`short`,month:`short`,day:`numeric`,year:`numeric`,hour:`numeric`,minute:`2-digit`})}var w={all:`All`,approvals:`Approvals`,fleet:`Fleet`,chats:`Chats`,accounts:`Accounts`},T={all:[`approvals`,`authority`,`fleet`,`leader`,`chats`,`accounts`],approvals:[`approvals`,`fleet`,`leader`],fleet:[`authority`,`fleet`,`leader`],chats:[`chats`],accounts:[`accounts`]},E={approvals:`the approvals inbox`,authority:`the autonomy grant`,fleet:`the fleet`,leader:`the Leader`,chats:`chats`,accounts:`account health`};function D(t,n){return n===`all`?[...t]:t.filter(t=>e[t.kind]===n)}function O(t){let n={all:t.length,approvals:0,fleet:0,chats:0,accounts:0};for(let r of t)n[e[r.kind]]+=1;return n}function k(e,t){let n=[];for(let r of T[t]){let t=e?.[r]??`unavailable`;t!==`ok`&&n.push({source:r,name:E[r],state:t})}return{vouched:n.length===0,silent:n}}function A(e){let t=e.silent.map(e=>e.state===`error`?`${e.name} failed to answer`:`${e.name} isn't reporting in this build`);return t.length===0?``:t.length===1?j(t[0]):j(`${t.slice(0,-1).join(`, `)} and ${t[t.length-1]}`)}function j(e){return e.charAt(0).toUpperCase()+e.slice(1)}var M=new Set([`approve`,`reject`,`veto`]);function N(e,t){return e.actions.find(e=>e.kind===t)??null}var P={approve:{title:`Approve this?`,confirmLabel:`Approve`},reject:{title:`Reject this?`,confirmLabel:`Reject`},veto:{title:`Veto this action?`,confirmLabel:`Veto`}};function F(e,t){if(t.confirm)return t.confirm;if(t.kind===`approve`||t.kind===`reject`||t.kind===`veto`){let n=P[t.kind];return{title:n.title,body:L(e).text,confirmLabel:n.confirmLabel}}return null}var I=/^(PR|[a-z][a-z-]*):\s+([\s\S]+)$/;function L(e){let t=null,n=e.title;if(e.kind===`approval`){let r=I.exec(e.title.trim());r&&(t=r[1]===`PR`?`pr`:r[1],n=r[2])}let r=h(n),i=[t===null?null:u(t),r.eyebrow].filter(e=>e!==null);return{kindLabel:i.length>0?i.join(` · `):null,text:r.text}}function R(e,t=Date.now()){let n=L(e),r=y(e.detail),i=c(e.subject.repo);return{kindLabel:n.kindLabel,title:n.text,fullTitle:e.title,run:r?{stats:b(r),statsSpoken:x(r),source:r.sourceLabel,sourceHint:r.sourceHint,partial:r.partial,model:r.model}:null,detail:r?r.rest:e.detail,repo:i,repoFull:i!==null&&e.subject.repo!==null&&e.subject.repo!==i?e.subject.repo:void 0,age:S(e.since,t),ageStamp:C(e.since)}}function z(e,t=Date.now()){let n=Date.parse(e);if(!Number.isFinite(n))return`—`;let r=Math.round((n-t)/1e3);if(r<=0)return`expired`;if(r<90)return`in ${r}s`;let i=Math.round(r/60);if(i<90)return`in ${i}m`;let a=Math.round(i/60);return a<48?`in ${a}h`:`in ${Math.round(a/24)}d`}function B(e,t){let n=i(e,t)?.label;return n&&n!==t?{text:n,raw:t}:{text:t,raw:void 0}}function V(e,r,i){let a=r.indexOf(`:`),o=a>0?r.slice(0,a):``,s=n(o)?o:null,c=s?r.slice(a+1):r,l=[...i?[i]:[],...e.filter(e=>e.id!==i&&(s===null||e.engine===s)).map(e=>e.id)];for(let n of l){let i=t(e,{seatId:n,model:c})?.label;if(i&&i!==r)return{text:i,raw:r}}return{text:r,raw:void 0}}export{h as C,o as S,b as _,A as a,S as b,L as c,O as d,k as f,s as g,x as h,F as i,V as l,a as m,w as n,D as o,z as p,N as r,R as s,M as t,B as u,u as v,c as w,y as x,C as y};
2
+ //# sourceMappingURL=needs-you-model-DL9EEd2L.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"needs-you-model-DL9EEd2L.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/approvals/approvals-model.ts","../../../../../../src/web-ui/routes/verse/shell/needs-you-model.ts"],"sourcesContent":["/**\n * routes/verse/approvals/approvals-model.ts — the pure decisions behind the\n * approvals queue: what order rows come in, and exactly what a human is\n * agreeing to when they press Approve.\n *\n * Kept framework-free and unit-tested because both are easy to get subtly\n * wrong: \"pending first\" must survive a status filter that also returns\n * decided rows, and the approve consequence sentence is the last thing\n * standing between a click and a real pull request against a real remote.\n */\nimport type { Proposal, ProposalKind } from '../../../data/api-types.js';\nimport { ENGINE_LABEL } from '../verse-model.js';\n\n/** Pending first, then newest first within each group. Stable and total. */\nexport function orderProposals(rows: readonly Proposal[]): Proposal[] {\n return [...rows].sort((a, b) => {\n const pendingA = a.status === 'pending' ? 0 : 1;\n const pendingB = b.status === 'pending' ? 0 : 1;\n if (pendingA !== pendingB) return pendingA - pendingB;\n const tsA = Date.parse(a.createdAt);\n const tsB = Date.parse(b.createdAt);\n const safeA = Number.isNaN(tsA) ? 0 : tsA;\n const safeB = Number.isNaN(tsB) ? 0 : tsB;\n if (safeA !== safeB) return safeB - safeA;\n return a.id.localeCompare(b.id);\n });\n}\n\nexport type RiskClass = NonNullable<Proposal['riskClass']>;\n\n/** high → medium → low → unstated. Used for the risk column's sort affordance. */\nexport function riskRank(risk: Proposal['riskClass']): number {\n switch (risk) {\n case 'high':\n return 0;\n case 'medium':\n return 1;\n case 'low':\n return 2;\n default:\n return 3;\n }\n}\n\n/** Client-side narrowing over whatever page the server returned. */\nexport function filterProposals(rows: readonly Proposal[], search: string, repo: string): Proposal[] {\n const s = search.trim().toLowerCase();\n const r = repo.trim().toLowerCase();\n if (!s && !r) return [...rows];\n return rows.filter((p) => {\n if (s && !p.title.toLowerCase().includes(s) && !(p.summary ?? '').toLowerCase().includes(s)) return false;\n if (r && !(p.repo ?? '').toLowerCase().includes(r)) return false;\n return true;\n });\n}\n\n/**\n * What approving this proposal actually does, in one sentence, naming the\n * repo. `pr` is the dangerous one: it pushes a branch to the remote and opens\n * a real pull request, which is visible to other people and cannot be undone\n * from the dialog. The confirm step MUST show this before the click.\n */\nexport function describeApproveConsequence(kind: ProposalKind | string, repo: string | null): string {\n // The project's NAME, not its absolute path: a sandbox checkout under\n // /private/tmp/claude-501/… is unreadable in a sentence. The confirm dialog\n // still prints the full path once, as the exact place the write lands.\n const where = repoName(repo) ?? 'the target repository';\n switch (kind) {\n case 'pr':\n return `Pushes a branch to ${where}'s remote and opens a real pull request. Other people can see it immediately, and this dialog cannot undo it.`;\n case 'patch':\n return `Writes the diff to ${where} on disk now. Nothing is pushed, but the working tree changes.`;\n default:\n return `Applies this ${String(kind)} proposal to ${where} now.`;\n }\n}\n\n/** True when approving reaches a remote — the loudest confirm wording. */\nexport function reachesRemote(kind: ProposalKind | string): boolean {\n return kind === 'pr';\n}\n\n/** The engine that produced the diff, as a short display string. */\nexport function engineOf(proposal: Pick<Proposal, 'engineModel' | 'engineTier'>): string | null {\n if (proposal.engineModel) return proposal.engineModel;\n if (proposal.engineTier) return proposal.engineTier;\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Readable detail\n// ---------------------------------------------------------------------------\n\n/** \"/Users/m/repos/binshield/\" → \"binshield\"; null for no repo. */\nexport function repoName(repo: string | null | undefined): string | null {\n if (typeof repo !== 'string') return null;\n const trimmed = repo.trim().replace(/\\/+$/, '');\n if (trimmed.length === 0) return null;\n const last = trimmed.slice(trimmed.lastIndexOf('/') + 1);\n return last.length > 0 ? last : trimmed;\n}\n\nconst KIND_LABEL: Record<string, string> = {\n patch: 'Patch',\n pr: 'Pull request',\n deploy: 'Deploy',\n note: 'Note',\n 'desktop-action': 'Desktop action',\n 'browser-action': 'Browser action',\n};\n\n/** \"patch\" → \"Patch\", \"pr\" → \"Pull request\"; an unknown kind is shown as sent. */\nexport function kindLabel(kind: ProposalKind | string): string {\n return KIND_LABEL[kind] ?? String(kind);\n}\n\n/**\n * The server builds a run proposal's title as `${engine} run: ${goal.slice(0, 80)}`\n * — cut at 80 characters, mid-word, sometimes mid-quote. This is the one\n * place that cut is made readable.\n */\nexport const RUN_TITLE_GOAL_CAP = 80;\n\nexport interface ReadableTitle {\n /** \"Claude run\" when the title carried an `engine run:` prefix; null otherwise. */\n eyebrow: string | null;\n /** The title to print: never ends mid-word; a cut one ends in \"…\". */\n text: string;\n /** True when the server's title was cut short (the full text we have rides in a tooltip). */\n truncated: boolean;\n}\n\nfunction capitalize(word: string): string {\n return word.length === 0 ? word : word.charAt(0).toUpperCase() + word.slice(1);\n}\n\n/** The app's own display name for an engine (\"Claude\", \"Codex\"); any other engine capitalized (\"Ollama\"). */\nfunction engineDisplayName(engine: string): string {\n const key = engine.toLowerCase();\n return Object.prototype.hasOwnProperty.call(ENGINE_LABEL, key)\n ? ENGINE_LABEL[key as keyof typeof ENGINE_LABEL]\n : capitalize(key);\n}\n\n/** Close a quote the cut left open, so the title does not read as a stray mark. */\nfunction closeQuotes(text: string): string {\n let out = text;\n if ((out.match(/\"/g) ?? []).length % 2 === 1) out += '\"';\n if ((out.match(/\\u201c/g) ?? []).length > (out.match(/\\u201d/g) ?? []).length) out += '\\u201d';\n return out;\n}\n\n/** Drop a trailing partial word and end on \"…\". */\nfunction cutAtWord(text: string): string {\n const body = text.replace(/(?:\\u2026|\\.\\.\\.)$/, '');\n const space = body.lastIndexOf(' ');\n const whole = space > 0 ? body.slice(0, space) : body;\n return `${whole.replace(/[\\s,;:\\-\\u2013\\u2014]+$/, '')}\\u2026`;\n}\n\nexport function readableTitle(title: string): ReadableTitle {\n const raw = typeof title === 'string' ? title.trim() : '';\n // Only the engines the sandboxed runner names — \"Dry run: …\" is a title, not an engine.\n const run = /^(\\[partial\\]\\s*)?(claude|codex|grok|local|ollama|gemini|api[\\w-]*) run:\\s*(.*)$/is.exec(raw);\n // \"Partial Claude run\", never \"Partial claude run\": the engine is a name either way.\n const eyebrow = run ? `${run[1] ? 'Partial ' : ''}${engineDisplayName(run[2]!)} run` : null;\n let text = run ? run[3]! : raw;\n // A title that already ends in an ellipsis right after a letter was cut mid-word upstream.\n const cutMidWord = /[\\p{L}\\p{N}](?:\\u2026|\\.\\.\\.)$/u.test(text);\n // A run goal at exactly the server's cap that does not end on a sentence boundary was sliced.\n const sliced = run !== null && text.length >= RUN_TITLE_GOAL_CAP && !/[.!?)\"'\\u201d\\u2026]$/.test(text);\n const truncated = cutMidWord || sliced;\n if (truncated) text = cutAtWord(text);\n text = closeQuotes(text);\n return { eyebrow, text: text.length > 0 ? text : raw, truncated };\n}\n\n/**\n * What a sandboxed run's summary line says, taken apart. The server writes\n * `[Partial ]<source> <engine:model> run produced N file(s) (+A/-D). <rest>`\n * (core/run/sandboxed-engine.ts); anything else parses to null and is shown\n * verbatim.\n */\nexport interface RunFacts {\n partial: boolean;\n /** The server's source label, verbatim (\"TITRR\", \"Best-of-N winner\"). */\n source: string;\n /** The source in plain words (\"Test-and-repair loop\"). */\n sourceLabel: string;\n /** What the source means, for a tooltip; null when the label says it already. */\n sourceHint: string | null;\n /** \"claude:claude-fable-5\". */\n model: string;\n files: number;\n insertions: number;\n deletions: number;\n /** Whatever the summary says after the run facts (\"Review before applying.\"), or null. */\n rest: string | null;\n}\n\nconst RUN_SUMMARY = /^(Partial )?(.+?) (\\S+) run produced (\\d+) file\\(s\\) \\(\\+(\\d+)\\/-(\\d+)\\)\\.?\\s*([\\s\\S]*)$/;\n\n/**\n * TITRR is internal shorthand (core/run/orchestrator.ts M78: Test → Iterate →\n * Test → Refine → Repeat). The operator sees the plain name; the acronym and\n * what it did ride in the tooltip.\n */\nconst TITRR_HINT =\n 'TITRR — Test, Iterate, Test, Refine, Repeat: after its change the run re-ran the repository\\u2019s tests and repaired the change until they passed or it ran out of attempts.';\n\nfunction describeSource(source: string): { label: string; hint: string | null } {\n if (/\\bTITRR\\b/.test(source)) {\n const rest = source.replace(/\\bTITRR\\b\\s*/, '').trim();\n const qualifier = rest === 'api-model' ? ' (API model)'\n : rest === 'api-model required-diff' ? ' (API model, retried for a missing diff)'\n : rest === 'api-model failed producer' ? ' (API model, producer failed)'\n : rest.length > 0 ? ` (${rest})` : '';\n return { label: `Test-and-repair loop${qualifier}`, hint: TITRR_HINT };\n }\n if (/^best-of-n/i.test(source)) {\n return { label: source, hint: 'Several models attempted this change in parallel; a judge compared them.' };\n }\n if (source === 'api-model') return { label: 'API model run', hint: null };\n if (source === 'Sandboxed') return { label: 'Sandboxed run', hint: 'Produced in an isolated sandbox checkout; nothing touched your working tree.' };\n return { label: source, hint: null };\n}\n\nexport function parseRunSummary(summary: string | null | undefined): RunFacts | null {\n if (typeof summary !== 'string') return null;\n const m = RUN_SUMMARY.exec(summary.trim());\n if (!m) return null;\n const { label, hint } = describeSource(m[2]!);\n const rest = m[7]!.trim();\n return {\n partial: m[1] !== undefined,\n source: m[2]!,\n sourceLabel: label,\n sourceHint: hint,\n model: m[3]!,\n files: Number(m[4]),\n insertions: Number(m[5]),\n deletions: Number(m[6]),\n rest: rest.length > 0 ? rest : null,\n };\n}\n\n/** \"2 files · +384 −0\" (a real minus sign, grouped thousands). */\nexport function formatDiffStats(facts: Pick<RunFacts, 'files' | 'insertions' | 'deletions'>): string {\n const n = (v: number) => v.toLocaleString('en-US');\n return `${n(facts.files)} ${facts.files === 1 ? 'file' : 'files'} \\u00b7 +${n(facts.insertions)} \\u2212${n(facts.deletions)}`;\n}\n\n/** The same stats as a sentence for assistive tech: \"2 files changed, 384 lines added, 0 removed\". */\nexport function describeDiffStats(facts: Pick<RunFacts, 'files' | 'insertions' | 'deletions'>): string {\n const n = (v: number) => v.toLocaleString('en-US');\n return `${n(facts.files)} ${facts.files === 1 ? 'file' : 'files'} changed, ${n(facts.insertions)} ${facts.insertions === 1 ? 'line' : 'lines'} added, ${n(facts.deletions)} removed`;\n}\n\n/**\n * \"just now\", \"5 minutes ago\", \"yesterday\", \"38 days ago\", then \"on Aug 17\"\n * past two months. Written out in full: the detail view has the room, and\n * \"38d\" is a sidebar abbreviation.\n */\nexport function longAgo(iso: string | null | undefined, now: number = Date.now()): string {\n if (typeof iso !== 'string') return 'at an unknown time';\n const then = Date.parse(iso);\n if (!Number.isFinite(then)) return 'at an unknown time';\n const seconds = Math.max(0, Math.round((now - then) / 1000));\n if (seconds < 45) return 'just now';\n const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });\n const minutes = Math.round(seconds / 60);\n if (minutes < 60) return rtf.format(-minutes, 'minute');\n const hours = Math.round(minutes / 60);\n if (hours < 24) return rtf.format(-hours, 'hour');\n const days = Math.round(hours / 24);\n if (days <= 60) return rtf.format(-days, 'day');\n return `on ${new Date(then).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' })}`;\n}\n\n/** A local date and time for a tooltip: \"Mon, Aug 17, 3:12 PM\". */\nexport function localStamp(iso: string | null | undefined): string | undefined {\n if (typeof iso !== 'string') return undefined;\n const t = Date.parse(iso);\n if (!Number.isFinite(t)) return undefined;\n return new Date(t).toLocaleString([], { weekday: 'short', month: 'short', day: 'numeric', year: 'numeric', hour: 'numeric', minute: '2-digit' });\n}\n","/**\n * routes/verse/shell/needs-you-model.ts — the Needs-you drawer as data (unit\n * C1): which items a split shows, how many each split has, whether the drawer\n * may say \"All clear\", and what a key press does to an item.\n *\n * Pure. The items come from GET /api/verse/activity (C1's own producers plus\n * Track B's, R1); each carries its own actions, so nothing here knows what a\n * grant or an owner-lane PR is.\n *\n * How a row READS (needsYouRowView) borrows the approvals detail view's text\n * helpers rather than growing a second copy: an approval item's title and\n * detail are the same proposal title and run summary that view already\n * untangles.\n */\nimport {\n NEEDS_YOU_KIND_CATEGORY,\n type NeedsYouAction,\n type NeedsYouActionKind,\n type NeedsYouItem,\n type NeedsYouSource,\n type VerseActivitySources,\n} from '../../../../core/verse/workbench-types.js';\nimport {\n describeDiffStats,\n formatDiffStats,\n kindLabel,\n localStamp,\n longAgo,\n parseRunSummary,\n readableTitle,\n repoName,\n} from '../approvals/approvals-model.js';\nimport type { VerseSeat } from '../../../data/api-types.js';\nimport { isVerseEngine, modelOptionFor, seatById } from '../verse-model.js';\nimport type { NeedsYouSplit } from '../verse-ui-store.js';\n\nexport const SPLIT_LABEL: Readonly<Record<NeedsYouSplit, string>> = {\n all: 'All',\n approvals: 'Approvals',\n fleet: 'Fleet',\n chats: 'Chats',\n accounts: 'Accounts',\n};\n\n/**\n * Which producers can put an item in each split. \"All clear\" is only\n * claimed for a split whose every producer answered: an owner-lane PR is in\n * Approvals but comes from the FLEET producer, so Approvals is only vouched\n * for when the fleet source answered too.\n */\nexport const SPLIT_SOURCES: Readonly<Record<NeedsYouSplit, readonly NeedsYouSource[]>> = {\n all: ['approvals', 'authority', 'fleet', 'leader', 'chats', 'accounts'],\n approvals: ['approvals', 'fleet', 'leader'],\n fleet: ['authority', 'fleet', 'leader'],\n chats: ['chats'],\n accounts: ['accounts'],\n};\n\nconst SOURCE_NAME: Readonly<Record<NeedsYouSource, string>> = {\n approvals: 'the approvals inbox',\n authority: 'the autonomy grant',\n fleet: 'the fleet',\n leader: 'the Leader',\n chats: 'chats',\n accounts: 'account health',\n};\n\nexport function itemsForSplit(items: readonly NeedsYouItem[], split: NeedsYouSplit): NeedsYouItem[] {\n if (split === 'all') return [...items];\n return items.filter((item) => NEEDS_YOU_KIND_CATEGORY[item.kind] === split);\n}\n\nexport function splitCounts(items: readonly NeedsYouItem[]): Record<NeedsYouSplit, number> {\n const counts: Record<NeedsYouSplit, number> = { all: items.length, approvals: 0, fleet: 0, chats: 0, accounts: 0 };\n for (const item of items) counts[NEEDS_YOU_KIND_CATEGORY[item.kind]] += 1;\n return counts;\n}\n\nexport interface SplitCoverage {\n /** Every producer feeding this split answered. */\n vouched: boolean;\n /** Operator-language names of the ones that did not, with why. */\n silent: Array<{ source: NeedsYouSource; name: string; state: 'unavailable' | 'error' }>;\n}\n\n/** Null sources (activity itself unavailable) vouch for nothing. */\nexport function splitCoverage(sources: VerseActivitySources | null, split: NeedsYouSplit): SplitCoverage {\n const silent: SplitCoverage['silent'] = [];\n for (const source of SPLIT_SOURCES[split]) {\n const state = sources?.[source] ?? 'unavailable';\n if (state !== 'ok') silent.push({ source, name: SOURCE_NAME[source], state });\n }\n return { vouched: silent.length === 0, silent };\n}\n\n/** \"the fleet isn't reporting yet and the Leader failed to answer\" — for the empty state. */\nexport function describeSilence(coverage: SplitCoverage): string {\n const phrases = coverage.silent.map((s) => (s.state === 'error' ? `${s.name} failed to answer` : `${s.name} isn't reporting in this build`));\n if (phrases.length === 0) return '';\n if (phrases.length === 1) return capitalise(phrases[0]!);\n return capitalise(`${phrases.slice(0, -1).join(', ')} and ${phrases[phrases.length - 1]}`);\n}\n\nfunction capitalise(text: string): string {\n return text.charAt(0).toUpperCase() + text.slice(1);\n}\n\n/** Approve / reject / veto ALWAYS confirm (SPEC-310C §1); other kinds only when the item says so. */\nexport const ALWAYS_CONFIRM: ReadonlySet<NeedsYouActionKind> = new Set(['approve', 'reject', 'veto']);\n\nexport function actionOf(item: NeedsYouItem, kind: NeedsYouActionKind): NeedsYouAction | null {\n return item.actions.find((a) => a.kind === kind) ?? null;\n}\n\nconst GENERIC_CONFIRM: Readonly<Record<'approve' | 'reject' | 'veto', { title: string; confirmLabel: string }>> = {\n approve: { title: 'Approve this?', confirmLabel: 'Approve' },\n reject: { title: 'Reject this?', confirmLabel: 'Reject' },\n veto: { title: 'Veto this action?', confirmLabel: 'Veto' },\n};\n\nexport interface ConfirmCopy {\n title: string;\n body: string;\n confirmLabel: string;\n}\n\n/** The dialog for `action` on `item`; null when the action runs without one. */\nexport function confirmCopy(item: NeedsYouItem, action: NeedsYouAction): ConfirmCopy | null {\n if (action.confirm) return action.confirm;\n if (action.kind === 'approve' || action.kind === 'reject' || action.kind === 'veto') {\n const generic = GENERIC_CONFIRM[action.kind];\n return { title: generic.title, body: readableItemTitle(item).text, confirmLabel: generic.confirmLabel };\n }\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// How a row reads\n// ---------------------------------------------------------------------------\n\n/**\n * The approvals producer titles an item `${kind === 'pr' ? 'PR' : kind}: ${proposal.title}`\n * (core/verse/activity.ts approvalItem). Only an `approval` item is taken\n * apart this way — \"Failed: Migrate the store\" is a chat title, not a kind.\n */\nconst APPROVAL_KIND_PREFIX = /^(PR|[a-z][a-z-]*):\\s+([\\s\\S]+)$/;\n\nexport interface ReadableItemTitle {\n /** \"Patch · Claude run\": the proposal kind and the engine the title led with; null when neither. */\n kindLabel: string | null;\n /** The title to print. Never ends mid-word — a cut one ends in \"…\". */\n text: string;\n}\n\nexport function readableItemTitle(item: Pick<NeedsYouItem, 'kind' | 'title'>): ReadableItemTitle {\n let proposalKind: string | null = null;\n let rest = item.title;\n if (item.kind === 'approval') {\n const m = APPROVAL_KIND_PREFIX.exec(item.title.trim());\n if (m) {\n proposalKind = m[1] === 'PR' ? 'pr' : m[1]!;\n rest = m[2]!;\n }\n }\n const title = readableTitle(rest);\n const parts = [proposalKind === null ? null : kindLabel(proposalKind), title.eyebrow].filter((p): p is string => p !== null);\n return { kindLabel: parts.length > 0 ? parts.join(' · ') : null, text: title.text };\n}\n\n/** A sandboxed run's facts, lifted out of the item's detail line. */\nexport interface NeedsYouRunView {\n /** \"2 files · +384 −0\". */\n stats: string;\n /** \"2 files changed, 384 lines added, 0 removed\" — what a screen reader says instead. */\n statsSpoken: string;\n /** \"Test-and-repair loop\", never \"TITRR\". */\n source: string;\n /** What the source means, for a tooltip. */\n sourceHint: string | null;\n partial: boolean;\n /** \"claude:claude-fable-5\". */\n model: string;\n}\n\n/** Everything a Needs-you row prints, in operator language. The raw server text survives only in tooltips. */\nexport interface NeedsYouRowView {\n kindLabel: string | null;\n title: string;\n /** The title exactly as the server sent it — the row's tooltip. */\n fullTitle: string;\n run: NeedsYouRunView | null;\n /** What the detail says beyond the run facts (\"Review before applying.\"), or the detail verbatim; null when nothing. */\n detail: string | null;\n /** \"binshield\", never a path. */\n repo: string | null;\n /** The repo as sent, as a tooltip, when it was more than the name. */\n repoFull: string | undefined;\n /** \"38 days ago\". */\n age: string;\n /** The exact local time, for a tooltip. */\n ageStamp: string | undefined;\n}\n\nexport function needsYouRowView(item: NeedsYouItem, now: number = Date.now()): NeedsYouRowView {\n const title = readableItemTitle(item);\n const facts = parseRunSummary(item.detail);\n const repo = repoName(item.subject.repo);\n return {\n kindLabel: title.kindLabel,\n title: title.text,\n fullTitle: item.title,\n run: facts\n ? {\n stats: formatDiffStats(facts),\n statsSpoken: describeDiffStats(facts),\n source: facts.sourceLabel,\n sourceHint: facts.sourceHint,\n partial: facts.partial,\n model: facts.model,\n }\n : null,\n detail: facts ? facts.rest : item.detail,\n repo,\n repoFull: repo !== null && item.subject.repo !== null && item.subject.repo !== repo ? item.subject.repo : undefined,\n age: longAgo(item.since, now),\n ageStamp: localStamp(item.since),\n };\n}\n\n/** \"closes in 24m\" / \"expired\" — for veto windows and grants. */\nexport function until(iso: string, now: number = Date.now()): string {\n const t = Date.parse(iso);\n if (!Number.isFinite(t)) return '—';\n const s = Math.round((t - now) / 1000);\n if (s <= 0) return 'expired';\n if (s < 90) return `in ${s}s`;\n const m = Math.round(s / 60);\n if (m < 90) return `in ${m}m`;\n const h = Math.round(m / 60);\n if (h < 48) return `in ${h}h`;\n return `in ${Math.round(h / 24)}d`;\n}\n\n// ---------------------------------------------------------------------------\n// Seats and models, by name\n// ---------------------------------------------------------------------------\n\n/** A seat or model as the operator knows it; `raw` is the id as sent, for a tooltip, when the text differs. */\nexport interface DisplayName {\n text: string;\n raw: string | undefined;\n}\n\n/**\n * \"Claude Max\" for `claude-a`: the roster's label (bootstrap seats — the name\n * the seat picker and Apps & Accounts use). An id the roster does not know is\n * shown as sent: it is all there is.\n */\nexport function seatDisplayName(seats: readonly VerseSeat[], seatId: string): DisplayName {\n const label = seatById(seats, seatId)?.label;\n return label && label !== seatId ? { text: label, raw: seatId } : { text: seatId, raw: undefined };\n}\n\n/**\n * \"Fable 5.1\" for a run's `claude:claude-fable-5-1`: the catalog label (the\n * model picker's) on the item's own seat first, then on any seat of the run's\n * engine — exact id, then canonical (verse-model `modelOptionFor`, so a\n * pre-alias `claude-opus-5.5` still finds `claude-opus-5-5`). A model no\n * catalog lists is shown as sent.\n */\nexport function runModelDisplayName(seats: readonly VerseSeat[], model: string, seatId: string | null): DisplayName {\n const colon = model.indexOf(':');\n const prefix = colon > 0 ? model.slice(0, colon) : '';\n const engine = isVerseEngine(prefix) ? prefix : null;\n // `local:qwen3.8:27b` keeps its tag: only a known engine prefix is split off.\n const id = engine ? model.slice(colon + 1) : model;\n const order = [\n ...(seatId ? [seatId] : []),\n ...seats.filter((seat) => seat.id !== seatId && (engine === null || seat.engine === engine)).map((seat) => seat.id),\n ];\n for (const candidate of order) {\n const label = modelOptionFor(seats, { seatId: candidate, model: id })?.label;\n if (label && label !== model) return { text: label, raw: model };\n }\n return { text: model, raw: undefined };\n}\n"],"mappings":"iHA8DA,SAAgB,EAA2B,EAA6B,EAA6B,CAInG,IAAM,EAAQ,EAAS,CAAI,GAAK,wBAChC,OAAQ,EAAR,CACE,IAAK,KACH,MAAO,sBAAsB,EAAM,+GACrC,IAAK,QACH,MAAO,sBAAsB,EAAM,gEACrC,QACE,MAAO,gBAAgB,OAAO,CAAI,EAAE,eAAe,EAAM,MAC7D,CACF,CAGA,SAAgB,EAAc,EAAsC,CAClE,OAAO,IAAS,IAClB,CAGA,SAAgB,EAAS,EAAuE,CAG9F,OAFI,EAAS,YAAoB,EAAS,YACtC,EAAS,WAAmB,EAAS,WAClC,IACT,CAOA,SAAgB,EAAS,EAAgD,CACvE,GAAI,OAAO,GAAS,SAAU,OAAO,KACrC,IAAM,EAAU,EAAK,KAAK,CAAC,CAAC,QAAQ,OAAQ,EAAE,EAC9C,GAAI,EAAQ,SAAW,EAAG,OAAO,KACjC,IAAM,EAAO,EAAQ,MAAM,EAAQ,YAAY,GAAG,EAAI,CAAC,EACvD,OAAO,EAAK,OAAS,EAAI,EAAO,CAClC,CAEA,IAAM,EAAqC,CACzC,MAAO,QACP,GAAI,eACJ,OAAQ,SACR,KAAM,OACN,iBAAkB,iBAClB,iBAAkB,gBACpB,EAGA,SAAgB,EAAU,EAAqC,CAC7D,OAAO,EAAW,IAAS,OAAO,CAAI,CACxC,CAkBA,SAAS,EAAW,EAAsB,CACxC,OAAO,EAAK,SAAW,EAAI,EAAO,EAAK,OAAO,CAAC,CAAC,CAAC,YAAY,EAAI,EAAK,MAAM,CAAC,CAC/E,CAGA,SAAS,EAAkB,EAAwB,CACjD,IAAM,EAAM,EAAO,YAAY,EAC/B,OAAO,OAAO,UAAU,eAAe,KAAK,EAAc,CAAG,EACzD,EAAa,GACb,EAAW,CAAG,CACpB,CAGA,SAAS,EAAY,EAAsB,CACzC,IAAI,EAAM,EAGV,OAFK,EAAI,MAAM,IAAI,GAAK,CAAC,EAAA,CAAG,OAAS,GAAM,IAAG,GAAO,MAChD,EAAI,MAAM,SAAS,GAAK,CAAC,EAAA,CAAG,QAAU,EAAI,MAAM,SAAS,GAAK,CAAC,EAAA,CAAG,SAAQ,GAAO,KAC/E,CACT,CAGA,SAAS,EAAU,EAAsB,CACvC,IAAM,EAAO,EAAK,QAAQ,qBAAsB,EAAE,EAC5C,EAAQ,EAAK,YAAY,GAAG,EAElC,MAAO,IADO,EAAQ,EAAI,EAAK,MAAM,EAAG,CAAK,EAAI,EAAA,CACjC,QAAQ,0BAA2B,EAAE,EAAE,OACzD,CAEA,SAAgB,EAAc,EAA8B,CAC1D,IAAM,EAAM,OAAO,GAAU,SAAW,EAAM,KAAK,EAAI,GAEjD,EAAM,qFAAqF,KAAK,CAAG,EAEnG,EAAU,EAAM,GAAG,EAAI,GAAK,WAAa,KAAK,EAAkB,EAAI,EAAG,EAAE,MAAQ,KACnF,EAAO,EAAM,EAAI,GAAM,EAErB,EAAa,kCAAkC,KAAK,CAAI,EAExD,EAAS,IAAQ,MAAQ,EAAK,QAAA,IAAgC,CAAC,wBAAwB,KAAK,CAAI,EAChG,EAAY,GAAc,EAGhC,OAFI,IAAW,EAAO,EAAU,CAAI,GACpC,EAAO,EAAY,CAAI,EAChB,CAAE,UAAS,KAAM,EAAK,OAAS,EAAI,EAAO,EAAK,WAAU,CAClE,CAyBA,IAAM,EAAc,2FAOd,EACJ,2KAEF,SAAS,EAAe,EAAwD,CAC9E,GAAI,YAAY,KAAK,CAAM,EAAG,CAC5B,IAAM,EAAO,EAAO,QAAQ,eAAgB,EAAE,CAAC,CAAC,KAAK,EAKrD,MAAO,CAAE,MAAO,uBAJE,IAAS,YAAc,eACrC,IAAS,0BAA4B,2CACnC,IAAS,4BAA8B,gCACrC,EAAK,OAAS,EAAI,KAAK,EAAK,GAAK,KACW,KAAM,CAAW,CACvE,CAMA,MALI,cAAc,KAAK,CAAM,EACpB,CAAE,MAAO,EAAQ,KAAM,0EAA2E,EAEvG,IAAW,YAAoB,CAAE,MAAO,gBAAiB,KAAM,IAAK,EACpE,IAAW,YAAoB,CAAE,MAAO,gBAAiB,KAAM,8EAA+E,EAC3I,CAAE,MAAO,EAAQ,KAAM,IAAK,CACrC,CAEA,SAAgB,EAAgB,EAAqD,CACnF,GAAI,OAAO,GAAY,SAAU,OAAO,KACxC,IAAM,EAAI,EAAY,KAAK,EAAQ,KAAK,CAAC,EACzC,GAAI,CAAC,EAAG,OAAO,KACf,GAAM,CAAE,QAAO,QAAS,EAAe,EAAE,EAAG,EACtC,EAAO,EAAE,EAAE,CAAE,KAAK,EACxB,MAAO,CACL,QAAS,EAAE,KAAO,IAAA,GAClB,OAAQ,EAAE,GACV,YAAa,EACb,WAAY,EACZ,MAAO,EAAE,GACT,MAAO,OAAO,EAAE,EAAE,EAClB,WAAY,OAAO,EAAE,EAAE,EACvB,UAAW,OAAO,EAAE,EAAE,EACtB,KAAM,EAAK,OAAS,EAAI,EAAO,IACjC,CACF,CAGA,SAAgB,EAAgB,EAAqE,CACnG,IAAM,EAAK,GAAc,EAAE,eAAe,OAAO,EACjD,MAAO,GAAG,EAAE,EAAM,KAAK,EAAE,GAAG,EAAM,QAAU,EAAI,OAAS,QAAQ,WAAW,EAAE,EAAM,UAAU,EAAE,SAAS,EAAE,EAAM,SAAS,GAC5H,CAGA,SAAgB,EAAkB,EAAqE,CACrG,IAAM,EAAK,GAAc,EAAE,eAAe,OAAO,EACjD,MAAO,GAAG,EAAE,EAAM,KAAK,EAAE,GAAG,EAAM,QAAU,EAAI,OAAS,QAAQ,YAAY,EAAE,EAAM,UAAU,EAAE,GAAG,EAAM,aAAe,EAAI,OAAS,QAAQ,UAAU,EAAE,EAAM,SAAS,EAAE,SAC7K,CAOA,SAAgB,EAAQ,EAAgC,EAAc,KAAK,IAAI,EAAW,CACxF,GAAI,OAAO,GAAQ,SAAU,MAAO,qBACpC,IAAM,EAAO,KAAK,MAAM,CAAG,EAC3B,GAAI,CAAC,OAAO,SAAS,CAAI,EAAG,MAAO,qBACnC,IAAM,EAAU,KAAK,IAAI,EAAG,KAAK,OAAO,EAAM,GAAQ,GAAI,CAAC,EAC3D,GAAI,EAAU,GAAI,MAAO,WACzB,IAAM,EAAM,IAAI,KAAK,mBAAmB,KAAM,CAAE,QAAS,MAAO,CAAC,EAC3D,EAAU,KAAK,MAAM,EAAU,EAAE,EACvC,GAAI,EAAU,GAAI,OAAO,EAAI,OAAO,CAAC,EAAS,QAAQ,EACtD,IAAM,EAAQ,KAAK,MAAM,EAAU,EAAE,EACrC,GAAI,EAAQ,GAAI,OAAO,EAAI,OAAO,CAAC,EAAO,MAAM,EAChD,IAAM,EAAO,KAAK,MAAM,EAAQ,EAAE,EAElC,OADI,GAAQ,GAAW,EAAI,OAAO,CAAC,EAAM,KAAK,EACvC,MAAM,IAAI,KAAK,CAAI,CAAC,CAAC,mBAAmB,QAAS,CAAE,MAAO,QAAS,IAAK,UAAW,KAAM,SAAU,CAAC,GAC7G,CAGA,SAAgB,EAAW,EAAoD,CAC7E,GAAI,OAAO,GAAQ,SAAU,OAC7B,IAAM,EAAI,KAAK,MAAM,CAAG,EACnB,UAAO,SAAS,CAAC,EACtB,OAAO,IAAI,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC,EAAG,CAAE,QAAS,QAAS,MAAO,QAAS,IAAK,UAAW,KAAM,UAAW,KAAM,UAAW,OAAQ,SAAU,CAAC,CACjJ,CCzPA,IAAa,EAAuD,CAClE,IAAK,MACL,UAAW,YACX,MAAO,QACP,MAAO,QACP,SAAU,UACZ,EAQa,EAA4E,CACvF,IAAK,CAAC,YAAa,YAAa,QAAS,SAAU,QAAS,UAAU,EACtE,UAAW,CAAC,YAAa,QAAS,QAAQ,EAC1C,MAAO,CAAC,YAAa,QAAS,QAAQ,EACtC,MAAO,CAAC,OAAO,EACf,SAAU,CAAC,UAAU,CACvB,EAEM,EAAwD,CAC5D,UAAW,sBACX,UAAW,qBACX,MAAO,YACP,OAAQ,aACR,MAAO,QACP,SAAU,gBACZ,EAEA,SAAgB,EAAc,EAAgC,EAAsC,CAElG,OADI,IAAU,MAAc,CAAC,GAAG,CAAK,EAC9B,EAAM,OAAQ,GAAS,EAAwB,EAAK,QAAU,CAAK,CAC5E,CAEA,SAAgB,EAAY,EAA+D,CACzF,IAAM,EAAwC,CAAE,IAAK,EAAM,OAAQ,UAAW,EAAG,MAAO,EAAG,MAAO,EAAG,SAAU,CAAE,EACjH,IAAK,IAAM,KAAQ,EAAO,EAAO,EAAwB,EAAK,QAAU,EACxE,OAAO,CACT,CAUA,SAAgB,EAAc,EAAsC,EAAqC,CACvG,IAAM,EAAkC,CAAC,EACzC,IAAK,IAAM,KAAU,EAAc,GAAQ,CACzC,IAAM,EAAQ,IAAU,IAAW,cAC/B,IAAU,MAAM,EAAO,KAAK,CAAE,SAAQ,KAAM,EAAY,GAAS,OAAM,CAAC,CAC9E,CACA,MAAO,CAAE,QAAS,EAAO,SAAW,EAAG,QAAO,CAChD,CAGA,SAAgB,EAAgB,EAAiC,CAC/D,IAAM,EAAU,EAAS,OAAO,IAAK,GAAO,EAAE,QAAU,QAAU,GAAG,EAAE,KAAK,mBAAqB,GAAG,EAAE,KAAK,+BAAgC,EAG3I,OAFI,EAAQ,SAAW,EAAU,GAC7B,EAAQ,SAAW,EAAU,EAAW,EAAQ,EAAG,EAChD,EAAW,GAAG,EAAQ,MAAM,EAAG,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,OAAO,EAAQ,EAAQ,OAAS,IAAI,CAC3F,CAEA,SAAS,EAAW,EAAsB,CACxC,OAAO,EAAK,OAAO,CAAC,CAAC,CAAC,YAAY,EAAI,EAAK,MAAM,CAAC,CACpD,CAGA,IAAa,EAAkD,IAAI,IAAI,CAAC,UAAW,SAAU,MAAM,CAAC,EAEpG,SAAgB,EAAS,EAAoB,EAAiD,CAC5F,OAAO,EAAK,QAAQ,KAAM,GAAM,EAAE,OAAS,CAAI,GAAK,IACtD,CAEA,IAAM,EAA4G,CAChH,QAAS,CAAE,MAAO,gBAAiB,aAAc,SAAU,EAC3D,OAAQ,CAAE,MAAO,eAAgB,aAAc,QAAS,EACxD,KAAM,CAAE,MAAO,oBAAqB,aAAc,MAAO,CAC3D,EASA,SAAgB,EAAY,EAAoB,EAA4C,CAC1F,GAAI,EAAO,QAAS,OAAO,EAAO,QAClC,GAAI,EAAO,OAAS,WAAa,EAAO,OAAS,UAAY,EAAO,OAAS,OAAQ,CACnF,IAAM,EAAU,EAAgB,EAAO,MACvC,MAAO,CAAE,MAAO,EAAQ,MAAO,KAAM,EAAkB,CAAI,CAAC,CAAC,KAAM,aAAc,EAAQ,YAAa,CACxG,CACA,OAAO,IACT,CAWA,IAAM,EAAuB,mCAS7B,SAAgB,EAAkB,EAA+D,CAC/F,IAAI,EAA8B,KAC9B,EAAO,EAAK,MAChB,GAAI,EAAK,OAAS,WAAY,CAC5B,IAAM,EAAI,EAAqB,KAAK,EAAK,MAAM,KAAK,CAAC,EACjD,IACF,EAAe,EAAE,KAAO,KAAO,KAAO,EAAE,GACxC,EAAO,EAAE,GAEb,CACA,IAAM,EAAQ,EAAc,CAAI,EAC1B,EAAQ,CAAC,IAAiB,KAAO,KAAO,EAAU,CAAY,EAAG,EAAM,OAAO,CAAC,CAAC,OAAQ,GAAmB,IAAM,IAAI,EAC3H,MAAO,CAAE,UAAW,EAAM,OAAS,EAAI,EAAM,KAAK,KAAK,EAAI,KAAM,KAAM,EAAM,IAAK,CACpF,CAoCA,SAAgB,EAAgB,EAAoB,EAAc,KAAK,IAAI,EAAoB,CAC7F,IAAM,EAAQ,EAAkB,CAAI,EAC9B,EAAQ,EAAgB,EAAK,MAAM,EACnC,EAAO,EAAS,EAAK,QAAQ,IAAI,EACvC,MAAO,CACL,UAAW,EAAM,UACjB,MAAO,EAAM,KACb,UAAW,EAAK,MAChB,IAAK,EACD,CACA,MAAO,EAAgB,CAAK,EAC5B,YAAa,EAAkB,CAAK,EACpC,OAAQ,EAAM,YACd,WAAY,EAAM,WAClB,QAAS,EAAM,QACf,MAAO,EAAM,KACf,EACE,KACJ,OAAQ,EAAQ,EAAM,KAAO,EAAK,OAClC,OACA,SAAU,IAAS,MAAQ,EAAK,QAAQ,OAAS,MAAQ,EAAK,QAAQ,OAAS,EAAO,EAAK,QAAQ,KAAO,IAAA,GAC1G,IAAK,EAAQ,EAAK,MAAO,CAAG,EAC5B,SAAU,EAAW,EAAK,KAAK,CACjC,CACF,CAGA,SAAgB,EAAM,EAAa,EAAc,KAAK,IAAI,EAAW,CACnE,IAAM,EAAI,KAAK,MAAM,CAAG,EACxB,GAAI,CAAC,OAAO,SAAS,CAAC,EAAG,MAAO,IAChC,IAAM,EAAI,KAAK,OAAO,EAAI,GAAO,GAAI,EACrC,GAAI,GAAK,EAAG,MAAO,UACnB,GAAI,EAAI,GAAI,MAAO,MAAM,EAAE,GAC3B,IAAM,EAAI,KAAK,MAAM,EAAI,EAAE,EAC3B,GAAI,EAAI,GAAI,MAAO,MAAM,EAAE,GAC3B,IAAM,EAAI,KAAK,MAAM,EAAI,EAAE,EAE3B,OADI,EAAI,GAAW,MAAM,EAAE,GACpB,MAAM,KAAK,MAAM,EAAI,EAAE,EAAE,EAClC,CAiBA,SAAgB,EAAgB,EAA6B,EAA6B,CACxF,IAAM,EAAQ,EAAS,EAAO,CAAM,CAAC,EAAE,MACvC,OAAO,GAAS,IAAU,EAAS,CAAE,KAAM,EAAO,IAAK,CAAO,EAAI,CAAE,KAAM,EAAQ,IAAK,IAAA,EAAU,CACnG,CASA,SAAgB,EAAoB,EAA6B,EAAe,EAAoC,CAClH,IAAM,EAAQ,EAAM,QAAQ,GAAG,EACzB,EAAS,EAAQ,EAAI,EAAM,MAAM,EAAG,CAAK,EAAI,GAC7C,EAAS,EAAc,CAAM,EAAI,EAAS,KAE1C,EAAK,EAAS,EAAM,MAAM,EAAQ,CAAC,EAAI,EACvC,EAAQ,CACZ,GAAI,EAAS,CAAC,CAAM,EAAI,CAAC,EACzB,GAAG,EAAM,OAAQ,GAAS,EAAK,KAAO,IAAW,IAAW,MAAQ,EAAK,SAAW,EAAO,CAAC,CAAC,IAAK,GAAS,EAAK,EAAE,CACpH,EACA,IAAK,IAAM,KAAa,EAAO,CAC7B,IAAM,EAAQ,EAAe,EAAO,CAAE,OAAQ,EAAW,MAAO,CAAG,CAAC,CAAC,EAAE,MACvE,GAAI,GAAS,IAAU,EAAO,MAAO,CAAE,KAAM,EAAO,IAAK,CAAM,CACjE,CACA,MAAO,CAAE,KAAM,EAAO,IAAK,IAAA,EAAU,CACvC"}
@@ -0,0 +1,2 @@
1
+ import{E as e,R as t,Z as n,j as r,rt as i,w as a}from"./VerseConsoleApp-DjPpZLo1.js";import{t as o}from"./open-terminal-request-BT1UE0fz.js";import{a as s}from"./terminal-client-CCSvMeEv.js";var c=`That terminal is closed — its tab is no longer open.`,l=1500;function u(e){let t=!1,n=()=>{t||(t=!0,r(),clearTimeout(a),setTimeout(e,0))},r=i(n),a=setTimeout(n,l)}function d(i,o,s){a();let c=s?{tabId:o,blockId:s}:{tabId:o},l=e();if(i===null||!l.mounted.includes(`chat`)||l.activeSessionId===i){i?r(i):t(`chat`),n(c);return}r(i),u(()=>n(c))}async function f(e,t){let n=o(e);if(!n)return!1;let r=n.sessionId??null,i=null;try{i=await(t.list??(()=>s.list()))()}catch{i=null}if(i){let e=i.tabs.find(e=>e.id===n.tabId);if(!e)return t.toast(i.available?c:i.reason??`The terminal is not available here.`,`neutral`),!1;r=e.sessionId}return d(r,n.tabId,n.blockId),!0}export{f as openTerminalTarget};
2
+ //# sourceMappingURL=open-terminal-BfbxGoYQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open-terminal-BfbxGoYQ.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/shell/open-terminal.ts"],"sourcesContent":["/**\n * routes/verse/shell/open-terminal.ts — open a terminal tab where it lives\n * (3.15): its chat, the Terminal pane, the tab focused and — with a block id —\n * that command block shown. The one handler behind every terminal pointer\n * (shell/open-terminal-request.ts lists them); VerseApp loads it on demand.\n *\n * 1. Ask the server which chat the tab belongs to (GET /api/verse/terminal).\n * A tab that is gone says so (a toast) instead of opening an empty pane.\n * If the server cannot answer, the caller's own sessionId is used.\n * 2. Open that chat (or the Chat surface, for a tab without one).\n * 3. Raise the Terminal pane request `{ tabId, blockId }` — AFTER the chat\n * switch has landed: the chat surface drops pane requests on a switch\n * (ChatSection → clearDockRequests), so a request raised before it would\n * be thrown away with the chat being left.\n */\nimport type { VerseTerminalListResponse } from '../../../data/api-types.js';\nimport { requestTerminal, subscribeDockState } from '../dock/dock-store.js';\nimport { terminalApi } from '../dock/terminal/terminal-client.js';\nimport { closeVerseOverlay, getVerseUiState, openVerseSession, setVerseSection } from '../verse-ui-store.js';\nimport { normalizeOpenTerminalRequest } from './open-terminal-request.js';\n\nexport const TERMINAL_GONE_MESSAGE = 'That terminal is closed — its tab is no longer open.';\n\n/** Longest wait for the chat switch before the request is raised anyway. */\nexport const SWITCH_WAIT_MS = 1500;\n\nexport interface OpenTerminalDeps {\n toast: (message: string, tone?: 'neutral' | 'success' | 'danger') => void;\n /** Test seam: the terminal list read. */\n list?: () => Promise<VerseTerminalListResponse>;\n}\n\n/**\n * Run `fn` once the chat surface has switched chats: the switch's dock update\n * (activateDockChat) is followed, in the same effect, by clearDockRequests —\n * so `fn` runs on the next task, after both. Falls back to a timer so a\n * switch that never reports cannot swallow the request.\n */\nfunction afterChatSwitch(fn: () => void): void {\n let done = false;\n const fire = (): void => {\n if (done) return;\n done = true;\n unsubscribe();\n clearTimeout(timer);\n setTimeout(fn, 0);\n };\n const unsubscribe = subscribeDockState(fire);\n const timer = setTimeout(fire, SWITCH_WAIT_MS);\n}\n\n/** Show the tab: open its chat (or the Chat surface) and request the Terminal pane on it. */\nexport function showTerminalTab(sessionId: string | null, tabId: string, blockId: string | null): void {\n closeVerseOverlay();\n const request = blockId ? { tabId, blockId } : { tabId };\n const ui = getVerseUiState();\n // No switch is coming when there is no chat to open, when the chat surface\n // is not mounted yet (it mounts on the stored selection and keeps pending\n // requests), or when that chat is already the open one.\n if (sessionId === null || !ui.mounted.includes('chat') || ui.activeSessionId === sessionId) {\n if (sessionId) openVerseSession(sessionId);\n else setVerseSection('chat');\n requestTerminal(request);\n return;\n }\n openVerseSession(sessionId);\n afterChatSwitch(() => requestTerminal(request));\n}\n\n/**\n * Open a terminal tab. Resolves true when it was opened, false when the\n * request was malformed or the tab no longer exists (the operator is told).\n * `target` is an OpenTerminalRequest or a raw event detail (VerseApp passes it unread): it is\n * validated here, so the first-paint shell carries no validator.\n */\nexport async function openTerminalTarget(target: unknown, deps: OpenTerminalDeps): Promise<boolean> {\n const clean = normalizeOpenTerminalRequest(target);\n if (!clean) return false;\n let sessionId = clean.sessionId ?? null;\n let listed: VerseTerminalListResponse | null = null;\n try {\n listed = await (deps.list ?? (() => terminalApi.list()))();\n } catch {\n listed = null; // could not check: open where the caller said; the pane reports a missing tab\n }\n if (listed) {\n const tab = listed.tabs.find((t) => t.id === clean.tabId);\n if (!tab) {\n deps.toast(listed.available ? TERMINAL_GONE_MESSAGE : listed.reason ?? 'The terminal is not available here.', 'neutral');\n return false;\n }\n sessionId = tab.sessionId;\n }\n showTerminalTab(sessionId, clean.tabId, clean.blockId);\n return true;\n}\n"],"mappings":"gMAqBA,IAAa,EAAwB,uDAGxB,EAAiB,KAc9B,SAAS,EAAgB,EAAsB,CAC7C,IAAI,EAAO,GACL,MAAmB,CACnB,IACJ,EAAO,GACP,EAAY,EACZ,aAAa,CAAK,EAClB,WAAW,EAAI,CAAC,EAClB,EACM,EAAc,EAAmB,CAAI,EACrC,EAAQ,WAAW,EAAM,CAAc,CAC/C,CAGA,SAAgB,EAAgB,EAA0B,EAAe,EAA8B,CACrG,EAAkB,EAClB,IAAM,EAAU,EAAU,CAAE,QAAO,SAAQ,EAAI,CAAE,OAAM,EACjD,EAAK,EAAgB,EAI3B,GAAI,IAAc,MAAQ,CAAC,EAAG,QAAQ,SAAS,MAAM,GAAK,EAAG,kBAAoB,EAAW,CACtF,EAAW,EAAiB,CAAS,EACpC,EAAgB,MAAM,EAC3B,EAAgB,CAAO,EACvB,MACF,CACA,EAAiB,CAAS,EAC1B,MAAsB,EAAgB,CAAO,CAAC,CAChD,CAQA,eAAsB,EAAmB,EAAiB,EAA0C,CAClG,IAAM,EAAQ,EAA6B,CAAM,EACjD,GAAI,CAAC,EAAO,MAAO,GACnB,IAAI,EAAY,EAAM,WAAa,KAC/B,EAA2C,KAC/C,GAAI,CACF,EAAS,MAAO,EAAK,WAAe,EAAY,KAAK,GAAA,CAAI,CAC3D,MAAQ,CACN,EAAS,IACX,CACA,GAAI,EAAQ,CACV,IAAM,EAAM,EAAO,KAAK,KAAM,GAAM,EAAE,KAAO,EAAM,KAAK,EACxD,GAAI,CAAC,EAEH,OADA,EAAK,MAAM,EAAO,UAAY,EAAwB,EAAO,QAAU,sCAAuC,SAAS,EAChH,GAET,EAAY,EAAI,SAClB,CAEA,OADA,EAAgB,EAAW,EAAM,MAAO,EAAM,OAAO,EAC9C,EACT"}
@@ -0,0 +1,2 @@
1
+ import{o as e}from"./VerseConsoleApp-DjPpZLo1.js";var t=/^t-[a-z0-9]{1,32}$/,n=/^b-\d{1,9}$/,r=/^[\w.-]{1,200}$/;function i(e){if(typeof e!=`object`||!e)return null;let i=e;if(typeof i.tabId!=`string`||!t.test(i.tabId))return null;let a=typeof i.blockId==`string`&&n.test(i.blockId)?i.blockId:null,o=typeof i.sessionId==`string`&&r.test(i.sessionId)?i.sessionId:null;return{tabId:i.tabId,blockId:a,sessionId:o}}function a(t){let n=i(t);n&&typeof window<`u`&&window.dispatchEvent(new CustomEvent(e,{detail:n}))}export{a as n,i as t};
2
+ //# sourceMappingURL=open-terminal-request-BT1UE0fz.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"open-terminal-request-BT1UE0fz.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/shell/open-terminal-request.ts"],"sourcesContent":["/**\n * routes/verse/shell/open-terminal-request.ts — \"open this terminal tab\" as a\n * window event (3.15), so every place that can point at a terminal tab goes\n * through ONE handler:\n *\n * - a desktop notification click (`open-terminal:<tab>[/<block>]`),\n * - a `/verse/?terminal=<tab>&block=<block>` deep link,\n * - a `verse://terminal/<tab>/<block>` link in chat text (MessageMarkdown),\n * - a Needs-you row whose target is a terminal (drawer, Command card).\n *\n * VerseApp listens (it holds the toast) and runs shell/open-terminal.ts, a\n * lazy chunk: this module is on the first-paint path and stays tiny —\n * validation and an event, nothing else.\n */\n\nimport { VERSE_OPEN_TERMINAL_EVENT } from './open-terminal-event.js';\n\nexport { VERSE_OPEN_TERMINAL_EVENT };\n\nconst TAB_RE = /^t-[a-z0-9]{1,32}$/;\nconst BLOCK_RE = /^b-\\d{1,9}$/;\nconst SESSION_RE = /^[\\w.-]{1,200}$/;\n\nexport interface OpenTerminalRequest {\n tabId: string;\n /** A command block of that tab to show. */\n blockId: string | null;\n /**\n * The chat the tab belongs to, when the caller already knows it (a\n * Needs-you item). The handler still asks the server — the tab may have\n * closed, or moved — and uses this only if it cannot.\n */\n sessionId?: string | null;\n}\n\n/** The request, cleaned; null when the tab id is not one (never guessed). */\nexport function normalizeOpenTerminalRequest(value: unknown): OpenTerminalRequest | null {\n if (value === null || typeof value !== 'object') return null;\n const v = value as Record<string, unknown>;\n if (typeof v['tabId'] !== 'string' || !TAB_RE.test(v['tabId'])) return null;\n const blockId = typeof v['blockId'] === 'string' && BLOCK_RE.test(v['blockId']) ? v['blockId'] : null;\n const sessionId = typeof v['sessionId'] === 'string' && SESSION_RE.test(v['sessionId']) ? v['sessionId'] : null;\n return { tabId: v['tabId'], blockId, sessionId };\n}\n\n/** Ask the shell to open a terminal tab (its chat, the Terminal pane, the block). */\nexport function requestOpenTerminal(request: OpenTerminalRequest): void {\n const clean = normalizeOpenTerminalRequest(request);\n if (!clean || typeof window === 'undefined') return;\n window.dispatchEvent(new CustomEvent(VERSE_OPEN_TERMINAL_EVENT, { detail: clean }));\n}\n\n/** The shell's side. Malformed requests are dropped. */\nexport function subscribeOpenTerminal(handler: (request: OpenTerminalRequest) => void): () => void {\n function onRequest(event: Event): void {\n const clean = normalizeOpenTerminalRequest((event as CustomEvent<unknown>).detail);\n if (clean) handler(clean);\n }\n window.addEventListener(VERSE_OPEN_TERMINAL_EVENT, onRequest);\n return () => window.removeEventListener(VERSE_OPEN_TERMINAL_EVENT, onRequest);\n}\n"],"mappings":"kDAmBA,IAAM,EAAS,qBACT,EAAW,cACX,EAAa,kBAenB,SAAgB,EAA6B,EAA4C,CACvF,GAAsB,OAAO,GAAU,WAAnC,EAA6C,OAAO,KACxD,IAAM,EAAI,EACV,GAAI,OAAO,EAAE,OAAa,UAAY,CAAC,EAAO,KAAK,EAAE,KAAQ,EAAG,OAAO,KACvE,IAAM,EAAU,OAAO,EAAE,SAAe,UAAY,EAAS,KAAK,EAAE,OAAU,EAAI,EAAE,QAAa,KAC3F,EAAY,OAAO,EAAE,WAAiB,UAAY,EAAW,KAAK,EAAE,SAAY,EAAI,EAAE,UAAe,KAC3G,MAAO,CAAE,MAAO,EAAE,MAAU,UAAS,WAAU,CACjD,CAGA,SAAgB,EAAoB,EAAoC,CACtE,IAAM,EAAQ,EAA6B,CAAO,EAC7C,GAAS,OAAO,OAAW,KAChC,OAAO,cAAc,IAAI,YAAY,EAA2B,CAAE,OAAQ,CAAM,CAAC,CAAC,CACpF"}
@@ -0,0 +1,2 @@
1
+ import{r as e}from"./rolldown-runtime-hePW80VL.js";import{s as t}from"./index-BC5Uslm5.js";import{C as n,M as r,V as i,a,i as o,t as s,u as c}from"./global-w7KDTTi0.js";import{c as l}from"./format-V6IiIMAL.js";import{n as u,t as d}from"./control-queries-BG53otwz.js";var f=e(t(),1);function p(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function m(e){return typeof e==`string`&&e.trim()!==``?e:null}function h(e){return typeof e==`boolean`?e:null}function g(e){return typeof e!=`number`||!Number.isFinite(e)||e<0?null:Math.floor(e)}function _(e){if(!p(e))return null;let t=m(e.kind);if(t===`until-paused`)return{kind:`until-paused`};if(t===`at-time`){let t=m(e.at);return t===null||Number.isNaN(Date.parse(t))?null:{kind:`at-time`,at:t}}if(t===`after-iterations`){let t=g(e.iterations);return t===null||t<=0?null:{kind:`after-iterations`,iterations:t}}return null}function v(e){if(!Array.isArray(e))return[];let t=[];for(let[n,r]of e.entries()){if(!p(r))continue;let e=m(r.repo);e!==null&&t.push({id:m(r.id)??`${e}:${n}`,repo:e,title:m(r.title)??`untitled change`,at:m(r.at),commit:m(r.commit)})}return t}function y(e){if(!Array.isArray(e))return[];let t=[];for(let[n,r]of e.entries()){if(!p(r))continue;let e=m(r.repo);e!==null&&t.push({id:m(r.id)??`${e}:${n}`,repo:e,title:m(r.title)??`untitled change`,at:m(r.at),reason:m(r.reason)??`no reason recorded`})}return t}function b(e){return p(e)?{tests:h(e.tests),lint:h(e.lint),typecheck:h(e.typecheck),autoMerge:h(e.autoMerge),branch:m(e.branch)}:null}function x(e){if(!p(e))return null;let t=m(e.runId);return t===null?null:{runId:t,startedAt:m(e.startedAt),stopRule:_(e.stopRule),iterationsDone:g(e.iterationsDone),repo:m(e.repo),activity:m(e.activity),merged:v(e.merged),discarded:y(e.discarded)}}function S(e){if(!p(e))return null;let t=h(e.armed);return t===null?null:{armed:t,run:x(e.run),repos:g(e.repos),...e.mirrors===void 0?{}:{mirrors:g(e.mirrors)},gate:b(e.gate)}}function C(e,t=new Date){let n=/^(\d{1,2}):(\d{2})$/.exec(e.trim());if(!n)return null;let r=Number(n[1]),i=Number(n[2]);if(!Number.isInteger(r)||!Number.isInteger(i)||r<0||r>23||i<0||i>59)return null;let a=new Date(t);return a.setHours(r,i,0,0),a.getTime()<=t.getTime()&&a.setDate(a.getDate()+1),a.toISOString()}function w(e){if(!e)return`—`;let t=Date.parse(e);return Number.isNaN(t)?`—`:new Date(t).toLocaleTimeString(void 0,{hour:`2-digit`,minute:`2-digit`})}function T(e,t=new Date){if(!e)return!1;let n=Date.parse(e);return!Number.isNaN(n)&&new Date(n).toDateString()!==t.toDateString()}function E(e,t=new Date){switch(e.kind){case`until-paused`:return`Runs until you pause it — no stop time, no iteration limit.`;case`at-time`:return`Stops at ${w(e.at)}${T(e.at,t)?` tomorrow`:``}.`;case`after-iterations`:return`Stops after ${e.iterations} ${e.iterations===1?`iteration`:`iterations`}.`}}function D(e,t,n=Date.now()){if(e===null)return{headline:`Stop rule not stated`,remaining:`—`,percent:null,reached:!1};if(e.kind===`until-paused`)return{headline:`Runs until you pause it`,remaining:`no stop time, no iteration limit`,percent:null,reached:!1};if(e.kind===`at-time`){let r=Date.parse(e.at);if(Number.isNaN(r))return{headline:`Stop time not readable`,remaining:`—`,percent:null,reached:!1};let i=`Stops at ${w(e.at)}`,a=r-n;if(a<=0)return{headline:i,remaining:`stop time reached`,percent:100,reached:!0};let o=t?.startedAt?Date.parse(t.startedAt):NaN,s=Number.isNaN(o)||r<=o?null:Math.min(100,Math.max(0,Math.round((n-o)/(r-o)*100)));return{headline:i,remaining:`${l(a)} left`,percent:s,reached:!1}}let r=t?.iterationsDone,i=`Stops after ${e.iterations} ${e.iterations===1?`iteration`:`iterations`}`;return typeof r==`number`?{headline:i,remaining:`${r} of ${e.iterations} done`,percent:Math.min(100,Math.round(r/e.iterations*100)),reached:r>=e.iterations}:{headline:i,remaining:`— of ${e.iterations} done`,percent:null,reached:!1}}function O(e,t=Date.now()){if(!e)return`—`;let n=Date.parse(e);return Number.isNaN(n)?`—`:l(Math.max(0,t-n))}function k(e){if(e===null)return[];let t=[];return e.tests===!0&&t.push(`tests`),e.lint===!0&&t.push(`lint`),e.typecheck===!0&&t.push(`typecheck`),t}function A(e){if(e===null)return[`tests`,`lint`,`typecheck`];let t=[];return e.tests===null&&t.push(`tests`),e.lint===null&&t.push(`lint`),e.typecheck===null&&t.push(`typecheck`),t}function j(e){return e.length===0?``:e.length===1?e[0]:`${e.slice(0,-1).join(`, `)} and ${e[e.length-1]}`}var M=`verse-overnight`,N=`/api/verse/overnight`;function P(e){return e instanceof s?e.status===404?`Overnight runs are not available on this server.`:`${N} answered HTTP ${e.status}.`:`${N} could not be reached.`}var F={key:M,fetch:async e=>{try{let t=S(await o(N,e));return t===null?{value:null,available:!0,reason:`Unrecognized response — update Ashlr.`}:{value:t,available:!0,reason:null}}catch(e){if(e instanceof s&&e.status===401||e instanceof DOMException&&e.name===`AbortError`)throw e;return{value:null,available:!1,reason:P(e)}}}};async function I(e,t){let i=n();if(!i)throw new u;let o=await a(e,t,i);return r(),o}function L(){i(M),i(d)}async function R(e){let t=await I(N,{action:`arm`,stopRule:e});return L(),t}async function z(){let e=await I(N,{action:`disarm`});return L(),e}var B=15e3;function V(e,t=B){let n=c(F);(0,f.useEffect)(()=>{if(!e)return;let r=null,i=()=>{r===null&&(r=setInterval(n,t))},a=()=>{r!==null&&(clearInterval(r),r=null)},o=()=>{if(document.visibilityState===`hidden`){a();return}n(),i()};return document.visibilityState!==`hidden`&&i(),document.addEventListener(`visibilitychange`,o),()=>{a(),document.removeEventListener(`visibilitychange`,o)}},[e,t,n])}export{E as a,A as c,D as d,V as i,j as l,z as n,O as o,F as r,k as s,R as t,C as u};
2
+ //# sourceMappingURL=overnight-queries-cjjogTzn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overnight-queries-cjjogTzn.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/autonomy/overnight-model.ts","../../../../../../src/web-ui/routes/verse/autonomy/overnight-queries.ts"],"sourcesContent":["/**\n * routes/verse/autonomy/overnight-model.ts — the pure half of the Overnight\n * panel: narrow the server's body, resolve the operator's stop rule, and\n * derive the one line that says how far the run is from stopping.\n *\n * Framework-free so it unit-tests without a DOM, and separate from the panel\n * because two of these functions are where the panel can most easily start\n * lying:\n *\n * - `projectOvernight` NARROWS, it does not cast. The route is being written\n * by another owner in parallel with this surface, so a field that drifts in\n * name or type has to degrade to `null` — which the panel renders as \"not\n * stated\" — rather than reach a render as `undefined` and crash, or reach\n * it as `0` and read as a fact. Same discipline as `fleet-model.ts`.\n * - `stopProgress` never invents a denominator. \"Until I pause it\" has no\n * progress, and drawing a bar for it would be a picture of a finish line\n * that does not exist.\n */\nimport { formatDuration, UNKNOWN } from './format.js';\nimport type {\n OvernightDiscard,\n OvernightGate,\n OvernightMerge,\n OvernightRun,\n OvernightStatus,\n OvernightStopRule,\n OvernightStopRuleKind,\n} from './overnight-contract.js';\n\n// ---------------------------------------------------------------------------\n// Narrowing\n// ---------------------------------------------------------------------------\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction str(value: unknown): string | null {\n return typeof value === 'string' && value.trim() !== '' ? value : null;\n}\n\nfunction bool(value: unknown): boolean | null {\n return typeof value === 'boolean' ? value : null;\n}\n\n/** A count. Negative and non-finite are not counts, so they are not observed. */\nfunction count(value: unknown): number | null {\n if (typeof value !== 'number' || !Number.isFinite(value) || value < 0) return null;\n return Math.floor(value);\n}\n\nexport function projectStopRule(raw: unknown): OvernightStopRule | null {\n if (!isRecord(raw)) return null;\n const kind = str(raw['kind']);\n if (kind === 'until-paused') return { kind: 'until-paused' };\n if (kind === 'at-time') {\n const at = str(raw['at']);\n // An unparseable instant is worse than no rule: it would render as a\n // countdown to NaN. Refuse it here so the panel can say \"not stated\".\n if (at === null || Number.isNaN(Date.parse(at))) return null;\n return { kind: 'at-time', at };\n }\n if (kind === 'after-iterations') {\n const iterations = count(raw['iterations']);\n if (iterations === null || iterations <= 0) return null;\n return { kind: 'after-iterations', iterations };\n }\n return null;\n}\n\nfunction projectMerges(raw: unknown): OvernightMerge[] {\n if (!Array.isArray(raw)) return [];\n const out: OvernightMerge[] = [];\n for (const [index, item] of raw.entries()) {\n if (!isRecord(item)) continue;\n const repo = str(item['repo']);\n if (repo === null) continue;\n out.push({\n id: str(item['id']) ?? `${repo}:${index}`,\n repo,\n title: str(item['title']) ?? 'untitled change',\n at: str(item['at']),\n commit: str(item['commit']),\n });\n }\n return out;\n}\n\nfunction projectDiscards(raw: unknown): OvernightDiscard[] {\n if (!Array.isArray(raw)) return [];\n const out: OvernightDiscard[] = [];\n for (const [index, item] of raw.entries()) {\n if (!isRecord(item)) continue;\n const repo = str(item['repo']);\n if (repo === null) continue;\n out.push({\n id: str(item['id']) ?? `${repo}:${index}`,\n repo,\n title: str(item['title']) ?? 'untitled change',\n at: str(item['at']),\n // A discard with no stated reason is the one row an operator will ask\n // about in the morning, so it says that it has none rather than being\n // rendered as a blank cell.\n reason: str(item['reason']) ?? 'no reason recorded',\n });\n }\n return out;\n}\n\nfunction projectGate(raw: unknown): OvernightGate | null {\n if (!isRecord(raw)) return null;\n return {\n tests: bool(raw['tests']),\n lint: bool(raw['lint']),\n typecheck: bool(raw['typecheck']),\n autoMerge: bool(raw['autoMerge']),\n branch: str(raw['branch']),\n };\n}\n\nfunction projectRun(raw: unknown): OvernightRun | null {\n if (!isRecord(raw)) return null;\n const runId = str(raw['runId']);\n if (runId === null) return null;\n return {\n runId,\n startedAt: str(raw['startedAt']),\n stopRule: projectStopRule(raw['stopRule']),\n iterationsDone: count(raw['iterationsDone']),\n repo: str(raw['repo']),\n activity: str(raw['activity']),\n merged: projectMerges(raw['merged']),\n discarded: projectDiscards(raw['discarded']),\n };\n}\n\n/**\n * `GET /api/verse/overnight` → a status, or null when the body is not one.\n *\n * `armed` is the single field this refuses to guess: a body that does not say\n * whether a run is armed is not a status, because \"nothing is armed\" is\n * exactly the claim a person checks before closing the laptop.\n */\nexport function projectOvernight(raw: unknown): OvernightStatus | null {\n if (!isRecord(raw)) return null;\n const armed = bool(raw['armed']);\n if (armed === null) return null;\n return {\n armed,\n run: projectRun(raw['run']),\n repos: count(raw['repos']),\n // Present-but-invalid reads as null (\"not recorded\"); absent stays absent,\n // so an older server is not shown as having lost a count it never sent.\n ...(raw['mirrors'] !== undefined ? { mirrors: count(raw['mirrors']) } : {}),\n gate: projectGate(raw['gate']),\n };\n}\n\n// ---------------------------------------------------------------------------\n// The operator's side of the stop rule\n// ---------------------------------------------------------------------------\n\n/** Smallest and largest iteration cap the form will send. */\nexport const ITERATIONS_MIN = 1;\nexport const ITERATIONS_MAX = 500;\n\n/**\n * Turn an `<input type=\"time\">` value (\"23:30\") into the next occurrence of\n * that wall-clock time, as an absolute instant.\n *\n * The whole point of arming this at 11pm is that \"07:00\" means tomorrow\n * morning. Resolving it on the client, in the operator's own zone, is what\n * makes that unambiguous by the time it reaches a server that may not share\n * the zone — and rounds to the minute, so a run armed at 06:59:58 for 07:00\n * does not stop two seconds later.\n */\nexport function resolveStopAt(value: string, now: Date = new Date()): string | null {\n const match = /^(\\d{1,2}):(\\d{2})$/.exec(value.trim());\n if (!match) return null;\n const hours = Number(match[1]);\n const minutes = Number(match[2]);\n if (!Number.isInteger(hours) || !Number.isInteger(minutes)) return null;\n if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59) return null;\n const at = new Date(now);\n at.setHours(hours, minutes, 0, 0);\n if (at.getTime() <= now.getTime()) at.setDate(at.getDate() + 1);\n return at.toISOString();\n}\n\n/** \"07:00\" as the operator's locale writes it — never a raw ISO string. */\nexport function formatStopClock(iso: string | null): string {\n if (!iso) return UNKNOWN;\n const ms = Date.parse(iso);\n if (Number.isNaN(ms)) return UNKNOWN;\n return new Date(ms).toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' });\n}\n\n/** True when the resolved instant is not today — \"07:00 tomorrow\". */\nexport function isNextDay(iso: string | null, now: Date = new Date()): boolean {\n if (!iso) return false;\n const ms = Date.parse(iso);\n if (Number.isNaN(ms)) return false;\n return new Date(ms).toDateString() !== now.toDateString();\n}\n\n/**\n * The sentence the Arm button is committing to, before the click.\n *\n * It restates the rule the operator chose in the operator's own units, so the\n * button is never the only description of what is about to be authorised.\n */\nexport function describeStopRule(rule: OvernightStopRule, now: Date = new Date()): string {\n switch (rule.kind) {\n case 'until-paused':\n return 'Runs until you pause it — no stop time, no iteration limit.';\n case 'at-time':\n return `Stops at ${formatStopClock(rule.at)}${isNextDay(rule.at, now) ? ' tomorrow' : ''}.`;\n case 'after-iterations':\n return `Stops after ${rule.iterations} ${rule.iterations === 1 ? 'iteration' : 'iterations'}.`;\n }\n}\n\n/** The short label each stop rule wears in the armed summary. */\nexport function stopRuleLabel(kind: OvernightStopRuleKind): string {\n switch (kind) {\n case 'until-paused':\n return 'Until paused';\n case 'at-time':\n return 'At a set time';\n case 'after-iterations':\n return 'After N iterations';\n }\n}\n\n// ---------------------------------------------------------------------------\n// How far to the stop condition\n// ---------------------------------------------------------------------------\n\nexport interface StopProgress {\n /** The rule, restated: \"Stops at 07:00\". */\n headline: string;\n /** How much is left: \"4h 12m left\", \"12 of 20 done\". */\n remaining: string;\n /** 0-100 for a meter, or null when there is no honest denominator. */\n percent: number | null;\n /** True once the condition is met and the loop should be winding down. */\n reached: boolean;\n}\n\n/**\n * How far the run is from its stop condition.\n *\n * `percent` is null for \"until I pause it\" on purpose: an open-ended run has\n * no finish line, and a bar with no denominator is the exact kind of confident\n * graphic this cockpit is not allowed to draw.\n */\nexport function stopProgress(\n rule: OvernightStopRule | null,\n run: OvernightRun | null,\n now: number = Date.now(),\n): StopProgress {\n if (rule === null) {\n return {\n headline: 'Stop rule not stated',\n remaining: UNKNOWN,\n percent: null,\n reached: false,\n };\n }\n\n if (rule.kind === 'until-paused') {\n return {\n headline: 'Runs until you pause it',\n remaining: 'no stop time, no iteration limit',\n percent: null,\n reached: false,\n };\n }\n\n if (rule.kind === 'at-time') {\n const at = Date.parse(rule.at);\n if (Number.isNaN(at)) {\n return { headline: 'Stop time not readable', remaining: UNKNOWN, percent: null, reached: false };\n }\n const headline = `Stops at ${formatStopClock(rule.at)}`;\n const left = at - now;\n if (left <= 0) {\n return { headline, remaining: 'stop time reached', percent: 100, reached: true };\n }\n const startedAt = run?.startedAt ? Date.parse(run.startedAt) : Number.NaN;\n // Elapsed over the run's whole window — which needs a start. Without one\n // the countdown is still true, so it is shown; only the bar is withheld.\n const percent =\n Number.isNaN(startedAt) || at <= startedAt\n ? null\n : Math.min(100, Math.max(0, Math.round(((now - startedAt) / (at - startedAt)) * 100)));\n return { headline, remaining: `${formatDuration(left)} left`, percent, reached: false };\n }\n\n const done = run?.iterationsDone;\n const headline = `Stops after ${rule.iterations} ${rule.iterations === 1 ? 'iteration' : 'iterations'}`;\n if (typeof done !== 'number') {\n return {\n headline,\n remaining: `${UNKNOWN} of ${rule.iterations} done`,\n percent: null,\n reached: false,\n };\n }\n return {\n headline,\n remaining: `${done} of ${rule.iterations} done`,\n percent: Math.min(100, Math.round((done / rule.iterations) * 100)),\n reached: done >= rule.iterations,\n };\n}\n\n/** \"3h 04m\" since the run started, or UNKNOWN when it never said. */\nexport function formatRunElapsed(startedAt: string | null | undefined, now: number = Date.now()): string {\n if (!startedAt) return UNKNOWN;\n const ms = Date.parse(startedAt);\n if (Number.isNaN(ms)) return UNKNOWN;\n return formatDuration(Math.max(0, now - ms));\n}\n\n/**\n * The checks named as one phrase: \"tests, lint and typecheck\".\n *\n * Only checks the server said `true` about are named. A `null` check is not\n * named as running AND not named as skipped — `gateCaveat` below says so in\n * words instead, because a gate an operator believes is running when it is not\n * is the single most expensive misreading this panel could cause.\n */\nexport function gateChecks(gate: OvernightGate | null): string[] {\n if (gate === null) return [];\n const named: string[] = [];\n if (gate.tests === true) named.push('tests');\n if (gate.lint === true) named.push('lint');\n if (gate.typecheck === true) named.push('typecheck');\n return named;\n}\n\n/** The checks the server would not commit to, if any. */\nexport function gateUnstated(gate: OvernightGate | null): string[] {\n if (gate === null) return ['tests', 'lint', 'typecheck'];\n const unstated: string[] = [];\n if (gate.tests === null) unstated.push('tests');\n if (gate.lint === null) unstated.push('lint');\n if (gate.typecheck === null) unstated.push('typecheck');\n return unstated;\n}\n\nexport function joinPhrase(parts: readonly string[]): string {\n if (parts.length === 0) return '';\n if (parts.length === 1) return parts[0]!;\n return `${parts.slice(0, -1).join(', ')} and ${parts[parts.length - 1]!}`;\n}\n","/**\n * routes/verse/autonomy/overnight-queries.ts — the one read and the one write\n * behind the Overnight panel: `GET /api/verse/overnight` and\n * `POST /api/verse/overnight`.\n *\n * Same contract as `control-queries.ts` and `fleet-queries.ts` — the read is a\n * QueryDef consumed through `useQuery` (cache-backed, so a poll never blanks a\n * populated panel); the write pulls the held mutation token from auth-store,\n * touches the hold on success, and invalidates exactly the keys it affects.\n * There is no new data layer here on purpose.\n *\n * TWO THINGS THAT ARE DELIBERATE:\n *\n * 1. **The read does not throw on absence.** The route does not exist yet —\n * four owners are building the engine, the permit, the budgets and the\n * local-only policy in parallel. A server without it answers 404, and 404\n * means \"this panel has no source yet\", not \"Autonomy is broken\". It comes\n * back as `OptionalFleetRead` (reused rather than re-declared, because two\n * shapes for \"a read that is allowed to be absent\" would be one too many)\n * and the panel renders a designed not-available state from `reason`.\n * 401 still propagates: an expired read session is an unauthorized state\n * for the whole surface, not a missing panel.\n *\n * 2. **There is no pause route here, and there must not be one.** The halt\n * this panel offers is the DAEMON-SCOPED pause — `~/.ashlr/daemon.paused`,\n * via `runDaemonAction('pause')` in control-queries.ts. Disarming stops\n * arming the next run; pausing stops the loop that is running now, and\n * they are different questions. Neither is `stopDaemon()`, which is\n * `setKill(true)` and therefore the emergency stop wearing a quieter name\n * (see the header of DaemonControls.tsx).\n */\nimport { ApiError, apiGet, apiPost } from '../../../data/client.js';\nimport { getMutationToken, touchMutationHold } from '../../../data/auth-store.js';\nimport { invalidate } from '../../../data/cache.js';\nimport type { QueryDef } from '../../../data/queries.js';\nimport { useRefetch } from '../../../data/hooks.js';\nimport { useEffect } from 'react';\nimport { VERSE_CONTROL_KEY, VerseControlLockedError } from './control-queries.js';\nimport type { OptionalFleetRead } from './fleet-contract.js';\nimport type {\n OvernightAction,\n OvernightActionResult,\n OvernightStatus,\n OvernightStopRule,\n} from './overnight-contract.js';\nimport { projectOvernight } from './overnight-model.js';\n\nexport const VERSE_OVERNIGHT_KEY = 'verse-overnight';\nexport const OVERNIGHT_PATH = '/api/verse/overnight';\n\nfunction describeAbsence(err: unknown): string {\n if (err instanceof ApiError) {\n if (err.status === 404) {\n // A missing route — not a run that refused to start.\n return 'Overnight runs are not available on this server.';\n }\n return `${OVERNIGHT_PATH} answered HTTP ${err.status}.`;\n }\n return `${OVERNIGHT_PATH} could not be reached.`;\n}\n\n/**\n * `GET /api/verse/overnight` — is a run armed, and what has it done.\n *\n * `value` is null both when the route was absent and when it answered\n * something this client could not narrow; `available` and `reason` are what\n * tell those two apart, and the panel words them differently.\n */\nexport const overnightQuery: QueryDef<OptionalFleetRead<OvernightStatus>> = {\n key: VERSE_OVERNIGHT_KEY,\n fetch: async (signal) => {\n try {\n const raw = await apiGet<unknown>(OVERNIGHT_PATH, signal);\n const value = projectOvernight(raw);\n if (value === null) {\n return {\n value: null,\n available: true,\n // Nothing is shown rather than guessed from an unknown shape.\n reason: 'Unrecognized response — update Ashlr.',\n };\n }\n return { value, available: true, reason: null };\n } catch (err) {\n if (err instanceof ApiError && err.status === 401) throw err;\n if (err instanceof DOMException && err.name === 'AbortError') throw err;\n return { value: null, available: false, reason: describeAbsence(err) };\n }\n },\n};\n\n// ---------------------------------------------------------------------------\n// Writes\n// ---------------------------------------------------------------------------\n\nasync function post<T>(path: string, body: unknown): Promise<T> {\n const token = getMutationToken();\n if (!token) throw new VerseControlLockedError();\n const result = await apiPost<T>(path, body, token);\n touchMutationHold();\n return result;\n}\n\nfunction invalidateOvernight(): void {\n invalidate(VERSE_OVERNIGHT_KEY);\n // Arming changes what the daemon will do next, and the control snapshot is\n // what the rest of the cockpit reads that from.\n invalidate(VERSE_CONTROL_KEY);\n}\n\n/** Arm an overnight run with exactly one stop rule. */\nexport async function armOvernight(stopRule: OvernightStopRule): Promise<OvernightActionResult> {\n const body: OvernightAction = { action: 'arm', stopRule };\n const result = await post<OvernightActionResult>(OVERNIGHT_PATH, body);\n invalidateOvernight();\n return result;\n}\n\n/**\n * Disarm: no further overnight run starts.\n *\n * This is NOT the halt. It stops the arrangement, not the loop — a run already\n * in flight keeps going until it is paused. The panel says so at the click.\n */\nexport async function disarmOvernight(): Promise<OvernightActionResult> {\n const body: OvernightAction = { action: 'disarm' };\n const result = await post<OvernightActionResult>(OVERNIGHT_PATH, body);\n invalidateOvernight();\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Polling\n// ---------------------------------------------------------------------------\n\n/**\n * Slower than the fleet's 4s: an overnight run's counters move on the scale of\n * whole iterations, and the thing an operator watches second by second (the\n * elapsed clock and the countdown) is derived locally from `useNow`.\n */\nexport const OVERNIGHT_POLL_MS = 15_000;\n\n/**\n * Keep the overnight status live while a run is armed and the tab is visible.\n *\n * Only while armed: a disarmed panel has one boolean to report and polling it\n * every fifteen seconds forever would be pure waste. Hidden tabs stop the\n * timer and take one immediate reading when they come back, so a panel\n * returned to in the morning is current on the first frame.\n */\nexport function useOvernightPolling(armed: boolean, intervalMs: number = OVERNIGHT_POLL_MS): void {\n const refetch = useRefetch(overnightQuery);\n\n useEffect(() => {\n if (!armed) return;\n let timer: ReturnType<typeof setInterval> | null = null;\n\n const start = (): void => {\n if (timer !== null) return;\n timer = setInterval(refetch, intervalMs);\n };\n const stop = (): void => {\n if (timer === null) return;\n clearInterval(timer);\n timer = null;\n };\n const onVisibility = (): void => {\n if (document.visibilityState === 'hidden') {\n stop();\n return;\n }\n refetch();\n start();\n };\n\n if (document.visibilityState !== 'hidden') start();\n document.addEventListener('visibilitychange', onVisibility);\n return () => {\n stop();\n document.removeEventListener('visibilitychange', onVisibility);\n };\n }, [armed, intervalMs, refetch]);\n}\n"],"mappings":"0RAiCA,SAAS,EAAS,EAAkD,CAClE,OAAO,OAAO,GAAU,YAAY,GAAkB,CAAC,MAAM,QAAQ,CAAK,CAC5E,CAEA,SAAS,EAAI,EAA+B,CAC1C,OAAO,OAAO,GAAU,UAAY,EAAM,KAAK,IAAM,GAAK,EAAQ,IACpE,CAEA,SAAS,EAAK,EAAgC,CAC5C,OAAO,OAAO,GAAU,UAAY,EAAQ,IAC9C,CAGA,SAAS,EAAM,EAA+B,CAE5C,OADI,OAAO,GAAU,UAAY,CAAC,OAAO,SAAS,CAAK,GAAK,EAAQ,EAAU,KACvE,KAAK,MAAM,CAAK,CACzB,CAEA,SAAgB,EAAgB,EAAwC,CACtE,GAAI,CAAC,EAAS,CAAG,EAAG,OAAO,KAC3B,IAAM,EAAO,EAAI,EAAI,IAAO,EAC5B,GAAI,IAAS,eAAgB,MAAO,CAAE,KAAM,cAAe,EAC3D,GAAI,IAAS,UAAW,CACtB,IAAM,EAAK,EAAI,EAAI,EAAK,EAIxB,OADI,IAAO,MAAQ,OAAO,MAAM,KAAK,MAAM,CAAE,CAAC,EAAU,KACjD,CAAE,KAAM,UAAW,IAAG,CAC/B,CACA,GAAI,IAAS,mBAAoB,CAC/B,IAAM,EAAa,EAAM,EAAI,UAAa,EAE1C,OADI,IAAe,MAAQ,GAAc,EAAU,KAC5C,CAAE,KAAM,mBAAoB,YAAW,CAChD,CACA,OAAO,IACT,CAEA,SAAS,EAAc,EAAgC,CACrD,GAAI,CAAC,MAAM,QAAQ,CAAG,EAAG,MAAO,CAAC,EACjC,IAAM,EAAwB,CAAC,EAC/B,IAAK,GAAM,CAAC,EAAO,KAAS,EAAI,QAAQ,EAAG,CACzC,GAAI,CAAC,EAAS,CAAI,EAAG,SACrB,IAAM,EAAO,EAAI,EAAK,IAAO,EACzB,IAAS,MACb,EAAI,KAAK,CACP,GAAI,EAAI,EAAK,EAAK,GAAK,GAAG,EAAK,GAAG,IAClC,OACA,MAAO,EAAI,EAAK,KAAQ,GAAK,kBAC7B,GAAI,EAAI,EAAK,EAAK,EAClB,OAAQ,EAAI,EAAK,MAAS,CAC5B,CAAC,CACH,CACA,OAAO,CACT,CAEA,SAAS,EAAgB,EAAkC,CACzD,GAAI,CAAC,MAAM,QAAQ,CAAG,EAAG,MAAO,CAAC,EACjC,IAAM,EAA0B,CAAC,EACjC,IAAK,GAAM,CAAC,EAAO,KAAS,EAAI,QAAQ,EAAG,CACzC,GAAI,CAAC,EAAS,CAAI,EAAG,SACrB,IAAM,EAAO,EAAI,EAAK,IAAO,EACzB,IAAS,MACb,EAAI,KAAK,CACP,GAAI,EAAI,EAAK,EAAK,GAAK,GAAG,EAAK,GAAG,IAClC,OACA,MAAO,EAAI,EAAK,KAAQ,GAAK,kBAC7B,GAAI,EAAI,EAAK,EAAK,EAIlB,OAAQ,EAAI,EAAK,MAAS,GAAK,oBACjC,CAAC,CACH,CACA,OAAO,CACT,CAEA,SAAS,EAAY,EAAoC,CAEvD,OADK,EAAS,CAAG,EACV,CACL,MAAO,EAAK,EAAI,KAAQ,EACxB,KAAM,EAAK,EAAI,IAAO,EACtB,UAAW,EAAK,EAAI,SAAY,EAChC,UAAW,EAAK,EAAI,SAAY,EAChC,OAAQ,EAAI,EAAI,MAAS,CAC3B,EAP2B,IAQ7B,CAEA,SAAS,EAAW,EAAmC,CACrD,GAAI,CAAC,EAAS,CAAG,EAAG,OAAO,KAC3B,IAAM,EAAQ,EAAI,EAAI,KAAQ,EAE9B,OADI,IAAU,KAAa,KACpB,CACL,QACA,UAAW,EAAI,EAAI,SAAY,EAC/B,SAAU,EAAgB,EAAI,QAAW,EACzC,eAAgB,EAAM,EAAI,cAAiB,EAC3C,KAAM,EAAI,EAAI,IAAO,EACrB,SAAU,EAAI,EAAI,QAAW,EAC7B,OAAQ,EAAc,EAAI,MAAS,EACnC,UAAW,EAAgB,EAAI,SAAY,CAC7C,CACF,CASA,SAAgB,EAAiB,EAAsC,CACrE,GAAI,CAAC,EAAS,CAAG,EAAG,OAAO,KAC3B,IAAM,EAAQ,EAAK,EAAI,KAAQ,EAE/B,OADI,IAAU,KAAa,KACpB,CACL,QACA,IAAK,EAAW,EAAI,GAAM,EAC1B,MAAO,EAAM,EAAI,KAAQ,EAGzB,GAAI,EAAI,UAAe,IAAA,GAAiD,CAAC,EAAtC,CAAE,QAAS,EAAM,EAAI,OAAU,CAAE,EACpE,KAAM,EAAY,EAAI,IAAO,CAC/B,CACF,CAoBA,SAAgB,EAAc,EAAe,EAAY,IAAI,KAAuB,CAClF,IAAM,EAAQ,sBAAsB,KAAK,EAAM,KAAK,CAAC,EACrD,GAAI,CAAC,EAAO,OAAO,KACnB,IAAM,EAAQ,OAAO,EAAM,EAAE,EACvB,EAAU,OAAO,EAAM,EAAE,EAE/B,GADI,CAAC,OAAO,UAAU,CAAK,GAAK,CAAC,OAAO,UAAU,CAAO,GACrD,EAAQ,GAAK,EAAQ,IAAM,EAAU,GAAK,EAAU,GAAI,OAAO,KACnE,IAAM,EAAK,IAAI,KAAK,CAAG,EAGvB,OAFA,EAAG,SAAS,EAAO,EAAS,EAAG,CAAC,EAC5B,EAAG,QAAQ,GAAK,EAAI,QAAQ,GAAG,EAAG,QAAQ,EAAG,QAAQ,EAAI,CAAC,EACvD,EAAG,YAAY,CACxB,CAGA,SAAgB,EAAgB,EAA4B,CAC1D,GAAI,CAAC,EAAK,MAAA,IACV,IAAM,EAAK,KAAK,MAAM,CAAG,EAEzB,OADI,OAAO,MAAM,CAAE,EAAG,IACf,IAAI,KAAK,CAAE,CAAC,CAAC,mBAAmB,IAAA,GAAW,CAAE,KAAM,UAAW,OAAQ,SAAU,CAAC,CAC1F,CAGA,SAAgB,EAAU,EAAoB,EAAY,IAAI,KAAiB,CAC7E,GAAI,CAAC,EAAK,MAAO,GACjB,IAAM,EAAK,KAAK,MAAM,CAAG,EAEzB,MADA,CAAI,OAAO,MAAM,CAAE,GACZ,IAAI,KAAK,CAAE,CAAC,CAAC,aAAa,IAAM,EAAI,aAAa,CAC1D,CAQA,SAAgB,EAAiB,EAAyB,EAAY,IAAI,KAAgB,CACxF,OAAQ,EAAK,KAAb,CACE,IAAK,eACH,MAAO,8DACT,IAAK,UACH,MAAO,YAAY,EAAgB,EAAK,EAAE,IAAI,EAAU,EAAK,GAAI,CAAG,EAAI,YAAc,GAAG,GAC3F,IAAK,mBACH,MAAO,eAAe,EAAK,WAAW,GAAG,EAAK,aAAe,EAAI,YAAc,aAAa,EAChG,CACF,CAoCA,SAAgB,EACd,EACA,EACA,EAAc,KAAK,IAAI,EACT,CACd,GAAI,IAAS,KACX,MAAO,CACL,SAAU,uBACV,UAAA,IACA,QAAS,KACT,QAAS,EACX,EAGF,GAAI,EAAK,OAAS,eAChB,MAAO,CACL,SAAU,0BACV,UAAW,mCACX,QAAS,KACT,QAAS,EACX,EAGF,GAAI,EAAK,OAAS,UAAW,CAC3B,IAAM,EAAK,KAAK,MAAM,EAAK,EAAE,EAC7B,GAAI,OAAO,MAAM,CAAE,EACjB,MAAO,CAAE,SAAU,yBAA0B,UAAA,IAAoB,QAAS,KAAM,QAAS,EAAM,EAEjG,IAAM,EAAW,YAAY,EAAgB,EAAK,EAAE,IAC9C,EAAO,EAAK,EAClB,GAAI,GAAQ,EACV,MAAO,CAAE,WAAU,UAAW,oBAAqB,QAAS,IAAK,QAAS,EAAK,EAEjF,IAAM,EAAY,GAAK,UAAY,KAAK,MAAM,EAAI,SAAS,EAAI,IAGzD,EACJ,OAAO,MAAM,CAAS,GAAK,GAAM,EAC7B,KACA,KAAK,IAAI,IAAK,KAAK,IAAI,EAAG,KAAK,OAAQ,EAAM,IAAc,EAAK,GAAc,GAAG,CAAC,CAAC,EACzF,MAAO,CAAE,WAAU,UAAW,GAAG,EAAe,CAAI,EAAE,OAAQ,UAAS,QAAS,EAAM,CACxF,CAEA,IAAM,EAAO,GAAK,eACZ,EAAW,eAAe,EAAK,WAAW,GAAG,EAAK,aAAe,EAAI,YAAc,eASzF,OARI,OAAO,GAAS,SAQb,CACL,WACA,UAAW,GAAG,EAAK,MAAM,EAAK,WAAW,OACzC,QAAS,KAAK,IAAI,IAAK,KAAK,MAAO,EAAO,EAAK,WAAc,GAAG,CAAC,EACjE,QAAS,GAAQ,EAAK,UACxB,EAZS,CACL,WACA,UAAW,QAAiB,EAAK,WAAW,OAC5C,QAAS,KACT,QAAS,EACX,CAQJ,CAGA,SAAgB,EAAiB,EAAsC,EAAc,KAAK,IAAI,EAAW,CACvG,GAAI,CAAC,EAAW,MAAA,IAChB,IAAM,EAAK,KAAK,MAAM,CAAS,EAE/B,OADI,OAAO,MAAM,CAAE,EAAG,IACf,EAAe,KAAK,IAAI,EAAG,EAAM,CAAE,CAAC,CAC7C,CAUA,SAAgB,EAAW,EAAsC,CAC/D,GAAI,IAAS,KAAM,MAAO,CAAC,EAC3B,IAAM,EAAkB,CAAC,EAIzB,OAHI,EAAK,QAAU,IAAM,EAAM,KAAK,OAAO,EACvC,EAAK,OAAS,IAAM,EAAM,KAAK,MAAM,EACrC,EAAK,YAAc,IAAM,EAAM,KAAK,WAAW,EAC5C,CACT,CAGA,SAAgB,EAAa,EAAsC,CACjE,GAAI,IAAS,KAAM,MAAO,CAAC,QAAS,OAAQ,WAAW,EACvD,IAAM,EAAqB,CAAC,EAI5B,OAHI,EAAK,QAAU,MAAM,EAAS,KAAK,OAAO,EAC1C,EAAK,OAAS,MAAM,EAAS,KAAK,MAAM,EACxC,EAAK,YAAc,MAAM,EAAS,KAAK,WAAW,EAC/C,CACT,CAEA,SAAgB,EAAW,EAAkC,CAG3D,OAFI,EAAM,SAAW,EAAU,GAC3B,EAAM,SAAW,EAAU,EAAM,GAC9B,GAAG,EAAM,MAAM,EAAG,EAAE,CAAC,CAAC,KAAK,IAAI,EAAE,OAAO,EAAM,EAAM,OAAS,IACtE,CCrTA,IAAa,EAAsB,kBACtB,EAAiB,uBAE9B,SAAS,EAAgB,EAAsB,CAQ7C,OAPI,aAAe,EACb,EAAI,SAAW,IAEV,mDAEF,GAAG,EAAe,iBAAiB,EAAI,OAAO,GAEhD,GAAG,EAAe,uBAC3B,CASA,IAAa,EAA+D,CAC1E,IAAK,EACL,MAAO,KAAO,IAAW,CACvB,GAAI,CAEF,IAAM,EAAQ,EAAiB,MADb,EAAgB,EAAgB,CAAM,CACtB,EASlC,OARI,IAAU,KACL,CACL,MAAO,KACP,UAAW,GAEX,OAAQ,uCACV,EAEK,CAAE,QAAO,UAAW,GAAM,OAAQ,IAAK,CAChD,OAAS,EAAK,CAEZ,GADI,aAAe,GAAY,EAAI,SAAW,KAC1C,aAAe,cAAgB,EAAI,OAAS,aAAc,MAAM,EACpE,MAAO,CAAE,MAAO,KAAM,UAAW,GAAO,OAAQ,EAAgB,CAAG,CAAE,CACvE,CACF,CACF,EAMA,eAAe,EAAQ,EAAc,EAA2B,CAC9D,IAAM,EAAQ,EAAiB,EAC/B,GAAI,CAAC,EAAO,MAAM,IAAI,EACtB,IAAM,EAAS,MAAM,EAAW,EAAM,EAAM,CAAK,EAEjD,OADA,EAAkB,EACX,CACT,CAEA,SAAS,GAA4B,CACnC,EAAW,CAAmB,EAG9B,EAAW,CAAiB,CAC9B,CAGA,eAAsB,EAAa,EAA6D,CAE9F,IAAM,EAAS,MAAM,EAA4B,EAAgB,CADjC,OAAQ,MAAO,UACkB,CAAI,EAErE,OADA,EAAoB,EACb,CACT,CAQA,eAAsB,GAAkD,CAEtE,IAAM,EAAS,MAAM,EAA4B,EAAgB,CADjC,OAAQ,QACyB,CAAI,EAErE,OADA,EAAoB,EACb,CACT,CAWA,IAAa,EAAoB,KAUjC,SAAgB,EAAoB,EAAgB,EAAqB,EAAyB,CAChG,IAAM,EAAU,EAAW,CAAc,GAEzC,EAAA,EAAA,UAAA,KAAgB,CACd,GAAI,CAAC,EAAO,OACZ,IAAI,EAA+C,KAE7C,MAAoB,CACpB,IAAU,OACd,EAAQ,YAAY,EAAS,CAAU,EACzC,EACM,MAAmB,CACnB,IAAU,OACd,cAAc,CAAK,EACnB,EAAQ,KACV,EACM,MAA2B,CAC/B,GAAI,SAAS,kBAAoB,SAAU,CACzC,EAAK,EACL,MACF,CACA,EAAQ,EACR,EAAM,CACR,EAIA,OAFI,SAAS,kBAAoB,UAAU,EAAM,EACjD,SAAS,iBAAiB,mBAAoB,CAAY,MAC7C,CACX,EAAK,EACL,SAAS,oBAAoB,mBAAoB,CAAY,CAC/D,CACF,EAAG,CAAC,EAAO,EAAY,CAAO,CAAC,CACjC"}
@@ -0,0 +1,2 @@
1
+ import{A as e}from"./VerseConsoleApp-DjPpZLo1.js";var t=`ashlr:palette-query`,n=200,r=null;function i(i){let a=i.trim().replace(/[.!?]+$/,``).slice(0,n);if(a){r=a,e(`palette`);try{window.dispatchEvent(new CustomEvent(t,{detail:a}))}catch{}}}function a(){let e=r;return r=null,e}export{i as n,a as r,t};
2
+ //# sourceMappingURL=palette-handoff-XL2WWc9I.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"palette-handoff-XL2WWc9I.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/voice/palette-handoff.ts"],"sourcesContent":["/**\n * routes/verse/voice/palette-handoff.ts — voice command mode (⌃⌥⇧V): the\n * dictated words become the ⌘K query, so the existing palette model (fuzzy\n * match over the command catalog, chats, seats, projects) picks the command\n * and the operator confirms with ↩. Nothing runs by voice alone.\n *\n * Tiny on purpose: CommandPalette imports it, and it must not pull the voice\n * UI into the palette chunk.\n */\nimport { openVerseOverlay } from '../verse-ui-store.js';\n\nexport const PALETTE_QUERY_EVENT = 'ashlr:palette-query';\nconst QUERY_MAX = 200;\n\nlet pending: string | null = null;\n\n/** Open ⌘K with `text` as its query (or replace the query if it is open). */\nexport function handOffToPalette(text: string): void {\n const query = text.trim().replace(/[.!?]+$/, '').slice(0, QUERY_MAX);\n if (!query) return;\n pending = query;\n openVerseOverlay('palette');\n try {\n window.dispatchEvent(new CustomEvent(PALETTE_QUERY_EVENT, { detail: query }));\n } catch {\n /* no window */\n }\n}\n\n/** The palette's initial query, once. */\nexport function takePaletteQuery(): string | null {\n const query = pending;\n pending = null;\n return query;\n}\n"],"mappings":"kDAWA,IAAa,EAAsB,sBAC7B,EAAY,IAEd,EAAyB,KAG7B,SAAgB,EAAiB,EAAoB,CACnD,IAAM,EAAQ,EAAK,KAAK,CAAC,CAAC,QAAQ,UAAW,EAAE,CAAC,CAAC,MAAM,EAAG,CAAS,EAC9D,KAEL,CADA,EAAU,EACV,EAAiB,SAAS,EAC1B,GAAI,CACF,OAAO,cAAc,IAAI,YAAY,EAAqB,CAAE,OAAQ,CAAM,CAAC,CAAC,CAC9E,MAAQ,CAER,CAL0B,CAM5B,CAGA,SAAgB,GAAkC,CAChD,IAAM,EAAQ,EAEd,MADA,GAAU,KACH,CACT"}
@@ -0,0 +1,3 @@
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/ChecksPanel-D9r8koxq.js","assets/MutationTokenDialog-DlY2VLVh.js","assets/Dialog-DDHg9cuT.js","assets/focus-trap-BZeH0rVB.js","assets/use-token-gate-h5QAERLT.js","assets/format-V6IiIMAL.js","assets/format-D7nBg2bn.js","assets/verse-model-DAOz9LrY.js","assets/compaction-point-VL9oegWS.js","assets/seat-readiness-a5B9iqP-.js","assets/Switch-Cqc_bSoh.js","assets/global-1SED_aTT.css","assets/Dialog-tQ8kFulD.css","assets/MutationTokenDialog-CrfJ0PdD.css","assets/Button-DrnKsvnQ.css","assets/Switch-CU044EaE.css","assets/ChecksPanel-B6Ys0BH2.css","assets/dock-panes-DvQ6t4Nl.js","assets/tool-semantics-xF0Fw2Ck.js","assets/line-diff-B5Eonif2.js","assets/sources-queries-Cjk1rpDU.js","assets/diff-parser-BnW_HiQm.js","assets/verse-transcript-Dc-bk9l2.js","assets/verse-store-DAqqNIyD.js","assets/transient-events-nTLhMBND.js","assets/useVerseTranscript-BN_fMz6x.js","assets/useVerseSession-BOsgJzT5.js","assets/use-chat-activity-_tBmEPPN.js","assets/SourcesPanel-DlttePk7.js","assets/path-display-ZSzKoo8T.js","assets/ThinkingBlock-DZNlOGaV.js","assets/ChatSection-CXJa8QOi.js","assets/preloaded-6hKNGuRp.js","assets/EmptyState-B3YUPGaa.css","assets/ThinkingBlock-C1hAYcr3.css","assets/SourcesPanel-0z9q5i9l.css","assets/RouteErrorBoundary-DdxhTdZ6.css","assets/SkipToContent-c02H5dmz.css","assets/VerseConsoleApp-BmckthwC.css","assets/ChatSection-77pZka90.css","assets/TerminalPane-XZ5n3Pns.js","assets/ActionMenu-Z14OhnFI.js","assets/icons-C3G-y5j2.js","assets/verse-icons-vSkflmRB.js","assets/composer-queries-D1H4E0Ye.js","assets/ansi-B9NbRwnU.js","assets/agent-tools-client-DmJq7zlr.js","assets/chat-pane-data-CfbpeAYX.js","assets/multimodel-flows-DOHsEKUG.js","assets/context-queries-bnI3P0Wt.js","assets/composer-state-DTAoie2b.js","assets/multimodel-queries-xmBBUT6n.js","assets/ask-seat-O60AydbV.js","assets/terminal-icons-Dx6neM-J.js","assets/terminal-client-CCSvMeEv.js","assets/terminal-view-BSieiQvi.js","assets/useAutoSeat-Dpbn0XUv.js","assets/budget-queries-Nvx0H2XE.js","assets/policy-DS7wupkn.js","assets/headroom-CduXLVmZ.js","assets/CommandPalette.module-DqfCnLbZ.js","assets/ActionMenu-DPjsLU1g.css","assets/CommandPalette-C37YxUrr.css","assets/TerminalPane-CiO79zlq.css","assets/BrowserPanel-CECVGJBS.js","assets/Segmented-BA8RmKYq.js","assets/Segmented-BnjHbKzH.css","assets/BrowserPanel-CQO8rUsR.css","assets/ChangesPaneHost-Bnj_NcRa.js","assets/highlight-BCNIvJ85.js","assets/git-model-C1I4z_iQ.js","assets/GitDialogs-ekwzxl76.js","assets/checkpoint-queries-BKD2evmX.js","assets/DiffPane.module-CTk5rZn3.js","assets/pane-chrome.module-D7o-fVd0.js","assets/GitDialogs-ChreZUPG.css","assets/DiffPane-BAvvbBsf.css","assets/pane-chrome-8JmEhHVD.css","assets/ChangesPaneHost-IBUW2bXU.css","assets/ChatPanes-x_ySUIyR.js","assets/ProviderLogo-g2YWCmNY.js","assets/context-model-CKXUZd0O.js","assets/context-model-DYkDKK6C.js","assets/workspace-model-C-q_I8xN.js","assets/LiveTimer-B8t2iX5h.js","assets/command-catalog-B0ApAGD0.js","assets/tasks-model-Larlwtqy.js","assets/sidebar-model-COzIPSiP.js","assets/context.module-BijAfoJw.js","assets/LiveTimer-1w9hA2-h.css","assets/context-DiToyj6s.css","assets/ChatPanes-DtD218pR.css","assets/FilesPane-CoNjfkPP.js","assets/stub-panes.module-blrN0yxn.js","assets/stub-panes-ZSndIabX.css","assets/SourcesPane-QffcyDfA.js","assets/ReasoningPane-BARDPl4-.js"])))=>i.map(i=>d[i]);
2
+ import{n as e,r as t}from"./rolldown-runtime-hePW80VL.js";import{n,s as r,t as i}from"./index-BC5Uslm5.js";import{Bt as a,E as o,Ht as s,It as c,Kt as l,Lt as ee,Nt as u,Ot as d,Pt as te,R as ne,Z as re,dt as f,m as p,ut as m}from"./VerseConsoleApp-DjPpZLo1.js";import{a as h,f as g,g as _,h as ie,p as v,r as ae,u as oe,v as se,y}from"./dock-icons-DK7QcBXJ.js";import{a as ce,n as b,o as le,r as ue}from"./slots-DWlj_c7i.js";var x=t(r(),1);function de(){let e=u.composer,t=new Map;for(let[n,r]of Object.entries(d))if(e.includes(r.scope))for(let e of r.keys)t.set(c(e),n);return t}var fe=new Set(te.map(c));function S(e,t,n=I()){let r;try{r=l(e.trim().toLowerCase())}catch{return`"${e}" is not a chord`}let i=e.toLowerCase().split(`+`).slice(0,-1);if(!r.key||i.some(e=>![`mod`,`ctrl`,`shift`,`alt`].includes(e)))return`"${e}" is not a chord`;if(!r.mod&&!r.ctrl)return`"${e}" needs mod or ctrl — a bare key would eat typing`;let a=c(r);if(fe.has(a))return`"${e}" belongs to the system`;let o=de().get(a);if(o)return`"${e}" is already ${o}`;for(let r of n){if(r.id===t)continue;if(r.shortcut&&c(r.shortcut)===a)return`"${e}" is already the ${r.title} pane's`;let n=r.command?d[r.command]?.keys[0]:void 0;if(n&&c(n)===a)return`"${e}" is already the ${r.title} pane's`}return null}function C(e){let t=[];if(typeof e!=`object`||!e)return[`a pane definition must be an object`];(typeof e.id!=`string`||!f.test(e.id))&&t.push(`id "${String(e.id)}" must be lower-case letters, numbers and dashes`),(typeof e.title!=`string`||e.title.trim()===``)&&t.push(`title is required`);let n=e=>typeof e==`function`||typeof e==`object`&&!!e;return n(e.component)||t.push(`component must be a React component (lazy() is fine)`),n(e.icon)||t.push(`icon must be a React component`),e.command!==void 0&&!d[e.command]&&t.push(`command "${e.command}" has no key in shell/command-keys.ts`),t}var w=new Map,T=[],E=new Map,D=[],O=new Set,k=new Set;function A(e){k.has(e)||(k.add(e),typeof console<`u`&&console.warn(`[verse panes] ${e}`))}var j=e=>e.trim().toLowerCase();function pe(e,t){let n=null;for(let{def:r}of e){let e=r.command??n?.command??null,i=n?.shortcut??null;if(r.shortcut!==void 0){let n=e?d[e]?.keys[0]:void 0;if(n&&c(l(j(r.shortcut)))===c(n))i=null;else if(e)A(`pane "${r.id}": shortcut "${r.shortcut}" ignored — it opens with ${e}'s key`),i=null;else{let e=S(r.shortcut,r.id,t);e&&A(`pane "${r.id}": shortcut refused — ${e}`),i=e?null:l(j(r.shortcut))}}n=Object.freeze({id:r.id,title:r.title.trim(),icon:r.icon,component:r.component,command:e,shortcut:i,when:r.when??null,needsSession:r.needsSession??n?.needsSession??!0,order:r.order??n?.order??100,description:r.description??n?.description??null,toggle:r.toggle??n?.toggle??!1})}return n}function M(){let e=new Map;for(let t of T){let n=w.get(t);n&&n.length>0&&e.set(t,pe(n,e.values()))}E=e,D=Object.freeze([...e.values()].sort((e,t)=>e.order-t.order||T.indexOf(e.id)-T.indexOf(t.id)));for(let e of[...O])e()}function N(e,t){let n=C(e);if(n.length>0)return A(`pane "${String(e?.id)}" not registered: ${n.join(`; `)}`),()=>void 0;let r={def:e,builtin:t},i=w.get(e.id)??[];if(t){let e=i.findIndex(e=>!e.builtin);i.splice(e===-1?i.length:e,0,r)}else i.push(r);return w.set(e.id,i),T.includes(e.id)||T.push(e.id),M(),()=>{let t=w.get(e.id),n=t?.indexOf(r)??-1;t&&n!==-1&&(t.splice(n,1),t.length===0&&w.delete(e.id),M())}}function P(e){return N(e,!1)}function F(e){return N(e,!0)}function I(){return D}function L(e){return E.get(e)??null}function R(e,t){if(!e.when)return!0;try{return e.when(t)===!0}catch(t){return A(`pane "${e.id}": when() threw — ${t?.message??String(t)}`),!1}}function z(e){return D.filter(t=>R(t,e))}function B(e,t){let n=L(e);return n!==null&&R(n,t)}function V(e){return e.command?d[e.command]?.keys[0]??null:e.shortcut}function H(e,t=a()){let n=V(e);return n?s(n,t):null}function me(e,t=a()){for(let n of D)if(n.shortcut&&ee(e,n.shortcut,t))return n;return null}function U(e){return O.add(e),()=>O.delete(e)}function W(){return(0,x.useSyncExternalStore)(U,I,I)}function G(e){let t=null,n=null,r=()=>(n??=e().then(e=>t=e,e=>{throw n=null,e}),n);function i(e){let[n]=(0,x.useState)(()=>t),[i]=(0,x.useState)(()=>(0,x.lazy)(()=>r().then(e=>({default:e}))));return(0,x.createElement)(n??i,e)}return Object.assign(i,{preload:r})}function K(e=D){for(let t of e){let e=t.component.preload;typeof e==`function`&&e().catch(()=>void 0)}}function he(e){K(e.map(e=>L(e)).filter(e=>e!==null))}var q=n();function ge({size:e=16}){return(0,q.jsx)(`svg`,{viewBox:`0 0 16 16`,width:e,height:e,fill:`none`,stroke:`currentColor`,strokeWidth:1.5,strokeLinecap:`round`,strokeLinejoin:`round`,"aria-hidden":`true`,focusable:`false`,children:(0,q.jsx)(`path`,{d:`M3 4.5 4.5 6 7 3.5M3 10.5 4.5 12 7 9.5M9 5h4.5M9 11h4.5`})})}P({id:`checks`,title:`Checks`,icon:ge,order:55,description:`Git status, the PR, each CI check and review comments — with Auto-fix CI and Auto-merge for an agent.`,component:G(()=>i(()=>import(`./ChecksPanel-D9r8koxq.js`).then(e=>e.n).then(e=>function(t){return(0,q.jsx)(e.ChecksDockPane,{sessionId:t.sessionId,visible:t.visible,host:t.host})}),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16])))}),P({id:`sources`,title:`Sources`,icon:_,description:`Every file, page, search and doc this chat drew on — numbered, with the turns that cited each.`,component:G(()=>i(()=>import(`./dock-panes-DvQ6t4Nl.js`).then(e=>e.SourcesDockPane),__vite__mapDeps([17,18,19,20,21,22,23,8,24,25,26,27,28,29,30,31,32,11,33,34,35,36,37,38,39])))}),P({id:`reasoning`,title:`Reasoning`,icon:v,description:`The model's reasoning, turn by turn, with what each turn did.`,component:G(()=>i(()=>import(`./dock-panes-DvQ6t4Nl.js`).then(e=>e.ReasoningDockPane),__vite__mapDeps([17,18,19,20,21,22,23,8,24,25,26,27,28,29,30,31,32,11,33,34,35,36,37,38,39])))}),P({id:`terminal`,title:`Terminal`,icon:y,component:G(()=>i(()=>import(`./TerminalPane-XZ5n3Pns.js`).then(e=>e.TerminalRegistryPane),__vite__mapDeps([40,3,2,7,8,23,24,5,6,9,41,18,19,42,43,44,45,25,22,26,27,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,11,12,37,36,38,14,61,33,62,63])))});function J(e){o().section!==`chat`&&ne(`chat`),re(e)}p(`terminal.generate`,()=>J({assist:!0})),p(`terminal.history`,()=>J({history:!0}));var _e=e({BROWSER_PANE:()=>ve}),ve={id:`browser`,label:`Browser`,commandId:`pane.browser`,keywords:[`browser`,`web`,`preview`,`localhost`,`devtools`,`console`,`screenshot`],defaultSlot:`dock`,chatScoped:!0,load:()=>i(()=>import(`./BrowserPanel-CECVGJBS.js`).then(e=>({default:e.BrowserPanel})),__vite__mapDeps([64,1,2,3,65,42,44,4,5,6,7,8,9,10,31,32,23,24,27,26,11,12,13,66,14,15,36,37,38,39,67]))},ye=e({CHANGES_PANE:()=>be}),be={id:`changes`,label:`Changes`,commandId:`dock.diff`,keywords:[`changes`,`diff`,`review`,`checkpoint`,`undo`,`rewind`,`revert`,`git`],defaultSlot:`dock`,chatScoped:!0,description:`What each turn changed, reviewed hunk by hunk, with Undo turn — plus the uncommitted and branch diff.`,load:()=>i(()=>import(`./ChangesPaneHost-Bnj_NcRa.js`).then(e=>({default:e.ChangesPaneHost})),__vite__mapDeps([68,2,3,1,21,69,65,70,42,4,5,6,7,8,9,47,48,23,24,49,50,22,51,52,71,72,73,74,12,11,13,37,66,14,33,36,38,75,76,77,78]))};function xe({sessionId:e,roots:t,requests:n,host:r,visible:i}){return(0,q.jsx)(ce,{sessionId:e??``,roots:t,request:n.terminal,onSendToChat:r.sendToChat,visible:i})}function Se({sessionId:e,roots:t,requests:n,host:r,visible:i}){return(0,q.jsx)(ue,{sessionId:e??``,roots:t,request:n.preview,visible:i,onOpenTerminal:r.openTerminalBelow})}function Y({sessionId:e,roots:t,requests:n,turnFiles:r,host:i,visible:a}){return(0,q.jsx)(b,{sessionId:e??``,roots:t,request:n.diff,turnFiles:r,onAddToMessage:i.addToMessage,visible:a})}var Ce=G(()=>i(()=>import(`./ChatPanes-x_ySUIyR.js`).then(e=>e.TasksPaneBody),__vite__mapDeps([79,1,2,3,80,7,8,5,6,9,49,23,24,81,82,83,18,19,29,84,85,86,87,4,25,22,26,27,10,47,88,31,32,11,12,13,37,36,38,89,15,90,39,91]))),X=G(()=>i(()=>import(`./ChatPanes-x_ySUIyR.js`).then(e=>e.ContextPaneBody),__vite__mapDeps([79,1,2,3,80,7,8,5,6,9,49,23,24,81,82,83,18,19,29,84,85,86,87,4,25,22,26,27,10,47,88,31,32,11,12,13,37,36,38,89,15,90,39,91]))),we=G(()=>i(()=>import(`./FilesPane-CoNjfkPP.js`).then(e=>e.FilesPane),__vite__mapDeps([92,7,8,18,19,29,25,22,23,24,26,27,93,33,11,94]))),Te=G(()=>i(()=>import(`./SourcesPane-QffcyDfA.js`).then(e=>e.SourcesPane),__vite__mapDeps([95,7,8,29,18,19,43,42,25,22,23,24,26,27,93,11,36,37,38,33,94]))),Ee=G(()=>i(()=>import(`./ReasoningPane-BARDPl4-.js`).then(e=>e.ReasoningPane),__vite__mapDeps([96,30,25,22,23,8,24,26,27,93,18,19,33,34,11,94]))),Z=e=>()=>le(e),De={terminal:{icon:y,component:xe,order:10,toggle:!0,when:Z(`terminal-pane`),description:`A shell in this chat's folders. Commands the chat suggests paste here — you press Enter.`},browser:{icon:g,component:Se,order:20,toggle:!0,when:Z(`preview-pane`),description:`Your dev server or a page the chat made, live beside the conversation.`},diff:{icon:ie,component:Y,order:30,toggle:!0,when:Z(`diff-pane`),description:`What changed — this turn, uncommitted, or the whole branch — with notes you can send back.`},files:{icon:h,component:we,order:40,description:`The chat's folders, and every file it has read or changed.`},sources:{icon:_,component:Te,order:50,description:`The pages, searches and files an answer rests on.`},reasoning:{icon:v,component:Ee,order:60,description:`The model's thinking, turn by turn, beside the answer.`},tasks:{icon:se,component:Ce,order:70,needsSession:!1,description:`This turn's tool calls, and every other chat that is running.`},context:{icon:ae,component:X,order:80,needsSession:!1,description:`How full this chat's context is, its folders, memory and handoff.`}},Q=[];function Oe(){for(let e of Q)e();Q=m.map(e=>{let t=De[e.id];return F({id:e.id,title:e.label,...e.commandId?{command:e.commandId}:{},...t})})}Oe();var ke={changes:`diff`,review:`diff`,preview:`browser`};function Ae(e){if(typeof e!=`object`||!e)return!1;let t=e;return typeof t.id==`string`&&f.test(t.id)&&typeof t.label==`string`&&t.label.trim()!==``&&typeof t.load==`function`}function je(e){let t=[];for(let n of Object.keys(e).sort()){let r=e[n];if(typeof r==`object`&&r)for(let e of Object.values(r)){if(!Ae(e))continue;let n=ke[e.id]??e.id,r=L(n),i=e.load;P({id:n,title:e.label.trim(),icon:e.icon??r?.icon??oe,component:G(()=>i().then(e=>e.default)),needsSession:!1,...e.shortcut?{shortcut:e.shortcut}:{},...e.description?{description:e.description}:{}}),t.push(n)}}return t}var Me=e({UNIT_PANE_MODULES:()=>$,definitionProblems:()=>C,getPane:()=>L,isPaneAvailable:()=>B,lazyPane:()=>G,listPanes:()=>I,matchPaneShortcut:()=>me,paneApplies:()=>R,paneChord:()=>V,paneChordLabel:()=>H,panesFor:()=>z,preloadPaneIds:()=>he,preloadPanes:()=>K,registerBuiltinPane:()=>F,registerPane:()=>P,shortcutProblem:()=>S,subscribePanes:()=>U,usePanes:()=>W}),$=Object.assign({"../browser/register.ts":_e,"../changes/register.ts":ye});je($);export{R as a,K as c,B as i,W as l,Y as n,H as o,L as r,z as s,Me as t};
3
+ //# sourceMappingURL=panes-5GU8cuI9.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"mappings":"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","names":[],"ignoreList":[],"sources":["../../../../../../src/web-ui/routes/verse/panes/pane-registry.ts","../../../../../../src/web-ui/routes/verse/agents/checks.pane.tsx","../../../../../../src/web-ui/routes/verse/reasoning/reasoning.pane.tsx","../../../../../../src/web-ui/routes/verse/terminal/terminal.pane.tsx","../../../../../../src/web-ui/routes/verse/browser/register.ts","../../../../../../src/web-ui/routes/verse/changes/register.ts","../../../../../../src/web-ui/routes/verse/panes/builtin/SlotPanes.tsx","../../../../../../src/web-ui/routes/verse/panes/builtin-panes.tsx","../../../../../../src/web-ui/routes/verse/panes/register-adapter.ts","../../../../../../src/web-ui/routes/verse/panes/index.ts"],"sourcesContent":["/**\n * routes/verse/panes/pane-registry.ts — THE PANE REGISTRY: how anything\n * becomes a tab in the chat's panel area (the dock), without touching the\n * layout. See ./README.md for the guide; this file is the contract.\n *\n * registerPane({\n * id: 'reasoning',\n * title: 'Reasoning',\n * icon: ReasoningGlyph,\n * component: lazy(() => import('./ReasoningPane.js').then((m) => ({ default: m.ReasoningPane }))),\n * shortcut: 'mod+shift+y', // or `command:` for a catalog key\n * when: ({ session }) => session !== null,\n * });\n *\n * WHAT THE DOCK DOES WITH A PANE. It lists it in \"+ Add a pane\", the split\n * menu and (with `toggle`) the chat header; opens it on its key; renders its\n * component inside an error boundary and a Suspense boundary (so a lazy\n * component is its own chunk and a crash says so without taking the chat\n * down); keeps it MOUNTED while its tab is open (hidden, with\n * `visible: false`, when another tab is on top — stop timers then); and\n * remembers which panes each chat had open.\n *\n * REPLACING a pane. Registering an id that already exists REPLACES it (the\n * newest registration wins) and inherits what it did not say — its catalog\n * command, header toggle and order — so a unit swapping the stub Reasoning\n * pane for the real one writes only what changed. The returned function\n * unregisters that one registration, and the previous definition comes back.\n *\n * KEYS. A pane's chord is either a catalog command's (`command:`, for the\n * first-party panes — the palette and the shortcuts overlay list those) or\n * its own `shortcut:`. An own shortcut must use mod (Cmd/Ctrl) or ctrl, and is REFUSED\n * (with a console warning; the pane still registers, keyless) when it\n * collides with a catalog key live in the chat, a system chord, or another\n * pane's key. A pane can never steal a key.\n *\n * Framework-light: React only for types and the one subscription hook. This\n * module (and the panes it registers) load just after the chat's first\n * paint — never on it (VerseApp.first-paint.test.ts).\n */\nimport { createElement, lazy, useState, useSyncExternalStore, type ComponentType } from 'react';\nimport type { VerseEvent, VerseSession } from '../../../data/api-types.js';\nimport {\n COMMAND_KEYS,\n SCOPE_LAYERS,\n SYSTEM_RESERVED_CHORDS,\n chordId,\n chordMatches,\n detectKeyPlatform,\n formatChord,\n parseChord,\n type KeyChord,\n type KeyedCommandId,\n type KeyEventLike,\n type KeyPlatform,\n} from '../shell/command-keys.js';\nimport { PANE_ID_RE, type DockPresentation } from '../shell/dock-catalog.js';\nimport type { DiffPaneRequest, PreviewOpenRequest, TerminalOpenRequest, TurnFileChange } from '../shell/slots.js';\n\n// ===========================================================================\n// The contract\n// ===========================================================================\n\n/** The one-shot requests other parts of the chat aim at panes (\"Run in terminal\", a ± count, a dev server). */\nexport interface PaneRequests {\n terminal: TerminalOpenRequest | null;\n preview: PreviewOpenRequest | null;\n diff: (DiffPaneRequest & { nonce: number }) | null;\n}\n\n/** What a pane may ask of the workbench. Every call is safe at any time (a no-op when it cannot apply). */\nexport interface PaneHost {\n /** Put `text` in the composer, as its own paragraph (Terminal's \"Send selection to chat\"). */\n sendToChat(text: string): void;\n /** Draft `text` into the composer (\"Add to message\": `path:line: note`). */\n addToMessage(text: string): void;\n /** Open (and show) another pane by id. */\n openPane(id: string): void;\n /** Close this or another pane's tab. */\n closePane(id: string): void;\n /** Open the Terminal pane with a request (a tab at a root; a command PASTED, never run). */\n openTerminal(request: Omit<TerminalOpenRequest, 'nonce'>): void;\n /** The same, with Terminal as the lower half of a split under the pane on top. */\n openTerminalBelow(request: Omit<TerminalOpenRequest, 'nonce'>): void;\n /** Open the Changes pane at a root and scope (optionally one file). */\n openDiff(request: DiffPaneRequest): void;\n /** Switch the chat surface to another chat. */\n openSession(sessionId: string): void;\n}\n\n/**\n * The props every pane component receives. Stable: fields are only ever\n * ADDED. A pane that needs the live transcript subscribes itself\n * (`useVerseTranscript(sessionId)`), so a streamed token re-renders that\n * pane, not the dock.\n */\nexport interface PaneProps {\n /** This pane's id (one component may serve several registrations). */\n paneId: string;\n /** The open chat. Never null for a pane with `needsSession` (the default): the dock shows the empty state instead. */\n sessionId: string | null;\n session: VerseSession | null;\n /** The chat's folders, primary first. */\n roots: readonly string[];\n /** The chat's raw event log (what the transcript is built from). */\n events: readonly VerseEvent[];\n /** Files the chat's latest turn touched. */\n turnFiles: readonly TurnFileChange[];\n /** False while another tab is on top (or the panel is closed with the tab kept): stop timers, skip work. */\n visible: boolean;\n /** How the panel is drawn right now — a pane may choose a denser layout in `bottom`. */\n presentation: DockPresentation;\n requests: PaneRequests;\n host: PaneHost;\n}\n\n/** What `when` sees — enough to decide whether a pane applies to the chat that is open. */\nexport interface PaneContext {\n sessionId: string | null;\n session: VerseSession | null;\n roots: readonly string[];\n}\n\n/** A 16px line glyph (currentColor), like dock/dock-icons.tsx. */\nexport type PaneIcon = ComponentType<{ size?: number }>;\n\nexport interface PaneDefinition {\n /** Stable id: lower-case letters, numbers and dashes (`browser`, `test-runner`). Persisted in layouts. */\n id: string;\n /** Tab label and menu name: one or two words. */\n title: string;\n icon: PaneIcon;\n /** Usually `lazy(() => import(…))`, so the pane's code is its own chunk and loads on first open. */\n component: ComponentType<PaneProps>;\n /** Your own chord, as the key table writes it: 'mod+shift+y', 'ctrl+alt+p'. Refused on any collision. */\n shortcut?: string;\n /** First-party: the catalog command whose key opens this pane (its chord then comes from the catalog). */\n command?: KeyedCommandId;\n /** Whether the pane applies right now (e.g. only for a chat with a web seat). False hides its tab and menu entry. */\n when?: (context: PaneContext) => boolean;\n /** Needs an open chat (default true): without one the dock shows \"Open a chat to use …\" instead. */\n needsSession?: boolean;\n /** Menu / header order, ascending (first-party panes use 10…80; default 100). */\n order?: number;\n /** One sentence: what the pane is for. The empty state and the \"+\" menu teach with it. */\n description?: string;\n /** Show a toggle for it in the chat header (keep it to the few everyone uses). */\n toggle?: boolean;\n}\n\n/** A pane as the registry holds it: defaults applied, the chord resolved and vetted. */\nexport interface RegisteredPane {\n readonly id: string;\n readonly title: string;\n readonly icon: PaneIcon;\n readonly component: ComponentType<PaneProps>;\n readonly command: KeyedCommandId | null;\n /** The pane's OWN chord (not a catalog command's), after the collision check; null = none or refused. */\n readonly shortcut: KeyChord | null;\n readonly when: ((context: PaneContext) => boolean) | null;\n readonly needsSession: boolean;\n readonly order: number;\n readonly description: string | null;\n readonly toggle: boolean;\n}\n\n// ===========================================================================\n// Validation\n// ===========================================================================\n\n/** Every chord that is live while a pane's key would be (the composer layer: composer + chat + global). */\nfunction catalogChords(): Map<string, string> {\n const live = SCOPE_LAYERS.composer;\n const out = new Map<string, string>();\n for (const [id, spec] of Object.entries(COMMAND_KEYS)) {\n if (!live.includes(spec.scope)) continue;\n for (const chord of spec.keys) out.set(chordId(chord), id);\n }\n return out;\n}\n\nconst RESERVED = new Set(SYSTEM_RESERVED_CHORDS.map(chordId));\n\n/**\n * Why `text` cannot be pane `paneId`'s own shortcut, or null when it can.\n * Exported for tests and for units that want to check a chord up front.\n */\nexport function shortcutProblem(text: string, paneId: string, panes: Iterable<RegisteredPane> = listPanes()): string | null {\n let chord: KeyChord;\n try {\n chord = parseChord(text.trim().toLowerCase());\n } catch {\n return `\"${text}\" is not a chord`;\n }\n const modifiers = text.toLowerCase().split('+').slice(0, -1);\n if (!chord.key || modifiers.some((m) => !['mod', 'ctrl', 'shift', 'alt'].includes(m))) return `\"${text}\" is not a chord`;\n if (!chord.mod && !chord.ctrl) return `\"${text}\" needs mod or ctrl — a bare key would eat typing`;\n const id = chordId(chord);\n if (RESERVED.has(id)) return `\"${text}\" belongs to the system`;\n const owner = catalogChords().get(id);\n if (owner) return `\"${text}\" is already ${owner}`;\n for (const pane of panes) {\n if (pane.id === paneId) continue;\n if (pane.shortcut && chordId(pane.shortcut) === id) return `\"${text}\" is already the ${pane.title} pane's`;\n const command = pane.command ? COMMAND_KEYS[pane.command]?.keys[0] : undefined;\n if (command && chordId(command) === id) return `\"${text}\" is already the ${pane.title} pane's`;\n }\n return null;\n}\n\n/** Problems that make a definition unregistrable (an empty list = fine). */\nexport function definitionProblems(def: PaneDefinition): string[] {\n const problems: string[] = [];\n if (typeof def !== 'object' || def === null) return ['a pane definition must be an object'];\n if (typeof def.id !== 'string' || !PANE_ID_RE.test(def.id)) problems.push(`id \"${String(def.id)}\" must be lower-case letters, numbers and dashes`);\n if (typeof def.title !== 'string' || def.title.trim() === '') problems.push('title is required');\n const isComponent = (c: unknown) => typeof c === 'function' || (typeof c === 'object' && c !== null);\n if (!isComponent(def.component)) problems.push('component must be a React component (lazy() is fine)');\n if (!isComponent(def.icon)) problems.push('icon must be a React component');\n if (def.command !== undefined && !COMMAND_KEYS[def.command]) problems.push(`command \"${def.command}\" has no key in shell/command-keys.ts`);\n return problems;\n}\n\n// ===========================================================================\n// The registry\n// ===========================================================================\n\n/** Each id's registrations, oldest first; the LAST is the active one. */\n/** One registration. `builtin` ones sit UNDER every other registration of their id, whatever the load order. */\ninterface Layer {\n def: PaneDefinition;\n builtin: boolean;\n}\n\n/** Each id's registrations, bottom first; the effective pane folds them upward. */\nconst stacks = new Map<string, Layer[]>();\n/** Ids in first-registration order (the tie-break for equal `order`s). */\nconst firstSeen: string[] = [];\nlet effective = new Map<string, RegisteredPane>();\nlet snapshot: readonly RegisteredPane[] = [];\nconst listeners = new Set<() => void>();\nconst warned = new Set<string>();\n\nfunction warn(message: string): void {\n if (warned.has(message)) return;\n warned.add(message);\n if (typeof console !== 'undefined') console.warn(`[verse panes] ${message}`);\n}\n\nconst normalizeChordText = (text: string) => text.trim().toLowerCase();\n\n/**\n * Fold one id's layers: each registration inherits what it leaves unsaid\n * (command, toggle, order, needsSession, description) from the one below.\n * The own shortcut is vetted against the catalog and the panes resolved so\n * far — `resolved`, in first-registration order, so the older pane keeps a\n * contested key.\n */\nfunction fold(layers: readonly Layer[], resolved: Iterable<RegisteredPane>): RegisteredPane {\n let below = null as RegisteredPane | null;\n for (const { def } of layers) {\n const command: KeyedCommandId | null = def.command ?? below?.command ?? null;\n let shortcut: KeyChord | null = below?.shortcut ?? null;\n if (def.shortcut !== undefined) {\n const commandChord = command ? COMMAND_KEYS[command]?.keys[0] : undefined;\n if (commandChord && chordId(parseChord(normalizeChordText(def.shortcut))) === chordId(commandChord)) {\n shortcut = null; // the catalog already serves this key for this pane\n } else if (command) {\n warn(`pane \"${def.id}\": shortcut \"${def.shortcut}\" ignored — it opens with ${command}'s key`);\n shortcut = null;\n } else {\n const problem = shortcutProblem(def.shortcut, def.id, resolved);\n if (problem) warn(`pane \"${def.id}\": shortcut refused — ${problem}`);\n shortcut = problem ? null : parseChord(normalizeChordText(def.shortcut));\n }\n }\n below = Object.freeze({\n id: def.id,\n title: def.title.trim(),\n icon: def.icon,\n component: def.component,\n command,\n shortcut,\n when: def.when ?? null,\n needsSession: def.needsSession ?? below?.needsSession ?? true,\n order: def.order ?? below?.order ?? 100,\n description: def.description ?? below?.description ?? null,\n toggle: def.toggle ?? below?.toggle ?? false,\n });\n }\n return below!;\n}\n\nfunction publish(): void {\n const next = new Map<string, RegisteredPane>();\n for (const id of firstSeen) {\n const layers = stacks.get(id);\n if (layers && layers.length > 0) next.set(id, fold(layers, next.values()));\n }\n effective = next;\n // Order, then first registration: a stable menu no matter which module loaded first.\n snapshot = Object.freeze([...next.values()].sort((a, b) => a.order - b.order || firstSeen.indexOf(a.id) - firstSeen.indexOf(b.id)));\n for (const listener of [...listeners]) listener();\n}\n\nfunction addLayer(def: PaneDefinition, builtin: boolean): () => void {\n const problems = definitionProblems(def);\n if (problems.length > 0) {\n warn(`pane \"${String((def as Partial<PaneDefinition> | null)?.id)}\" not registered: ${problems.join('; ')}`);\n return () => undefined;\n }\n const layer: Layer = { def, builtin };\n const stack = stacks.get(def.id) ?? [];\n if (builtin) {\n // Under every non-builtin registration: a unit's replacement wins even if its module evaluated first.\n const firstOther = stack.findIndex((l) => !l.builtin);\n stack.splice(firstOther === -1 ? stack.length : firstOther, 0, layer);\n } else {\n stack.push(layer);\n }\n stacks.set(def.id, stack);\n if (!firstSeen.includes(def.id)) firstSeen.push(def.id);\n publish();\n return () => {\n const current = stacks.get(def.id);\n const index = current?.indexOf(layer) ?? -1;\n if (!current || index === -1) return;\n current.splice(index, 1);\n if (current.length === 0) stacks.delete(def.id);\n publish();\n };\n}\n\n/**\n * Add a pane — or replace the one with the same id. Returns a function that\n * removes THIS registration (the previous one, if any, comes back).\n *\n * Never throws: a malformed definition is reported on the console and\n * ignored, so one unit's mistake cannot take the other panes down.\n */\nexport function registerPane(def: PaneDefinition): () => void {\n return addLayer(def, false);\n}\n\n/**\n * The workbench's own panes (builtin-panes.tsx). Always UNDER any other\n * registration of the same id, so a unit's `registerPane` replaces the\n * first-party stub no matter which module evaluated first.\n */\nexport function registerBuiltinPane(def: PaneDefinition): () => void {\n return addLayer(def, true);\n}\n\n/** Every registered pane, in menu order (applicability NOT checked — see panesFor). */\nexport function listPanes(): readonly RegisteredPane[] {\n return snapshot;\n}\n\n/** The effective registration for `id`, or null. */\nexport function getPane(id: string): RegisteredPane | null {\n return effective.get(id) ?? null;\n}\n\n/** Does `pane` apply in `context`? A `when` that throws counts as no (and says so once). */\nexport function paneApplies(pane: RegisteredPane, context: PaneContext): boolean {\n if (!pane.when) return true;\n try {\n return pane.when(context) === true;\n } catch (err) {\n warn(`pane \"${pane.id}\": when() threw — ${(err as Error)?.message ?? String(err)}`);\n return false;\n }\n}\n\n/** The panes that apply in `context`, in menu order. */\nexport function panesFor(context: PaneContext): RegisteredPane[] {\n return snapshot.filter((pane) => paneApplies(pane, context));\n}\n\n/** Is `id` registered, and does it apply in `context`? */\nexport function isPaneAvailable(id: string, context: PaneContext): boolean {\n const pane = getPane(id);\n return pane !== null && paneApplies(pane, context);\n}\n\n/** The chord that opens `pane` — its catalog command's, else its own — or null. */\nexport function paneChord(pane: RegisteredPane): KeyChord | null {\n if (pane.command) return COMMAND_KEYS[pane.command]?.keys[0] ?? null;\n return pane.shortcut;\n}\n\n/** `paneChord`, printed for this platform (\"⇧⌘Y\" / \"Ctrl+Shift+Y\"). */\nexport function paneChordLabel(pane: RegisteredPane, platform: KeyPlatform = detectKeyPlatform()): string | null {\n const chord = paneChord(pane);\n return chord ? formatChord(chord, platform) : null;\n}\n\n/**\n * The pane whose OWN shortcut `event` presses, or null. Catalog-command\n * chords are not matched here — the catalog's key handling runs those.\n */\nexport function matchPaneShortcut(event: KeyEventLike, platform: KeyPlatform = detectKeyPlatform()): RegisteredPane | null {\n for (const pane of snapshot) {\n if (pane.shortcut && chordMatches(event, pane.shortcut, platform)) return pane;\n }\n return null;\n}\n\nexport function subscribePanes(listener: () => void): () => void {\n listeners.add(listener);\n return () => listeners.delete(listener);\n}\n\n/** Every registered pane, re-rendering when one is added, replaced or removed. */\nexport function usePanes(): readonly RegisteredPane[] {\n return useSyncExternalStore(subscribePanes, listPanes, listPanes);\n}\n\n// ===========================================================================\n// lazyPane — a pane component that is its own chunk, without the flash\n// ===========================================================================\n\n/** A pane component whose code loads on first use; `preload()` fetches it ahead of time. */\nexport type LazyPaneComponent = ComponentType<PaneProps> & { preload: () => Promise<unknown> };\n\n/**\n * Like `React.lazy`, for panes — and preferred to it:\n * - once the chunk is in, a NEW mount renders the pane in the same frame\n * (React.lazy suspends every fresh wrapper once, which flashes the\n * skeleton when a second tab of an already-loaded chunk opens);\n * - the dock calls `preload()` when it opens, so a tab's first click\n * usually finds its code already here;\n * - a failed download is not cached: \"Try again\" really tries again.\n *\n * component: lazyPane(() => import('./ReasoningPane.js').then((m) => m.ReasoningPane))\n */\nexport function lazyPane(load: () => Promise<ComponentType<PaneProps>>): LazyPaneComponent {\n let loaded: ComponentType<PaneProps> | null = null;\n let pending: Promise<ComponentType<PaneProps>> | null = null;\n const preload = (): Promise<ComponentType<PaneProps>> => {\n pending ??= load().then((c) => (loaded = c), (err: unknown) => { pending = null; throw err; });\n return pending;\n };\n function LazyPane(props: PaneProps) {\n // Chosen once per mount: swapping the component type later would remount the pane and drop its state.\n const [Ready] = useState<ComponentType<PaneProps> | null>(() => loaded);\n const [Deferred] = useState(() => lazy(() => preload().then((c) => ({ default: c }))));\n return createElement(Ready ?? Deferred, props);\n }\n return Object.assign(LazyPane, { preload });\n}\n\n/** Fetch the code of every registered pane that can be preloaded (the dock calls this when it opens). */\nexport function preloadPanes(panes: readonly RegisteredPane[] = snapshot): void {\n for (const pane of panes) {\n const preload = (pane.component as Partial<LazyPaneComponent>).preload;\n if (typeof preload === 'function') void preload().catch(() => undefined);\n }\n}\n\n/** `preloadPanes` for just these ids (the chat surface warms the tabs a chat is likely to open). */\nexport function preloadPaneIds(ids: readonly string[]): void {\n preloadPanes(ids.map((id) => getPane(id)).filter((p): p is RegisteredPane => p !== null));\n}\n\n/** Test seam: forget every registration (builtin-panes' `registerBuiltinPanes()` puts the first-party ones back). */\nexport function resetPaneRegistry(): void {\n stacks.clear();\n firstSeen.length = 0;\n warned.clear();\n publish();\n}\n","/**\n * routes/verse/agents/checks.pane.tsx — the chat dock's \"Checks\" pane: the\n * open chat's git status, PR, CI, review comments, Auto-fix CI and\n * Auto-merge (3.16 agents). Only the registration lives here — panes/index.ts\n * imports every `*.pane.tsx` eagerly after first paint — and the body is its\n * own lazy chunk (ChecksPanel.tsx).\n */\nimport type { PaneProps } from '../panes/pane-registry.js';\nimport { lazyPane, registerPane } from '../panes/pane-registry.js';\n\nfunction ChecksGlyph({ size = 16 }: { size?: number }) {\n return (\n <svg viewBox=\"0 0 16 16\" width={size} height={size} fill=\"none\" stroke=\"currentColor\" strokeWidth={1.5} strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\" focusable=\"false\">\n <path d=\"M3 4.5 4.5 6 7 3.5M3 10.5 4.5 12 7 9.5M9 5h4.5M9 11h4.5\" />\n </svg>\n );\n}\n\nregisterPane({\n id: 'checks',\n title: 'Checks',\n icon: ChecksGlyph,\n order: 55,\n description: 'Git status, the PR, each CI check and review comments — with Auto-fix CI and Auto-merge for an agent.',\n component: lazyPane(() =>\n import('./ChecksPanel.js').then((m) => function ChecksPane(props: PaneProps) {\n return <m.ChecksDockPane sessionId={props.sessionId} visible={props.visible} host={props.host} />;\n }),\n ),\n});\n","/**\n * routes/verse/reasoning/reasoning.pane.tsx — the Sources and Reasoning\n * panes, registered with the workbench pane registry (panes/README.md).\n *\n * Same ids as the first-party stubs, so these REPLACE them and inherit their\n * keys (⇧⌘S Sources, ⇧⌘Y Reasoning), order and catalog commands. Only the\n * registration lives here — panes/index.ts imports every `*.pane.tsx` eagerly\n * after first paint — and each body is its own lazy chunk.\n */\nimport { ReasoningGlyph, SourcesGlyph } from '../dock/dock-icons.js';\nimport { lazyPane, registerPane } from '../panes/pane-registry.js';\n\nregisterPane({\n id: 'sources',\n title: 'Sources',\n icon: SourcesGlyph,\n description: 'Every file, page, search and doc this chat drew on — numbered, with the turns that cited each.',\n component: lazyPane(() => import('./dock-panes.js').then((m) => m.SourcesDockPane)),\n});\n\nregisterPane({\n id: 'reasoning',\n title: 'Reasoning',\n icon: ReasoningGlyph,\n description: \"The model's reasoning, turn by turn, with what each turn did.\",\n component: lazyPane(() => import('./dock-panes.js').then((m) => m.ReasoningDockPane)),\n});\n","/**\n * terminal/terminal.pane.tsx — the 3.15 Terminal's registration in the pane\n * registry (panes/README.md). panes/index.ts discovers every `*.pane.tsx`\n * under routes/verse and imports it (after first paint).\n *\n * Id `terminal` REPLACES the first-party stub and inherits what this leaves\n * unsaid: the ⌃` key (dock.terminal), the header toggle, the first place in\n * the panel, `needsSession` (without a chat the dock says \"Open a chat to use\n * Terminal\") and the stub's description. ⌃⇧` (a new tab) and every\n * `requests.terminal` — Run in terminal, Apps [Launch ▸], a dev-server Start —\n * reach the panel as before.\n *\n * TINY ON PURPOSE: a registration and a lazy import. The panel — xterm, its\n * addons, the block view — is its own chunk, loaded when the pane first shows\n * (terminal-lazy.test.ts).\n *\n * 3.15: it also serves ⌘K \"Generate command…\" and \"Search terminal history…\"\n * (catalog ids terminal.generate / terminal.history) — here rather than in\n * ChatSection, so the chat's first paint carries none of it. Both go to Chat\n * and ask the panel for its prompt; the panel does the rest (nothing runs).\n */\nimport { requestTerminal } from '../dock/dock-store.js';\nimport { TerminalGlyph } from '../dock/dock-icons.js';\nimport { lazyPane, registerPane } from '../panes/pane-registry.js';\nimport { registerCommandHandler } from '../shell/command-bus.js';\nimport { getVerseUiState, setVerseSection } from '../verse-ui-store.js';\n\nexport const TERMINAL_PANE_ID = 'terminal';\n\nregisterPane({\n id: TERMINAL_PANE_ID,\n title: 'Terminal',\n icon: TerminalGlyph,\n component: lazyPane(() => import('./TerminalPane.js').then((m) => m.TerminalRegistryPane)),\n});\n\nfunction openTerminalPrompt(request: { assist: true } | { history: true }): void {\n if (getVerseUiState().section !== 'chat') setVerseSection('chat');\n requestTerminal(request);\n}\nregisterCommandHandler('terminal.generate', () => openTerminalPrompt({ assist: true }));\nregisterCommandHandler('terminal.history', () => openTerminalPrompt({ history: true }));\n","/**\n * routes/verse/browser/register.ts — the Browser pane's registration for the\n * workbench pane registry (routes/verse/panes/**, landing separately).\n *\n * This file is deliberately tiny and import-free apart from a LAZY import:\n * the registry can list the pane (id, label, command, where it docks) on\n * first paint without pulling the pane's code — BrowserPanel and everything\n * behind it (Button, icons, the token dialog) load only when it is opened\n * (VerseApp.first-paint.test.ts keeps those out of the first-paint graph).\n *\n * Until the registry lands, a host mounts it with:\n * const Browser = lazy(BROWSER_PANE.load);\n * <Suspense fallback={null}><Browser sessionId={id} visible={shown} /></Suspense>\n */\nimport type { ComponentType } from 'react';\nimport type { BrowserPanelProps } from './BrowserPanel.js';\n\nexport interface VersePaneRegistration<P> {\n /** Stable id (layout persistence, commands). */\n id: string;\n label: string;\n /** Command palette id that opens the pane. */\n commandId: string;\n /** Palette search words. */\n keywords: readonly string[];\n /** Where the pane prefers to dock when first opened. */\n defaultSlot: 'dock' | 'side' | 'main';\n /** Needs a chat to be useful (it still browses without one). */\n chatScoped: boolean;\n load: () => Promise<{ default: ComponentType<P> }>;\n}\n\nexport type { BrowserPanelProps };\n\nexport const BROWSER_PANE: VersePaneRegistration<BrowserPanelProps> = {\n id: 'browser',\n label: 'Browser',\n commandId: 'pane.browser',\n keywords: ['browser', 'web', 'preview', 'localhost', 'devtools', 'console', 'screenshot'],\n defaultSlot: 'dock',\n chatScoped: true,\n load: () => import('./BrowserPanel.js').then((m) => ({ default: m.BrowserPanel })),\n};\n","/**\n * routes/verse/changes/register.ts — the Changes pane's registration for the\n * workbench pane registry (routes/verse/panes/README.md, \"a self-describing\n * register.ts\"). panes/index.ts discovers this file; register-adapter.ts maps\n * the id `changes` onto the first-party `diff` pane and REPLACES it, keeping\n * its key (⇧⌘D), order, icon and header toggle.\n *\n * Import-free apart from a LAZY import, so listing the pane costs nothing on\n * first paint: ChangesPaneHost and everything behind it (the checkpoint\n * client, the diff grid, the git dialogs) is its own chunk, loaded when the\n * pane opens.\n */\nimport type { ComponentType } from 'react';\nimport type { PaneProps } from '../panes/pane-registry.js';\n\nexport const CHANGES_PANE: {\n id: string;\n label: string;\n commandId: string;\n keywords: readonly string[];\n defaultSlot: 'dock';\n chatScoped: boolean;\n description: string;\n load: () => Promise<{ default: ComponentType<PaneProps> }>;\n} = {\n id: 'changes',\n label: 'Changes',\n commandId: 'dock.diff',\n keywords: ['changes', 'diff', 'review', 'checkpoint', 'undo', 'rewind', 'revert', 'git'],\n defaultSlot: 'dock',\n chatScoped: true,\n description: 'What each turn changed, reviewed hunk by hunk, with Undo turn — plus the uncommitted and branch diff.',\n load: () => import('./ChangesPaneHost.js').then((m) => ({ default: m.ChangesPaneHost })),\n};\n","/**\n * routes/verse/panes/builtin/SlotPanes.tsx — the first-party Terminal,\n * Browser and Changes panes: thin adapters from PaneProps to the C0 slot\n * each renders through (shell/slots.tsx), so xterm, the page preview and the\n * diff viewer stay in their owners' lazy chunks.\n *\n * A unit replacing one of these (the Terminal, Browser or Harness agent)\n * registers its own component under the same id — see ../README.md — and\n * this adapter simply stops being used.\n */\nimport type { PaneProps } from '../pane-registry.js';\nimport { DiffPaneSlot, PreviewPaneSlot, TerminalPaneSlot } from '../../shell/slots.js';\n\nexport function TerminalPaneBody({ sessionId, roots, requests, host, visible }: PaneProps) {\n return <TerminalPaneSlot sessionId={sessionId ?? ''} roots={roots} request={requests.terminal} onSendToChat={host.sendToChat} visible={visible} />;\n}\n\nexport function BrowserPaneBody({ sessionId, roots, requests, host, visible }: PaneProps) {\n // Dev-server Start: Terminal opens BELOW the browser, so the page appears\n // on top when its port answers (SPEC-310C acceptance step 3).\n return <PreviewPaneSlot sessionId={sessionId ?? ''} roots={roots} request={requests.preview} visible={visible} onOpenTerminal={host.openTerminalBelow} />;\n}\n\nexport function ChangesPaneBody({ sessionId, roots, requests, turnFiles, host, visible }: PaneProps) {\n return <DiffPaneSlot sessionId={sessionId ?? ''} roots={roots} request={requests.diff} turnFiles={turnFiles} onAddToMessage={host.addToMessage} visible={visible} />;\n}\n","/**\n * routes/verse/panes/builtin-panes.tsx — the workbench's first-party panes,\n * registered UNDER any unit's registration of the same id (so a unit's\n * `registerPane({ id: 'reasoning', … })` replaces the stub whatever the\n * module order). Metadata comes from shell/dock-catalog.ts DOCK_PANES;\n * bodies are lazy, so each loads the first time its tab opens.\n *\n * id title key body\n * terminal Terminal ⌃` C4's TerminalPane through its slot\n * browser Browser ⇧⌘B C4's PreviewPane through its slot\n * diff Changes ⇧⌘D C5's DiffPane through its slot\n * files Files ⇧⌘O stub: folders + files read / changed\n * sources Sources ⇧⌘S stub: pages, searches, files read\n * reasoning Reasoning ⇧⌘Y stub: the chat's thinking, by turn\n * tasks Tasks — this turn's calls + other running chats\n * context Context — usage, roots, memory, handoff\n */\nimport type { ComponentType } from 'react';\nimport {\n ContextGlyph,\n FilesGlyph,\n PreviewGlyph,\n ReasoningGlyph,\n ReviewGlyph,\n SourcesGlyph,\n TasksGlyph,\n TerminalGlyph,\n} from '../dock/dock-icons.js';\nimport { DOCK_PANES, type BuiltinPaneId } from '../shell/dock-catalog.js';\nimport { isSlotAvailable } from '../shell/slots.js';\nimport { BrowserPaneBody, ChangesPaneBody, TerminalPaneBody } from './builtin/SlotPanes.js';\nimport { lazyPane, registerBuiltinPane, type PaneDefinition, type PaneIcon, type PaneProps } from './pane-registry.js';\n\ntype Body = ComponentType<PaneProps>;\n\nconst TasksBody = lazyPane(() => import('./builtin/ChatPanes.js').then((m) => m.TasksPaneBody));\nconst ContextBody = lazyPane(() => import('./builtin/ChatPanes.js').then((m) => m.ContextPaneBody));\nconst FilesBody = lazyPane(() => import('./builtin/FilesPane.js').then((m) => m.FilesPane));\nconst SourcesBody = lazyPane(() => import('./builtin/SourcesPane.js').then((m) => m.SourcesPane));\nconst ReasoningBody = lazyPane(() => import('./builtin/ReasoningPane.js').then((m) => m.ReasoningPane));\n\ninterface BuiltinExtras {\n icon: PaneIcon;\n component: Body;\n description: string;\n order: number;\n toggle?: boolean;\n needsSession?: boolean;\n when?: PaneDefinition['when'];\n}\n\n/** A slot pane exists once its owner's file is in the build (shell/slots.tsx). */\nconst slotLanded = (slot: Parameters<typeof isSlotAvailable>[0]) => () => isSlotAvailable(slot);\n\nconst EXTRAS: Readonly<Record<BuiltinPaneId, BuiltinExtras>> = {\n terminal: {\n icon: TerminalGlyph, component: TerminalPaneBody, order: 10, toggle: true, when: slotLanded('terminal-pane'),\n description: \"A shell in this chat's folders. Commands the chat suggests paste here — you press Enter.\",\n },\n browser: {\n icon: PreviewGlyph, component: BrowserPaneBody, order: 20, toggle: true, when: slotLanded('preview-pane'),\n description: 'Your dev server or a page the chat made, live beside the conversation.',\n },\n diff: {\n icon: ReviewGlyph, component: ChangesPaneBody, order: 30, toggle: true, when: slotLanded('diff-pane'),\n description: 'What changed — this turn, uncommitted, or the whole branch — with notes you can send back.',\n },\n files: {\n icon: FilesGlyph, component: FilesBody, order: 40,\n description: \"The chat's folders, and every file it has read or changed.\",\n },\n sources: {\n icon: SourcesGlyph, component: SourcesBody, order: 50,\n description: 'The pages, searches and files an answer rests on.',\n },\n reasoning: {\n icon: ReasoningGlyph, component: ReasoningBody, order: 60,\n description: \"The model's thinking, turn by turn, beside the answer.\",\n },\n tasks: {\n icon: TasksGlyph, component: TasksBody, order: 70, needsSession: false,\n description: \"This turn's tool calls, and every other chat that is running.\",\n },\n context: {\n icon: ContextGlyph, component: ContextBody, order: 80, needsSession: false,\n description: \"How full this chat's context is, its folders, memory and handoff.\",\n },\n};\n\nlet disposers: Array<() => void> = [];\n\n/** Register (or re-register, after a registry reset) every first-party pane. Idempotent. */\nexport function registerBuiltinPanes(): void {\n for (const dispose of disposers) dispose();\n disposers = DOCK_PANES.map((meta) => {\n const extra = EXTRAS[meta.id];\n return registerBuiltinPane({\n id: meta.id,\n title: meta.label,\n ...(meta.commandId ? { command: meta.commandId } : {}),\n ...extra,\n });\n });\n}\n\nregisterBuiltinPanes();\n","/**\n * routes/verse/panes/register-adapter.ts — panes that describe themselves\n * in a unit's `register.ts` (the shape the Browser, Terminal, Reasoning +\n * Sources and Changes units ship while the registry was landing):\n *\n * export const BROWSER_PANE = {\n * id: 'browser', label: 'Browser', commandId: 'pane.browser',\n * keywords: […], defaultSlot: 'dock', chatScoped: true,\n * load: () => import('./BrowserPanel.js').then((m) => ({ default: m.BrowserPanel })),\n * };\n *\n * panes/index.ts discovers every `routes/verse/<unit>/register.ts` and hands\n * its exports here. Each export of that shape becomes a registered pane —\n * REPLACING the first-party one with the same id (so it keeps that pane's\n * key, order and header toggle) — and anything else in the file is ignored.\n *\n * The unit's component gets the full PaneProps. Components written against\n * the smaller `{ sessionId, visible }` contract simply ignore the rest; they\n * are handed `sessionId: null` when no chat is open (these panes accept it),\n * so `needsSession` is false for them.\n */\nimport type { ComponentType } from 'react';\nimport { PanelRightGlyph } from '../dock/dock-icons.js';\nimport { PANE_ID_RE } from '../shell/dock-catalog.js';\nimport { getPane, lazyPane, registerPane, type PaneIcon, type PaneProps } from './pane-registry.js';\n\n/** The self-description a unit's `register.ts` exports. */\nexport interface UnitPaneRegistration {\n id: string;\n label: string;\n commandId?: string;\n keywords?: readonly string[];\n defaultSlot?: 'dock' | 'side' | 'main';\n chatScoped?: boolean;\n /** Optional: a 16px glyph; the first-party pane's icon (or a generic panel glyph) otherwise. */\n icon?: PaneIcon;\n /** Optional: its own chord ('mod+alt+t'); vetted like any pane shortcut. */\n shortcut?: string;\n description?: string;\n load: () => Promise<{ default: ComponentType<never> }>;\n}\n\n/** Ids a unit may use for a first-party pane under another name. */\nconst ID_ALIASES: Readonly<Record<string, string>> = { changes: 'diff', review: 'diff', preview: 'browser' };\n\nexport function isUnitPaneRegistration(value: unknown): value is UnitPaneRegistration {\n if (value === null || typeof value !== 'object') return false;\n const v = value as Record<string, unknown>;\n return typeof v['id'] === 'string' && PANE_ID_RE.test(v['id']) && typeof v['label'] === 'string' && v['label'].trim() !== ''\n && typeof v['load'] === 'function';\n}\n\n/**\n * Register every pane the given modules describe. Returns the ids registered\n * (for tests) — duplicates across modules: the later module wins, like any\n * replacement.\n */\nexport function registerUnitPanes(modules: Record<string, unknown>): string[] {\n const ids: string[] = [];\n for (const path of Object.keys(modules).sort()) {\n const mod = modules[path];\n if (mod === null || typeof mod !== 'object') continue;\n for (const value of Object.values(mod as Record<string, unknown>)) {\n if (!isUnitPaneRegistration(value)) continue;\n const id = ID_ALIASES[value.id] ?? value.id;\n const existing = getPane(id);\n const load = value.load;\n registerPane({\n id,\n title: value.label.trim(),\n icon: value.icon ?? existing?.icon ?? PanelRightGlyph,\n component: lazyPane(() => load().then((m) => m.default as unknown as ComponentType<PaneProps>)),\n needsSession: false,\n ...(value.shortcut ? { shortcut: value.shortcut } : {}),\n ...(value.description ? { description: value.description } : {}),\n });\n ids.push(id);\n }\n }\n return ids;\n}\n","/**\n * routes/verse/panes/index.ts — the pane system's entry: the registry API,\n * the first-party panes, and every other unit's panes, DISCOVERED.\n *\n * DISCOVERY. Any file named `*.pane.ts` / `*.pane.tsx` under routes/verse/\n * is imported here (eagerly — it only registers; its component stays a\n * `lazy()` import of its own chunk). So a unit adds a pane by adding ONE\n * file in its own directory, e.g. routes/verse/reasoning/reasoning.pane.tsx:\n *\n * import { lazyPane, registerPane } from '../panes/pane-registry.js';\n * registerPane({ id: 'reasoning', title: 'Reasoning', icon: ReasoningGlyph,\n * component: lazyPane(() => import('./ReasoningPane.js').then((m) => m.ReasoningPane)) });\n *\n * Load order does not matter: first-party panes always sit under a unit's\n * registration of the same id (pane-registry.ts registerBuiltinPane).\n *\n * The chat loads this module just after first paint (preloaded), never on\n * it — keep `*.pane.tsx` files to a registration and a lazy import.\n */\nimport './builtin-panes.js';\nimport { registerUnitPanes } from './register-adapter.js';\n\n/**\n * Every `*.pane.ts(x)` under routes/verse — keyed by path, evaluated for\n * their registrations. Exported so the registry test can check discovery.\n */\nexport const DISCOVERED_PANE_MODULES: Record<string, unknown> = import.meta.glob(['../**/*.pane.ts', '../**/*.pane.tsx'], { eager: true });\n\n/**\n * Every unit's `register.ts` (routes/verse/<unit>/register.ts) — the\n * self-describing form (`export const BROWSER_PANE = { id, label, load, … }`)\n * units shipped while the registry was landing. Each such export becomes a\n * registered pane (register-adapter.ts); a unit whose file has not landed is\n * simply an absent key. Registered AFTER the first-party panes (this body\n * runs once every import above has evaluated), so they replace the stubs.\n */\nexport const UNIT_PANE_MODULES: Record<string, unknown> = import.meta.glob('../*/register.ts', { eager: true });\nexport const UNIT_PANE_IDS: readonly string[] = registerUnitPanes(UNIT_PANE_MODULES);\n\nexport * from './pane-registry.js';\nexport { isUnitPaneRegistration, registerUnitPanes, type UnitPaneRegistration } from './register-adapter.js';\nexport { registerBuiltinPanes } from './builtin-panes.js';\n"],"file":"panes-5GU8cuI9.js"}
@@ -0,0 +1,2 @@
1
+ import{r as e}from"./rolldown-runtime-hePW80VL.js";import{s as t}from"./index-BC5Uslm5.js";import{o as n}from"./tool-semantics-xF0Fw2Ck.js";var r=e(t(),1),i=[],a=(0,r.createContext)(i);function o(e){return e}function s(e){return e.replace(/\\/g,`/`).replace(/\/+$/,``).replace(/^\/private(?=\/(?:tmp|var|etc)(?:\/|$))/,``).replace(/^[A-Z](?=:)/,e=>e.toLowerCase())}function c(e,t=i){let n=s(e),r=``;for(let e of t){let t=s(e);t.length>r.length&&!/^(?:[a-z]:)?$/.test(t)&&(n===t||n.startsWith(`${t}/`))&&(r=t)}let a=e.replace(/[\\/]+$/,``);if(r){let e=n.length-r.length-1;return e>0?a.slice(a.length-e):a.slice(Math.max(a.lastIndexOf(`/`),a.lastIndexOf(`\\`))+1)}if(!/^(?:[\\/]|[A-Za-z]:[\\/])/.test(e))return e.replace(/^\.[\\/]/,``);let o=e.includes(`/`)?`/`:`\\`,c=e.replace(/^[A-Za-z]:/,``).split(/[\\/]/).filter(Boolean);return c.length>4?`…${o}${c.slice(-3).join(o)}`:e}function l(e){let t=typeof e==`object`&&e?e:null;return t&&typeof t.command!=`string`&&typeof t.cmd!=`string`?n(t)[0]??null:null}function u(){let e=(0,r.useContext)(a);return(0,r.useCallback)(t=>c(t,e),[e])}export{u as a,l as i,o as n,c as r,a as t};
2
+ //# sourceMappingURL=path-display-ZSzKoo8T.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-display-ZSzKoo8T.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/chat/path-display.ts"],"sourcesContent":["/**\n * routes/verse/chat/path-display.ts — how a file path READS in the chat.\n *\n * Tool payloads carry whatever path the CLI used, and that is usually\n * absolute: `/private/tmp/…/scratchpad/e2e-proj-39/math.ts` for a file the\n * operator knows as `math.ts`. Shown raw, the one part that identifies the\n * file is what the row's ellipsis clips. So every path the transcript draws\n * goes through `displayPath`:\n *\n * 1. relative to the chat's roots (the longest root that contains it wins —\n * a worktree nested in its repo is its own root). Paths and roots are\n * compared as `keyOf`s, so `\\` vs `/`, a trailing separator, macOS's\n * `/private/tmp` for `/tmp` and `c:` for `C:` all still match; the rest\n * is sliced out of the ORIGINAL path, in the CLI's own separators;\n * 2. otherwise as the hub sent it when it is relative or `~/…`;\n * 3. otherwise, when it is long, its last three segments behind `…/`.\n *\n * HOME. The hub rewrites the operator's OWN home to `~` on every payload\n * (sanitizePublicJson) and is the only side that knows which home that is —\n * so a `~/…` path or root already says it, and matches as-is. Nothing here\n * guesses a home from `/Users/<x>`, `/home/<x>` or `C:\\Users\\<x>`: one that\n * reaches the browser is another account's or /Users/Shared, and drawing it\n * as `~` (or as in-project, via a `~` root) passes it off as the operator's.\n *\n * Display only. The full path stays in the tooltip and is never rewritten in\n * anything handed back to a tool, a search or a jump anchor. (It is in the\n * chat's first-paint chunk, hence the terse body.)\n */\nimport { createContext, useCallback, useContext } from 'react';\nimport { pathsIn } from './tool-semantics.js';\n\nconst NO_ROOTS: readonly string[] = [];\n\n/** The chat's roots, primary first (Workspace provides them; Transcript can override). */\nexport const PathRootsContext = createContext<readonly string[]>(NO_ROOTS);\n\n/**\n * A path as the operator's home reads: unchanged. The hub already spelled\n * that home `~`; any other `/Users/<x>` is someone else's (see HOME above).\n * Kept as the one seam home display goes through (SessionRoots uses it).\n */\nexport function abbreviateHome(path: string): string {\n return path;\n}\n\n/**\n * One folder's comparable form: `/` separators, no trailing one, the\n * `/private` alias folded (/tmp, /var and /etc are symlinks into it and roots\n * are not realpath'd), a lower-case drive letter. Only the fold changes the\n * length, and only at the head — so a matched tail maps back onto the original.\n */\nfunction keyOf(path: string): string {\n return path.replace(/\\\\/g, '/').replace(/\\/+$/, '')\n .replace(/^\\/private(?=\\/(?:tmp|var|etc)(?:\\/|$))/, '')\n .replace(/^[A-Z](?=:)/, (d) => d.toLowerCase());\n}\n\n/** What the transcript draws for `path`; the full path belongs in the tooltip. */\nexport function displayPath(path: string, roots: readonly string[] = NO_ROOTS): string {\n const key = keyOf(path);\n let root = '';\n for (const raw of roots) {\n const r = keyOf(raw);\n // A bare `/`, `C:` or `\\\\` root would claim every path on the machine.\n if (r.length > root.length && !/^(?:[a-z]:)?$/.test(r) && (key === r || key.startsWith(`${r}/`))) root = r;\n }\n const own = path.replace(/[\\\\/]+$/, '');\n // Inside a root: the rest of the path, or — for the root itself — its name.\n if (root) {\n const rest = key.length - root.length - 1;\n return rest > 0 ? own.slice(own.length - rest) : own.slice(Math.max(own.lastIndexOf('/'), own.lastIndexOf('\\\\')) + 1);\n }\n if (!/^(?:[\\\\/]|[A-Za-z]:[\\\\/])/.test(path)) return path.replace(/^\\.[\\\\/]/, '');\n const sep = path.includes('/') ? '/' : '\\\\';\n const parts = path.replace(/^[A-Za-z]:/, '').split(/[\\\\/]/).filter(Boolean);\n return parts.length > 4 ? `…${sep}${parts.slice(-3).join(sep)}` : path;\n}\n\n/**\n * The file a tool call names, when it runs no command — a shell call keeps\n * its command line verbatim (rewriting a command is not display).\n */\nexport function inputPath(input: unknown): string | null {\n const rec = input !== null && typeof input === 'object' ? input as Record<string, unknown> : null;\n return rec && typeof rec.command !== 'string' && typeof rec.cmd !== 'string' ? pathsIn(rec)[0] ?? null : null;\n}\n\n/** `displayPath` bound to the roots in context. */\nexport function useDisplayPath(): (path: string) => string {\n const roots = useContext(PathRootsContext);\n return useCallback((path: string) => displayPath(path, roots), [roots]);\n}\n"],"mappings":"2JA+BM,EAA8B,CAAC,EAGxB,GAAA,EAAmB,EAAA,cAAA,CAAiC,CAAQ,EAOzE,SAAgB,EAAe,EAAsB,CACnD,OAAO,CACT,CAQA,SAAS,EAAM,EAAsB,CACnC,OAAO,EAAK,QAAQ,MAAO,GAAG,CAAC,CAAC,QAAQ,OAAQ,EAAE,CAAC,CAChD,QAAQ,0CAA2C,EAAE,CAAC,CACtD,QAAQ,cAAgB,GAAM,EAAE,YAAY,CAAC,CAClD,CAGA,SAAgB,EAAY,EAAc,EAA2B,EAAkB,CACrF,IAAM,EAAM,EAAM,CAAI,EAClB,EAAO,GACX,IAAK,IAAM,KAAO,EAAO,CACvB,IAAM,EAAI,EAAM,CAAG,EAEf,EAAE,OAAS,EAAK,QAAU,CAAC,gBAAgB,KAAK,CAAC,IAAM,IAAQ,GAAK,EAAI,WAAW,GAAG,EAAE,EAAE,KAAI,EAAO,EAC3G,CACA,IAAM,EAAM,EAAK,QAAQ,UAAW,EAAE,EAEtC,GAAI,EAAM,CACR,IAAM,EAAO,EAAI,OAAS,EAAK,OAAS,EACxC,OAAO,EAAO,EAAI,EAAI,MAAM,EAAI,OAAS,CAAI,EAAI,EAAI,MAAM,KAAK,IAAI,EAAI,YAAY,GAAG,EAAG,EAAI,YAAY,IAAI,CAAC,EAAI,CAAC,CACtH,CACA,GAAI,CAAC,4BAA4B,KAAK,CAAI,EAAG,OAAO,EAAK,QAAQ,WAAY,EAAE,EAC/E,IAAM,EAAM,EAAK,SAAS,GAAG,EAAI,IAAM,KACjC,EAAQ,EAAK,QAAQ,aAAc,EAAE,CAAC,CAAC,MAAM,OAAO,CAAC,CAAC,OAAO,OAAO,EAC1E,OAAO,EAAM,OAAS,EAAI,IAAI,IAAM,EAAM,MAAM,EAAE,CAAC,CAAC,KAAK,CAAG,IAAM,CACpE,CAMA,SAAgB,EAAU,EAA+B,CACvD,IAAM,EAAwB,OAAO,GAAU,UAAnC,EAA8C,EAAmC,KAC7F,OAAO,GAAO,OAAO,EAAI,SAAY,UAAY,OAAO,EAAI,KAAQ,SAAW,EAAQ,CAAG,CAAC,CAAC,IAAM,KAAO,IAC3G,CAGA,SAAgB,GAA2C,CACzD,IAAM,GAAA,EAAQ,EAAA,WAAA,CAAW,CAAgB,EACzC,OAAA,EAAO,EAAA,YAAA,CAAa,GAAiB,EAAY,EAAM,CAAK,EAAG,CAAC,CAAK,CAAC,CACxE"}
@@ -0,0 +1,2 @@
1
+ import{R as e}from"./VerseConsoleApp-DjPpZLo1.js";import{n as t}from"./composer-draft-DB025_AW.js";var n=/(^|\s)![a-z0-9][a-z0-9-]{1,47}(?:@v?\d{1,6})?(?=\s|$)/g;function r(e,t){let r=e.replace(n,(e,t)=>t).replace(/^\s+/,``);return r?`${t} ${r}`:`${t} `}function i(e,t){let n=Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype,`value`)?.set;n?n.call(e,t):e.value=t,e.dispatchEvent(new Event(`input`,{bubbles:!0})),e.focus();let r=e.value.length;try{e.setSelectionRange(r,r)}catch{}}function a(e,n){let a=t(n);return!a||a.disabled?!1:(i(a,r(a.value,e)),!0)}async function o(t,n={}){e(`chat`);let r=Date.now()+(n.waitMs??3e3);for(;;){if(a(t,n.root))return!0;if(Date.now()>=r)return!1;await new Promise(e=>setTimeout(e,60))}}export{a as n,o as t};
2
+ //# sourceMappingURL=playbook-composer-D04tqOmU.js.map