@ashlr/hub 3.16.0 → 3.16.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 (997) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +2 -2
  3. package/dist/authority-surface.json +5 -5
  4. package/dist/build-identity.json +2 -2
  5. package/dist/core/daemon/loop.js +1 -0
  6. package/dist/core/daemon/loop.js.map +1 -1
  7. package/dist/core/daemon/tick-hooks.d.ts +2 -0
  8. package/dist/core/daemon/tick-hooks.js.map +1 -1
  9. package/dist/core/fleet/tick-hooks-live.d.ts +2 -1
  10. package/dist/core/fleet/tick-hooks-live.js +49 -7
  11. package/dist/core/fleet/tick-hooks-live.js.map +1 -1
  12. package/dist/core/web/public/next/assets/ActionMenu-Bv-kQxD4.js +2 -0
  13. package/dist/core/web/public/next/assets/ActionMenu-Bv-kQxD4.js.map +1 -0
  14. package/dist/core/web/public/next/assets/Advanced-Be7Frv-G.js +2 -0
  15. package/dist/core/web/public/next/assets/Advanced-Be7Frv-G.js.map +1 -0
  16. package/dist/core/web/public/next/assets/AgentDetailScreen-DzqHmufO.js +2 -0
  17. package/dist/core/web/public/next/assets/AgentDetailScreen-DzqHmufO.js.map +1 -0
  18. package/dist/core/web/public/next/assets/AgentToolsSheet-D00kLnIq.js +2 -0
  19. package/dist/core/web/public/next/assets/AgentToolsSheet-D00kLnIq.js.map +1 -0
  20. package/dist/core/web/public/next/assets/AgentToolsStrip-CSus9Dr3.js +2 -0
  21. package/dist/core/web/public/next/assets/AgentToolsStrip-CSus9Dr3.js.map +1 -0
  22. package/dist/core/web/public/next/assets/AgentsScreen-WoR0oSLZ.js +2 -0
  23. package/dist/core/web/public/next/assets/AgentsScreen-WoR0oSLZ.js.map +1 -0
  24. package/dist/core/web/public/next/assets/AgentsSection-D5mKoOhH.js +3 -0
  25. package/dist/core/web/public/next/assets/AgentsSection-D5mKoOhH.js.map +1 -0
  26. package/dist/core/web/public/next/assets/App-Uy6lDpKw.js +8 -0
  27. package/dist/core/web/public/next/assets/App-Uy6lDpKw.js.map +1 -0
  28. package/dist/core/web/public/next/assets/AppsSection-Cfhmc4r3.js +2 -0
  29. package/dist/core/web/public/next/assets/AppsSection-Cfhmc4r3.js.map +1 -0
  30. package/dist/core/web/public/next/assets/AreaTrend-Bz3ETKPk.js +2 -0
  31. package/dist/core/web/public/next/assets/AreaTrend-Bz3ETKPk.js.map +1 -0
  32. package/dist/core/web/public/next/assets/AutomationsSection-D4K8db0o.js +2 -0
  33. package/dist/core/web/public/next/assets/AutomationsSection-D4K8db0o.js.map +1 -0
  34. package/dist/core/web/public/next/assets/AutonomyOffState-DUiNMgr8.js +3 -0
  35. package/dist/core/web/public/next/assets/AutonomyOffState-DUiNMgr8.js.map +1 -0
  36. package/dist/core/web/public/next/assets/AutonomySection-wxRZ7vSw.js +2 -0
  37. package/dist/core/web/public/next/assets/AutonomySection-wxRZ7vSw.js.map +1 -0
  38. package/dist/core/web/public/next/assets/AutonomyStatus-B-PCVnFO.js +2 -0
  39. package/dist/core/web/public/next/assets/AutonomyStatus-B-PCVnFO.js.map +1 -0
  40. package/dist/core/web/public/next/assets/BranchBar-Bs4r_Vh6.js +2 -0
  41. package/dist/core/web/public/next/assets/BranchBar-Bs4r_Vh6.js.map +1 -0
  42. package/dist/core/web/public/next/assets/BrowserPanel-BMQcviI1.js +7 -0
  43. package/dist/core/web/public/next/assets/BrowserPanel-BMQcviI1.js.map +1 -0
  44. package/dist/core/web/public/next/assets/BudgetControl-A4TEONtT.js +2 -0
  45. package/dist/core/web/public/next/assets/BudgetControl-A4TEONtT.js.map +1 -0
  46. package/dist/core/web/public/next/assets/Button-CMR_Op-0.js +2 -0
  47. package/dist/core/web/public/next/assets/Button-CMR_Op-0.js.map +1 -0
  48. package/dist/core/web/public/next/assets/CapacityStrip-B-2NDrA5.js +2 -0
  49. package/dist/core/web/public/next/assets/CapacityStrip-B-2NDrA5.js.map +1 -0
  50. package/dist/core/web/public/next/assets/ChangesPaneHost-CS5qGjwM.js +16 -0
  51. package/dist/core/web/public/next/assets/ChangesPaneHost-CS5qGjwM.js.map +1 -0
  52. package/dist/core/web/public/next/assets/ChartFrame-sZTnZkVd.js +2 -0
  53. package/dist/core/web/public/next/assets/ChartFrame-sZTnZkVd.js.map +1 -0
  54. package/dist/core/web/public/next/assets/ChatPanes-CicgTVpN.js +2 -0
  55. package/dist/core/web/public/next/assets/ChatPanes-CicgTVpN.js.map +1 -0
  56. package/dist/core/web/public/next/assets/ChatSection-Cc6sudpF.js +3 -0
  57. package/dist/core/web/public/next/assets/ChatSection-Cc6sudpF.js.map +1 -0
  58. package/dist/core/web/public/next/assets/ChecksPanel-BGWgv8Zb.js +5 -0
  59. package/dist/core/web/public/next/assets/ChecksPanel-BGWgv8Zb.js.map +1 -0
  60. package/dist/core/web/public/next/assets/CloudBudgetForm-CqsidwfU.js +2 -0
  61. package/dist/core/web/public/next/assets/CloudBudgetForm-CqsidwfU.js.map +1 -0
  62. package/dist/core/web/public/next/assets/CommandPalette-rwEZ20MN.js +3 -0
  63. package/dist/core/web/public/next/assets/CommandPalette-rwEZ20MN.js.map +1 -0
  64. package/dist/core/web/public/next/assets/CommandSection-C2CLkVXN.js +3 -0
  65. package/dist/core/web/public/next/assets/CommandSection-C2CLkVXN.js.map +1 -0
  66. package/dist/core/web/public/next/assets/CommandWorkflowForm-DAbPIdI3.js +9 -0
  67. package/dist/core/web/public/next/assets/CommandWorkflowForm-DAbPIdI3.js.map +1 -0
  68. package/dist/core/web/public/next/assets/CommandWorkflowPicker-fqHtzYXX.js +3 -0
  69. package/dist/core/web/public/next/assets/CommandWorkflowPicker-fqHtzYXX.js.map +1 -0
  70. package/dist/core/web/public/next/assets/CompareDialog-Cwfpaa8I.js +4 -0
  71. package/dist/core/web/public/next/assets/CompareDialog-Cwfpaa8I.js.map +1 -0
  72. package/dist/core/web/public/next/assets/ComputerControl-DU0cuVSY.js +2 -0
  73. package/dist/core/web/public/next/assets/ComputerControl-DU0cuVSY.js.map +1 -0
  74. package/dist/core/web/public/next/assets/ConfirmDialog-B_wCnbcC.js +2 -0
  75. package/dist/core/web/public/next/assets/ConfirmDialog-B_wCnbcC.js.map +1 -0
  76. package/dist/core/web/public/next/assets/DeleteChatDialog-CxMh53yX.js +2 -0
  77. package/dist/core/web/public/next/assets/DeleteChatDialog-CxMh53yX.js.map +1 -0
  78. package/dist/core/web/public/next/assets/DevinStopDialog-D9Bziccz.js +2 -0
  79. package/dist/core/web/public/next/assets/DevinStopDialog-D9Bziccz.js.map +1 -0
  80. package/dist/core/web/public/next/assets/Dialog-DI5D6Is2.js +2 -0
  81. package/dist/core/web/public/next/assets/Dialog-DI5D6Is2.js.map +1 -0
  82. package/dist/core/web/public/next/assets/DiffPane-Buo19Bqr.js +2 -0
  83. package/dist/core/web/public/next/assets/DiffPane-Buo19Bqr.js.map +1 -0
  84. package/dist/core/web/public/next/assets/DiffViewer-dO0RQoqA.js +2 -0
  85. package/dist/core/web/public/next/assets/DiffViewer-dO0RQoqA.js.map +1 -0
  86. package/dist/core/web/public/next/assets/DockHost-KJUHjoiG.js +2 -0
  87. package/dist/core/web/public/next/assets/DockHost-KJUHjoiG.js.map +1 -0
  88. package/dist/core/web/public/next/assets/EmptyState-C3BUt2Ev.js +2 -0
  89. package/dist/core/web/public/next/assets/EmptyState-C3BUt2Ev.js.map +1 -0
  90. package/dist/core/web/public/next/assets/Epistemic-DlG2QqKJ.js +2 -0
  91. package/dist/core/web/public/next/assets/Epistemic-DlG2QqKJ.js.map +1 -0
  92. package/dist/core/web/public/next/assets/EvidenceTimeline-D1GB9F-f.js +2 -0
  93. package/dist/core/web/public/next/assets/EvidenceTimeline-D1GB9F-f.js.map +1 -0
  94. package/dist/core/web/public/next/assets/FilesPane-icSP5vPt.js +2 -0
  95. package/dist/core/web/public/next/assets/FilesPane-icSP5vPt.js.map +1 -0
  96. package/dist/core/web/public/next/assets/FleetScreen-V_X8SeD3.js +2 -0
  97. package/dist/core/web/public/next/assets/FleetScreen-V_X8SeD3.js.map +1 -0
  98. package/dist/core/web/public/next/assets/FleetSection-xyhfpRJy.js +5 -0
  99. package/dist/core/web/public/next/assets/FleetSection-xyhfpRJy.js.map +1 -0
  100. package/dist/core/web/public/next/assets/Funnel-BlzQ5FOU.js +2 -0
  101. package/dist/core/web/public/next/assets/Funnel-BlzQ5FOU.js.map +1 -0
  102. package/dist/core/web/public/next/assets/GearTray-Dvu-ee-h.js +2 -0
  103. package/dist/core/web/public/next/assets/GearTray-Dvu-ee-h.js.map +1 -0
  104. package/dist/core/web/public/next/assets/GitDialogs-o0eCEqAN.js +2 -0
  105. package/dist/core/web/public/next/assets/GitDialogs-o0eCEqAN.js.map +1 -0
  106. package/dist/core/web/public/next/assets/GrowthSection-CyqJOzob.js +3 -0
  107. package/dist/core/web/public/next/assets/GrowthSection-CyqJOzob.js.map +1 -0
  108. package/dist/core/web/public/next/assets/HandoffDialog-0uTNyK99.js +2 -0
  109. package/dist/core/web/public/next/assets/HandoffDialog-0uTNyK99.js.map +1 -0
  110. package/dist/core/web/public/next/assets/HomeBody-DJjN3GTV.js +3 -0
  111. package/dist/core/web/public/next/assets/HomeBody-DJjN3GTV.js.map +1 -0
  112. package/dist/core/web/public/next/assets/HomeSeats-IJvjh9iH.js +2 -0
  113. package/dist/core/web/public/next/assets/HomeSeats-IJvjh9iH.js.map +1 -0
  114. package/dist/core/web/public/next/assets/Input-CsSZI8QC.js +2 -0
  115. package/dist/core/web/public/next/assets/Input-CsSZI8QC.js.map +1 -0
  116. package/dist/core/web/public/next/assets/LaunchDialog-DReYqlI0.js +9 -0
  117. package/dist/core/web/public/next/assets/LaunchDialog-DReYqlI0.js.map +1 -0
  118. package/dist/core/web/public/next/assets/LeaderCard-82indlOE.js +2 -0
  119. package/dist/core/web/public/next/assets/LeaderCard-82indlOE.js.map +1 -0
  120. package/dist/core/web/public/next/assets/LeaderConversation-8hDF6Gh3.js +3 -0
  121. package/dist/core/web/public/next/assets/LeaderConversation-8hDF6Gh3.js.map +1 -0
  122. package/dist/core/web/public/next/assets/LeaderScreen-BxPiwHcT.js +2 -0
  123. package/dist/core/web/public/next/assets/LeaderScreen-BxPiwHcT.js.map +1 -0
  124. package/dist/core/web/public/next/assets/LessonsPanel-BG558qil.js +2 -0
  125. package/dist/core/web/public/next/assets/LessonsPanel-BG558qil.js.map +1 -0
  126. package/dist/core/web/public/next/assets/LiveTimer-DUgUBr49.js +2 -0
  127. package/dist/core/web/public/next/assets/LiveTimer-DUgUBr49.js.map +1 -0
  128. package/dist/core/web/public/next/assets/LocalSeatBadge-D6U4Q2P3.js +2 -0
  129. package/dist/core/web/public/next/assets/LocalSeatBadge-D6U4Q2P3.js.map +1 -0
  130. package/dist/core/web/public/next/assets/MatrixHeatmap-Brn70z84.js +2 -0
  131. package/dist/core/web/public/next/assets/MatrixHeatmap-Brn70z84.js.map +1 -0
  132. package/dist/core/web/public/next/assets/McpSection-Dz8Ga2Rg.js +2 -0
  133. package/dist/core/web/public/next/assets/McpSection-Dz8Ga2Rg.js.map +1 -0
  134. package/dist/core/web/public/next/assets/MessageMarkdown-CQfYQaXB.js +3 -0
  135. package/dist/core/web/public/next/assets/MessageMarkdown-CQfYQaXB.js.map +1 -0
  136. package/dist/core/web/public/next/assets/MessageMarkdownRenderer-DPaNQMj8.js +72 -0
  137. package/dist/core/web/public/next/assets/MessageMarkdownRenderer-DPaNQMj8.js.map +1 -0
  138. package/dist/core/web/public/next/assets/Meter-TnD7Ris6.js +2 -0
  139. package/dist/core/web/public/next/assets/Meter-TnD7Ris6.js.map +1 -0
  140. package/dist/core/web/public/next/assets/MicButton-Dc9g2Z_E.js +2 -0
  141. package/dist/core/web/public/next/assets/MicButton-Dc9g2Z_E.js.map +1 -0
  142. package/dist/core/web/public/next/assets/MindSection-DGpYq8c7.js +3 -0
  143. package/dist/core/web/public/next/assets/MindSection-DGpYq8c7.js.map +1 -0
  144. package/dist/core/web/public/next/assets/MobileComposer-DbSZ2rxa.js +2 -0
  145. package/dist/core/web/public/next/assets/MobileComposer-DbSZ2rxa.js.map +1 -0
  146. package/dist/core/web/public/next/assets/MobileGuardSheet-qQJev_w3.js +2 -0
  147. package/dist/core/web/public/next/assets/MobileGuardSheet-qQJev_w3.js.map +1 -0
  148. package/dist/core/web/public/next/assets/MobileRuntime-BEnY4Uvs.js +3 -0
  149. package/dist/core/web/public/next/assets/MobileRuntime-BEnY4Uvs.js.map +1 -0
  150. package/dist/core/web/public/next/assets/MoreScreen-CG0E5S8G.js +2 -0
  151. package/dist/core/web/public/next/assets/MoreScreen-CG0E5S8G.js.map +1 -0
  152. package/dist/core/web/public/next/assets/MultiModelBar-DgMyP8IC.js +7 -0
  153. package/dist/core/web/public/next/assets/MultiModelBar-DgMyP8IC.js.map +1 -0
  154. package/dist/core/web/public/next/assets/MutationTokenDialog-T3r9EtHi.js +2 -0
  155. package/dist/core/web/public/next/assets/MutationTokenDialog-T3r9EtHi.js.map +1 -0
  156. package/dist/core/web/public/next/assets/NeedsYouDrawer-BDAcTlK8.js +3 -0
  157. package/dist/core/web/public/next/assets/NeedsYouDrawer-BDAcTlK8.js.map +1 -0
  158. package/dist/core/web/public/next/assets/NeedsYouList-BFubkjzF.js +2 -0
  159. package/dist/core/web/public/next/assets/NeedsYouList-BFubkjzF.js.map +1 -0
  160. package/dist/core/web/public/next/assets/NeedsYouScreen-B3Dk15T_.js +2 -0
  161. package/dist/core/web/public/next/assets/NeedsYouScreen-B3Dk15T_.js.map +1 -0
  162. package/dist/core/web/public/next/assets/NewAgentScreen-zf1bqGYC.js +2 -0
  163. package/dist/core/web/public/next/assets/NewAgentScreen-zf1bqGYC.js.map +1 -0
  164. package/dist/core/web/public/next/assets/NewChatDialog-el95cRTF.js +4 -0
  165. package/dist/core/web/public/next/assets/NewChatDialog-el95cRTF.js.map +1 -0
  166. package/dist/core/web/public/next/assets/OnboardingFlow-Bi8gZOuz.js +3 -0
  167. package/dist/core/web/public/next/assets/OnboardingFlow-Bi8gZOuz.js.map +1 -0
  168. package/dist/core/web/public/next/assets/OnboardingGate-CRexmMn5.js +3 -0
  169. package/dist/core/web/public/next/assets/OnboardingGate-CRexmMn5.js.map +1 -0
  170. package/dist/core/web/public/next/assets/PlaybooksSection-R2_wyVpQ.js +9 -0
  171. package/dist/core/web/public/next/assets/PlaybooksSection-R2_wyVpQ.js.map +1 -0
  172. package/dist/core/web/public/next/assets/PreviewPane-Djw_GJ20.js +2 -0
  173. package/dist/core/web/public/next/assets/PreviewPane-Djw_GJ20.js.map +1 -0
  174. package/dist/core/web/public/next/assets/ProviderLogo-DIfJXNWf.js +2 -0
  175. package/dist/core/web/public/next/assets/ProviderLogo-DIfJXNWf.js.map +1 -0
  176. package/dist/core/web/public/next/assets/RailStatus-B3eI2AaD.js +2 -0
  177. package/dist/core/web/public/next/assets/RailStatus-B3eI2AaD.js.map +1 -0
  178. package/dist/core/web/public/next/assets/ReasoningPane-ExT8XgQB.js +2 -0
  179. package/dist/core/web/public/next/assets/ReasoningPane-ExT8XgQB.js.map +1 -0
  180. package/dist/core/web/public/next/assets/ReasoningSheet-YF4OS4lM.js +2 -0
  181. package/dist/core/web/public/next/assets/ReasoningSheet-YF4OS4lM.js.map +1 -0
  182. package/dist/core/web/public/next/assets/RefreshIndicator-BJoefKSa.js +2 -0
  183. package/dist/core/web/public/next/assets/RefreshIndicator-BJoefKSa.js.map +1 -0
  184. package/dist/core/web/public/next/assets/RemoteMobileApp-C2SflRkm.js +2 -0
  185. package/dist/core/web/public/next/assets/RemoteMobileApp-C2SflRkm.js.map +1 -0
  186. package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-FkAdn3Sv.js +7 -0
  187. package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-FkAdn3Sv.js.map +1 -0
  188. package/dist/core/web/public/next/assets/ResourcesChrome-CFHrLqmA.js +3 -0
  189. package/dist/core/web/public/next/assets/ResourcesChrome-CFHrLqmA.js.map +1 -0
  190. package/dist/core/web/public/next/assets/ResourcesDrawer-DtnZgDr_.js +3 -0
  191. package/dist/core/web/public/next/assets/ResourcesDrawer-DtnZgDr_.js.map +1 -0
  192. package/dist/core/web/public/next/assets/RouteErrorBoundary-DTz5-ndE.js +2 -0
  193. package/dist/core/web/public/next/assets/RouteErrorBoundary-DTz5-ndE.js.map +1 -0
  194. package/dist/core/web/public/next/assets/RunInCloudAction-DvoDMV54.js +2 -0
  195. package/dist/core/web/public/next/assets/RunInCloudAction-DvoDMV54.js.map +1 -0
  196. package/dist/core/web/public/next/assets/RunInDevinAction-BwCkFxLX.js +2 -0
  197. package/dist/core/web/public/next/assets/RunInDevinAction-BwCkFxLX.js.map +1 -0
  198. package/dist/core/web/public/next/assets/ScreenHost-jdgnt5U2.js +3 -0
  199. package/dist/core/web/public/next/assets/ScreenHost-jdgnt5U2.js.map +1 -0
  200. package/dist/core/web/public/next/assets/SeatSelector-DnpH5D_D.js +3 -0
  201. package/dist/core/web/public/next/assets/SeatSelector-DnpH5D_D.js.map +1 -0
  202. package/dist/core/web/public/next/assets/Segmented-BECZDbsg.js +2 -0
  203. package/dist/core/web/public/next/assets/Segmented-BECZDbsg.js.map +1 -0
  204. package/dist/core/web/public/next/assets/Select-DjQDkPJU.js +2 -0
  205. package/dist/core/web/public/next/assets/Select-DjQDkPJU.js.map +1 -0
  206. package/dist/core/web/public/next/assets/SessionGate-CWuI8dDR.js +2 -0
  207. package/dist/core/web/public/next/assets/SessionGate-CWuI8dDR.js.map +1 -0
  208. package/dist/core/web/public/next/assets/SessionInsightChip-DRsIQu29.js +2 -0
  209. package/dist/core/web/public/next/assets/SessionInsightChip-DRsIQu29.js.map +1 -0
  210. package/dist/core/web/public/next/assets/SessionSearch-Bya3EXJl.js +2 -0
  211. package/dist/core/web/public/next/assets/SessionSearch-Bya3EXJl.js.map +1 -0
  212. package/dist/core/web/public/next/assets/SettingsSection-CXjiHNQb.js +2 -0
  213. package/dist/core/web/public/next/assets/SettingsSection-CXjiHNQb.js.map +1 -0
  214. package/dist/core/web/public/next/assets/SetupChecklist-YUMOJNbk.js +2 -0
  215. package/dist/core/web/public/next/assets/SetupChecklist-YUMOJNbk.js.map +1 -0
  216. package/dist/core/web/public/next/assets/ShadowDecisions-BP2WgGMi.js +3 -0
  217. package/dist/core/web/public/next/assets/ShadowDecisions-BP2WgGMi.js.map +1 -0
  218. package/dist/core/web/public/next/assets/Sheet-Czuz3h6A.js +2 -0
  219. package/dist/core/web/public/next/assets/Sheet-Czuz3h6A.js.map +1 -0
  220. package/dist/core/web/public/next/assets/ShortcutsOverlay-D_ICte5N.js +2 -0
  221. package/dist/core/web/public/next/assets/ShortcutsOverlay-D_ICte5N.js.map +1 -0
  222. package/dist/core/web/public/next/assets/Sidebar-CcI1_B9Y.js +3 -0
  223. package/dist/core/web/public/next/assets/Sidebar-CcI1_B9Y.js.map +1 -0
  224. package/dist/core/web/public/next/assets/SkipToContent-B0GAKhYQ.js +2 -0
  225. package/dist/core/web/public/next/assets/SkipToContent-B0GAKhYQ.js.map +1 -0
  226. package/dist/core/web/public/next/assets/Slider-Dzv55CNY.js +2 -0
  227. package/dist/core/web/public/next/assets/Slider-Dzv55CNY.js.map +1 -0
  228. package/dist/core/web/public/next/assets/SourcesPane-rxRCi7cL.js +2 -0
  229. package/dist/core/web/public/next/assets/SourcesPane-rxRCi7cL.js.map +1 -0
  230. package/dist/core/web/public/next/assets/SourcesPanel-LyMp7aLt.js +2 -0
  231. package/dist/core/web/public/next/assets/SourcesPanel-LyMp7aLt.js.map +1 -0
  232. package/dist/core/web/public/next/assets/StatTile-1_HPOflX.js +2 -0
  233. package/dist/core/web/public/next/assets/StatTile-1_HPOflX.js.map +1 -0
  234. package/dist/core/web/public/next/assets/StatusBadge-zR7YgIa8.js +2 -0
  235. package/dist/core/web/public/next/assets/StatusBadge-zR7YgIa8.js.map +1 -0
  236. package/dist/core/web/public/next/assets/StepBand-BGX2RpFV.js +2 -0
  237. package/dist/core/web/public/next/assets/StepBand-BGX2RpFV.js.map +1 -0
  238. package/dist/core/web/public/next/assets/Surface-BEToBKC3.js +2 -0
  239. package/dist/core/web/public/next/assets/Surface-BEToBKC3.js.map +1 -0
  240. package/dist/core/web/public/next/assets/Swimlane-DAf7u5p3.js +2 -0
  241. package/dist/core/web/public/next/assets/Swimlane-DAf7u5p3.js.map +1 -0
  242. package/dist/core/web/public/next/assets/Switch-mvc9lQcT.js +2 -0
  243. package/dist/core/web/public/next/assets/Switch-mvc9lQcT.js.map +1 -0
  244. package/dist/core/web/public/next/assets/Tag-Chqolzxz.js +2 -0
  245. package/dist/core/web/public/next/assets/Tag-Chqolzxz.js.map +1 -0
  246. package/dist/core/web/public/next/assets/TerminalPane-4wn3AxS0.js +3 -0
  247. package/dist/core/web/public/next/assets/TerminalPane-4wn3AxS0.js.map +1 -0
  248. package/dist/core/web/public/next/assets/TerminalPane-D7-O0ssr.js +26 -0
  249. package/dist/core/web/public/next/assets/TerminalPane-D7-O0ssr.js.map +1 -0
  250. package/dist/core/web/public/next/assets/ThinkingBlock-gWESdTxs.js +2 -0
  251. package/dist/core/web/public/next/assets/ThinkingBlock-gWESdTxs.js.map +1 -0
  252. package/dist/core/web/public/next/assets/UniverseConsoleApp-XqJvgt7b.js +2 -0
  253. package/dist/core/web/public/next/assets/UniverseConsoleApp-XqJvgt7b.js.map +1 -0
  254. package/dist/core/web/public/next/assets/UniverseView-D0j9HVku.js +9 -0
  255. package/dist/core/web/public/next/assets/UniverseView-D0j9HVku.js.map +1 -0
  256. package/dist/core/web/public/next/assets/UsageSection-DnSPo4Ua.js +3 -0
  257. package/dist/core/web/public/next/assets/UsageSection-DnSPo4Ua.js.map +1 -0
  258. package/dist/core/web/public/next/assets/UsePlaybookAction-71M3gO7g.js +2 -0
  259. package/dist/core/web/public/next/assets/UsePlaybookAction-71M3gO7g.js.map +1 -0
  260. package/dist/core/web/public/next/assets/VerseConsoleApp-DO84Xscn.js +3 -0
  261. package/dist/core/web/public/next/assets/VerseConsoleApp-DO84Xscn.js.map +1 -0
  262. package/dist/core/web/public/next/assets/VerseMobileApp-CrCDQcw5.js +3 -0
  263. package/dist/core/web/public/next/assets/VerseMobileApp-CrCDQcw5.js.map +1 -0
  264. package/dist/core/web/public/next/assets/VerseShared-CFE5B-IY.js +2 -0
  265. package/dist/core/web/public/next/assets/VerseShared-CFE5B-IY.js.map +1 -0
  266. package/dist/core/web/public/next/assets/VoiceHud-CumHX7If.js +2 -0
  267. package/dist/core/web/public/next/assets/VoiceHud-CumHX7If.js.map +1 -0
  268. package/dist/core/web/public/next/assets/VoiceInput-CWTVwTwV.js +2 -0
  269. package/dist/core/web/public/next/assets/VoiceInput-CWTVwTwV.js.map +1 -0
  270. package/dist/core/web/public/next/assets/WikiSection-BIGSx4z-.js +2 -0
  271. package/dist/core/web/public/next/assets/WikiSection-BIGSx4z-.js.map +1 -0
  272. package/dist/core/web/public/next/assets/Workspace-5sa9Xggd.js +6 -0
  273. package/dist/core/web/public/next/assets/Workspace-5sa9Xggd.js.map +1 -0
  274. package/dist/core/web/public/next/assets/actions-BPyW8QC-.js +2 -0
  275. package/dist/core/web/public/next/assets/actions-BPyW8QC-.js.map +1 -0
  276. package/dist/core/web/public/next/assets/agent-tools-client-Si2ncqwV.js +2 -0
  277. package/dist/core/web/public/next/assets/agent-tools-client-Si2ncqwV.js.map +1 -0
  278. package/dist/core/web/public/next/assets/agent-transcript-model-D-34Ll59.js +7 -0
  279. package/dist/core/web/public/next/assets/agent-transcript-model-D-34Ll59.js.map +1 -0
  280. package/dist/core/web/public/next/assets/agents-focus-E_TBTTmZ.js +2 -0
  281. package/dist/core/web/public/next/assets/agents-focus-E_TBTTmZ.js.map +1 -0
  282. package/dist/core/web/public/next/assets/app-version-y5sfMXiE.js +2 -0
  283. package/dist/core/web/public/next/assets/app-version-y5sfMXiE.js.map +1 -0
  284. package/dist/core/web/public/next/assets/apps-model-BnjwUIUH.js +2 -0
  285. package/dist/core/web/public/next/assets/apps-model-BnjwUIUH.js.map +1 -0
  286. package/dist/core/web/public/next/assets/ask-seat-CWE-jY2D.js +2 -0
  287. package/dist/core/web/public/next/assets/ask-seat-CWE-jY2D.js.map +1 -0
  288. package/dist/core/web/public/next/assets/authority-model-DVMxkDV4.js +2 -0
  289. package/dist/core/web/public/next/assets/authority-model-DVMxkDV4.js.map +1 -0
  290. package/dist/core/web/public/next/assets/automations-focus-B-lklYid.js +2 -0
  291. package/dist/core/web/public/next/assets/automations-focus-B-lklYid.js.map +1 -0
  292. package/dist/core/web/public/next/assets/budget-model-Bwv4MZSa.js +2 -0
  293. package/dist/core/web/public/next/assets/budget-model-Bwv4MZSa.js.map +1 -0
  294. package/dist/core/web/public/next/assets/budget-queries-t-Bdoly3.js +2 -0
  295. package/dist/core/web/public/next/assets/budget-queries-t-Bdoly3.js.map +1 -0
  296. package/dist/core/web/public/next/assets/capacity-strip-model-CJ5F-CtB.js +2 -0
  297. package/dist/core/web/public/next/assets/capacity-strip-model-CJ5F-CtB.js.map +1 -0
  298. package/dist/core/web/public/next/assets/charts-Di0_Q980.js +2 -0
  299. package/dist/core/web/public/next/assets/charts-Di0_Q980.js.map +1 -0
  300. package/dist/core/web/public/next/assets/chat-pane-data-5MDEsLff.js +2 -0
  301. package/dist/core/web/public/next/assets/chat-pane-data-5MDEsLff.js.map +1 -0
  302. package/dist/core/web/public/next/assets/checkpoint-queries-6thqsAiE.js +2 -0
  303. package/dist/core/web/public/next/assets/checkpoint-queries-6thqsAiE.js.map +1 -0
  304. package/dist/core/web/public/next/assets/cloud-model-CzKeuxfm.js +2 -0
  305. package/dist/core/web/public/next/assets/cloud-model-CzKeuxfm.js.map +1 -0
  306. package/dist/core/web/public/next/assets/cloud-queries-DrR_QeUK.js +2 -0
  307. package/dist/core/web/public/next/assets/cloud-queries-DrR_QeUK.js.map +1 -0
  308. package/dist/core/web/public/next/assets/command-catalog-COH2G2xv.js +2 -0
  309. package/dist/core/web/public/next/assets/command-catalog-COH2G2xv.js.map +1 -0
  310. package/dist/core/web/public/next/assets/composer-queries-GxFt1UQm.js +2 -0
  311. package/dist/core/web/public/next/assets/composer-queries-GxFt1UQm.js.map +1 -0
  312. package/dist/core/web/public/next/assets/composer-state-DTAoie2b.js +2 -0
  313. package/dist/core/web/public/next/assets/composer-state-DTAoie2b.js.map +1 -0
  314. package/dist/core/web/public/next/assets/connectivity-zM4_O-XZ.js +2 -0
  315. package/dist/core/web/public/next/assets/connectivity-zM4_O-XZ.js.map +1 -0
  316. package/dist/core/web/public/next/assets/context-model-CKXUZd0O.js +2 -0
  317. package/dist/core/web/public/next/assets/context-model-CKXUZd0O.js.map +1 -0
  318. package/dist/core/web/public/next/assets/context-model-DYkDKK6C.js +3 -0
  319. package/dist/core/web/public/next/assets/context-model-DYkDKK6C.js.map +1 -0
  320. package/dist/core/web/public/next/assets/context-queries-D0Aydl5L.js +2 -0
  321. package/dist/core/web/public/next/assets/context-queries-D0Aydl5L.js.map +1 -0
  322. package/dist/core/web/public/next/assets/control-queries-C5uQTzJi.js +2 -0
  323. package/dist/core/web/public/next/assets/control-queries-C5uQTzJi.js.map +1 -0
  324. package/dist/core/web/public/next/assets/copy-setup-IHGsNfkz.js +2 -0
  325. package/dist/core/web/public/next/assets/copy-setup-IHGsNfkz.js.map +1 -0
  326. package/dist/core/web/public/next/assets/deep-link-DgTIAuc2.js +2 -0
  327. package/dist/core/web/public/next/assets/deep-link-DgTIAuc2.js.map +1 -0
  328. package/dist/core/web/public/next/assets/device-permissions-BplZgouU.js +2 -0
  329. package/dist/core/web/public/next/assets/device-permissions-BplZgouU.js.map +1 -0
  330. package/dist/core/web/public/next/assets/devin-queries-Bltl6Jz2.js +2 -0
  331. package/dist/core/web/public/next/assets/devin-queries-Bltl6Jz2.js.map +1 -0
  332. package/dist/core/web/public/next/assets/dock-icons-DPXFt10d.js +2 -0
  333. package/dist/core/web/public/next/assets/dock-icons-DPXFt10d.js.map +1 -0
  334. package/dist/core/web/public/next/assets/dock-panes-DNSv-1Tq.js +2 -0
  335. package/dist/core/web/public/next/assets/dock-panes-DNSv-1Tq.js.map +1 -0
  336. package/dist/core/web/public/next/assets/fleet-control-queries-DZEa-aFz.js +2 -0
  337. package/dist/core/web/public/next/assets/fleet-control-queries-DZEa-aFz.js.map +1 -0
  338. package/dist/core/web/public/next/assets/fleet-model-D4n8ErhA.js +2 -0
  339. package/dist/core/web/public/next/assets/fleet-model-D4n8ErhA.js.map +1 -0
  340. package/dist/core/web/public/next/assets/fleet-queries-BO1MHMFz.js +2 -0
  341. package/dist/core/web/public/next/assets/fleet-queries-BO1MHMFz.js.map +1 -0
  342. package/dist/core/web/public/next/assets/fleet-state-yM0mV9_P.js +3 -0
  343. package/dist/core/web/public/next/assets/fleet-state-yM0mV9_P.js.map +1 -0
  344. package/dist/core/web/public/next/assets/focus-trap-C2rynI8q.js +2 -0
  345. package/dist/core/web/public/next/assets/focus-trap-C2rynI8q.js.map +1 -0
  346. package/dist/core/web/public/next/assets/format-V6IiIMAL.js +2 -0
  347. package/dist/core/web/public/next/assets/format-V6IiIMAL.js.map +1 -0
  348. package/dist/core/web/public/next/assets/git-model-rVA0Jd0g.js +5 -0
  349. package/dist/core/web/public/next/assets/git-model-rVA0Jd0g.js.map +1 -0
  350. package/dist/core/web/public/next/assets/global-CYfRwH6t.js +3 -0
  351. package/dist/core/web/public/next/assets/global-CYfRwH6t.js.map +1 -0
  352. package/dist/core/web/public/next/assets/guarded-action-A9ZsIE8S.js +3 -0
  353. package/dist/core/web/public/next/assets/guarded-action-A9ZsIE8S.js.map +1 -0
  354. package/dist/core/web/public/next/assets/guarded-runners-xMakDn92.js +2 -0
  355. package/dist/core/web/public/next/assets/guarded-runners-xMakDn92.js.map +1 -0
  356. package/dist/core/web/public/next/assets/headroom-C4dyfw7P.js +2 -0
  357. package/dist/core/web/public/next/assets/headroom-C4dyfw7P.js.map +1 -0
  358. package/dist/core/web/public/next/assets/health-queries-BHoSyIcL.js +2 -0
  359. package/dist/core/web/public/next/assets/health-queries-BHoSyIcL.js.map +1 -0
  360. package/dist/core/web/public/next/assets/icons-BBm_Cy62.js +2 -0
  361. package/dist/core/web/public/next/assets/icons-BBm_Cy62.js.map +1 -0
  362. package/dist/core/web/public/next/assets/index-_izD07R9.js +11 -0
  363. package/dist/core/web/public/next/assets/index-_izD07R9.js.map +1 -0
  364. package/dist/core/web/public/next/assets/jev-queries-D-AMM0sw.js +2 -0
  365. package/dist/core/web/public/next/assets/jev-queries-D-AMM0sw.js.map +1 -0
  366. package/dist/core/web/public/next/assets/ladder-queries-BIpJVqxu.js +2 -0
  367. package/dist/core/web/public/next/assets/ladder-queries-BIpJVqxu.js.map +1 -0
  368. package/dist/core/web/public/next/assets/leader-focus-Dh4gXTSi.js +2 -0
  369. package/dist/core/web/public/next/assets/leader-focus-Dh4gXTSi.js.map +1 -0
  370. package/dist/core/web/public/next/assets/live-model-D97AfBFz.js +2 -0
  371. package/dist/core/web/public/next/assets/live-model-D97AfBFz.js.map +1 -0
  372. package/dist/core/web/public/next/assets/mind.module-rVKz51LB.js +2 -0
  373. package/dist/core/web/public/next/assets/mind.module-rVKz51LB.js.map +1 -0
  374. package/dist/core/web/public/next/assets/mobile-actions-V26-lGbH.js +2 -0
  375. package/dist/core/web/public/next/assets/mobile-actions-V26-lGbH.js.map +1 -0
  376. package/dist/core/web/public/next/assets/mobile-toast-9-WQbWQu.js +2 -0
  377. package/dist/core/web/public/next/assets/mobile-toast-9-WQbWQu.js.map +1 -0
  378. package/dist/core/web/public/next/assets/multimodel-flows-D309YXSk.js +7 -0
  379. package/dist/core/web/public/next/assets/multimodel-flows-D309YXSk.js.map +1 -0
  380. package/dist/core/web/public/next/assets/multimodel-queries-BuslyWtq.js +2 -0
  381. package/dist/core/web/public/next/assets/multimodel-queries-BuslyWtq.js.map +1 -0
  382. package/dist/core/web/public/next/assets/mutations-B9AZoqNR.js +2 -0
  383. package/dist/core/web/public/next/assets/mutations-B9AZoqNR.js.map +1 -0
  384. package/dist/core/web/public/next/assets/nav-DC0ynjdb.js +2 -0
  385. package/dist/core/web/public/next/assets/nav-DC0ynjdb.js.map +1 -0
  386. package/dist/core/web/public/next/assets/needs-you-actions-BOHN9fg7.js +2 -0
  387. package/dist/core/web/public/next/assets/needs-you-actions-BOHN9fg7.js.map +1 -0
  388. package/dist/core/web/public/next/assets/needs-you-model-ChGg3r5r.js +2 -0
  389. package/dist/core/web/public/next/assets/needs-you-model-ChGg3r5r.js.map +1 -0
  390. package/dist/core/web/public/next/assets/open-terminal-5F1FNUEB.js +2 -0
  391. package/dist/core/web/public/next/assets/open-terminal-5F1FNUEB.js.map +1 -0
  392. package/dist/core/web/public/next/assets/open-terminal-request-SjPIZmAt.js +2 -0
  393. package/dist/core/web/public/next/assets/open-terminal-request-SjPIZmAt.js.map +1 -0
  394. package/dist/core/web/public/next/assets/overnight-queries-Dc46kMfg.js +2 -0
  395. package/dist/core/web/public/next/assets/overnight-queries-Dc46kMfg.js.map +1 -0
  396. package/dist/core/web/public/next/assets/palette-handoff-xkWF9v2M.js +2 -0
  397. package/dist/core/web/public/next/assets/palette-handoff-xkWF9v2M.js.map +1 -0
  398. package/dist/core/web/public/next/assets/panes-DOXM13lF.js +3 -0
  399. package/dist/core/web/public/next/assets/panes-DOXM13lF.js.map +1 -0
  400. package/dist/core/web/public/next/assets/path-display-C6BmdnBS.js +2 -0
  401. package/dist/core/web/public/next/assets/path-display-C6BmdnBS.js.map +1 -0
  402. package/dist/core/web/public/next/assets/percent-text-CSk89zQF.js +2 -0
  403. package/dist/core/web/public/next/assets/percent-text-CSk89zQF.js.map +1 -0
  404. package/dist/core/web/public/next/assets/playbook-composer-Bz-fFxXW.js +2 -0
  405. package/dist/core/web/public/next/assets/playbook-composer-Bz-fFxXW.js.map +1 -0
  406. package/dist/core/web/public/next/assets/playbook-focus-BXu0yrHF.js +2 -0
  407. package/dist/core/web/public/next/assets/playbook-focus-BXu0yrHF.js.map +1 -0
  408. package/dist/core/web/public/next/assets/playbooks-queries-Cpnl3avl.js +2 -0
  409. package/dist/core/web/public/next/assets/playbooks-queries-Cpnl3avl.js.map +1 -0
  410. package/dist/core/web/public/next/assets/preloaded-E_jepvvg.js +2 -0
  411. package/dist/core/web/public/next/assets/preloaded-E_jepvvg.js.map +1 -0
  412. package/dist/core/web/public/next/assets/primitives-Bynv7bPl.js +1 -0
  413. package/dist/core/web/public/next/assets/pwa-D2lyCiGV.js +2 -0
  414. package/dist/core/web/public/next/assets/pwa-D2lyCiGV.js.map +1 -0
  415. package/dist/core/web/public/next/assets/queries-C0Bs3TOo.js +2 -0
  416. package/dist/core/web/public/next/assets/queries-C0Bs3TOo.js.map +1 -0
  417. package/dist/core/web/public/next/assets/reasoning-pref-DDPtfTM3.js +2 -0
  418. package/dist/core/web/public/next/assets/reasoning-pref-DDPtfTM3.js.map +1 -0
  419. package/dist/core/web/public/next/assets/remote-session-Dj27m1xb.js +3 -0
  420. package/dist/core/web/public/next/assets/remote-session-Dj27m1xb.js.map +1 -0
  421. package/dist/core/web/public/next/assets/resolved-store-B2iJa5C2.js +2 -0
  422. package/dist/core/web/public/next/assets/resolved-store-B2iJa5C2.js.map +1 -0
  423. package/dist/core/web/public/next/assets/resources-queries-pVRhOTEt.js +2 -0
  424. package/dist/core/web/public/next/assets/resources-queries-pVRhOTEt.js.map +1 -0
  425. package/dist/core/web/public/next/assets/reveal-anchor-BAMmxMeu.js +2 -0
  426. package/dist/core/web/public/next/assets/reveal-anchor-BAMmxMeu.js.map +1 -0
  427. package/dist/core/web/public/next/assets/rolldown-runtime-hePW80VL.js +1 -0
  428. package/dist/core/web/public/next/assets/seat-readiness-a5B9iqP-.js +2 -0
  429. package/dist/core/web/public/next/assets/seat-readiness-a5B9iqP-.js.map +1 -0
  430. package/dist/core/web/public/next/assets/seat-subscription-Cut6eC-8.js +2 -0
  431. package/dist/core/web/public/next/assets/seat-subscription-Cut6eC-8.js.map +1 -0
  432. package/dist/core/web/public/next/assets/sheet-BxZSmdad.js +2 -0
  433. package/dist/core/web/public/next/assets/sheet-BxZSmdad.js.map +1 -0
  434. package/dist/core/web/public/next/assets/sidebar-model-COzIPSiP.js +2 -0
  435. package/dist/core/web/public/next/assets/sidebar-model-COzIPSiP.js.map +1 -0
  436. package/dist/core/web/public/next/assets/slots-BJc3RJkV.js +3 -0
  437. package/dist/core/web/public/next/assets/slots-BJc3RJkV.js.map +1 -0
  438. package/dist/core/web/public/next/assets/sources-queries-DCKiXNAt.js +4 -0
  439. package/dist/core/web/public/next/assets/sources-queries-DCKiXNAt.js.map +1 -0
  440. package/dist/core/web/public/next/assets/sse-It4xa040.js +2 -0
  441. package/dist/core/web/public/next/assets/sse-It4xa040.js.map +1 -0
  442. package/dist/core/web/public/next/assets/surface-data-NFl_uS--.js +2 -0
  443. package/dist/core/web/public/next/assets/surface-data-NFl_uS--.js.map +1 -0
  444. package/dist/core/web/public/next/assets/surface-prefetch-jMaLNI6z.js +2 -0
  445. package/dist/core/web/public/next/assets/surface-prefetch-jMaLNI6z.js.map +1 -0
  446. package/dist/core/web/public/next/assets/tasks-model-CbmPgWL8.js +2 -0
  447. package/dist/core/web/public/next/assets/tasks-model-CbmPgWL8.js.map +1 -0
  448. package/dist/core/web/public/next/assets/terminal-client-DTXAf2-x.js +2 -0
  449. package/dist/core/web/public/next/assets/terminal-client-DTXAf2-x.js.map +1 -0
  450. package/dist/core/web/public/next/assets/terminal-icons-qBCOwqu-.js +2 -0
  451. package/dist/core/web/public/next/assets/terminal-icons-qBCOwqu-.js.map +1 -0
  452. package/dist/core/web/public/next/assets/terminal-view-CksH3CsK.js +6 -0
  453. package/dist/core/web/public/next/assets/terminal-view-CksH3CsK.js.map +1 -0
  454. package/dist/core/web/public/next/assets/thread-data-C8z55msn.js +2 -0
  455. package/dist/core/web/public/next/assets/thread-data-C8z55msn.js.map +1 -0
  456. package/dist/core/web/public/next/assets/ui-parts-CcpmRBwj.js +2 -0
  457. package/dist/core/web/public/next/assets/ui-parts-CcpmRBwj.js.map +1 -0
  458. package/dist/core/web/public/next/assets/usage-queries-BxrTLCaJ.js +2 -0
  459. package/dist/core/web/public/next/assets/usage-queries-BxrTLCaJ.js.map +1 -0
  460. package/dist/core/web/public/next/assets/use-chat-activity-O8I0Ho0m.js +2 -0
  461. package/dist/core/web/public/next/assets/use-chat-activity-O8I0Ho0m.js.map +1 -0
  462. package/dist/core/web/public/next/assets/use-guarded-action-BZ6Bye9l.js +2 -0
  463. package/dist/core/web/public/next/assets/use-guarded-action-BZ6Bye9l.js.map +1 -0
  464. package/dist/core/web/public/next/assets/use-ticker-CUsNALmP.js +2 -0
  465. package/dist/core/web/public/next/assets/use-ticker-CUsNALmP.js.map +1 -0
  466. package/dist/core/web/public/next/assets/use-token-gate-DgnO9fbv.js +2 -0
  467. package/dist/core/web/public/next/assets/use-token-gate-DgnO9fbv.js.map +1 -0
  468. package/dist/core/web/public/next/assets/useAutoSeat-CIEXM-Q5.js +2 -0
  469. package/dist/core/web/public/next/assets/useAutoSeat-CIEXM-Q5.js.map +1 -0
  470. package/dist/core/web/public/next/assets/useOnboarding-BAmRBxkI.js +2 -0
  471. package/dist/core/web/public/next/assets/useOnboarding-BAmRBxkI.js.map +1 -0
  472. package/dist/core/web/public/next/assets/useSeatHealth-DPkSSddF.js +2 -0
  473. package/dist/core/web/public/next/assets/useSeatHealth-DPkSSddF.js.map +1 -0
  474. package/dist/core/web/public/next/assets/useSeatsRefresh-CpsRhfmt.js +2 -0
  475. package/dist/core/web/public/next/assets/useSeatsRefresh-CpsRhfmt.js.map +1 -0
  476. package/dist/core/web/public/next/assets/useVerseSession-DeW1iFpw.js +2 -0
  477. package/dist/core/web/public/next/assets/useVerseSession-DeW1iFpw.js.map +1 -0
  478. package/dist/core/web/public/next/assets/useVerseTranscript-CvUqjRmZ.js +2 -0
  479. package/dist/core/web/public/next/assets/useVerseTranscript-CvUqjRmZ.js.map +1 -0
  480. package/dist/core/web/public/next/assets/verse-bootstrap-query-ANtL2OPN.js +2 -0
  481. package/dist/core/web/public/next/assets/verse-bootstrap-query-ANtL2OPN.js.map +1 -0
  482. package/dist/core/web/public/next/assets/verse-icons-C92Qt7rh.js +2 -0
  483. package/dist/core/web/public/next/assets/verse-icons-C92Qt7rh.js.map +1 -0
  484. package/dist/core/web/public/next/assets/verse-model-DAOz9LrY.js +2 -0
  485. package/dist/core/web/public/next/assets/verse-model-DAOz9LrY.js.map +1 -0
  486. package/dist/core/web/public/next/assets/warmup-B2DWWeeC.js +3 -0
  487. package/dist/core/web/public/next/assets/warmup-B2DWWeeC.js.map +1 -0
  488. package/dist/core/web/public/next/assets/why-seat-model-Bn6O26JJ.js +2 -0
  489. package/dist/core/web/public/next/assets/why-seat-model-Bn6O26JJ.js.map +1 -0
  490. package/dist/core/web/public/next/assets/wiki-focus-CwC-yoT9.js +2 -0
  491. package/dist/core/web/public/next/assets/wiki-focus-CwC-yoT9.js.map +1 -0
  492. package/dist/core/web/public/next/assets/workspace-model-C-q_I8xN.js +2 -0
  493. package/dist/core/web/public/next/assets/workspace-model-C-q_I8xN.js.map +1 -0
  494. package/dist/core/web/public/next/index.html +2 -1
  495. package/dist/core/web/remote-gateway-policy.js +5 -0
  496. package/dist/core/web/remote-gateway-policy.js.map +1 -1
  497. package/dist/core/web/static.d.ts +4 -3
  498. package/dist/core/web/static.js +8 -5
  499. package/dist/core/web/static.js.map +1 -1
  500. package/dist/release-dependency-inventory.json +1 -1
  501. package/node_modules/fast-uri/index.js +20 -5
  502. package/node_modules/fast-uri/lib/utils.js +8 -1
  503. package/node_modules/fast-uri/package.json +1 -1
  504. package/node_modules/fast-uri/test/component-safe-serialization.test.js +58 -0
  505. package/node_modules/fast-uri/test/ipv6-validation.test.js +34 -0
  506. package/node_modules/ip-address/README.md +134 -134
  507. package/node_modules/ip-address/dist/address-error.d.ts +11 -0
  508. package/node_modules/ip-address/dist/address-error.js.map +1 -1
  509. package/node_modules/ip-address/dist/ipv4.d.ts +22 -6
  510. package/node_modules/ip-address/dist/ipv4.js +22 -6
  511. package/node_modules/ip-address/dist/ipv4.js.map +1 -1
  512. package/node_modules/ip-address/dist/ipv6.d.ts +26 -8
  513. package/node_modules/ip-address/dist/ipv6.js +46 -29
  514. package/node_modules/ip-address/dist/ipv6.js.map +1 -1
  515. package/node_modules/ip-address/dist/v6/constants.js +1 -0
  516. package/node_modules/ip-address/dist/v6/constants.js.map +1 -1
  517. package/node_modules/ip-address/package.json +1 -1
  518. package/package.json +5 -4
  519. package/dist/core/web/public/next/assets/ActionMenu-Bia8Re6u.js +0 -2
  520. package/dist/core/web/public/next/assets/ActionMenu-Bia8Re6u.js.map +0 -1
  521. package/dist/core/web/public/next/assets/Advanced-C1LtnA8c.js +0 -2
  522. package/dist/core/web/public/next/assets/Advanced-C1LtnA8c.js.map +0 -1
  523. package/dist/core/web/public/next/assets/AgentDetailScreen-DuoXrbol.js +0 -2
  524. package/dist/core/web/public/next/assets/AgentDetailScreen-DuoXrbol.js.map +0 -1
  525. package/dist/core/web/public/next/assets/AgentToolsSheet-Bdfk4SF-.js +0 -2
  526. package/dist/core/web/public/next/assets/AgentToolsSheet-Bdfk4SF-.js.map +0 -1
  527. package/dist/core/web/public/next/assets/AgentToolsStrip-BN1otiqC.js +0 -2
  528. package/dist/core/web/public/next/assets/AgentToolsStrip-BN1otiqC.js.map +0 -1
  529. package/dist/core/web/public/next/assets/AgentsScreen-BxHFaI48.js +0 -2
  530. package/dist/core/web/public/next/assets/AgentsScreen-BxHFaI48.js.map +0 -1
  531. package/dist/core/web/public/next/assets/AgentsSection-mYIA8Lyk.js +0 -3
  532. package/dist/core/web/public/next/assets/AgentsSection-mYIA8Lyk.js.map +0 -1
  533. package/dist/core/web/public/next/assets/App-DebYuj1v.js +0 -8
  534. package/dist/core/web/public/next/assets/App-DebYuj1v.js.map +0 -1
  535. package/dist/core/web/public/next/assets/AppsSection-W30duGQA.js +0 -2
  536. package/dist/core/web/public/next/assets/AppsSection-W30duGQA.js.map +0 -1
  537. package/dist/core/web/public/next/assets/AreaTrend-ZnnIjBGU.js +0 -2
  538. package/dist/core/web/public/next/assets/AreaTrend-ZnnIjBGU.js.map +0 -1
  539. package/dist/core/web/public/next/assets/AutomationsSection-B4N0V-vz.js +0 -2
  540. package/dist/core/web/public/next/assets/AutomationsSection-B4N0V-vz.js.map +0 -1
  541. package/dist/core/web/public/next/assets/AutonomyOffState-C9S_FXc0.js +0 -3
  542. package/dist/core/web/public/next/assets/AutonomyOffState-C9S_FXc0.js.map +0 -1
  543. package/dist/core/web/public/next/assets/AutonomySection-oMQfNEQN.js +0 -2
  544. package/dist/core/web/public/next/assets/AutonomySection-oMQfNEQN.js.map +0 -1
  545. package/dist/core/web/public/next/assets/AutonomyStatus-CdHOyhrV.js +0 -2
  546. package/dist/core/web/public/next/assets/AutonomyStatus-CdHOyhrV.js.map +0 -1
  547. package/dist/core/web/public/next/assets/BranchBar-Bo5b8-hr.js +0 -2
  548. package/dist/core/web/public/next/assets/BranchBar-Bo5b8-hr.js.map +0 -1
  549. package/dist/core/web/public/next/assets/BrowserPanel-D02omBK0.js +0 -7
  550. package/dist/core/web/public/next/assets/BrowserPanel-D02omBK0.js.map +0 -1
  551. package/dist/core/web/public/next/assets/BudgetControl-BtPTi8qI.js +0 -2
  552. package/dist/core/web/public/next/assets/BudgetControl-BtPTi8qI.js.map +0 -1
  553. package/dist/core/web/public/next/assets/Button-DP2ImS5n.js +0 -2
  554. package/dist/core/web/public/next/assets/Button-DP2ImS5n.js.map +0 -1
  555. package/dist/core/web/public/next/assets/CapacityStrip-ChYPcr23.js +0 -2
  556. package/dist/core/web/public/next/assets/CapacityStrip-ChYPcr23.js.map +0 -1
  557. package/dist/core/web/public/next/assets/ChangesPaneHost-C53_94Kn.js +0 -16
  558. package/dist/core/web/public/next/assets/ChangesPaneHost-C53_94Kn.js.map +0 -1
  559. package/dist/core/web/public/next/assets/ChartFrame-CtFLETWA.js +0 -2
  560. package/dist/core/web/public/next/assets/ChartFrame-CtFLETWA.js.map +0 -1
  561. package/dist/core/web/public/next/assets/ChatPanes-CyAK9VAi.js +0 -2
  562. package/dist/core/web/public/next/assets/ChatPanes-CyAK9VAi.js.map +0 -1
  563. package/dist/core/web/public/next/assets/ChatSection-DV9smoPe.js +0 -3
  564. package/dist/core/web/public/next/assets/ChatSection-DV9smoPe.js.map +0 -1
  565. package/dist/core/web/public/next/assets/ChecksPanel-B6T2sjc_.js +0 -5
  566. package/dist/core/web/public/next/assets/ChecksPanel-B6T2sjc_.js.map +0 -1
  567. package/dist/core/web/public/next/assets/CloudBudgetForm-D8RbdAC7.js +0 -2
  568. package/dist/core/web/public/next/assets/CloudBudgetForm-D8RbdAC7.js.map +0 -1
  569. package/dist/core/web/public/next/assets/CommandPalette-C04gGTES.js +0 -3
  570. package/dist/core/web/public/next/assets/CommandPalette-C04gGTES.js.map +0 -1
  571. package/dist/core/web/public/next/assets/CommandSection-Be8VFAEU.js +0 -3
  572. package/dist/core/web/public/next/assets/CommandSection-Be8VFAEU.js.map +0 -1
  573. package/dist/core/web/public/next/assets/CommandWorkflowForm-D5A7c2PE.js +0 -9
  574. package/dist/core/web/public/next/assets/CommandWorkflowForm-D5A7c2PE.js.map +0 -1
  575. package/dist/core/web/public/next/assets/CommandWorkflowPicker-CGrRWfzQ.js +0 -3
  576. package/dist/core/web/public/next/assets/CommandWorkflowPicker-CGrRWfzQ.js.map +0 -1
  577. package/dist/core/web/public/next/assets/CompareDialog-C2ryiEtF.js +0 -4
  578. package/dist/core/web/public/next/assets/CompareDialog-C2ryiEtF.js.map +0 -1
  579. package/dist/core/web/public/next/assets/ComputerControl-C4oW7Zim.js +0 -2
  580. package/dist/core/web/public/next/assets/ComputerControl-C4oW7Zim.js.map +0 -1
  581. package/dist/core/web/public/next/assets/ConfirmDialog-J8CszPmj.js +0 -2
  582. package/dist/core/web/public/next/assets/ConfirmDialog-J8CszPmj.js.map +0 -1
  583. package/dist/core/web/public/next/assets/DeleteChatDialog-BT5y9cR2.js +0 -2
  584. package/dist/core/web/public/next/assets/DeleteChatDialog-BT5y9cR2.js.map +0 -1
  585. package/dist/core/web/public/next/assets/DevinStopDialog-CADdSqha.js +0 -2
  586. package/dist/core/web/public/next/assets/DevinStopDialog-CADdSqha.js.map +0 -1
  587. package/dist/core/web/public/next/assets/Dialog-BYIKNPcH.js +0 -2
  588. package/dist/core/web/public/next/assets/Dialog-BYIKNPcH.js.map +0 -1
  589. package/dist/core/web/public/next/assets/DiffPane-D_CC9a5x.js +0 -2
  590. package/dist/core/web/public/next/assets/DiffPane-D_CC9a5x.js.map +0 -1
  591. package/dist/core/web/public/next/assets/DiffViewer-DjtLl7ro.js +0 -2
  592. package/dist/core/web/public/next/assets/DiffViewer-DjtLl7ro.js.map +0 -1
  593. package/dist/core/web/public/next/assets/DockHost-BHbosAjM.js +0 -2
  594. package/dist/core/web/public/next/assets/DockHost-BHbosAjM.js.map +0 -1
  595. package/dist/core/web/public/next/assets/EmptyState-BEXDoNZd.js +0 -2
  596. package/dist/core/web/public/next/assets/EmptyState-BEXDoNZd.js.map +0 -1
  597. package/dist/core/web/public/next/assets/Epistemic-BPBAmLNh.js +0 -2
  598. package/dist/core/web/public/next/assets/Epistemic-BPBAmLNh.js.map +0 -1
  599. package/dist/core/web/public/next/assets/EvidenceTimeline-D2nuo6Oo.js +0 -2
  600. package/dist/core/web/public/next/assets/EvidenceTimeline-D2nuo6Oo.js.map +0 -1
  601. package/dist/core/web/public/next/assets/FilesPane-BQBcWyxr.js +0 -2
  602. package/dist/core/web/public/next/assets/FilesPane-BQBcWyxr.js.map +0 -1
  603. package/dist/core/web/public/next/assets/FleetScreen-YXDuVwKd.js +0 -2
  604. package/dist/core/web/public/next/assets/FleetScreen-YXDuVwKd.js.map +0 -1
  605. package/dist/core/web/public/next/assets/FleetSection-D2M7u9zG.js +0 -5
  606. package/dist/core/web/public/next/assets/FleetSection-D2M7u9zG.js.map +0 -1
  607. package/dist/core/web/public/next/assets/Funnel-rnPUaoN7.js +0 -2
  608. package/dist/core/web/public/next/assets/Funnel-rnPUaoN7.js.map +0 -1
  609. package/dist/core/web/public/next/assets/GearTray-Cc14h572.js +0 -2
  610. package/dist/core/web/public/next/assets/GearTray-Cc14h572.js.map +0 -1
  611. package/dist/core/web/public/next/assets/GitDialogs-BSTlyNJR.js +0 -2
  612. package/dist/core/web/public/next/assets/GitDialogs-BSTlyNJR.js.map +0 -1
  613. package/dist/core/web/public/next/assets/GrowthSection-BK63EJn9.js +0 -3
  614. package/dist/core/web/public/next/assets/GrowthSection-BK63EJn9.js.map +0 -1
  615. package/dist/core/web/public/next/assets/HandoffDialog-DD4M-C7v.js +0 -2
  616. package/dist/core/web/public/next/assets/HandoffDialog-DD4M-C7v.js.map +0 -1
  617. package/dist/core/web/public/next/assets/HomeBody-OEhTpkk9.js +0 -3
  618. package/dist/core/web/public/next/assets/HomeBody-OEhTpkk9.js.map +0 -1
  619. package/dist/core/web/public/next/assets/HomeSeats-CJCxRUlD.js +0 -2
  620. package/dist/core/web/public/next/assets/HomeSeats-CJCxRUlD.js.map +0 -1
  621. package/dist/core/web/public/next/assets/Input-BEF-ScuG.js +0 -2
  622. package/dist/core/web/public/next/assets/Input-BEF-ScuG.js.map +0 -1
  623. package/dist/core/web/public/next/assets/LaunchDialog-CERI717u.js +0 -9
  624. package/dist/core/web/public/next/assets/LaunchDialog-CERI717u.js.map +0 -1
  625. package/dist/core/web/public/next/assets/LeaderCard-3P95vgVU.js +0 -2
  626. package/dist/core/web/public/next/assets/LeaderCard-3P95vgVU.js.map +0 -1
  627. package/dist/core/web/public/next/assets/LeaderConversation-DjZS2PrX.js +0 -3
  628. package/dist/core/web/public/next/assets/LeaderConversation-DjZS2PrX.js.map +0 -1
  629. package/dist/core/web/public/next/assets/LeaderScreen-Dw5jDfWv.js +0 -2
  630. package/dist/core/web/public/next/assets/LeaderScreen-Dw5jDfWv.js.map +0 -1
  631. package/dist/core/web/public/next/assets/LessonsPanel-Wy6TVWEv.js +0 -2
  632. package/dist/core/web/public/next/assets/LessonsPanel-Wy6TVWEv.js.map +0 -1
  633. package/dist/core/web/public/next/assets/LiveTimer-c18lVIBC.js +0 -2
  634. package/dist/core/web/public/next/assets/LiveTimer-c18lVIBC.js.map +0 -1
  635. package/dist/core/web/public/next/assets/LocalSeatBadge-BfUUuXE5.js +0 -2
  636. package/dist/core/web/public/next/assets/LocalSeatBadge-BfUUuXE5.js.map +0 -1
  637. package/dist/core/web/public/next/assets/MatrixHeatmap-DTOumwCS.js +0 -2
  638. package/dist/core/web/public/next/assets/MatrixHeatmap-DTOumwCS.js.map +0 -1
  639. package/dist/core/web/public/next/assets/McpSection-D9eJislZ.js +0 -2
  640. package/dist/core/web/public/next/assets/McpSection-D9eJislZ.js.map +0 -1
  641. package/dist/core/web/public/next/assets/MessageMarkdown-Dkw4V24c.js +0 -3
  642. package/dist/core/web/public/next/assets/MessageMarkdown-Dkw4V24c.js.map +0 -1
  643. package/dist/core/web/public/next/assets/MessageMarkdownRenderer-VOSfkJpd.js +0 -72
  644. package/dist/core/web/public/next/assets/MessageMarkdownRenderer-VOSfkJpd.js.map +0 -1
  645. package/dist/core/web/public/next/assets/Meter-dMqKBaVV.js +0 -2
  646. package/dist/core/web/public/next/assets/Meter-dMqKBaVV.js.map +0 -1
  647. package/dist/core/web/public/next/assets/MicButton-92I_NsaT.js +0 -2
  648. package/dist/core/web/public/next/assets/MicButton-92I_NsaT.js.map +0 -1
  649. package/dist/core/web/public/next/assets/MindSection-CaGckJiR.js +0 -3
  650. package/dist/core/web/public/next/assets/MindSection-CaGckJiR.js.map +0 -1
  651. package/dist/core/web/public/next/assets/MobileComposer-BOFWmkku.js +0 -2
  652. package/dist/core/web/public/next/assets/MobileComposer-BOFWmkku.js.map +0 -1
  653. package/dist/core/web/public/next/assets/MobileGuardSheet-CY3Iulte.js +0 -2
  654. package/dist/core/web/public/next/assets/MobileGuardSheet-CY3Iulte.js.map +0 -1
  655. package/dist/core/web/public/next/assets/MobileRuntime-C-GtV4jT.js +0 -3
  656. package/dist/core/web/public/next/assets/MobileRuntime-C-GtV4jT.js.map +0 -1
  657. package/dist/core/web/public/next/assets/MoreScreen-BaH8iEnb.js +0 -2
  658. package/dist/core/web/public/next/assets/MoreScreen-BaH8iEnb.js.map +0 -1
  659. package/dist/core/web/public/next/assets/MultiModelBar-7DHuXGht.js +0 -7
  660. package/dist/core/web/public/next/assets/MultiModelBar-7DHuXGht.js.map +0 -1
  661. package/dist/core/web/public/next/assets/MutationTokenDialog-D522NXsm.js +0 -2
  662. package/dist/core/web/public/next/assets/MutationTokenDialog-D522NXsm.js.map +0 -1
  663. package/dist/core/web/public/next/assets/NeedsYouDrawer-6ud1RHOU.js +0 -3
  664. package/dist/core/web/public/next/assets/NeedsYouDrawer-6ud1RHOU.js.map +0 -1
  665. package/dist/core/web/public/next/assets/NeedsYouList-E-yy-xKE.js +0 -2
  666. package/dist/core/web/public/next/assets/NeedsYouList-E-yy-xKE.js.map +0 -1
  667. package/dist/core/web/public/next/assets/NeedsYouScreen-D13Q7iU8.js +0 -2
  668. package/dist/core/web/public/next/assets/NeedsYouScreen-D13Q7iU8.js.map +0 -1
  669. package/dist/core/web/public/next/assets/NewAgentScreen-BLtU1u-d.js +0 -2
  670. package/dist/core/web/public/next/assets/NewAgentScreen-BLtU1u-d.js.map +0 -1
  671. package/dist/core/web/public/next/assets/NewChatDialog-BL15LCaj.js +0 -4
  672. package/dist/core/web/public/next/assets/NewChatDialog-BL15LCaj.js.map +0 -1
  673. package/dist/core/web/public/next/assets/OnboardingFlow-7LRC7FlX.js +0 -3
  674. package/dist/core/web/public/next/assets/OnboardingFlow-7LRC7FlX.js.map +0 -1
  675. package/dist/core/web/public/next/assets/OnboardingGate-DRlv8QZ5.js +0 -3
  676. package/dist/core/web/public/next/assets/OnboardingGate-DRlv8QZ5.js.map +0 -1
  677. package/dist/core/web/public/next/assets/PlaybooksSection-D_uQ-NB3.js +0 -9
  678. package/dist/core/web/public/next/assets/PlaybooksSection-D_uQ-NB3.js.map +0 -1
  679. package/dist/core/web/public/next/assets/PreviewPane-DubyNi8H.js +0 -2
  680. package/dist/core/web/public/next/assets/PreviewPane-DubyNi8H.js.map +0 -1
  681. package/dist/core/web/public/next/assets/ProviderLogo-CWrojWjI.js +0 -2
  682. package/dist/core/web/public/next/assets/ProviderLogo-CWrojWjI.js.map +0 -1
  683. package/dist/core/web/public/next/assets/RailStatus-xjOcjL0v.js +0 -2
  684. package/dist/core/web/public/next/assets/RailStatus-xjOcjL0v.js.map +0 -1
  685. package/dist/core/web/public/next/assets/ReasoningPane-M7ZfvEc5.js +0 -2
  686. package/dist/core/web/public/next/assets/ReasoningPane-M7ZfvEc5.js.map +0 -1
  687. package/dist/core/web/public/next/assets/ReasoningSheet-RLLj2oys.js +0 -2
  688. package/dist/core/web/public/next/assets/ReasoningSheet-RLLj2oys.js.map +0 -1
  689. package/dist/core/web/public/next/assets/RefreshIndicator-CEMRNruu.js +0 -2
  690. package/dist/core/web/public/next/assets/RefreshIndicator-CEMRNruu.js.map +0 -1
  691. package/dist/core/web/public/next/assets/RemoteMobileApp-BcXsVw0z.js +0 -2
  692. package/dist/core/web/public/next/assets/RemoteMobileApp-BcXsVw0z.js.map +0 -1
  693. package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-BC_Q_i0I.js +0 -7
  694. package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-BC_Q_i0I.js.map +0 -1
  695. package/dist/core/web/public/next/assets/ResourcesChrome-CPcTYvZR.js +0 -3
  696. package/dist/core/web/public/next/assets/ResourcesChrome-CPcTYvZR.js.map +0 -1
  697. package/dist/core/web/public/next/assets/ResourcesDrawer-C6VzGCSv.js +0 -3
  698. package/dist/core/web/public/next/assets/ResourcesDrawer-C6VzGCSv.js.map +0 -1
  699. package/dist/core/web/public/next/assets/RouteErrorBoundary-Cc9GsjZz.js +0 -2
  700. package/dist/core/web/public/next/assets/RouteErrorBoundary-Cc9GsjZz.js.map +0 -1
  701. package/dist/core/web/public/next/assets/RunInCloudAction-P_hDsqjX.js +0 -2
  702. package/dist/core/web/public/next/assets/RunInCloudAction-P_hDsqjX.js.map +0 -1
  703. package/dist/core/web/public/next/assets/RunInDevinAction-CfNpQCP3.js +0 -2
  704. package/dist/core/web/public/next/assets/RunInDevinAction-CfNpQCP3.js.map +0 -1
  705. package/dist/core/web/public/next/assets/ScreenHost-BBYihlNQ.js +0 -3
  706. package/dist/core/web/public/next/assets/ScreenHost-BBYihlNQ.js.map +0 -1
  707. package/dist/core/web/public/next/assets/SeatSelector-DSd_pxg2.js +0 -3
  708. package/dist/core/web/public/next/assets/SeatSelector-DSd_pxg2.js.map +0 -1
  709. package/dist/core/web/public/next/assets/Segmented-CtwuFlbY.js +0 -2
  710. package/dist/core/web/public/next/assets/Segmented-CtwuFlbY.js.map +0 -1
  711. package/dist/core/web/public/next/assets/Select-zXMdgblm.js +0 -2
  712. package/dist/core/web/public/next/assets/Select-zXMdgblm.js.map +0 -1
  713. package/dist/core/web/public/next/assets/SessionGate-88QiSoXo.js +0 -2
  714. package/dist/core/web/public/next/assets/SessionGate-88QiSoXo.js.map +0 -1
  715. package/dist/core/web/public/next/assets/SessionInsightChip-CaPvisvI.js +0 -2
  716. package/dist/core/web/public/next/assets/SessionInsightChip-CaPvisvI.js.map +0 -1
  717. package/dist/core/web/public/next/assets/SessionSearch-Ch3veGxY.js +0 -2
  718. package/dist/core/web/public/next/assets/SessionSearch-Ch3veGxY.js.map +0 -1
  719. package/dist/core/web/public/next/assets/SettingsSection-DLSYZEFc.js +0 -2
  720. package/dist/core/web/public/next/assets/SettingsSection-DLSYZEFc.js.map +0 -1
  721. package/dist/core/web/public/next/assets/SetupChecklist-DFAVVLpJ.js +0 -2
  722. package/dist/core/web/public/next/assets/SetupChecklist-DFAVVLpJ.js.map +0 -1
  723. package/dist/core/web/public/next/assets/ShadowDecisions-Gtrbo4US.js +0 -3
  724. package/dist/core/web/public/next/assets/ShadowDecisions-Gtrbo4US.js.map +0 -1
  725. package/dist/core/web/public/next/assets/Sheet-D72WH4mP.js +0 -2
  726. package/dist/core/web/public/next/assets/Sheet-D72WH4mP.js.map +0 -1
  727. package/dist/core/web/public/next/assets/ShortcutsOverlay-DKetDlCR.js +0 -2
  728. package/dist/core/web/public/next/assets/ShortcutsOverlay-DKetDlCR.js.map +0 -1
  729. package/dist/core/web/public/next/assets/Sidebar-CqOJle0q.js +0 -3
  730. package/dist/core/web/public/next/assets/Sidebar-CqOJle0q.js.map +0 -1
  731. package/dist/core/web/public/next/assets/SkipToContent-C7UObcP2.js +0 -2
  732. package/dist/core/web/public/next/assets/SkipToContent-C7UObcP2.js.map +0 -1
  733. package/dist/core/web/public/next/assets/Slider-Bi5q-21C.js +0 -2
  734. package/dist/core/web/public/next/assets/Slider-Bi5q-21C.js.map +0 -1
  735. package/dist/core/web/public/next/assets/SourcesPane-D7Raaor0.js +0 -2
  736. package/dist/core/web/public/next/assets/SourcesPane-D7Raaor0.js.map +0 -1
  737. package/dist/core/web/public/next/assets/SourcesPanel-CCSdY5Os.js +0 -2
  738. package/dist/core/web/public/next/assets/SourcesPanel-CCSdY5Os.js.map +0 -1
  739. package/dist/core/web/public/next/assets/StatTile-BS_dzInS.js +0 -2
  740. package/dist/core/web/public/next/assets/StatTile-BS_dzInS.js.map +0 -1
  741. package/dist/core/web/public/next/assets/StatusBadge-CJbb9DhR.js +0 -2
  742. package/dist/core/web/public/next/assets/StatusBadge-CJbb9DhR.js.map +0 -1
  743. package/dist/core/web/public/next/assets/StepBand-Bfj1YYTl.js +0 -2
  744. package/dist/core/web/public/next/assets/StepBand-Bfj1YYTl.js.map +0 -1
  745. package/dist/core/web/public/next/assets/Surface-CV-NXGIM.js +0 -2
  746. package/dist/core/web/public/next/assets/Surface-CV-NXGIM.js.map +0 -1
  747. package/dist/core/web/public/next/assets/Swimlane-DbUp4tjD.js +0 -2
  748. package/dist/core/web/public/next/assets/Swimlane-DbUp4tjD.js.map +0 -1
  749. package/dist/core/web/public/next/assets/Switch-BtEo9Cku.js +0 -2
  750. package/dist/core/web/public/next/assets/Switch-BtEo9Cku.js.map +0 -1
  751. package/dist/core/web/public/next/assets/Tag-CMFqY2MP.js +0 -2
  752. package/dist/core/web/public/next/assets/Tag-CMFqY2MP.js.map +0 -1
  753. package/dist/core/web/public/next/assets/TerminalPane-BCjlhc3t.js +0 -26
  754. package/dist/core/web/public/next/assets/TerminalPane-BCjlhc3t.js.map +0 -1
  755. package/dist/core/web/public/next/assets/TerminalPane-DIwGSCA9.js +0 -3
  756. package/dist/core/web/public/next/assets/TerminalPane-DIwGSCA9.js.map +0 -1
  757. package/dist/core/web/public/next/assets/ThinkingBlock-Db8qnuKz.js +0 -2
  758. package/dist/core/web/public/next/assets/ThinkingBlock-Db8qnuKz.js.map +0 -1
  759. package/dist/core/web/public/next/assets/UniverseConsoleApp-ksreONXM.js +0 -2
  760. package/dist/core/web/public/next/assets/UniverseConsoleApp-ksreONXM.js.map +0 -1
  761. package/dist/core/web/public/next/assets/UniverseView-CfT9Dsl7.js +0 -9
  762. package/dist/core/web/public/next/assets/UniverseView-CfT9Dsl7.js.map +0 -1
  763. package/dist/core/web/public/next/assets/UsageSection-DypcdQys.js +0 -3
  764. package/dist/core/web/public/next/assets/UsageSection-DypcdQys.js.map +0 -1
  765. package/dist/core/web/public/next/assets/UsePlaybookAction-Bxwqrpwe.js +0 -2
  766. package/dist/core/web/public/next/assets/UsePlaybookAction-Bxwqrpwe.js.map +0 -1
  767. package/dist/core/web/public/next/assets/VerseConsoleApp-kFOEmnGC.js +0 -3
  768. package/dist/core/web/public/next/assets/VerseConsoleApp-kFOEmnGC.js.map +0 -1
  769. package/dist/core/web/public/next/assets/VerseMobileApp-BTGF5yuZ.js +0 -3
  770. package/dist/core/web/public/next/assets/VerseMobileApp-BTGF5yuZ.js.map +0 -1
  771. package/dist/core/web/public/next/assets/VerseShared-_pMXKs8m.js +0 -2
  772. package/dist/core/web/public/next/assets/VerseShared-_pMXKs8m.js.map +0 -1
  773. package/dist/core/web/public/next/assets/VoiceHud-B_hiHfnQ.js +0 -2
  774. package/dist/core/web/public/next/assets/VoiceHud-B_hiHfnQ.js.map +0 -1
  775. package/dist/core/web/public/next/assets/VoiceInput-B7yrGchr.js +0 -2
  776. package/dist/core/web/public/next/assets/VoiceInput-B7yrGchr.js.map +0 -1
  777. package/dist/core/web/public/next/assets/WikiSection-BXu4aZyr.js +0 -2
  778. package/dist/core/web/public/next/assets/WikiSection-BXu4aZyr.js.map +0 -1
  779. package/dist/core/web/public/next/assets/Workspace-BYT3iuNM.js +0 -6
  780. package/dist/core/web/public/next/assets/Workspace-BYT3iuNM.js.map +0 -1
  781. package/dist/core/web/public/next/assets/actions-CyO4R-IO.js +0 -2
  782. package/dist/core/web/public/next/assets/actions-CyO4R-IO.js.map +0 -1
  783. package/dist/core/web/public/next/assets/agent-tools-client-FgVNokGh.js +0 -2
  784. package/dist/core/web/public/next/assets/agent-tools-client-FgVNokGh.js.map +0 -1
  785. package/dist/core/web/public/next/assets/agent-transcript-model-CRa_I3eR.js +0 -7
  786. package/dist/core/web/public/next/assets/agent-transcript-model-CRa_I3eR.js.map +0 -1
  787. package/dist/core/web/public/next/assets/agents-focus-D2hd-RNJ.js +0 -2
  788. package/dist/core/web/public/next/assets/agents-focus-D2hd-RNJ.js.map +0 -1
  789. package/dist/core/web/public/next/assets/app-version-DDlXX8-W.js +0 -2
  790. package/dist/core/web/public/next/assets/app-version-DDlXX8-W.js.map +0 -1
  791. package/dist/core/web/public/next/assets/apps-model-DLQgiczq.js +0 -2
  792. package/dist/core/web/public/next/assets/apps-model-DLQgiczq.js.map +0 -1
  793. package/dist/core/web/public/next/assets/ask-seat-zMpqJABI.js +0 -2
  794. package/dist/core/web/public/next/assets/ask-seat-zMpqJABI.js.map +0 -1
  795. package/dist/core/web/public/next/assets/authority-model-BvLFgPaX.js +0 -2
  796. package/dist/core/web/public/next/assets/authority-model-BvLFgPaX.js.map +0 -1
  797. package/dist/core/web/public/next/assets/automations-focus-zqI9oIl8.js +0 -2
  798. package/dist/core/web/public/next/assets/automations-focus-zqI9oIl8.js.map +0 -1
  799. package/dist/core/web/public/next/assets/budget-model-CKd0d1Cj.js +0 -2
  800. package/dist/core/web/public/next/assets/budget-model-CKd0d1Cj.js.map +0 -1
  801. package/dist/core/web/public/next/assets/budget-queries-q7mCG9Ek.js +0 -2
  802. package/dist/core/web/public/next/assets/budget-queries-q7mCG9Ek.js.map +0 -1
  803. package/dist/core/web/public/next/assets/capacity-strip-model-pdIEweaZ.js +0 -2
  804. package/dist/core/web/public/next/assets/capacity-strip-model-pdIEweaZ.js.map +0 -1
  805. package/dist/core/web/public/next/assets/charts-D3I0q4hG.js +0 -2
  806. package/dist/core/web/public/next/assets/charts-D3I0q4hG.js.map +0 -1
  807. package/dist/core/web/public/next/assets/chat-pane-data-DIDV7uIU.js +0 -2
  808. package/dist/core/web/public/next/assets/chat-pane-data-DIDV7uIU.js.map +0 -1
  809. package/dist/core/web/public/next/assets/checkpoint-queries-DjrDEsN-.js +0 -2
  810. package/dist/core/web/public/next/assets/checkpoint-queries-DjrDEsN-.js.map +0 -1
  811. package/dist/core/web/public/next/assets/cloud-model-DuboHWPT.js +0 -2
  812. package/dist/core/web/public/next/assets/cloud-model-DuboHWPT.js.map +0 -1
  813. package/dist/core/web/public/next/assets/cloud-queries-DQF1a_R-.js +0 -2
  814. package/dist/core/web/public/next/assets/cloud-queries-DQF1a_R-.js.map +0 -1
  815. package/dist/core/web/public/next/assets/command-catalog-BzHSIzIS.js +0 -2
  816. package/dist/core/web/public/next/assets/command-catalog-BzHSIzIS.js.map +0 -1
  817. package/dist/core/web/public/next/assets/composer-queries-BEYuD6Qr.js +0 -2
  818. package/dist/core/web/public/next/assets/composer-queries-BEYuD6Qr.js.map +0 -1
  819. package/dist/core/web/public/next/assets/composer-state-B4KVc2ZZ.js +0 -2
  820. package/dist/core/web/public/next/assets/composer-state-B4KVc2ZZ.js.map +0 -1
  821. package/dist/core/web/public/next/assets/connectivity-Svn7iy2K.js +0 -2
  822. package/dist/core/web/public/next/assets/connectivity-Svn7iy2K.js.map +0 -1
  823. package/dist/core/web/public/next/assets/context-model-C9EIuPJ_.js +0 -2
  824. package/dist/core/web/public/next/assets/context-model-C9EIuPJ_.js.map +0 -1
  825. package/dist/core/web/public/next/assets/context-model-DU3OPiBC.js +0 -3
  826. package/dist/core/web/public/next/assets/context-model-DU3OPiBC.js.map +0 -1
  827. package/dist/core/web/public/next/assets/context-queries-Cgb_XvRv.js +0 -2
  828. package/dist/core/web/public/next/assets/context-queries-Cgb_XvRv.js.map +0 -1
  829. package/dist/core/web/public/next/assets/control-queries-Clgsy_eH.js +0 -2
  830. package/dist/core/web/public/next/assets/control-queries-Clgsy_eH.js.map +0 -1
  831. package/dist/core/web/public/next/assets/copy-setup-C-hDt9sS.js +0 -2
  832. package/dist/core/web/public/next/assets/copy-setup-C-hDt9sS.js.map +0 -1
  833. package/dist/core/web/public/next/assets/deep-link-Cgvchdy7.js +0 -2
  834. package/dist/core/web/public/next/assets/deep-link-Cgvchdy7.js.map +0 -1
  835. package/dist/core/web/public/next/assets/device-permissions-JmqkyrDw.js +0 -2
  836. package/dist/core/web/public/next/assets/device-permissions-JmqkyrDw.js.map +0 -1
  837. package/dist/core/web/public/next/assets/devin-queries-DKgeD4_S.js +0 -2
  838. package/dist/core/web/public/next/assets/devin-queries-DKgeD4_S.js.map +0 -1
  839. package/dist/core/web/public/next/assets/dock-icons-CRHjXBWm.js +0 -2
  840. package/dist/core/web/public/next/assets/dock-icons-CRHjXBWm.js.map +0 -1
  841. package/dist/core/web/public/next/assets/dock-panes-C98u13Bi.js +0 -2
  842. package/dist/core/web/public/next/assets/dock-panes-C98u13Bi.js.map +0 -1
  843. package/dist/core/web/public/next/assets/fleet-control-queries-BLoc5Gza.js +0 -2
  844. package/dist/core/web/public/next/assets/fleet-control-queries-BLoc5Gza.js.map +0 -1
  845. package/dist/core/web/public/next/assets/fleet-model-CPTadBFK.js +0 -2
  846. package/dist/core/web/public/next/assets/fleet-model-CPTadBFK.js.map +0 -1
  847. package/dist/core/web/public/next/assets/fleet-queries-69WuY-dt.js +0 -2
  848. package/dist/core/web/public/next/assets/fleet-queries-69WuY-dt.js.map +0 -1
  849. package/dist/core/web/public/next/assets/fleet-state-CCdBRK-m.js +0 -3
  850. package/dist/core/web/public/next/assets/fleet-state-CCdBRK-m.js.map +0 -1
  851. package/dist/core/web/public/next/assets/focus-trap-C8MiYlLZ.js +0 -2
  852. package/dist/core/web/public/next/assets/focus-trap-C8MiYlLZ.js.map +0 -1
  853. package/dist/core/web/public/next/assets/format-CcEKjUou.js +0 -2
  854. package/dist/core/web/public/next/assets/format-CcEKjUou.js.map +0 -1
  855. package/dist/core/web/public/next/assets/git-model-DL3MwN93.js +0 -5
  856. package/dist/core/web/public/next/assets/git-model-DL3MwN93.js.map +0 -1
  857. package/dist/core/web/public/next/assets/global-BWc2NPzv.js +0 -3
  858. package/dist/core/web/public/next/assets/global-BWc2NPzv.js.map +0 -1
  859. package/dist/core/web/public/next/assets/guarded-action-BK2_U5ho.js +0 -3
  860. package/dist/core/web/public/next/assets/guarded-action-BK2_U5ho.js.map +0 -1
  861. package/dist/core/web/public/next/assets/guarded-runners-Q0UkoY3H.js +0 -2
  862. package/dist/core/web/public/next/assets/guarded-runners-Q0UkoY3H.js.map +0 -1
  863. package/dist/core/web/public/next/assets/headroom-CP99UxyV.js +0 -2
  864. package/dist/core/web/public/next/assets/headroom-CP99UxyV.js.map +0 -1
  865. package/dist/core/web/public/next/assets/health-queries-D8TwNTDQ.js +0 -2
  866. package/dist/core/web/public/next/assets/health-queries-D8TwNTDQ.js.map +0 -1
  867. package/dist/core/web/public/next/assets/icons-U34oiN9M.js +0 -2
  868. package/dist/core/web/public/next/assets/icons-U34oiN9M.js.map +0 -1
  869. package/dist/core/web/public/next/assets/index-BbDqdepe.js +0 -11
  870. package/dist/core/web/public/next/assets/index-BbDqdepe.js.map +0 -1
  871. package/dist/core/web/public/next/assets/jev-queries-CiQDnM5r.js +0 -2
  872. package/dist/core/web/public/next/assets/jev-queries-CiQDnM5r.js.map +0 -1
  873. package/dist/core/web/public/next/assets/ladder-queries-Cf64JB04.js +0 -2
  874. package/dist/core/web/public/next/assets/ladder-queries-Cf64JB04.js.map +0 -1
  875. package/dist/core/web/public/next/assets/leader-focus-azN19kfO.js +0 -2
  876. package/dist/core/web/public/next/assets/leader-focus-azN19kfO.js.map +0 -1
  877. package/dist/core/web/public/next/assets/live-model-DHX_2gOu.js +0 -2
  878. package/dist/core/web/public/next/assets/live-model-DHX_2gOu.js.map +0 -1
  879. package/dist/core/web/public/next/assets/mind.module-BJpuH2JT.js +0 -2
  880. package/dist/core/web/public/next/assets/mind.module-BJpuH2JT.js.map +0 -1
  881. package/dist/core/web/public/next/assets/mobile-actions-CvGouAAH.js +0 -2
  882. package/dist/core/web/public/next/assets/mobile-actions-CvGouAAH.js.map +0 -1
  883. package/dist/core/web/public/next/assets/mobile-toast-C_UP13GQ.js +0 -2
  884. package/dist/core/web/public/next/assets/mobile-toast-C_UP13GQ.js.map +0 -1
  885. package/dist/core/web/public/next/assets/multimodel-flows-C377w9oZ.js +0 -7
  886. package/dist/core/web/public/next/assets/multimodel-flows-C377w9oZ.js.map +0 -1
  887. package/dist/core/web/public/next/assets/multimodel-queries-_Y1QXAqq.js +0 -2
  888. package/dist/core/web/public/next/assets/multimodel-queries-_Y1QXAqq.js.map +0 -1
  889. package/dist/core/web/public/next/assets/mutations-DL4u2kRQ.js +0 -2
  890. package/dist/core/web/public/next/assets/mutations-DL4u2kRQ.js.map +0 -1
  891. package/dist/core/web/public/next/assets/nav-CM-mJcSq.js +0 -2
  892. package/dist/core/web/public/next/assets/nav-CM-mJcSq.js.map +0 -1
  893. package/dist/core/web/public/next/assets/needs-you-actions-DF2zEltF.js +0 -2
  894. package/dist/core/web/public/next/assets/needs-you-actions-DF2zEltF.js.map +0 -1
  895. package/dist/core/web/public/next/assets/needs-you-model-DqmU5YOe.js +0 -2
  896. package/dist/core/web/public/next/assets/needs-you-model-DqmU5YOe.js.map +0 -1
  897. package/dist/core/web/public/next/assets/open-terminal-BAnwAOoA.js +0 -2
  898. package/dist/core/web/public/next/assets/open-terminal-BAnwAOoA.js.map +0 -1
  899. package/dist/core/web/public/next/assets/open-terminal-request-f5_ItEpF.js +0 -2
  900. package/dist/core/web/public/next/assets/open-terminal-request-f5_ItEpF.js.map +0 -1
  901. package/dist/core/web/public/next/assets/overnight-queries-BP6viiM5.js +0 -2
  902. package/dist/core/web/public/next/assets/overnight-queries-BP6viiM5.js.map +0 -1
  903. package/dist/core/web/public/next/assets/palette-handoff-Bmq98lDl.js +0 -2
  904. package/dist/core/web/public/next/assets/palette-handoff-Bmq98lDl.js.map +0 -1
  905. package/dist/core/web/public/next/assets/panes-BjUzIDw6.js +0 -3
  906. package/dist/core/web/public/next/assets/panes-BjUzIDw6.js.map +0 -1
  907. package/dist/core/web/public/next/assets/path-display-HyxETV-f.js +0 -2
  908. package/dist/core/web/public/next/assets/path-display-HyxETV-f.js.map +0 -1
  909. package/dist/core/web/public/next/assets/playbook-composer-DwuBBP4I.js +0 -2
  910. package/dist/core/web/public/next/assets/playbook-composer-DwuBBP4I.js.map +0 -1
  911. package/dist/core/web/public/next/assets/playbook-focus-B9xzeUMw.js +0 -2
  912. package/dist/core/web/public/next/assets/playbook-focus-B9xzeUMw.js.map +0 -1
  913. package/dist/core/web/public/next/assets/playbooks-queries-C8j1Aswo.js +0 -2
  914. package/dist/core/web/public/next/assets/playbooks-queries-C8j1Aswo.js.map +0 -1
  915. package/dist/core/web/public/next/assets/preloaded-CLDUOHXJ.js +0 -2
  916. package/dist/core/web/public/next/assets/preloaded-CLDUOHXJ.js.map +0 -1
  917. package/dist/core/web/public/next/assets/primitives-BEXDE-HP.js +0 -1
  918. package/dist/core/web/public/next/assets/pwa-lVT_VRkK.js +0 -2
  919. package/dist/core/web/public/next/assets/pwa-lVT_VRkK.js.map +0 -1
  920. package/dist/core/web/public/next/assets/queries-T7ZUVqyA.js +0 -2
  921. package/dist/core/web/public/next/assets/queries-T7ZUVqyA.js.map +0 -1
  922. package/dist/core/web/public/next/assets/reasoning-pref-CWEri5xB.js +0 -2
  923. package/dist/core/web/public/next/assets/reasoning-pref-CWEri5xB.js.map +0 -1
  924. package/dist/core/web/public/next/assets/remote-session-BPULIfdG.js +0 -3
  925. package/dist/core/web/public/next/assets/remote-session-BPULIfdG.js.map +0 -1
  926. package/dist/core/web/public/next/assets/resolved-store-Ba-W6Uhy.js +0 -2
  927. package/dist/core/web/public/next/assets/resolved-store-Ba-W6Uhy.js.map +0 -1
  928. package/dist/core/web/public/next/assets/resources-queries-CKyXyaDY.js +0 -2
  929. package/dist/core/web/public/next/assets/resources-queries-CKyXyaDY.js.map +0 -1
  930. package/dist/core/web/public/next/assets/reveal-anchor-Djk1vGLl.js +0 -2
  931. package/dist/core/web/public/next/assets/reveal-anchor-Djk1vGLl.js.map +0 -1
  932. package/dist/core/web/public/next/assets/seat-readiness-CvEmMBol.js +0 -2
  933. package/dist/core/web/public/next/assets/seat-readiness-CvEmMBol.js.map +0 -1
  934. package/dist/core/web/public/next/assets/seat-subscription-BClqZwau.js +0 -2
  935. package/dist/core/web/public/next/assets/seat-subscription-BClqZwau.js.map +0 -1
  936. package/dist/core/web/public/next/assets/sheet-D0ciShoy.js +0 -2
  937. package/dist/core/web/public/next/assets/sheet-D0ciShoy.js.map +0 -1
  938. package/dist/core/web/public/next/assets/sidebar-model-BZ9Wh1lR.js +0 -2
  939. package/dist/core/web/public/next/assets/sidebar-model-BZ9Wh1lR.js.map +0 -1
  940. package/dist/core/web/public/next/assets/slots-m3L6Ints.js +0 -3
  941. package/dist/core/web/public/next/assets/slots-m3L6Ints.js.map +0 -1
  942. package/dist/core/web/public/next/assets/sources-queries-DeIlxb3A.js +0 -4
  943. package/dist/core/web/public/next/assets/sources-queries-DeIlxb3A.js.map +0 -1
  944. package/dist/core/web/public/next/assets/sse-CK65-Cun.js +0 -2
  945. package/dist/core/web/public/next/assets/sse-CK65-Cun.js.map +0 -1
  946. package/dist/core/web/public/next/assets/surface-data-DoN8peNV.js +0 -2
  947. package/dist/core/web/public/next/assets/surface-data-DoN8peNV.js.map +0 -1
  948. package/dist/core/web/public/next/assets/surface-prefetch-CVNIptSl.js +0 -2
  949. package/dist/core/web/public/next/assets/surface-prefetch-CVNIptSl.js.map +0 -1
  950. package/dist/core/web/public/next/assets/tasks-model-BueAhEAf.js +0 -2
  951. package/dist/core/web/public/next/assets/tasks-model-BueAhEAf.js.map +0 -1
  952. package/dist/core/web/public/next/assets/terminal-client-DO0eRhRi.js +0 -2
  953. package/dist/core/web/public/next/assets/terminal-client-DO0eRhRi.js.map +0 -1
  954. package/dist/core/web/public/next/assets/terminal-icons-COMoAiDd.js +0 -2
  955. package/dist/core/web/public/next/assets/terminal-icons-COMoAiDd.js.map +0 -1
  956. package/dist/core/web/public/next/assets/terminal-view-DkVXx7Xk.js +0 -6
  957. package/dist/core/web/public/next/assets/terminal-view-DkVXx7Xk.js.map +0 -1
  958. package/dist/core/web/public/next/assets/thread-data-Dq7QugaD.js +0 -2
  959. package/dist/core/web/public/next/assets/thread-data-Dq7QugaD.js.map +0 -1
  960. package/dist/core/web/public/next/assets/ui-parts-2JLq2ZSq.js +0 -2
  961. package/dist/core/web/public/next/assets/ui-parts-2JLq2ZSq.js.map +0 -1
  962. package/dist/core/web/public/next/assets/usage-queries-CDKUE4e0.js +0 -2
  963. package/dist/core/web/public/next/assets/usage-queries-CDKUE4e0.js.map +0 -1
  964. package/dist/core/web/public/next/assets/use-chat-activity-BaNWmI2A.js +0 -2
  965. package/dist/core/web/public/next/assets/use-chat-activity-BaNWmI2A.js.map +0 -1
  966. package/dist/core/web/public/next/assets/use-guarded-action-D4m4Mlzr.js +0 -2
  967. package/dist/core/web/public/next/assets/use-guarded-action-D4m4Mlzr.js.map +0 -1
  968. package/dist/core/web/public/next/assets/use-ticker-PQ_oYxn5.js +0 -2
  969. package/dist/core/web/public/next/assets/use-ticker-PQ_oYxn5.js.map +0 -1
  970. package/dist/core/web/public/next/assets/use-token-gate-_JPjMD5z.js +0 -2
  971. package/dist/core/web/public/next/assets/use-token-gate-_JPjMD5z.js.map +0 -1
  972. package/dist/core/web/public/next/assets/useAutoSeat-CkyqgwX9.js +0 -2
  973. package/dist/core/web/public/next/assets/useAutoSeat-CkyqgwX9.js.map +0 -1
  974. package/dist/core/web/public/next/assets/useOnboarding-3r8T1GBP.js +0 -2
  975. package/dist/core/web/public/next/assets/useOnboarding-3r8T1GBP.js.map +0 -1
  976. package/dist/core/web/public/next/assets/useSeatHealth-C08b9zut.js +0 -2
  977. package/dist/core/web/public/next/assets/useSeatHealth-C08b9zut.js.map +0 -1
  978. package/dist/core/web/public/next/assets/useSeatsRefresh-BGsdylUl.js +0 -2
  979. package/dist/core/web/public/next/assets/useSeatsRefresh-BGsdylUl.js.map +0 -1
  980. package/dist/core/web/public/next/assets/useVerseSession-0MnfpcHg.js +0 -2
  981. package/dist/core/web/public/next/assets/useVerseSession-0MnfpcHg.js.map +0 -1
  982. package/dist/core/web/public/next/assets/useVerseTranscript-B6wLDOv8.js +0 -2
  983. package/dist/core/web/public/next/assets/useVerseTranscript-B6wLDOv8.js.map +0 -1
  984. package/dist/core/web/public/next/assets/verse-bootstrap-query-BR5ypA8b.js +0 -2
  985. package/dist/core/web/public/next/assets/verse-bootstrap-query-BR5ypA8b.js.map +0 -1
  986. package/dist/core/web/public/next/assets/verse-icons-BQxBZk9k.js +0 -2
  987. package/dist/core/web/public/next/assets/verse-icons-BQxBZk9k.js.map +0 -1
  988. package/dist/core/web/public/next/assets/verse-model-CkF3q2IH.js +0 -2
  989. package/dist/core/web/public/next/assets/verse-model-CkF3q2IH.js.map +0 -1
  990. package/dist/core/web/public/next/assets/warmup-CqTK8yIn.js +0 -3
  991. package/dist/core/web/public/next/assets/warmup-CqTK8yIn.js.map +0 -1
  992. package/dist/core/web/public/next/assets/why-seat-model-Dh4-Ty9n.js +0 -2
  993. package/dist/core/web/public/next/assets/why-seat-model-Dh4-Ty9n.js.map +0 -1
  994. package/dist/core/web/public/next/assets/wiki-focus-CisQb_pM.js +0 -2
  995. package/dist/core/web/public/next/assets/wiki-focus-CisQb_pM.js.map +0 -1
  996. package/dist/core/web/public/next/assets/workspace-model-DRGckE8q.js +0 -2
  997. package/dist/core/web/public/next/assets/workspace-model-DRGckE8q.js.map +0 -1
@@ -1,7 +0,0 @@
1
- import{l as e}from"./index-BbDqdepe.js";import{R as t}from"./global-BWc2NPzv.js";import{A as n}from"./VerseConsoleApp-kFOEmnGC.js";import{a as r,m as i}from"./VerseShared-_pMXKs8m.js";import{i as a}from"./verse-store-DAqqNIyD.js";import{r as o,t as s}from"./context-queries-Cgb_XvRv.js";import"./composer-state-B4KVc2ZZ.js";import{t as c}from"./verse-transcript-Dc-bk9l2.js";import{i as l,o as u}from"./multimodel-queries-_Y1QXAqq.js";function d(e){return e instanceof Error&&e.message?e.message:typeof e==`string`&&e?e:`The request failed.`}function f(e){let t=new Set,n=[];for(let r of e)if(r.seatId&&!t.has(r.seatId)&&(t.add(r.seatId),n.push(r),n.length===3))break;return n}async function p(e,t,n){let r=f(e);return Promise.all(r.map(async e=>{let r=null;try{if(r=(await n.createSession(e)).id,n.link)try{await n.link(r)}catch{}return await n.sendTurn(r,t),{target:e,ok:!0,sessionId:r}}catch(t){return{target:e,ok:!1,sessionId:r,error:d(t)}}}))}function m(e,t,n=3){let r=[...e?[e]:[],...t],i=[],a=new Set,o=e=>{i.length>=n||i.some(t=>t.seatId===e.seatId)||(i.push(e),a.add(e.engine))};if(e&&e.tier===`elite`&&!e.local){for(let e of r)!a.has(e.engine)&&e.tier===`elite`&&!e.local&&o(e);for(let e of r)a.has(e.engine)||o(e);for(let e of r)o(e);return i.slice(0,n)}for(let e of r)!a.has(e.engine)&&!e.local&&o(e);let s=r.find(e=>e.local);s&&!i.some(e=>e.local)&&(i.length===n&&i.pop(),o(s));for(let e of r)o(e);return i.slice(0,n)}var h=new Set([`devin`]);function g(e,t){return t.find(t=>t.engine!==e&&!h.has(t.engine))??null}var _=24e3;function v(e,t){return e.length<=t?e:`${e.slice(0,t)}\n…(truncated for review)`}function y(e){let t=[`You are reviewing work produced by another model (${e.authorLabel}). Be an independent, skeptical reviewer.`,`The repository is open to you: read files or run read-only commands (such as a diff) to check claims, but change nothing.`,`Start with one line: "Verdict: ship", "Verdict: fix first" or "Verdict: wrong", then list concrete problems (correctness, missed edge cases, security, simpler alternatives), most important first. Say plainly when you find nothing.`];if(e.question&&t.push(``,`The request was:`,``,v(e.question.trim(),4e3)),e.answer&&t.push(``,`The answer to review:`,``,v(e.answer.trim(),_)),e.diff){let n=v(e.diff.trim(),_),r=Math.max(0,...Array.from(n.matchAll(/`+/g),e=>e[0].length)),i="`".repeat(Math.max(3,r+1));t.push(``,`The changes to review:`,``,`${i}diff`,n,i)}return t.join(`
2
- `)}function b(e,t){return t?`${t.trim()}\n\n---\n\nThe request to answer now:\n\n${e}`:e}var x=.55,S=[/\bI(?:'m| am) not (?:sure|certain)\b/i,/\bI (?:don't|do not) know\b/i,/\bI (?:can't|cannot|am unable to|'m unable to)\b/i,/\bunable to (?:determine|access|find|help)\b/i,/\bas an AI\b/i,/\bI (?:don't|do not) have access\b/i,/\bwithout more (?:context|information)\b/i,/\bit(?:'s| is) (?:unclear|hard to say)\b/i];function C(e){let t=new Map;for(let n of e.split(`
3
- `)){let e=n.trim();if(e.length<12)continue;let r=(t.get(e)??0)+1;if(r>=3)return!0;t.set(e,r)}return!1}function w(e){let t=e.trimEnd();return t.length<400?!1:/```\s*$/.test(t)&&(t.match(/```/g)??[]).length%2==1?!0:!/[.!?:)\]`"'*>|]$/.test(t)}function T(e){let t=[],n=e.text.trim();if(!e.ok)return{escalate:!0,confidence:0,reasons:[`The local turn did not finish cleanly.`]};if(n.length===0)return{escalate:!0,confidence:0,reasons:[`The local model returned nothing.`]};let r=1,i=e.classification.difficulty===`low`;n.length<40&&!i&&(e.toolUses??0)===0&&(r-=.5,t.push(`The answer is very short for the question.`));let a=S.filter(e=>e.test(n)).length;return a>0&&(r-=Math.min(.6,.3*a),t.push(a===1?`The answer hedges.`:`The answer hedges ${a} times.`)),C(n)&&(r-=.5,t.push(`The answer repeats itself.`)),w(n)&&(r-=.3,t.push(`The answer looks cut off.`)),(e.classification.kind===`code`||e.classification.kind===`debug`||e.classification.kind===`refactor`)&&!/```/.test(n)&&(e.toolUses??0)===0&&(r-=.3,t.push(`A code request got neither code nor edits.`)),r=Math.max(0,Math.round(r*100)/100),t.length===0&&t.push(`The draft reads complete.`),{escalate:r<x,confidence:r,reasons:t}}function E(e,t,n,r){let i=t.length>6e3?`${t.slice(0,6e3)}\n…(draft truncated)`:t;return[e.trim(),``,`---`,`A local model (${r}) drafted an answer first; it was escalated because: ${n.reasons.join(` `)}`,`Use it only if it is right. Its draft:`,``,i.split(`
4
- `).map(e=>`> ${e}`).join(`
5
- `)].join(`
6
- `)}function D(e){return Math.ceil(e.length/4)}var O={review:/\b(review|critique|audit|look over|second opinion|sanity[- ]check|double[- ]check|code review|pr review|poke holes)\b/i,debug:/\b(error|exception|stack ?trace|traceback|failing|fails|failed|bug|crash(?:es|ed)?|broken|doesn'?t work|not working|segfault|panic|regression|flaky|TypeError|ReferenceError|undefined is not|cannot read propert)/i,refactor:/\b(refactor|restructure|clean ?up|extract (?:a |the )?\w+|migrate|port (?:it|this|the)|rename (?:all|every)|split (?:up|into)|consolidate|decouple)\b/i,plan:/\b(plan|design|architect(?:ure)?|approach|strategy|roadmap|trade-?offs?|should (?:we|i)|how should|pros and cons|options for|spec(?:ification)?)\b/i,code:/\b(implement|write|add|create|build|fix|make|update|change|wire|hook up|remove|delete|replace|convert|generate)\b/i,codeNoun:/\b(function|class|component|endpoint|tests?|script|handler|route|migration|schema)\b/i,bulk:/\b(all files|every file|across the (?:repo|codebase|project)|bulk|batch|each of (?:the|these)|every (?:module|package|test)|codemod|mass[- ]rename)\b/i,question:/^\s*(what|why|how|when|where|who|which|is|are|does|do|can|could|should|would|will|explain|tell me)\b/i,explain:/\b(explain|what does|what is|how does|walk me through|summari[sz]e|describe|meaning of|difference between)\b/i,hard:/\b(architect(?:ure)?|concurren(?:t|cy)|race condition|deadlock|security|vulnerab|auth(?:entication|orization)?|migration|performance|optimi[sz]e|distributed|memory leak|end[- ]to[- ]end|from scratch|entire|whole (?:codebase|repo|system)|complex|tricky|subtle|production)\b/i,easy:/\b(typo|quick|simple|small|tiny|trivial|one[- ]liner|rename|bump|format|lint|comment|docstring)\b/i,stackTrace:/(^\s+at .+\(.+:\d+:\d+\)$)|(Traceback \(most recent call last\))|(^\s*File ".+", line \d+)/m},k={question:{low:`quick question`,medium:`question`,high:`hard question`},explain:{low:`quick explanation`,medium:`explanation`,high:`deep explanation`},code:{low:`small code change`,medium:`code change`,high:`hard code change`},debug:{low:`quick fix`,medium:`debugging`,high:`hard debugging`},refactor:{low:`small refactor`,medium:`refactor`,high:`hard refactor`},review:{low:`quick review`,medium:`review`,high:`deep review`},plan:{low:`quick plan`,medium:`planning`,high:`architecture planning`},bulk:{low:`bulk edit`,medium:`bulk edit`,high:`large bulk edit`}};function A(e){return e===`review`?`review`:e===`plan`?`plan`:e===`bulk`?`bulk`:`code`}function j(e,t,n){if(O.bulk.test(e))return n.push(`touches many files`),`bulk`;if(O.review.test(e))return n.push(`asks for a review`),`review`;if(O.stackTrace.test(e))return n.push(`stack trace`),`debug`;if(O.debug.test(e))return n.push(`names a failure`),`debug`;if(O.refactor.test(e))return n.push(`restructures code`),`refactor`;if(O.plan.test(e))return n.push(`asks for a plan or design`),`plan`;let r=O.code.test(e);return O.explain.test(e)&&!r?(n.push(`asks for an explanation`),`explain`):(O.question.test(e)||e.trim().endsWith(`?`))&&!r&&!t?(n.push(`a question`),`question`):((r||t||O.codeNoun.test(e))&&n.push(t?`includes code`:`asks for a change`),`code`)}function M(e,t){return e>2e3||t>=4?`large`:e<120&&t<=1?`small`:`medium`}function N(e,t={}){let n=e.trim(),r=[],i=D(n),a=/```/.test(n)||/^( {4}|\t)\S/m.test(n),o=(n.match(/(^|\s)@[\w./-]+/g)??[]).length+(n.match(/\b[\w-]+\/[\w./-]+\.(?:ts|tsx|js|jsx|py|go|rs|java|rb|swift|kt|css|md|json|ya?ml)\b/g)??[]).length;o>0&&r.push(o===1?`1 file named`:`${o} files named`);let s=j(n,a,r),c=M(i,o);c===`large`&&r.push(`≈${i.toLocaleString(`en-US`)} tokens`);let l=`medium`,u=O.hard.test(n),d=O.easy.test(n);u&&r.push(`hard subject`),u||c===`large`||s===`plan`&&c!==`small`||s===`refactor`&&o>=2?l=`high`:(d||c===`small`&&(s===`question`||s===`explain`))&&(l=`low`,d&&r.push(`small by its own words`));let f=t.contextTokens??0;return l===`low`&&f>15e4&&(l=`medium`,r.push(`deep into a long chat`)),{kind:s,task:A(s),difficulty:l,size:c,estTokens:i,label:k[s][l],signals:r}}var P=2,F=1.5;Object.freeze({up:1,down:-1,retry:-.5,"switch-away":-.5,"switch-to":.5,"auto-followed":.1,"auto-overridden":-.5,"compare-won":1,"compare-lost":-.25,escalated:-.5,"draft-accepted":1});function I(e,t){return`${e}|seat:${t}`}function L(e,t){return`${e}|engine:${t}`}var R={question:`questions`,explain:`explanations`,code:`code changes`,debug:`debugging`,refactor:`refactors`,review:`reviews`,plan:`planning`,bulk:`bulk edits`};function z(e,t,n){if(!e)return{tilt:0,phrase:null};let r=e[I(t,n.seatId)],i=e[L(t,n.engine)],a=r&&r.n>=3?r:i&&i.n>=3?i:null;if(!a)return{tilt:0,phrase:null};let o=a.score/(a.n+P),s=-Math.max(-1.5,Math.min(F,o*2*F));if(Math.abs(s)<.15)return{tilt:0,phrase:null};let c=a.up+a.down,l=c>0?` (${a.up} of ${c} signals positive)`:``,u=s<0?`you've preferred ${n.label} for ${R[t]}${l}`:`you've passed over ${n.label} for ${R[t]}${l}`;return{tilt:Math.round(s*1e3)/1e3,phrase:u}}function B(e,t,n,r){return t.map(t=>({at:r,seatId:t.seatId,engine:t.engine,kind:n,signal:t.sessionId===e?`compare-won`:`compare-lost`,sessionId:t.sessionId,...t.model?{model:t.model}:{}}))}var V=e({DEFAULT_FLOW_API:()=>H,escalate:()=>Q,looksLikePlan:()=>K,pickWinner:()=>X,quickHandoff:()=>q,quickHandoffFromChat:()=>J,routeMessage:()=>G,siblingRequest:()=>U,startCompare:()=>Y,startReview:()=>Z}),H={createSession:r,createHandoffSession:s,fetchHandoffPreview:o,sendTurn:i,link:l,outcome:u,saveDraft:t,open:n};function U(e,t,n){let r={projectPath:e.projectPath,seatId:t.seatId},i=(e.extraRoots??[]).filter(t=>typeof t==`string`&&t.length>0&&t!==e.projectPath);i.length>0&&(r.extraRoots=i),t.model&&(r.model=t.model);let a=n?.trim();return a&&(r.title=a.slice(0,120)),r}async function W(e,t,n,r){if(t.turnCount>0){let i=await e.fetchHandoffPreview(t.id);return{session:await e.createHandoffSession({source:t,seatId:n.seatId,...n.model?{model:n.model}:{},...r?{title:r}:{}}),note:i.text}}return{session:await e.createSession(U(t,n,r)),note:null}}async function G(e,t){let{session:n,note:r}=await W(e,t.source,t.target);return await e.sendTurn(n.id,b(t.text,r)),e.outcome({seatId:t.target.seatId,kind:t.kind,signal:t.overridden?`switch-to`:`auto-followed`,sessionId:n.id}),t.overridden&&e.outcome({seatId:t.overridden.seatId,kind:t.kind,signal:`auto-overridden`}),e.open(n.id),n}function K(e){return e?/^#{1,4}\s*(?:the\s+)?plan\b/im.test(e)?!0:(e.match(/^\s*(?:\d+[.)]|[-*] \[[ x]\])\s+\S/gm)??[]).length>=3:!1}async function q(e,t){let n=K(t.lastAssistant),r=await e.fetchHandoffPreview(t.source.id,n?{includeLastAssistant:!0}:{}),i=await e.createHandoffSession({source:t.source,seatId:t.target.seatId,...t.target.model?{model:t.target.model}:{}});return e.saveDraft(i.id,r.text),e.outcome({seatId:t.source.seatId,kind:t.kind,signal:`switch-away`,sessionId:t.source.id}),e.outcome({seatId:t.target.seatId,kind:t.kind,signal:`switch-to`,sessionId:i.id}),e.open(i.id),i}async function J(e,t,n=H){let r=a(e).session;if(!r||r.turnCount===0)return null;let i=c(e).items,o=``,s=null;for(let e=i.length-1;e>=0;--e){let t=i[e];if(s===null&&t.kind===`assistant`&&(s=t.text),t.kind===`user`){o=t.text;break}}return q(n,{source:r,target:t,lastAssistant:s,kind:N(o).kind})}async function Y(e,t){let n=t.source.turnCount>0?(await e.fetchHandoffPreview(t.source.id)).text:null,r=e=>`${t.source.title.slice(0,80)} · ${e}`;return p(t.targets,b(t.text,n),{createSession:n=>t.source.turnCount>0?e.createHandoffSession({source:t.source,seatId:n.seatId,...n.model?{model:n.model}:{},title:r(n.label)}):e.createSession(U(t.source,n,r(n.label))),sendTurn:(t,n)=>e.sendTurn(t,n),link:n=>e.link({parentSessionId:t.source.id,childSessionId:n,relation:`compare`})})}async function X(e,t){let n=B(t.winnerSessionId,t.entries,t.kind,new Date().toISOString());await Promise.all(n.map(t=>e.outcome({seatId:t.seatId,kind:t.kind,signal:t.signal,...t.sessionId?{sessionId:t.sessionId}:{},...t.model?{model:t.model}:{}}))),e.open(t.winnerSessionId)}async function Z(e,t){let n=await e.createSession(U(t.source,t.reviewer,`Review · ${t.source.title.slice(0,80)}`));return e.link({parentSessionId:t.source.id,childSessionId:n.id,relation:`review`}),await e.sendTurn(n.id,y({question:t.question,answer:t.answer,authorLabel:t.authorLabel})),n}async function Q(e,t){let{session:n,note:r}=await W(e,t.source,t.target);return e.link({parentSessionId:t.source.id,childSessionId:n.id,relation:`escalate`}),await e.sendTurn(n.id,b(E(t.question,t.draft,t.verdict,t.draftLabel),r)),e.outcome({seatId:t.source.seatId,kind:t.kind,signal:`escalated`,sessionId:t.source.id}),e.open(n.id),n}export{G as a,Z as c,T as d,g as f,X as i,z as l,y as m,Q as n,U as o,m as p,V as r,Y as s,H as t,N as u};
7
- //# sourceMappingURL=multimodel-flows-C377w9oZ.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"multimodel-flows-C377w9oZ.js","names":[],"sources":["../../../../../../src/core/verse/multimodel/compare.ts","../../../../../../src/core/verse/multimodel/escalation.ts","../../../../../../src/core/verse/multimodel/classify.ts","../../../../../../src/core/verse/multimodel/learning.ts","../../../../../../src/web-ui/routes/verse/multimodel/multimodel-flows.ts"],"sourcesContent":["/**\n * Compare and cross-family review — the same prompt to 2–3 seats at once, and\n * \"ask another model to review this\" in one click.\n *\n * FAN-OUT GOES THROUGH THE FRONT DOOR. `fanOut` takes its two effects as\n * injected functions, and the app passes the SAME `createVerseSession` /\n * `sendVerseTurn` a hand-typed chat uses — so every answer passes the spend\n * chokepoint, the readiness gate, the local-only gate and the mutation token.\n * One seat failing (not ready, signed out, refused) never sinks the others:\n * each target settles on its own and reports why.\n *\n * Every Compare answer is a real chat, linked to its thread\n * (`relation: 'compare'`), so \"pick one to continue\" is simply opening that\n * chat — its context is already there — and the per-chat meter counts all of\n * them.\n *\n * BROWSER-SAFE and deterministic (the effects are injected).\n */\nimport type { SeatAdviceOption } from './types.js';\n\n/** Most seats one Compare may fan out to. */\nexport const COMPARE_MAX_SEATS = 3;\n\nexport interface CompareTarget {\n seatId: string;\n model: string | null;\n label: string;\n engine: string;\n}\n\nexport interface FanOutDeps {\n /** Create a chat on `target` (POST /api/verse/sessions); resolves to its id. */\n createSession(target: CompareTarget): Promise<{ id: string }>;\n /** Send turn 1 (POST /api/verse/sessions/:id/turns). */\n sendTurn(sessionId: string, text: string): Promise<unknown>;\n /** Record the thread link (best effort — a failure here never fails the answer). */\n link?(childSessionId: string): Promise<unknown>;\n}\n\nexport type FanOutEntry =\n | { target: CompareTarget; ok: true; sessionId: string }\n | { target: CompareTarget; ok: false; sessionId: string | null; error: string };\n\nfunction message(err: unknown): string {\n if (err instanceof Error && err.message) return err.message;\n return typeof err === 'string' && err ? err : 'The request failed.';\n}\n\n/** Distinct seats, capped at COMPARE_MAX_SEATS, in the caller's order. */\nexport function normalizeTargets(targets: readonly CompareTarget[]): CompareTarget[] {\n const seen = new Set<string>();\n const out: CompareTarget[] = [];\n for (const t of targets) {\n if (!t.seatId || seen.has(t.seatId)) continue;\n seen.add(t.seatId);\n out.push(t);\n if (out.length === COMPARE_MAX_SEATS) break;\n }\n return out;\n}\n\n/**\n * Send `text` to every target in parallel. Never throws: each entry says\n * whether its chat was created and its turn accepted.\n */\nexport async function fanOut(targets: readonly CompareTarget[], text: string, deps: FanOutDeps): Promise<FanOutEntry[]> {\n const list = normalizeTargets(targets);\n return Promise.all(list.map(async (target): Promise<FanOutEntry> => {\n let sessionId: string | null = null;\n try {\n sessionId = (await deps.createSession(target)).id;\n if (deps.link) {\n try { await deps.link(sessionId); } catch { /* the meter just misses this link */ }\n }\n await deps.sendTurn(sessionId, text);\n return { target, ok: true, sessionId };\n } catch (err) {\n return { target, ok: false, sessionId, error: message(err) };\n }\n }));\n}\n\n/**\n * Default Compare set: the Auto choice plus the best seats of OTHER engines\n * (a second account of the same provider is not a second opinion).\n *\n * - Elite work (the Auto choice is a hosted elite seat): the elite partners\n * against each other — typically Claude + Codex + Devin (3.15).\n * - Everything else: with one local model when there is one — so a typical\n * set is two hosted seats + local.\n */\nexport function defaultCompareSet(choice: SeatAdviceOption | null, alternatives: readonly SeatAdviceOption[], max = COMPARE_MAX_SEATS): SeatAdviceOption[] {\n const pool = [...(choice ? [choice] : []), ...alternatives];\n const out: SeatAdviceOption[] = [];\n const engines = new Set<string>();\n const take = (o: SeatAdviceOption) => {\n if (out.length >= max || out.some((x) => x.seatId === o.seatId)) return;\n out.push(o);\n engines.add(o.engine);\n };\n if (choice && choice.tier === 'elite' && !choice.local) {\n for (const o of pool) if (!engines.has(o.engine) && o.tier === 'elite' && !o.local) take(o);\n for (const o of pool) if (!engines.has(o.engine)) take(o);\n for (const o of pool) take(o);\n return out.slice(0, max);\n }\n for (const o of pool) if (!engines.has(o.engine) && !o.local) take(o);\n const local = pool.find((o) => o.local);\n if (local && !out.some((o) => o.local)) {\n // Make room for one local voice when the set is all paid seats.\n if (out.length === max) out.pop();\n take(local);\n }\n for (const o of pool) take(o);\n return out.slice(0, max);\n}\n\n/**\n * The reviewer for cross-family review: the best-ranked seat whose engine\n * differs from the author's. Claude-on-Ollama (`local`) counts as a different\n * family from `claude` — it is a different model. Null when every candidate\n * shares the author's engine.\n *\n * Devin REVIEWS nothing here: its answers are reviewed like anyone's, but it\n * is never auto-picked to deliver a verdict (\"Verdict: ship\") on another\n * model's work — the same producer-not-judge line the fleet holds (a decision\n * left to Mason, 3.15).\n */\nexport const NEVER_AUTO_REVIEWER_ENGINES: ReadonlySet<string> = new Set(['devin']);\n\nexport function crossFamilyReviewer(authorEngine: string, ranked: readonly SeatAdviceOption[]): SeatAdviceOption | null {\n return ranked.find((o) => o.engine !== authorEngine && !NEVER_AUTO_REVIEWER_ENGINES.has(o.engine)) ?? null;\n}\n\nexport interface ReviewSubject {\n /** What Mason asked, when reviewing an answer. */\n question?: string | null;\n /** The answer under review. */\n answer?: string | null;\n /** `git diff --stat` / a diff excerpt, when reviewing changes. */\n diff?: string | null;\n authorLabel: string;\n}\n\nconst REVIEW_MAX_CHARS = 24_000;\n\nfunction cap(text: string, max: number): string {\n return text.length <= max ? text : `${text.slice(0, max)}\\n…(truncated for review)`;\n}\n\n/** The review turn: an independent critique, read-only, with a verdict line first. */\nexport function reviewPrompt(subject: ReviewSubject): string {\n const parts = [\n `You are reviewing work produced by another model (${subject.authorLabel}). Be an independent, skeptical reviewer.`,\n 'The repository is open to you: read files or run read-only commands (such as a diff) to check claims, but change nothing.',\n 'Start with one line: \"Verdict: ship\", \"Verdict: fix first\" or \"Verdict: wrong\", then list concrete problems (correctness, missed edge cases, security, simpler alternatives), most important first. Say plainly when you find nothing.',\n ];\n if (subject.question) parts.push('', 'The request was:', '', cap(subject.question.trim(), 4_000));\n if (subject.answer) parts.push('', 'The answer to review:', '', cap(subject.answer.trim(), REVIEW_MAX_CHARS));\n if (subject.diff) {\n const diff = cap(subject.diff.trim(), REVIEW_MAX_CHARS);\n // A fence longer than any backtick run inside: a diff of Markdown that\n // itself holds ``` must not close the block early.\n const longest = Math.max(0, ...Array.from(diff.matchAll(/`+/g), (m) => m[0].length));\n const fence = '`'.repeat(Math.max(3, longest + 1));\n parts.push('', 'The changes to review:', '', `${fence}diff`, diff, fence);\n }\n return parts.join('\\n');\n}\n\n/**\n * Turn 1 of a Compare chat. Mid-thread, each seat gets the zero-spend handoff\n * note first (none of them has the conversation), then the prompt.\n */\nexport function comparePrompt(text: string, handoffNote: string | null): string {\n if (!handoffNote) return text;\n return `${handoffNote.trim()}\\n\\n---\\n\\nThe request to answer now:\\n\\n${text}`;\n}\n","/**\n * Cheap-first escalation — a local model drafts, a frontier seat is used only\n * when it is needed. Two PURE decisions and one piece of arithmetic:\n *\n * triage(classification) BEFORE sending: is this message one a local model\n * should even try? Hard work, large messages and a\n * confident \"needs frontier\" from the decision\n * layer go straight to the frontier seat — a weak\n * draft there would cost a round trip and save\n * nothing.\n * assessDraft(draft) AFTER the local turn: is the draft good enough?\n * Legible heuristics, each named in the verdict —\n * the turn failed, the answer is empty or cut off,\n * it hedges, it loops, an edit request produced no\n * code. Below ESCALATE_BELOW the composer escalates.\n * savedUsd(tokens, price) What answering locally saved, at the frontier\n * seat's API list price — an EQUIVALENT (a Max\n * subscription is not billed per token), labelled\n * as such wherever it is shown.\n *\n * Escalation itself is an ordinary handoff: the conversation continues on the\n * frontier seat from the zero-spend handoff note, with the local draft quoted\n * for it to check — through the same session routes as any other turn.\n *\n * BROWSER-SAFE.\n */\nimport type { PromptClassification } from './types.js';\n\n/** A draft scoring below this is escalated. */\nexport const ESCALATE_BELOW = 0.55;\n\nexport interface TriageVerdict {\n route: 'local' | 'frontier';\n reason: string;\n}\n\nexport function triage(cls: PromptClassification, opts: { localAvailable: boolean }): TriageVerdict {\n if (!opts.localAvailable) return { route: 'frontier', reason: 'No local model is running, so there is nothing to draft with.' };\n if ((cls.needsFrontier ?? 0) >= 0.7) return { route: 'frontier', reason: `Jev says this needs a frontier model (${Math.round((cls.needsFrontier ?? 0) * 100)}%).` };\n if (cls.difficulty === 'high') return { route: 'frontier', reason: `A ${cls.label} goes straight to a frontier seat — a local draft would not save anything.` };\n if (cls.size === 'large') return { route: 'frontier', reason: 'A message this large goes straight to a frontier seat.' };\n return { route: 'local', reason: `A ${cls.label} — a local model drafts it first.` };\n}\n\nexport interface DraftInput {\n text: string;\n /** The turn ended cleanly (turn-done ok). */\n ok: boolean;\n classification: PromptClassification;\n /** Tool calls the turn made (an edit request answered with edits has no code block to show). */\n toolUses?: number;\n}\n\nexport interface DraftVerdict {\n escalate: boolean;\n /** 0–1: how much the heuristics trust the draft. */\n confidence: number;\n /** Every heuristic that fired, as a short sentence. */\n reasons: string[];\n}\n\nconst HEDGES = [\n /\\bI(?:'m| am) not (?:sure|certain)\\b/i,\n /\\bI (?:don't|do not) know\\b/i,\n /\\bI (?:can't|cannot|am unable to|'m unable to)\\b/i,\n /\\bunable to (?:determine|access|find|help)\\b/i,\n /\\bas an AI\\b/i,\n /\\bI (?:don't|do not) have access\\b/i,\n /\\bwithout more (?:context|information)\\b/i,\n /\\bit(?:'s| is) (?:unclear|hard to say)\\b/i,\n];\n\n/** A line repeated three or more times — small models loop. */\nfunction loops(text: string): boolean {\n const counts = new Map<string, number>();\n for (const raw of text.split('\\n')) {\n const line = raw.trim();\n if (line.length < 12) continue;\n const n = (counts.get(line) ?? 0) + 1;\n if (n >= 3) return true;\n counts.set(line, n);\n }\n return false;\n}\n\nfunction cutOff(text: string): boolean {\n const t = text.trimEnd();\n if (t.length < 400) return false;\n if (/```\\s*$/.test(t) && (t.match(/```/g) ?? []).length % 2 === 1) return true;\n return !/[.!?:)\\]`\"'*>|]$/.test(t);\n}\n\nexport function assessDraft(input: DraftInput): DraftVerdict {\n const reasons: string[] = [];\n const text = input.text.trim();\n if (!input.ok) return { escalate: true, confidence: 0, reasons: ['The local turn did not finish cleanly.'] };\n if (text.length === 0) return { escalate: true, confidence: 0, reasons: ['The local model returned nothing.'] };\n\n let confidence = 1;\n const trivial = input.classification.difficulty === 'low';\n // A short reply after edits made through tools is a normal \"done\".\n if (text.length < 40 && !trivial && (input.toolUses ?? 0) === 0) {\n confidence -= 0.5;\n reasons.push('The answer is very short for the question.');\n }\n const hedges = HEDGES.filter((re) => re.test(text)).length;\n if (hedges > 0) {\n confidence -= Math.min(0.6, 0.3 * hedges);\n reasons.push(hedges === 1 ? 'The answer hedges.' : `The answer hedges ${hedges} times.`);\n }\n if (loops(text)) {\n confidence -= 0.5;\n reasons.push('The answer repeats itself.');\n }\n if (cutOff(text)) {\n confidence -= 0.3;\n reasons.push('The answer looks cut off.');\n }\n const edit = input.classification.kind === 'code' || input.classification.kind === 'debug' || input.classification.kind === 'refactor';\n if (edit && !/```/.test(text) && (input.toolUses ?? 0) === 0) {\n confidence -= 0.3;\n reasons.push('A code request got neither code nor edits.');\n }\n confidence = Math.max(0, Math.round(confidence * 100) / 100);\n if (reasons.length === 0) reasons.push('The draft reads complete.');\n return { escalate: confidence < ESCALATE_BELOW, confidence, reasons };\n}\n\nexport interface ListPrice {\n /** USD per million input tokens. */\n inPerM: number;\n /** USD per million output tokens. */\n outPerM: number;\n}\n\n/** What `tokens` would have cost at `price` (cache reads at a tenth of the input rate). */\nexport function listCostUsd(tokens: { input: number; output: number; cacheRead?: number }, price: ListPrice): number {\n const usd = (tokens.input * price.inPerM + (tokens.cacheRead ?? 0) * price.inPerM * 0.1 + tokens.output * price.outPerM) / 1_000_000;\n return Math.round(usd * 10_000) / 10_000;\n}\n\n/** The escalation turn: the question again, with the local draft quoted for the frontier seat to check. */\nexport function escalationPrompt(question: string, draft: string, verdict: DraftVerdict, draftSeatLabel: string): string {\n const quoted = draft.length > 6_000 ? `${draft.slice(0, 6_000)}\\n…(draft truncated)` : draft;\n return [\n question.trim(),\n '',\n `---`,\n `A local model (${draftSeatLabel}) drafted an answer first; it was escalated because: ${verdict.reasons.join(' ')}`,\n 'Use it only if it is right. Its draft:',\n '',\n quoted.split('\\n').map((l) => `> ${l}`).join('\\n'),\n ].join('\\n');\n}\n","/**\n * Prompt classification for the Auto seat — kind, size, difficulty — from the\n * text alone. PURE, deterministic, no model call: it runs in the browser on\n * every pause in typing, so it has to be instant and it must never send the\n * draft anywhere.\n *\n * It is deliberately a small set of legible rules rather than a scorer: the\n * Auto line shows the verdict (\"quick question\", \"hard refactor\") and the\n * operator must be able to see why and disagree. When the rules are unsure\n * they say `medium`, which leaves the router's own quality order in charge.\n *\n * BROWSER-SAFE.\n */\nimport type { RoutingDifficulty, RoutingTask } from '../../routing/types.js';\nimport type { PromptClassification, PromptKind, PromptSize } from './types.js';\n\n/** chars / 4, rounded up — the same estimator the handoff and fit badges use. */\nexport function estimateTokens(text: string): number {\n return Math.ceil(text.length / 4);\n}\n\nconst RE = {\n review: /\\b(review|critique|audit|look over|second opinion|sanity[- ]check|double[- ]check|code review|pr review|poke holes)\\b/i,\n debug: /\\b(error|exception|stack ?trace|traceback|failing|fails|failed|bug|crash(?:es|ed)?|broken|doesn'?t work|not working|segfault|panic|regression|flaky|TypeError|ReferenceError|undefined is not|cannot read propert)/i,\n refactor: /\\b(refactor|restructure|clean ?up|extract (?:a |the )?\\w+|migrate|port (?:it|this|the)|rename (?:all|every)|split (?:up|into)|consolidate|decouple)\\b/i,\n plan: /\\b(plan|design|architect(?:ure)?|approach|strategy|roadmap|trade-?offs?|should (?:we|i)|how should|pros and cons|options for|spec(?:ification)?)\\b/i,\n /** Asking for a change: an imperative verb. */\n code: /\\b(implement|write|add|create|build|fix|make|update|change|wire|hook up|remove|delete|replace|convert|generate)\\b/i,\n /** Code nouns: a change when paired with a verb, but \"what does this function do?\" is still a question. */\n codeNoun: /\\b(function|class|component|endpoint|tests?|script|handler|route|migration|schema)\\b/i,\n bulk: /\\b(all files|every file|across the (?:repo|codebase|project)|bulk|batch|each of (?:the|these)|every (?:module|package|test)|codemod|mass[- ]rename)\\b/i,\n question: /^\\s*(what|why|how|when|where|who|which|is|are|does|do|can|could|should|would|will|explain|tell me)\\b/i,\n explain: /\\b(explain|what does|what is|how does|walk me through|summari[sz]e|describe|meaning of|difference between)\\b/i,\n hard: /\\b(architect(?:ure)?|concurren(?:t|cy)|race condition|deadlock|security|vulnerab|auth(?:entication|orization)?|migration|performance|optimi[sz]e|distributed|memory leak|end[- ]to[- ]end|from scratch|entire|whole (?:codebase|repo|system)|complex|tricky|subtle|production)\\b/i,\n easy: /\\b(typo|quick|simple|small|tiny|trivial|one[- ]liner|rename|bump|format|lint|comment|docstring)\\b/i,\n stackTrace: /(^\\s+at .+\\(.+:\\d+:\\d+\\)$)|(Traceback \\(most recent call last\\))|(^\\s*File \".+\", line \\d+)/m,\n};\n\nconst LABEL: Record<PromptKind, Record<RoutingDifficulty, string>> = {\n question: { low: 'quick question', medium: 'question', high: 'hard question' },\n explain: { low: 'quick explanation', medium: 'explanation', high: 'deep explanation' },\n code: { low: 'small code change', medium: 'code change', high: 'hard code change' },\n debug: { low: 'quick fix', medium: 'debugging', high: 'hard debugging' },\n refactor: { low: 'small refactor', medium: 'refactor', high: 'hard refactor' },\n review: { low: 'quick review', medium: 'review', high: 'deep review' },\n plan: { low: 'quick plan', medium: 'planning', high: 'architecture planning' },\n bulk: { low: 'bulk edit', medium: 'bulk edit', high: 'large bulk edit' },\n};\n\n/** The Auto line's noun phrase for a kind at a difficulty (\"hard refactor\"). */\nexport function promptLabel(kind: PromptKind, difficulty: RoutingDifficulty): string {\n return LABEL[kind][difficulty];\n}\n\nexport function taskOf(kind: PromptKind): RoutingTask {\n if (kind === 'review') return 'review';\n if (kind === 'plan') return 'plan';\n if (kind === 'bulk') return 'bulk';\n return 'code';\n}\n\nfunction kindOf(text: string, hasCode: boolean, signals: string[]): PromptKind {\n // Order matters: the most specific intent wins. \"Review this fix\" is a\n // review, \"plan the refactor\" is a plan, a pasted trace is debugging.\n if (RE.bulk.test(text)) { signals.push('touches many files'); return 'bulk'; }\n if (RE.review.test(text)) { signals.push('asks for a review'); return 'review'; }\n if (RE.stackTrace.test(text)) { signals.push('stack trace'); return 'debug'; }\n if (RE.debug.test(text)) { signals.push('names a failure'); return 'debug'; }\n if (RE.refactor.test(text)) { signals.push('restructures code'); return 'refactor'; }\n if (RE.plan.test(text)) { signals.push('asks for a plan or design'); return 'plan'; }\n const verb = RE.code.test(text);\n if (RE.explain.test(text) && !verb) { signals.push('asks for an explanation'); return 'explain'; }\n if ((RE.question.test(text) || text.trim().endsWith('?')) && !verb && !hasCode) { signals.push('a question'); return 'question'; }\n if (verb || hasCode || RE.codeNoun.test(text)) { signals.push(hasCode ? 'includes code' : 'asks for a change'); return 'code'; }\n return 'code';\n}\n\nfunction sizeOf(tokens: number, fileRefs: number): PromptSize {\n if (tokens > 2_000 || fileRefs >= 4) return 'large';\n if (tokens < 120 && fileRefs <= 1) return 'small';\n return 'medium';\n}\n\n/**\n * Classify one message. `contextTokens` is what the chat already holds — a\n * small question deep into a 400k-token session is not a small turn.\n */\nexport function classifyPrompt(text: string, opts: { contextTokens?: number | null } = {}): PromptClassification {\n const trimmed = text.trim();\n const signals: string[] = [];\n const estTokens = estimateTokens(trimmed);\n const hasCode = /```/.test(trimmed) || /^( {4}|\\t)\\S/m.test(trimmed);\n const fileRefs = (trimmed.match(/(^|\\s)@[\\w./-]+/g) ?? []).length\n + (trimmed.match(/\\b[\\w-]+\\/[\\w./-]+\\.(?:ts|tsx|js|jsx|py|go|rs|java|rb|swift|kt|css|md|json|ya?ml)\\b/g) ?? []).length;\n if (fileRefs > 0) signals.push(fileRefs === 1 ? '1 file named' : `${fileRefs} files named`);\n\n const kind = kindOf(trimmed, hasCode, signals);\n const size = sizeOf(estTokens, fileRefs);\n if (size === 'large') signals.push(`≈${estTokens.toLocaleString('en-US')} tokens`);\n\n let difficulty: RoutingDifficulty = 'medium';\n const hard = RE.hard.test(trimmed);\n const easy = RE.easy.test(trimmed);\n if (hard) signals.push('hard subject');\n if (hard || size === 'large' || (kind === 'plan' && size !== 'small') || (kind === 'refactor' && fileRefs >= 2)) {\n difficulty = 'high';\n } else if (easy || (size === 'small' && (kind === 'question' || kind === 'explain'))) {\n difficulty = 'low';\n if (easy) signals.push('small by its own words');\n }\n // A long chat makes every turn heavier: the whole prefix is re-sent.\n const context = opts.contextTokens ?? 0;\n if (difficulty === 'low' && context > 150_000) {\n difficulty = 'medium';\n signals.push('deep into a long chat');\n }\n\n return { kind, task: taskOf(kind), difficulty, size, estTokens, label: LABEL[kind][difficulty], signals };\n}\n","/**\n * What the Auto seat learns from Mason — PURE aggregation of the outcome log\n * (thumbs, retries, switches, Compare picks, overrides, escalations) into a\n * small per-(kind, seat) and per-(kind, engine) table, and the bounded TILT\n * that table applies to the router's ranking.\n *\n * Rules that keep it honest:\n * - Evidence decays (half-life 14 days): last month's Codex outage should\n * not keep Codex out of reviews forever.\n * - Nothing tilts on fewer than MIN_SIGNALS decayed signals, and the score is\n * shrunk toward zero (score / (n + PRIOR)), so one thumbs-down never moves\n * a seat.\n * - The tilt is bounded (±MAX_TILT positions): learning re-orders close\n * calls, it never overrides eligibility — a spent or signed-out seat stays\n * out no matter how much Mason likes it, and a local-only repo stays local.\n * - Seat-level evidence wins over engine-level (two Codex accounts can\n * behave differently); engine-level fills in for a seat never used.\n *\n * BROWSER-SAFE.\n */\nimport type { LearnedStat, LearnedTable, OutcomeSignal, PromptKind, SeatOutcome } from './types.js';\n\nexport const LEARNING_HALF_LIFE_MS = 14 * 24 * 60 * 60 * 1000;\nexport const LEARNING_MIN_SIGNALS = 3;\n/** Pseudo-count the score is shrunk toward zero with. */\nconst PRIOR = 2;\n/** The most a learned preference can move a seat, in ranking positions. */\nexport const LEARNING_MAX_TILT = 1.5;\n\n/** Signed weight of each signal, for the seat it names. */\nexport const SIGNAL_WEIGHT: Readonly<Record<OutcomeSignal, number>> = Object.freeze({\n up: 1,\n down: -1,\n retry: -0.5,\n 'switch-away': -0.5,\n 'switch-to': 0.5,\n 'auto-followed': 0.1,\n 'auto-overridden': -0.5,\n 'compare-won': 1,\n 'compare-lost': -0.25,\n escalated: -0.5,\n 'draft-accepted': 1,\n});\n\nexport function seatKey(kind: PromptKind, seatId: string): string {\n return `${kind}|seat:${seatId}`;\n}\n\nexport function engineKey(kind: PromptKind, engine: string): string {\n return `${kind}|engine:${engine}`;\n}\n\nfunction add(table: LearnedTable, key: string, weight: number, decay: number): void {\n const stat: LearnedStat = table[key] ?? { score: 0, n: 0, up: 0, down: 0 };\n stat.score += weight * decay;\n stat.n += decay;\n if (weight > 0) stat.up += 1;\n if (weight < 0) stat.down += 1;\n table[key] = stat;\n}\n\n/** Fold outcomes into the table, newest evidence weighted most. Malformed rows are skipped. */\nexport function aggregateOutcomes(outcomes: readonly SeatOutcome[], nowMs: number): LearnedTable {\n const table: LearnedTable = {};\n for (const o of outcomes) {\n const weight = SIGNAL_WEIGHT[o.signal];\n const at = Date.parse(o.at);\n if (weight === undefined || !Number.isFinite(at) || typeof o.seatId !== 'string' || typeof o.kind !== 'string') continue;\n const age = Math.max(0, nowMs - at);\n const decay = Math.pow(0.5, age / LEARNING_HALF_LIFE_MS);\n add(table, seatKey(o.kind, o.seatId), weight, decay);\n if (typeof o.engine === 'string' && o.engine) add(table, engineKey(o.kind, o.engine), weight, decay);\n }\n // Round for a stable wire shape.\n for (const stat of Object.values(table)) {\n stat.score = Math.round(stat.score * 1000) / 1000;\n stat.n = Math.round(stat.n * 1000) / 1000;\n }\n return table;\n}\n\nexport interface LearnedTilt {\n /** Added to the seat's ranking position: NEGATIVE moves it up. 0 = no evidence. */\n tilt: number;\n /** \"you've rated Codex well for reviews (4 of 5 up)\" — null when no tilt. */\n phrase: string | null;\n}\n\nconst KIND_PLURAL: Record<PromptKind, string> = {\n question: 'questions',\n explain: 'explanations',\n code: 'code changes',\n debug: 'debugging',\n refactor: 'refactors',\n review: 'reviews',\n plan: 'planning',\n bulk: 'bulk edits',\n};\n\n/** The tilt learned evidence gives one seat for one kind of message. */\nexport function learnedTilt(table: LearnedTable | null | undefined, kind: PromptKind, seat: { seatId: string; engine: string; label: string }): LearnedTilt {\n if (!table) return { tilt: 0, phrase: null };\n const bySeat = table[seatKey(kind, seat.seatId)];\n const byEngine = table[engineKey(kind, seat.engine)];\n const stat = bySeat && bySeat.n >= LEARNING_MIN_SIGNALS ? bySeat : byEngine && byEngine.n >= LEARNING_MIN_SIGNALS ? byEngine : null;\n if (!stat) return { tilt: 0, phrase: null };\n const shrunk = stat.score / (stat.n + PRIOR);\n const tilt = -Math.max(-LEARNING_MAX_TILT, Math.min(LEARNING_MAX_TILT, shrunk * 2 * LEARNING_MAX_TILT));\n if (Math.abs(tilt) < 0.15) return { tilt: 0, phrase: null };\n const total = stat.up + stat.down;\n const tally = total > 0 ? ` (${stat.up} of ${total} signals positive)` : '';\n const phrase = tilt < 0\n ? `you've preferred ${seat.label} for ${KIND_PLURAL[kind]}${tally}`\n : `you've passed over ${seat.label} for ${KIND_PLURAL[kind]}${tally}`;\n return { tilt: Math.round(tilt * 1000) / 1000, phrase };\n}\n\n/**\n * The outcome rows one Compare pick produces: the winner `compare-won`, every\n * other answer `compare-lost`.\n */\nexport function compareOutcomes(\n winnerSessionId: string,\n entries: ReadonlyArray<{ sessionId: string; seatId: string; engine: string; model?: string }>,\n kind: PromptKind,\n at: string,\n): SeatOutcome[] {\n return entries.map((e) => ({\n at,\n seatId: e.seatId,\n engine: e.engine,\n kind,\n signal: e.sessionId === winnerSessionId ? 'compare-won' : 'compare-lost',\n sessionId: e.sessionId,\n ...(e.model ? { model: e.model } : {}),\n }));\n}\n","/**\n * routes/verse/multimodel/multimodel-flows.ts — the multi-model actions, as\n * sequences of ORDINARY session calls.\n *\n * Every flow here is built from the same four calls a hand-driven chat makes\n * — create a session, build the zero-spend handoff note, send a turn, open a\n * chat — so each spent turn passes the server's spend chokepoint, readiness\n * gate, local-only gate and mutation token exactly as a typed message does.\n * The calls are injected (`FlowApi`) so the flows are testable without a\n * server; `DEFAULT_FLOW_API` wires the real ones.\n *\n * routeMessage Auto sent this message to another seat: continue the\n * conversation there (handoff note + the message).\n * quickHandoff One click from the seat chip: note built, chat created on\n * the target, note PREFILLED in its composer, chat opened.\n * Nothing is spent until Mason presses Send.\n * startCompare The same prompt to 2–3 seats in parallel (compare.ts fanOut).\n * pickWinner \"Continue with this one\": record the pick, open that chat.\n * startReview A cross-family reviewer asked about the last answer.\n * escalate Cheap-first: a weak local draft moves to a frontier seat.\n */\nimport type { VerseCreateSessionRequest, VerseHandoffPreview, VerseHandoffPreviewRequest, VerseSession, VerseTurnResponse } from '../../../../core/verse/types.js';\nimport { comparePrompt, fanOut, reviewPrompt, type CompareTarget, type FanOutEntry } from '../../../../core/verse/multimodel/compare.js';\nimport { escalationPrompt, type DraftVerdict } from '../../../../core/verse/multimodel/escalation.js';\nimport { classifyPrompt } from '../../../../core/verse/multimodel/classify.js';\nimport { compareOutcomes } from '../../../../core/verse/multimodel/learning.js';\nimport type { PromptKind, SeatOutcomeRequest, ThreadLinkRequest } from '../../../../core/verse/multimodel/types.js';\nimport { saveDraft } from '../chat/composer-state.js';\nimport { createHandoffSession, fetchHandoffPreview, type HandoffSessionInput } from '../context/context-queries.js';\nimport { createVerseSession, sendVerseTurn } from '../verse-queries.js';\nimport { getVerseSessionHead } from '../verse-store.js';\nimport { getVerseTranscript } from '../verse-transcript.js';\nimport { openVerseSession } from '../verse-ui-store.js';\nimport { linkThread, recordOutcome } from './multimodel-queries.js';\n\nexport interface FlowApi {\n createSession(req: VerseCreateSessionRequest): Promise<VerseSession>;\n createHandoffSession(input: HandoffSessionInput): Promise<VerseSession>;\n fetchHandoffPreview(sessionId: string, req?: VerseHandoffPreviewRequest): Promise<VerseHandoffPreview>;\n sendTurn(sessionId: string, text: string): Promise<VerseTurnResponse | unknown>;\n link(req: ThreadLinkRequest): Promise<boolean>;\n outcome(req: SeatOutcomeRequest): Promise<boolean>;\n saveDraft(sessionId: string, text: string): void;\n open(sessionId: string): void;\n}\n\nexport const DEFAULT_FLOW_API: FlowApi = {\n createSession: createVerseSession,\n createHandoffSession,\n fetchHandoffPreview,\n sendTurn: sendVerseTurn,\n link: linkThread,\n outcome: recordOutcome,\n saveDraft,\n open: openVerseSession,\n};\n\nexport interface FlowTarget {\n seatId: string;\n model: string | null;\n label: string;\n engine: string;\n}\n\n/**\n * A new chat on the SAME pinned roots as `source`, with no handoff: the\n * source's own `projectPath` + `extraRoots` (never its workspace id — see\n * context-queries `createHandoffSession` for why pinned roots are the honest set).\n */\nexport function siblingRequest(source: VerseSession, target: FlowTarget, title?: string): VerseCreateSessionRequest {\n const req: VerseCreateSessionRequest = { projectPath: source.projectPath, seatId: target.seatId };\n const extras = (source.extraRoots ?? []).filter((r) => typeof r === 'string' && r.length > 0 && r !== source.projectPath);\n if (extras.length > 0) req.extraRoots = extras;\n if (target.model) req.model = target.model;\n const t = title?.trim();\n if (t) req.title = t.slice(0, 120);\n return req;\n}\n\n/** Continue `source` on `target`: a handoff mid-thread, a plain sibling chat when it has no turns yet. */\nasync function continuation(api: FlowApi, source: VerseSession, target: FlowTarget, title?: string): Promise<{ session: VerseSession; note: string | null }> {\n if (source.turnCount > 0) {\n const preview = await api.fetchHandoffPreview(source.id);\n const session = await api.createHandoffSession({ source, seatId: target.seatId, ...(target.model ? { model: target.model } : {}), ...(title ? { title } : {}) });\n return { session, note: preview.text };\n }\n return { session: await api.createSession(siblingRequest(source, target, title)), note: null };\n}\n\nexport async function routeMessage(\n api: FlowApi,\n input: { source: VerseSession; target: FlowTarget; text: string; kind: PromptKind; overridden?: { seatId: string } | null },\n): Promise<VerseSession> {\n const { session, note } = await continuation(api, input.source, input.target);\n await api.sendTurn(session.id, comparePrompt(input.text, note));\n void api.outcome({ seatId: input.target.seatId, kind: input.kind, signal: input.overridden ? 'switch-to' : 'auto-followed', sessionId: session.id });\n if (input.overridden) void api.outcome({ seatId: input.overridden.seatId, kind: input.kind, signal: 'auto-overridden' });\n api.open(session.id);\n return session;\n}\n\n/** A plan worth carrying verbatim: a \"Plan\" heading, or three or more numbered / checklist steps. */\nexport function looksLikePlan(text: string | null | undefined): boolean {\n if (!text) return false;\n if (/^#{1,4}\\s*(?:the\\s+)?plan\\b/im.test(text)) return true;\n return (text.match(/^\\s*(?:\\d+[.)]|[-*] \\[[ x]\\])\\s+\\S/gm) ?? []).length >= 3;\n}\n\nexport async function quickHandoff(\n api: FlowApi,\n input: { source: VerseSession; target: FlowTarget; lastAssistant?: string | null; kind: PromptKind },\n): Promise<VerseSession> {\n // The last answer rides along verbatim when it is a plan — the note's own\n // sections list files and asks, but not the plan the agent just wrote.\n const carryPlan = looksLikePlan(input.lastAssistant);\n const preview = await api.fetchHandoffPreview(input.source.id, carryPlan ? { includeLastAssistant: true } : {});\n const session = await api.createHandoffSession({ source: input.source, seatId: input.target.seatId, ...(input.target.model ? { model: input.target.model } : {}) });\n api.saveDraft(session.id, preview.text);\n void api.outcome({ seatId: input.source.seatId, kind: input.kind, signal: 'switch-away', sessionId: input.source.id });\n void api.outcome({ seatId: input.target.seatId, kind: input.kind, signal: 'switch-to', sessionId: session.id });\n api.open(session.id);\n return session;\n}\n\n/**\n * `quickHandoff` for a chat by id — what the seat chip calls. Reads the chat's\n * record and last answer from the store (this module is lazy, so the\n * transcript derivation stays off the composer's first-paint path).\n */\nexport async function quickHandoffFromChat(sessionId: string, target: FlowTarget, api: FlowApi = DEFAULT_FLOW_API): Promise<VerseSession | null> {\n const source = getVerseSessionHead(sessionId).session;\n // Nothing to hand off yet: the caller opens a plain new chat instead.\n if (!source || source.turnCount === 0) return null;\n const items = getVerseTranscript(sessionId).items;\n let lastUser = '';\n let lastAssistant: string | null = null;\n for (let i = items.length - 1; i >= 0; i -= 1) {\n const it = items[i]!;\n if (lastAssistant === null && it.kind === 'assistant') lastAssistant = it.text;\n if (it.kind === 'user') { lastUser = it.text; break; }\n }\n return quickHandoff(api, { source, target, lastAssistant, kind: classifyPrompt(lastUser).kind });\n}\n\nexport async function startCompare(\n api: FlowApi,\n input: { source: VerseSession; targets: readonly FlowTarget[]; text: string },\n): Promise<FanOutEntry[]> {\n // One note for every seat: built once, zero spend.\n const note = input.source.turnCount > 0 ? (await api.fetchHandoffPreview(input.source.id)).text : null;\n const title = (label: string) => `${input.source.title.slice(0, 80)} · ${label}`;\n return fanOut(input.targets as readonly CompareTarget[], comparePrompt(input.text, note), {\n createSession: (t) => (input.source.turnCount > 0\n ? api.createHandoffSession({ source: input.source, seatId: t.seatId, ...(t.model ? { model: t.model } : {}), title: title(t.label) })\n : api.createSession(siblingRequest(input.source, t, title(t.label)))),\n sendTurn: (id, text) => api.sendTurn(id, text),\n link: (child) => api.link({ parentSessionId: input.source.id, childSessionId: child, relation: 'compare' }),\n });\n}\n\nexport async function pickWinner(\n api: FlowApi,\n input: { winnerSessionId: string; entries: ReadonlyArray<{ sessionId: string; seatId: string; engine: string; model?: string }>; kind: PromptKind },\n): Promise<void> {\n const rows = compareOutcomes(input.winnerSessionId, input.entries, input.kind, new Date().toISOString());\n await Promise.all(rows.map((r) => api.outcome({ seatId: r.seatId, kind: r.kind, signal: r.signal, ...(r.sessionId ? { sessionId: r.sessionId } : {}), ...(r.model ? { model: r.model } : {}) })));\n api.open(input.winnerSessionId);\n}\n\nexport async function startReview(\n api: FlowApi,\n input: { source: VerseSession; reviewer: FlowTarget; question: string | null; answer: string; authorLabel: string },\n): Promise<VerseSession> {\n const session = await api.createSession(siblingRequest(input.source, input.reviewer, `Review · ${input.source.title.slice(0, 80)}`));\n void api.link({ parentSessionId: input.source.id, childSessionId: session.id, relation: 'review' });\n await api.sendTurn(session.id, reviewPrompt({ question: input.question, answer: input.answer, authorLabel: input.authorLabel }));\n return session;\n}\n\nexport async function escalate(\n api: FlowApi,\n input: { source: VerseSession; target: FlowTarget; question: string; draft: string; verdict: DraftVerdict; draftLabel: string; kind: PromptKind },\n): Promise<VerseSession> {\n const { session, note } = await continuation(api, input.source, input.target);\n void api.link({ parentSessionId: input.source.id, childSessionId: session.id, relation: 'escalate' });\n await api.sendTurn(session.id, comparePrompt(escalationPrompt(input.question, input.draft, input.verdict, input.draftLabel), note));\n void api.outcome({ seatId: input.source.seatId, kind: input.kind, signal: 'escalated', sessionId: input.source.id });\n api.open(session.id);\n return session;\n}\n"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import{C as e,M as t,V as n,a as r,i}from"./global-BWc2NPzv.js";import{r as a}from"./VerseShared-_pMXKs8m.js";var o=`/api/verse/multimodel`,s=`${o}/context`,c=`${o}/outcome`,l=`${o}/link`,u=`${o}/meter`,d=`${o}/local/warm`,f=`${o}/label`,p=`verse-multimodel-context:`,m=`verse-multimodel-meter:`;function h(e){let t=`sessionId`in e?`?sessionId=${encodeURIComponent(e.sessionId)}`:e.projectPath?`?projectPath=${encodeURIComponent(e.projectPath)}`:``;return{key:`${p}${t}`,fetch:e=>i(`${s}${t}`,e)}}function g(e){return{key:`${m}${e}`,fetch:t=>i(`${u}?sessionId=${encodeURIComponent(e)}`,t)}}function _(){let t=e();if(!t)throw new a;return t}async function v(e){let n=await r(f,e,_());return t(),n}async function y(e){try{return await r(c,e,_()),t(),!0}catch{return!1}}async function b(e){try{return await r(l,e,_()),t(),n(`${m}${e.parentSessionId}`),!0}catch{return!1}}async function x(e){let n=await r(d,{seatId:e},_());return t(),n}function S(e){n(`${m}${e}`)}export{h as a,b as i,S as n,y as o,v as r,x as s,g as t};
2
- //# sourceMappingURL=multimodel-queries-_Y1QXAqq.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"multimodel-queries-_Y1QXAqq.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"}
@@ -1,2 +0,0 @@
1
- import{C as e,H as t,M as n,V as r,a as i}from"./global-BWc2NPzv.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-DL4u2kRQ.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mutations-DL4u2kRQ.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"}
@@ -1,2 +0,0 @@
1
- import{A as e,I as t,O as n}from"./VerseConsoleApp-kFOEmnGC.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(e,n=null){t(e),n&&requestAnimationFrame(()=>{document.getElementById(i(n))?a(n):requestAnimationFrame(()=>a(n))})}function s(t){e(t)}export{a,r as i,o as n,s as r,i as t};
2
- //# sourceMappingURL=nav-CM-mJcSq.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"nav-CM-mJcSq.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"}
@@ -1,2 +0,0 @@
1
- import{n as e,s as t,u as n}from"./index-BbDqdepe.js";import{C as r,H as i,M as a,V as o,a as s,t as c}from"./global-BWc2NPzv.js";import{B as l,ft as u,k as d}from"./VerseShared-_pMXKs8m.js";import{t as f}from"./leader-thread-types-CDb-VPPO.js";import{t as p}from"./resolved-store-Ba-W6Uhy.js";import{t as m}from"./Input-BEF-ScuG.js";import{c as h,i as g,t as _}from"./needs-you-model-DqmU5YOe.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=n(t(),1),x=e(),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}`)),d()}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),d=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??d;l({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}: ${d}`,`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-DF2zEltF.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"needs-you-actions-DF2zEltF.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":"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"}
@@ -1,2 +0,0 @@
1
- import{G as e}from"./VerseShared-_pMXKs8m.js";import{g as t,m as n,n as r,x as i}from"./verse-model-CkF3q2IH.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-DqmU5YOe.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"needs-you-model-DqmU5YOe.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":"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"}
@@ -1,2 +0,0 @@
1
- import{A as e,C as t,I as n,T as r,Y as i,tt as a}from"./VerseConsoleApp-kFOEmnGC.js";import{t as o}from"./open-terminal-request-f5_ItEpF.js";import{a as s}from"./terminal-client-DO0eRhRi.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(i),setTimeout(e,0))},r=a(n),i=setTimeout(n,l)}function d(a,o,s){t();let c=s?{tabId:o,blockId:s}:{tabId:o},l=r();if(a===null||!l.mounted.includes(`chat`)||l.activeSessionId===a){a?e(a):n(`chat`),i(c);return}e(a),u(()=>i(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-BAnwAOoA.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"open-terminal-BAnwAOoA.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"}
@@ -1,2 +0,0 @@
1
- import{a as e}from"./VerseConsoleApp-kFOEmnGC.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-f5_ItEpF.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"open-terminal-request-f5_ItEpF.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"}
@@ -1,2 +0,0 @@
1
- import{s as e,u as t}from"./index-BbDqdepe.js";import{C as n,M as r,V as i,a,i as o,t as s,u as c}from"./global-BWc2NPzv.js";import{c as l}from"./format-CcEKjUou.js";import{n as u,t as d}from"./control-queries-Clgsy_eH.js";var f=t(e(),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-BP6viiM5.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"overnight-queries-BP6viiM5.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":"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"}
@@ -1,2 +0,0 @@
1
- import{k as e}from"./VerseConsoleApp-kFOEmnGC.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-Bmq98lDl.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"palette-handoff-Bmq98lDl.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"}