@ashlr/hub 3.10.0 → 3.11.0

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 (534) hide show
  1. package/CHANGELOG.md +156 -0
  2. package/README.md +343 -82
  3. package/dist/authority-surface.json +109 -29
  4. package/dist/build-identity.json +2 -2
  5. package/dist/cli/cloud.d.ts +39 -0
  6. package/dist/cli/cloud.js +448 -0
  7. package/dist/cli/cloud.js.map +1 -0
  8. package/dist/cli/completions.js +4 -0
  9. package/dist/cli/completions.js.map +1 -1
  10. package/dist/cli/help.js +2 -0
  11. package/dist/cli/help.js.map +1 -1
  12. package/dist/cli/index.d.ts +1 -0
  13. package/dist/cli/index.js +10 -0
  14. package/dist/cli/index.js.map +1 -1
  15. package/dist/core/cloud/backlog.d.ts +17 -0
  16. package/dist/core/cloud/backlog.js +177 -0
  17. package/dist/core/cloud/backlog.js.map +1 -0
  18. package/dist/core/cloud/budget.d.ts +19 -0
  19. package/dist/core/cloud/budget.js +99 -0
  20. package/dist/core/cloud/budget.js.map +1 -0
  21. package/dist/core/cloud/checkout.d.ts +41 -0
  22. package/dist/core/cloud/checkout.js +168 -0
  23. package/dist/core/cloud/checkout.js.map +1 -0
  24. package/dist/core/cloud/cloud-api.d.ts +86 -0
  25. package/dist/core/cloud/cloud-api.js +599 -0
  26. package/dist/core/cloud/cloud-api.js.map +1 -0
  27. package/dist/core/cloud/delivery-contract.d.ts +25 -0
  28. package/dist/core/cloud/delivery-contract.js +138 -0
  29. package/dist/core/cloud/delivery-contract.js.map +1 -0
  30. package/dist/core/cloud/improvement-backlog.d.ts +11 -0
  31. package/dist/core/cloud/improvement-backlog.js +26 -0
  32. package/dist/core/cloud/improvement-backlog.js.map +1 -0
  33. package/dist/core/cloud/launcher.d.ts +68 -0
  34. package/dist/core/cloud/launcher.js +312 -0
  35. package/dist/core/cloud/launcher.js.map +1 -0
  36. package/dist/core/cloud/service.d.ts +51 -0
  37. package/dist/core/cloud/service.js +215 -0
  38. package/dist/core/cloud/service.js.map +1 -0
  39. package/dist/core/cloud/store.d.ts +41 -0
  40. package/dist/core/cloud/store.js +278 -0
  41. package/dist/core/cloud/store.js.map +1 -0
  42. package/dist/core/cloud/tracker.d.ts +30 -0
  43. package/dist/core/cloud/tracker.js +152 -0
  44. package/dist/core/cloud/tracker.js.map +1 -0
  45. package/dist/core/cloud/types.d.ts +233 -0
  46. package/dist/core/cloud/types.js +73 -0
  47. package/dist/core/cloud/types.js.map +1 -0
  48. package/dist/core/daemon/capacity-publisher.d.ts +19 -0
  49. package/dist/core/daemon/capacity-publisher.js +49 -2
  50. package/dist/core/daemon/capacity-publisher.js.map +1 -1
  51. package/dist/core/daemon/overnight-status.d.ts +13 -0
  52. package/dist/core/daemon/overnight-status.js +93 -8
  53. package/dist/core/daemon/overnight-status.js.map +1 -1
  54. package/dist/core/fleet/dispatch-router.js +26 -9
  55. package/dist/core/fleet/dispatch-router.js.map +1 -1
  56. package/dist/core/fleet/fleet-runtime-journal.js +12 -5
  57. package/dist/core/fleet/fleet-runtime-journal.js.map +1 -1
  58. package/dist/core/fleet/fleet-types.d.ts +13 -0
  59. package/dist/core/routing/budget-store.js +11 -5
  60. package/dist/core/routing/budget-store.js.map +1 -1
  61. package/dist/core/routing/capacity-history-api.d.ts +30 -0
  62. package/dist/core/routing/capacity-history-api.js +147 -0
  63. package/dist/core/routing/capacity-history-api.js.map +1 -0
  64. package/dist/core/routing/capacity-history-types.d.ts +63 -0
  65. package/dist/core/routing/capacity-history-types.js +18 -0
  66. package/dist/core/routing/capacity-history-types.js.map +1 -0
  67. package/dist/core/routing/capacity-history.d.ts +130 -0
  68. package/dist/core/routing/capacity-history.js +654 -0
  69. package/dist/core/routing/capacity-history.js.map +1 -0
  70. package/dist/core/routing/headroom.d.ts +5 -1
  71. package/dist/core/routing/headroom.js +82 -41
  72. package/dist/core/routing/headroom.js.map +1 -1
  73. package/dist/core/routing/router.d.ts +8 -1
  74. package/dist/core/routing/router.js +49 -16
  75. package/dist/core/routing/router.js.map +1 -1
  76. package/dist/core/routing/seat-reasons.d.ts +35 -0
  77. package/dist/core/routing/seat-reasons.js +48 -0
  78. package/dist/core/routing/seat-reasons.js.map +1 -0
  79. package/dist/core/routing/types.d.ts +37 -0
  80. package/dist/core/routing/types.js.map +1 -1
  81. package/dist/core/verse/activity-api.d.ts +3 -1
  82. package/dist/core/verse/activity-api.js +16 -1
  83. package/dist/core/verse/activity-api.js.map +1 -1
  84. package/dist/core/verse/activity.d.ts +7 -0
  85. package/dist/core/verse/activity.js +23 -0
  86. package/dist/core/verse/activity.js.map +1 -1
  87. package/dist/core/verse/fleet-history-types.d.ts +12 -4
  88. package/dist/core/verse/fleet-history-types.js +4 -2
  89. package/dist/core/verse/fleet-history-types.js.map +1 -1
  90. package/dist/core/verse/fleet-live-api.d.ts +14 -1
  91. package/dist/core/verse/fleet-live-api.js +31 -11
  92. package/dist/core/verse/fleet-live-api.js.map +1 -1
  93. package/dist/core/verse/preferences.d.ts +3 -1
  94. package/dist/core/verse/preferences.js +5 -2
  95. package/dist/core/verse/preferences.js.map +1 -1
  96. package/dist/core/verse/types.d.ts +5 -1
  97. package/dist/core/verse/types.js.map +1 -1
  98. package/dist/core/verse/verse-api.d.ts +1 -1
  99. package/dist/core/verse/verse-api.js +4 -1
  100. package/dist/core/verse/verse-api.js.map +1 -1
  101. package/dist/core/vision/leader-cloud.d.ts +63 -0
  102. package/dist/core/vision/leader-cloud.js +134 -0
  103. package/dist/core/vision/leader-cloud.js.map +1 -0
  104. package/dist/core/vision/leader.d.ts +6 -0
  105. package/dist/core/vision/leader.js +12 -1
  106. package/dist/core/vision/leader.js.map +1 -1
  107. package/dist/core/web/public/next/assets/{ActionMenu-DhbNne-M.js → ActionMenu-CQvNJvHY.js} +2 -2
  108. package/dist/core/web/public/next/assets/{ActionMenu-DhbNne-M.js.map → ActionMenu-CQvNJvHY.js.map} +1 -1
  109. package/dist/core/web/public/next/assets/Advanced-Bywv_iYR.css +1 -0
  110. package/dist/core/web/public/next/assets/Advanced-DEM93sKI.js +2 -0
  111. package/dist/core/web/public/next/assets/Advanced-DEM93sKI.js.map +1 -0
  112. package/dist/core/web/public/next/assets/{App-DyBg1v_q.js → App-CimXmK0L.js} +5 -5
  113. package/dist/core/web/public/next/assets/{App-DyBg1v_q.js.map → App-CimXmK0L.js.map} +1 -1
  114. package/dist/core/web/public/next/assets/AppsSection-D6U-dSj6.js +2 -0
  115. package/dist/core/web/public/next/assets/AppsSection-D6U-dSj6.js.map +1 -0
  116. package/dist/core/web/public/next/assets/AreaTrend-LD9lCPkT.js +2 -0
  117. package/dist/core/web/public/next/assets/AreaTrend-LD9lCPkT.js.map +1 -0
  118. package/dist/core/web/public/next/assets/AutonomySection-3V9pUyxm.js +2 -0
  119. package/dist/core/web/public/next/assets/{AutonomySection-CoMngwNB.js.map → AutonomySection-3V9pUyxm.js.map} +1 -1
  120. package/dist/core/web/public/next/assets/BranchBar-BZNQ50YE.css +1 -0
  121. package/dist/core/web/public/next/assets/BranchBar-U8UdpfEB.js +2 -0
  122. package/dist/core/web/public/next/assets/BranchBar-U8UdpfEB.js.map +1 -0
  123. package/dist/core/web/public/next/assets/BudgetControl-DOTlMSmW.js +2 -0
  124. package/dist/core/web/public/next/assets/BudgetControl-DOTlMSmW.js.map +1 -0
  125. package/dist/core/web/public/next/assets/BurnDown-x4PWH9JF.js +2 -0
  126. package/dist/core/web/public/next/assets/BurnDown-x4PWH9JF.js.map +1 -0
  127. package/dist/core/web/public/next/assets/{Button-0-nNbv1h.js → Button-DYv_KKxr.js} +2 -2
  128. package/dist/core/web/public/next/assets/{Button-0-nNbv1h.js.map → Button-DYv_KKxr.js.map} +1 -1
  129. package/dist/core/web/public/next/assets/CapacityStrip-C667yQe8.js +2 -0
  130. package/dist/core/web/public/next/assets/CapacityStrip-C667yQe8.js.map +1 -0
  131. package/dist/core/web/public/next/assets/CapacityStrip-Cc28CyWk.css +1 -0
  132. package/dist/core/web/public/next/assets/ChatSection-CCcIPpOq.js +3 -0
  133. package/dist/core/web/public/next/assets/{ChatSection-B9cdRKUh.js.map → ChatSection-CCcIPpOq.js.map} +1 -1
  134. package/dist/core/web/public/next/assets/CloudBudgetForm-DJeJvBEu.js +2 -0
  135. package/dist/core/web/public/next/assets/CloudBudgetForm-DJeJvBEu.js.map +1 -0
  136. package/dist/core/web/public/next/assets/{CommandPalette-GpeCSrPy.js → CommandPalette-FiD4N8XD.js} +2 -2
  137. package/dist/core/web/public/next/assets/{CommandPalette-GpeCSrPy.js.map → CommandPalette-FiD4N8XD.js.map} +1 -1
  138. package/dist/core/web/public/next/assets/CommandSection-DN8KwH-X.js +2 -0
  139. package/dist/core/web/public/next/assets/CommandSection-DN8KwH-X.js.map +1 -0
  140. package/dist/core/web/public/next/assets/Composer-ByzxOJK6.css +1 -0
  141. package/dist/core/web/public/next/assets/Composer.module-C8U73KdQ.js +2 -0
  142. package/dist/core/web/public/next/assets/{Composer.module-DJMdrqNt.js.map → Composer.module-C8U73KdQ.js.map} +1 -1
  143. package/dist/core/web/public/next/assets/DiffPane-BAvvbBsf.css +1 -0
  144. package/dist/core/web/public/next/assets/DiffPane-DLJ3gGGK.js +2 -0
  145. package/dist/core/web/public/next/assets/DiffPane-DLJ3gGGK.js.map +1 -0
  146. package/dist/core/web/public/next/assets/{DiffViewer-tOGWk0CA.js → DiffViewer-B7NWPjIO.js} +2 -2
  147. package/dist/core/web/public/next/assets/{DiffViewer-tOGWk0CA.js.map → DiffViewer-B7NWPjIO.js.map} +1 -1
  148. package/dist/core/web/public/next/assets/DockHost-B4RaYOET.css +1 -0
  149. package/dist/core/web/public/next/assets/DockHost-DvR-hPhZ.js +2 -0
  150. package/dist/core/web/public/next/assets/DockHost-DvR-hPhZ.js.map +1 -0
  151. package/dist/core/web/public/next/assets/{EmptyState-DdJ4CxtO.js → EmptyState-DhNgDDrF.js} +2 -2
  152. package/dist/core/web/public/next/assets/{EmptyState-DdJ4CxtO.js.map → EmptyState-DhNgDDrF.js.map} +1 -1
  153. package/dist/core/web/public/next/assets/{Epistemic-BLjM5y_y.js → Epistemic-uARPnx9x.js} +2 -2
  154. package/dist/core/web/public/next/assets/{Epistemic-BLjM5y_y.js.map → Epistemic-uARPnx9x.js.map} +1 -1
  155. package/dist/core/web/public/next/assets/FleetSection-CFiWeOEs.css +1 -0
  156. package/dist/core/web/public/next/assets/FleetSection-D_zRBCub.js +3 -0
  157. package/dist/core/web/public/next/assets/FleetSection-D_zRBCub.js.map +1 -0
  158. package/dist/core/web/public/next/assets/Funnel-CL8uHONq.js +2 -0
  159. package/dist/core/web/public/next/assets/Funnel-CL8uHONq.js.map +1 -0
  160. package/dist/core/web/public/next/assets/GearTray-C7k4l_BW.js +2 -0
  161. package/dist/core/web/public/next/assets/GearTray-C7k4l_BW.js.map +1 -0
  162. package/dist/core/web/public/next/assets/GrowthSection-DwdNSGj8.js +2 -0
  163. package/dist/core/web/public/next/assets/GrowthSection-DwdNSGj8.js.map +1 -0
  164. package/dist/core/web/public/next/assets/HandoffDialog-FPVOqOMN.js +2 -0
  165. package/dist/core/web/public/next/assets/HandoffDialog-FPVOqOMN.js.map +1 -0
  166. package/dist/core/web/public/next/assets/{Input-CTu0CycC.js → Input-B9-VLcHS.js} +2 -2
  167. package/dist/core/web/public/next/assets/{Input-CTu0CycC.js.map → Input-B9-VLcHS.js.map} +1 -1
  168. package/dist/core/web/public/next/assets/{LeaderCard-BuSDeATv.js → LeaderCard-4R0BhDzT.js} +2 -2
  169. package/dist/core/web/public/next/assets/{LeaderCard-BuSDeATv.js.map → LeaderCard-4R0BhDzT.js.map} +1 -1
  170. package/dist/core/web/public/next/assets/{MatrixHeatmap-9dKgJ_pT.css → MatrixHeatmap-Bmnvo1l1.css} +1 -1
  171. package/dist/core/web/public/next/assets/MatrixHeatmap-DiuushcS.js +2 -0
  172. package/dist/core/web/public/next/assets/MatrixHeatmap-DiuushcS.js.map +1 -0
  173. package/dist/core/web/public/next/assets/McpSection-CJ__OJKl.js +2 -0
  174. package/dist/core/web/public/next/assets/{McpSection-1UncWBpW.js.map → McpSection-CJ__OJKl.js.map} +1 -1
  175. package/dist/core/web/public/next/assets/MessageMarkdown-Cgh5f1-Q.css +1 -0
  176. package/dist/core/web/public/next/assets/MessageMarkdown-qWKyJvAQ.js +3 -0
  177. package/dist/core/web/public/next/assets/{MessageMarkdown-C4pl9LI5.js.map → MessageMarkdown-qWKyJvAQ.js.map} +1 -1
  178. package/dist/core/web/public/next/assets/{MessageMarkdownRenderer-CZsF77ZM.js → MessageMarkdownRenderer-x05TrsrW.js} +2 -2
  179. package/dist/core/web/public/next/assets/{MessageMarkdownRenderer-CZsF77ZM.js.map → MessageMarkdownRenderer-x05TrsrW.js.map} +1 -1
  180. package/dist/core/web/public/next/assets/{Meter-C18ciKz4.js → Meter-D-hncpkO.js} +2 -2
  181. package/dist/core/web/public/next/assets/{Meter-C18ciKz4.js.map → Meter-D-hncpkO.js.map} +1 -1
  182. package/dist/core/web/public/next/assets/MindSection-BjXHkQPS.js +2 -0
  183. package/dist/core/web/public/next/assets/MindSection-BjXHkQPS.js.map +1 -0
  184. package/dist/core/web/public/next/assets/MutationTokenDialog-SkRxqV_I.js +2 -0
  185. package/dist/core/web/public/next/assets/MutationTokenDialog-SkRxqV_I.js.map +1 -0
  186. package/dist/core/web/public/next/assets/NeedsYouDrawer-BpvidnM2.css +1 -0
  187. package/dist/core/web/public/next/assets/NeedsYouDrawer-rSd1ZHAR.js +2 -0
  188. package/dist/core/web/public/next/assets/NeedsYouDrawer-rSd1ZHAR.js.map +1 -0
  189. package/dist/core/web/public/next/assets/NeedsYouList-CG-nB1tr.js +2 -0
  190. package/dist/core/web/public/next/assets/NeedsYouList-CG-nB1tr.js.map +1 -0
  191. package/dist/core/web/public/next/assets/NeedsYouList-CruOt4JT.css +1 -0
  192. package/dist/core/web/public/next/assets/NewChatDialog-BeDQ1eW3.js +3 -0
  193. package/dist/core/web/public/next/assets/{NewChatDialog-B_BsS9pr.js.map → NewChatDialog-BeDQ1eW3.js.map} +1 -1
  194. package/dist/core/web/public/next/assets/OnboardingFlow-CkTZtt-m.js +2 -0
  195. package/dist/core/web/public/next/assets/{OnboardingFlow-CtCPpgoX.js.map → OnboardingFlow-CkTZtt-m.js.map} +1 -1
  196. package/dist/core/web/public/next/assets/PreviewPane-DoMsJSG3.css +1 -0
  197. package/dist/core/web/public/next/assets/PreviewPane-kzbbSK4u.js +2 -0
  198. package/dist/core/web/public/next/assets/PreviewPane-kzbbSK4u.js.map +1 -0
  199. package/dist/core/web/public/next/assets/RailStatus-D-t2gPae.js +2 -0
  200. package/dist/core/web/public/next/assets/RailStatus-D-t2gPae.js.map +1 -0
  201. package/dist/core/web/public/next/assets/{RefreshIndicator-CnhEovMZ.js → RefreshIndicator-BLnr9IOM.js} +2 -2
  202. package/dist/core/web/public/next/assets/{RefreshIndicator-CnhEovMZ.js.map → RefreshIndicator-BLnr9IOM.js.map} +1 -1
  203. package/dist/core/web/public/next/assets/{ResourcePoolConsoleApp-28gLwmwV.js → ResourcePoolConsoleApp-BeG0gBif.js} +4 -4
  204. package/dist/core/web/public/next/assets/{ResourcePoolConsoleApp-28gLwmwV.js.map → ResourcePoolConsoleApp-BeG0gBif.js.map} +1 -1
  205. package/dist/core/web/public/next/assets/ResourcesChrome-B3Z3O98t.css +1 -0
  206. package/dist/core/web/public/next/assets/ResourcesChrome-BzV6bkIa.js +3 -0
  207. package/dist/core/web/public/next/assets/ResourcesChrome-BzV6bkIa.js.map +1 -0
  208. package/dist/core/web/public/next/assets/ResourcesDrawer-CSKIO_wZ.css +1 -0
  209. package/dist/core/web/public/next/assets/ResourcesDrawer-o4ILHdep.js +2 -0
  210. package/dist/core/web/public/next/assets/ResourcesDrawer-o4ILHdep.js.map +1 -0
  211. package/dist/core/web/public/next/assets/{RouteErrorBoundary-AyUPCIb3.js → RouteErrorBoundary-C5SxA2Dg.js} +2 -2
  212. package/dist/core/web/public/next/assets/{RouteErrorBoundary-AyUPCIb3.js.map → RouteErrorBoundary-C5SxA2Dg.js.map} +1 -1
  213. package/dist/core/web/public/next/assets/RunInCloudAction-C3LBp7C4.js +2 -0
  214. package/dist/core/web/public/next/assets/RunInCloudAction-C3LBp7C4.js.map +1 -0
  215. package/dist/core/web/public/next/assets/SeatSelector-DpvvbjNm.js +3 -0
  216. package/dist/core/web/public/next/assets/{SeatSelector-DaUO-zoK.js.map → SeatSelector-DpvvbjNm.js.map} +1 -1
  217. package/dist/core/web/public/next/assets/{Segmented-B_8c_83S.js → Segmented-BL40udoO.js} +2 -2
  218. package/dist/core/web/public/next/assets/{Segmented-B_8c_83S.js.map → Segmented-BL40udoO.js.map} +1 -1
  219. package/dist/core/web/public/next/assets/{Select-Bl5g5Dt_.js → Select-FWLnAw_j.js} +2 -2
  220. package/dist/core/web/public/next/assets/{Select-Bl5g5Dt_.js.map → Select-FWLnAw_j.js.map} +1 -1
  221. package/dist/core/web/public/next/assets/{SessionInsightChip-w0I21q0c.js → SessionInsightChip-CWye87Ju.js} +2 -2
  222. package/dist/core/web/public/next/assets/{SessionInsightChip-w0I21q0c.js.map → SessionInsightChip-CWye87Ju.js.map} +1 -1
  223. package/dist/core/web/public/next/assets/SessionSearch-YvCHFUuN.js +2 -0
  224. package/dist/core/web/public/next/assets/{SessionSearch-B5aQ0BCM.js.map → SessionSearch-YvCHFUuN.js.map} +1 -1
  225. package/dist/core/web/public/next/assets/SettingsSection-Dr18upeE.js +2 -0
  226. package/dist/core/web/public/next/assets/SettingsSection-Dr18upeE.js.map +1 -0
  227. package/dist/core/web/public/next/assets/{Sheet-CVjk-cLI.js → Sheet-DZKcQXQg.js} +2 -2
  228. package/dist/core/web/public/next/assets/{Sheet-CVjk-cLI.js.map → Sheet-DZKcQXQg.js.map} +1 -1
  229. package/dist/core/web/public/next/assets/{ShortcutsOverlay-BiBjnBcc.js → ShortcutsOverlay-BpDimdPq.js} +2 -2
  230. package/dist/core/web/public/next/assets/{ShortcutsOverlay-BiBjnBcc.js.map → ShortcutsOverlay-BpDimdPq.js.map} +1 -1
  231. package/dist/core/web/public/next/assets/Sidebar-BRc1vGDF.css +1 -0
  232. package/dist/core/web/public/next/assets/Sidebar-BoBzBEFX.js +3 -0
  233. package/dist/core/web/public/next/assets/Sidebar-BoBzBEFX.js.map +1 -0
  234. package/dist/core/web/public/next/assets/{Slider-BS9MU5ZV.js → Slider-DUMo9HDD.js} +2 -2
  235. package/dist/core/web/public/next/assets/{Slider-BS9MU5ZV.js.map → Slider-DUMo9HDD.js.map} +1 -1
  236. package/dist/core/web/public/next/assets/{StatusBadge-DAf-ArKE.js → StatusBadge-BwnBNFQr.js} +2 -2
  237. package/dist/core/web/public/next/assets/{StatusBadge-DAf-ArKE.js.map → StatusBadge-BwnBNFQr.js.map} +1 -1
  238. package/dist/core/web/public/next/assets/StepBand-PDXMIlRk.js +2 -0
  239. package/dist/core/web/public/next/assets/StepBand-PDXMIlRk.js.map +1 -0
  240. package/dist/core/web/public/next/assets/{Surface-CiYOdNKQ.js → Surface-B3TZVoER.js} +2 -2
  241. package/dist/core/web/public/next/assets/{Surface-CiYOdNKQ.js.map → Surface-B3TZVoER.js.map} +1 -1
  242. package/dist/core/web/public/next/assets/Swimlane-DR4OgON_.js +2 -0
  243. package/dist/core/web/public/next/assets/Swimlane-DR4OgON_.js.map +1 -0
  244. package/dist/core/web/public/next/assets/{Switch-BzRXtNPt.js → Switch-CcR5Llk5.js} +2 -2
  245. package/dist/core/web/public/next/assets/{Switch-BzRXtNPt.js.map → Switch-CcR5Llk5.js.map} +1 -1
  246. package/dist/core/web/public/next/assets/{Tag-DEEbDz7T.js → Tag-_-K1h7Hk.js} +2 -2
  247. package/dist/core/web/public/next/assets/{Tag-DEEbDz7T.js.map → Tag-_-K1h7Hk.js.map} +1 -1
  248. package/dist/core/web/public/next/assets/TerminalPane-BwfMbnJz.css +1 -0
  249. package/dist/core/web/public/next/assets/TerminalPane-_1aH4ndN.js +7 -0
  250. package/dist/core/web/public/next/assets/TerminalPane-_1aH4ndN.js.map +1 -0
  251. package/dist/core/web/public/next/assets/UniverseConsoleApp-BUsq-inZ.js +2 -0
  252. package/dist/core/web/public/next/assets/{UniverseConsoleApp-DKqAf-eD.js.map → UniverseConsoleApp-BUsq-inZ.js.map} +1 -1
  253. package/dist/core/web/public/next/assets/{UniverseView-D6081LQL.js → UniverseView-Dogy_dsB.js} +2 -2
  254. package/dist/core/web/public/next/assets/{UniverseView-D6081LQL.js.map → UniverseView-Dogy_dsB.js.map} +1 -1
  255. package/dist/core/web/public/next/assets/UsageSection-DiX_dTyo.js +2 -0
  256. package/dist/core/web/public/next/assets/UsageSection-DiX_dTyo.js.map +1 -0
  257. package/dist/core/web/public/next/assets/UsageSection-DsB-Jqyl.css +1 -0
  258. package/dist/core/web/public/next/assets/VerseConsoleApp-Cxqr-3qc.css +1 -0
  259. package/dist/core/web/public/next/assets/VerseConsoleApp-WVeyJnW7.js +3 -0
  260. package/dist/core/web/public/next/assets/VerseConsoleApp-WVeyJnW7.js.map +1 -0
  261. package/dist/core/web/public/next/assets/Workspace-BYW9dm90.css +1 -0
  262. package/dist/core/web/public/next/assets/Workspace-BbxZHwQd.js +10 -0
  263. package/dist/core/web/public/next/assets/Workspace-BbxZHwQd.js.map +1 -0
  264. package/dist/core/web/public/next/assets/actions-Ddfg2iLl.css +1 -0
  265. package/dist/core/web/public/next/assets/actions-s2lfm_5k.js +2 -0
  266. package/dist/core/web/public/next/assets/actions-s2lfm_5k.js.map +1 -0
  267. package/dist/core/web/public/next/assets/apps-model-CDFvmsQV.js +2 -0
  268. package/dist/core/web/public/next/assets/apps-model-CDFvmsQV.js.map +1 -0
  269. package/dist/core/web/public/next/assets/{budget-queries-Dacv1VYP.js → budget-queries-wUshcovN.js} +2 -2
  270. package/dist/core/web/public/next/assets/{budget-queries-Dacv1VYP.js.map → budget-queries-wUshcovN.js.map} +1 -1
  271. package/dist/core/web/public/next/assets/calendar-day-BxBYHfX1.js +2 -0
  272. package/dist/core/web/public/next/assets/calendar-day-BxBYHfX1.js.map +1 -0
  273. package/dist/core/web/public/next/assets/capacity-strip-model-Bj_9ztzs.js +2 -0
  274. package/dist/core/web/public/next/assets/capacity-strip-model-Bj_9ztzs.js.map +1 -0
  275. package/dist/core/web/public/next/assets/charts-CMSgAUKn.js +2 -0
  276. package/dist/core/web/public/next/assets/charts-CMSgAUKn.js.map +1 -0
  277. package/dist/core/web/public/next/assets/cloud-C1KPNRHC.css +1 -0
  278. package/dist/core/web/public/next/assets/cloud-queries-CnV1yaNG.js +2 -0
  279. package/dist/core/web/public/next/assets/cloud-queries-CnV1yaNG.js.map +1 -0
  280. package/dist/core/web/public/next/assets/cloud.module-CiwatLj3.js +2 -0
  281. package/dist/core/web/public/next/assets/cloud.module-CiwatLj3.js.map +1 -0
  282. package/dist/core/web/public/next/assets/colors-BZ3a9wFf.js +2 -0
  283. package/dist/core/web/public/next/assets/colors-BZ3a9wFf.js.map +1 -0
  284. package/dist/core/web/public/next/assets/{command-bus-CpYuam1F.js → command-bus-DqimKCUY.js} +2 -2
  285. package/dist/core/web/public/next/assets/{command-bus-CpYuam1F.js.map → command-bus-DqimKCUY.js.map} +1 -1
  286. package/dist/core/web/public/next/assets/command-catalog-BdtDH93o.js +2 -0
  287. package/dist/core/web/public/next/assets/command-catalog-BdtDH93o.js.map +1 -0
  288. package/dist/core/web/public/next/assets/{composer-keys-CYz4U4Bg.js → composer-keys-DBRymxQn.js} +2 -2
  289. package/dist/core/web/public/next/assets/{composer-keys-CYz4U4Bg.js.map → composer-keys-DBRymxQn.js.map} +1 -1
  290. package/dist/core/web/public/next/assets/context-model-Dwd49-dp.js +2 -0
  291. package/dist/core/web/public/next/assets/context-model-Dwd49-dp.js.map +1 -0
  292. package/dist/core/web/public/next/assets/context-model-MT17V86_.js +2 -0
  293. package/dist/core/web/public/next/assets/context-model-MT17V86_.js.map +1 -0
  294. package/dist/core/web/public/next/assets/context-queries-xVKIeynP.js +2 -0
  295. package/dist/core/web/public/next/assets/context-queries-xVKIeynP.js.map +1 -0
  296. package/dist/core/web/public/next/assets/context.module-BijAfoJw.js +2 -0
  297. package/dist/core/web/public/next/assets/context.module-BijAfoJw.js.map +1 -0
  298. package/dist/core/web/public/next/assets/{control-queries-BGjarMm9.js → control-queries-DOZR-D8G.js} +2 -2
  299. package/dist/core/web/public/next/assets/{control-queries-BGjarMm9.js.map → control-queries-DOZR-D8G.js.map} +1 -1
  300. package/dist/core/web/public/next/assets/dark-since-DOMvtB_G.js +2 -0
  301. package/dist/core/web/public/next/assets/dark-since-DOMvtB_G.js.map +1 -0
  302. package/dist/core/web/public/next/assets/dock-icons-8EtARwUm.js +2 -0
  303. package/dist/core/web/public/next/assets/dock-icons-8EtARwUm.js.map +1 -0
  304. package/dist/core/web/public/next/assets/dock-panes-UKS-mXhr.js +2 -0
  305. package/dist/core/web/public/next/assets/{dock-panes-BNTLvX7G.js.map → dock-panes-UKS-mXhr.js.map} +1 -1
  306. package/dist/core/web/public/next/assets/{dock-store-_E5h6TEq.js → dock-store-BA1cHOYA.js} +2 -2
  307. package/dist/core/web/public/next/assets/{dock-store-_E5h6TEq.js.map → dock-store-BA1cHOYA.js.map} +1 -1
  308. package/dist/core/web/public/next/assets/fleet-model-CNe8Wh-s.js +2 -0
  309. package/dist/core/web/public/next/assets/fleet-model-CNe8Wh-s.js.map +1 -0
  310. package/dist/core/web/public/next/assets/fleet-queries-BSdRlUwJ.js +2 -0
  311. package/dist/core/web/public/next/assets/fleet-queries-BSdRlUwJ.js.map +1 -0
  312. package/dist/core/web/public/next/assets/format-B8DAVcn2.js +2 -0
  313. package/dist/core/web/public/next/assets/format-B8DAVcn2.js.map +1 -0
  314. package/dist/core/web/public/next/assets/format-DKrNjdwD.js +2 -0
  315. package/dist/core/web/public/next/assets/format-DKrNjdwD.js.map +1 -0
  316. package/dist/core/web/public/next/assets/{git-model-5v5xGobf.js → git-model-CivuBY_D.js} +2 -2
  317. package/dist/core/web/public/next/assets/{git-model-5v5xGobf.js.map → git-model-CivuBY_D.js.map} +1 -1
  318. package/dist/core/web/public/next/assets/global-Di2PUgj4.js +2 -0
  319. package/dist/core/web/public/next/assets/global-Di2PUgj4.js.map +1 -0
  320. package/dist/core/web/public/next/assets/{guarded-action-vOPc8v75.js → guarded-action-CvOHcqyH.js} +2 -2
  321. package/dist/core/web/public/next/assets/{guarded-action-vOPc8v75.js.map → guarded-action-CvOHcqyH.js.map} +1 -1
  322. package/dist/core/web/public/next/assets/{icons-DWb24OA6.js → icons-B_yuAgdN.js} +2 -2
  323. package/dist/core/web/public/next/assets/{icons-DWb24OA6.js.map → icons-B_yuAgdN.js.map} +1 -1
  324. package/dist/core/web/public/next/assets/{index-afDA8cwW.js → index-oAAq8XJa.js} +3 -3
  325. package/dist/core/web/public/next/assets/{index-afDA8cwW.js.map → index-oAAq8XJa.js.map} +1 -1
  326. package/dist/core/web/public/next/assets/live-model-DCw_IFRI.js +2 -0
  327. package/dist/core/web/public/next/assets/live-model-DCw_IFRI.js.map +1 -0
  328. package/dist/core/web/public/next/assets/local-model-DFyjKX0b.js +2 -0
  329. package/dist/core/web/public/next/assets/local-model-DFyjKX0b.js.map +1 -0
  330. package/dist/core/web/public/next/assets/mind-B9PzLcl0.css +1 -0
  331. package/dist/core/web/public/next/assets/mind.module-vnuJcwvD.js +2 -0
  332. package/dist/core/web/public/next/assets/mind.module-vnuJcwvD.js.map +1 -0
  333. package/dist/core/web/public/next/assets/mutations-Dpsql5t7.js +2 -0
  334. package/dist/core/web/public/next/assets/{mutations-C6E10SPX.js.map → mutations-Dpsql5t7.js.map} +1 -1
  335. package/dist/core/web/public/next/assets/{overnight-queries-CCGfiS-g.js → overnight-queries-X-44Gsw5.js} +2 -2
  336. package/dist/core/web/public/next/assets/{overnight-queries-CCGfiS-g.js.map → overnight-queries-X-44Gsw5.js.map} +1 -1
  337. package/dist/core/web/public/next/assets/pane-chrome-8JmEhHVD.css +1 -0
  338. package/dist/core/web/public/next/assets/pane-chrome.module-D7o-fVd0.js +2 -0
  339. package/dist/core/web/public/next/assets/pane-chrome.module-D7o-fVd0.js.map +1 -0
  340. package/dist/core/web/public/next/assets/primitives-BDIcUvob.js +1 -0
  341. package/dist/core/web/public/next/assets/{queries-BuYIEHst.js → queries-BA4rNGD-.js} +2 -2
  342. package/dist/core/web/public/next/assets/{queries-BuYIEHst.js.map → queries-BA4rNGD-.js.map} +1 -1
  343. package/dist/core/web/public/next/assets/{reasoning-pref-BVzGczV7.js → reasoning-pref-B9-DJUXP.js} +2 -2
  344. package/dist/core/web/public/next/assets/{reasoning-pref-BVzGczV7.js.map → reasoning-pref-B9-DJUXP.js.map} +1 -1
  345. package/dist/core/web/public/next/assets/seat-subscription-CH6fW4fJ.js +2 -0
  346. package/dist/core/web/public/next/assets/seat-subscription-CH6fW4fJ.js.map +1 -0
  347. package/dist/core/web/public/next/assets/{section-visibility-CSrsTcwK.js → section-visibility-qFqc_d4Z.js} +2 -2
  348. package/dist/core/web/public/next/assets/{section-visibility-CSrsTcwK.js.map → section-visibility-qFqc_d4Z.js.map} +1 -1
  349. package/dist/core/web/public/next/assets/{sidebar-model-C8fyqSQY.js → sidebar-model-M1GaQU5l.js} +2 -2
  350. package/dist/core/web/public/next/assets/{sidebar-model-C8fyqSQY.js.map → sidebar-model-M1GaQU5l.js.map} +1 -1
  351. package/dist/core/web/public/next/assets/slots-Ds9ZIqUL.js +3 -0
  352. package/dist/core/web/public/next/assets/{slots-W8gkmdfE.js.map → slots-Ds9ZIqUL.js.map} +1 -1
  353. package/dist/core/web/public/next/assets/surface-data-J52iIGMD.js +2 -0
  354. package/dist/core/web/public/next/assets/surface-data-J52iIGMD.js.map +1 -0
  355. package/dist/core/web/public/next/assets/surface-prefetch-CgZ-LEJK.js +2 -0
  356. package/dist/core/web/public/next/assets/surface-prefetch-CgZ-LEJK.js.map +1 -0
  357. package/dist/core/web/public/next/assets/tasks-model-ent8f0jZ.js +2 -0
  358. package/dist/core/web/public/next/assets/{tasks-model-CnYQzgxk.js.map → tasks-model-ent8f0jZ.js.map} +1 -1
  359. package/dist/core/web/public/next/assets/{terminal-icons-CxUYaWX9.js → terminal-icons-DJTK7QpR.js} +2 -2
  360. package/dist/core/web/public/next/assets/{terminal-icons-CxUYaWX9.js.map → terminal-icons-DJTK7QpR.js.map} +1 -1
  361. package/dist/core/web/public/next/assets/{tool-semantics-CTRuLF5j.js → tool-semantics-GX8ScuSH.js} +2 -2
  362. package/dist/core/web/public/next/assets/{tool-semantics-CTRuLF5j.js.map → tool-semantics-GX8ScuSH.js.map} +1 -1
  363. package/dist/core/web/public/next/assets/{turn-files-BvB5LLNw.js → turn-files-BPHQzYuH.js} +2 -2
  364. package/dist/core/web/public/next/assets/{turn-files-BvB5LLNw.js.map → turn-files-BPHQzYuH.js.map} +1 -1
  365. package/dist/core/web/public/next/assets/types-D5XOdyw8.js +2 -0
  366. package/dist/core/web/public/next/assets/types-D5XOdyw8.js.map +1 -0
  367. package/dist/core/web/public/next/assets/{usage-queries-CQOpeE1H.js → usage-queries-Bn8ccqyN.js} +2 -2
  368. package/dist/core/web/public/next/assets/{usage-queries-CQOpeE1H.js.map → usage-queries-Bn8ccqyN.js.map} +1 -1
  369. package/dist/core/web/public/next/assets/use-guarded-action-C2HlSzkz.js +2 -0
  370. package/dist/core/web/public/next/assets/use-guarded-action-C2HlSzkz.js.map +1 -0
  371. package/dist/core/web/public/next/assets/{use-ticker-hryPXnyp.js → use-ticker-BNc1H4ZC.js} +2 -2
  372. package/dist/core/web/public/next/assets/{use-ticker-hryPXnyp.js.map → use-ticker-BNc1H4ZC.js.map} +1 -1
  373. package/dist/core/web/public/next/assets/use-token-gate-B3IJL6bf.js +2 -0
  374. package/dist/core/web/public/next/assets/use-token-gate-B3IJL6bf.js.map +1 -0
  375. package/dist/core/web/public/next/assets/{useActivity-Cg_9-7nt.js → useActivity-Bk3XgXjL.js} +2 -2
  376. package/dist/core/web/public/next/assets/{useActivity-Cg_9-7nt.js.map → useActivity-Bk3XgXjL.js.map} +1 -1
  377. package/dist/core/web/public/next/assets/useChartWidth-BAtVgn2n.css +1 -0
  378. package/dist/core/web/public/next/assets/useChartWidth-lZ9PrQn0.js +2 -0
  379. package/dist/core/web/public/next/assets/useChartWidth-lZ9PrQn0.js.map +1 -0
  380. package/dist/core/web/public/next/assets/{useSeatsRefresh-4Ov9eT1F.js → useSeatsRefresh-CG4jczeL.js} +2 -2
  381. package/dist/core/web/public/next/assets/{useSeatsRefresh-4Ov9eT1F.js.map → useSeatsRefresh-CG4jczeL.js.map} +1 -1
  382. package/dist/core/web/public/next/assets/verse-model-D7NZQFAR.js +2 -0
  383. package/dist/core/web/public/next/assets/verse-model-D7NZQFAR.js.map +1 -0
  384. package/dist/core/web/public/next/assets/{verse-queries-BjQoOTwv.js → verse-queries-DvIJcn6Z.js} +2 -2
  385. package/dist/core/web/public/next/assets/{verse-queries-BjQoOTwv.js.map → verse-queries-DvIJcn6Z.js.map} +1 -1
  386. package/dist/core/web/public/next/assets/verse-store-DjBWj04q.js +3 -0
  387. package/dist/core/web/public/next/assets/verse-store-DjBWj04q.js.map +1 -0
  388. package/dist/core/web/public/next/assets/verse-ui-store-zafyzXKD.js +3 -0
  389. package/dist/core/web/public/next/assets/{verse-ui-store-KTTKfv-T.js.map → verse-ui-store-zafyzXKD.js.map} +1 -1
  390. package/dist/core/web/public/next/assets/{viewport-ZB86jdES.js → viewport-BEqGUoTA.js} +2 -2
  391. package/dist/core/web/public/next/assets/{viewport-ZB86jdES.js.map → viewport-BEqGUoTA.js.map} +1 -1
  392. package/dist/core/web/public/next/assets/warmup-BR6pxAKs.js +3 -0
  393. package/dist/core/web/public/next/assets/warmup-BR6pxAKs.js.map +1 -0
  394. package/dist/core/web/public/next/assets/{workspace-model-4hq_Mv3N.js → workspace-model-D_tWD5Wt.js} +2 -2
  395. package/dist/core/web/public/next/assets/{workspace-model-4hq_Mv3N.js.map → workspace-model-D_tWD5Wt.js.map} +1 -1
  396. package/dist/core/web/public/next/index.html +1 -1
  397. package/dist/release-dependency-inventory.json +1 -1
  398. package/package.json +1 -1
  399. package/dist/core/web/public/next/assets/Advanced-CHjxJt2z.css +0 -1
  400. package/dist/core/web/public/next/assets/Advanced-DM0DYibH.js +0 -2
  401. package/dist/core/web/public/next/assets/Advanced-DM0DYibH.js.map +0 -1
  402. package/dist/core/web/public/next/assets/AppsSection-CXxbfPJQ.js +0 -2
  403. package/dist/core/web/public/next/assets/AppsSection-CXxbfPJQ.js.map +0 -1
  404. package/dist/core/web/public/next/assets/AreaTrend-gUVXkfhf.js +0 -2
  405. package/dist/core/web/public/next/assets/AreaTrend-gUVXkfhf.js.map +0 -1
  406. package/dist/core/web/public/next/assets/AutonomySection-CoMngwNB.js +0 -2
  407. package/dist/core/web/public/next/assets/BranchBar-C-NovaXr.js +0 -2
  408. package/dist/core/web/public/next/assets/BranchBar-C-NovaXr.js.map +0 -1
  409. package/dist/core/web/public/next/assets/BranchBar-C9BpPVLr.css +0 -1
  410. package/dist/core/web/public/next/assets/BudgetControl-P5lMxHvQ.js +0 -2
  411. package/dist/core/web/public/next/assets/BudgetControl-P5lMxHvQ.js.map +0 -1
  412. package/dist/core/web/public/next/assets/BurnDown-4P1LDoCL.js +0 -2
  413. package/dist/core/web/public/next/assets/BurnDown-4P1LDoCL.js.map +0 -1
  414. package/dist/core/web/public/next/assets/CapacityStrip-D6Yyg4a1.js +0 -2
  415. package/dist/core/web/public/next/assets/CapacityStrip-D6Yyg4a1.js.map +0 -1
  416. package/dist/core/web/public/next/assets/CapacityStrip-wgFP9MUA.css +0 -1
  417. package/dist/core/web/public/next/assets/ChatSection-B9cdRKUh.js +0 -3
  418. package/dist/core/web/public/next/assets/CommandSection-BC0uXim_.js +0 -2
  419. package/dist/core/web/public/next/assets/CommandSection-BC0uXim_.js.map +0 -1
  420. package/dist/core/web/public/next/assets/Composer-CkcwbQhG.css +0 -1
  421. package/dist/core/web/public/next/assets/Composer.module-DJMdrqNt.js +0 -2
  422. package/dist/core/web/public/next/assets/DiffPane-5uLKa0au.js +0 -2
  423. package/dist/core/web/public/next/assets/DiffPane-5uLKa0au.js.map +0 -1
  424. package/dist/core/web/public/next/assets/DiffPane-Csboxnn0.css +0 -1
  425. package/dist/core/web/public/next/assets/DockHost-BGnTgdIb.css +0 -1
  426. package/dist/core/web/public/next/assets/DockHost-CBV_6Ehi.js +0 -2
  427. package/dist/core/web/public/next/assets/DockHost-CBV_6Ehi.js.map +0 -1
  428. package/dist/core/web/public/next/assets/FleetSection-DuJcQCGg.js +0 -3
  429. package/dist/core/web/public/next/assets/FleetSection-DuJcQCGg.js.map +0 -1
  430. package/dist/core/web/public/next/assets/FleetSection-w9AjqfTR.css +0 -1
  431. package/dist/core/web/public/next/assets/Funnel-qX3Hlbce.js +0 -2
  432. package/dist/core/web/public/next/assets/Funnel-qX3Hlbce.js.map +0 -1
  433. package/dist/core/web/public/next/assets/GearTray-kVGP1coG.js +0 -2
  434. package/dist/core/web/public/next/assets/GearTray-kVGP1coG.js.map +0 -1
  435. package/dist/core/web/public/next/assets/GrowthSection-CYxJ9MH5.js +0 -2
  436. package/dist/core/web/public/next/assets/GrowthSection-CYxJ9MH5.js.map +0 -1
  437. package/dist/core/web/public/next/assets/HandoffDialog-DHZo3Ev0.js +0 -2
  438. package/dist/core/web/public/next/assets/HandoffDialog-DHZo3Ev0.js.map +0 -1
  439. package/dist/core/web/public/next/assets/MatrixHeatmap-B_JWCjZx.js +0 -2
  440. package/dist/core/web/public/next/assets/MatrixHeatmap-B_JWCjZx.js.map +0 -1
  441. package/dist/core/web/public/next/assets/McpSection-1UncWBpW.js +0 -2
  442. package/dist/core/web/public/next/assets/MessageMarkdown-C4pl9LI5.js +0 -3
  443. package/dist/core/web/public/next/assets/MessageMarkdown-Czcl3L_Q.css +0 -1
  444. package/dist/core/web/public/next/assets/MindSection-C3fCw_fD.js +0 -2
  445. package/dist/core/web/public/next/assets/MindSection-C3fCw_fD.js.map +0 -1
  446. package/dist/core/web/public/next/assets/MutationTokenDialog-Dn0tzCrh.js +0 -2
  447. package/dist/core/web/public/next/assets/MutationTokenDialog-Dn0tzCrh.js.map +0 -1
  448. package/dist/core/web/public/next/assets/NeedsYouDrawer-CuNYJCJ0.js +0 -2
  449. package/dist/core/web/public/next/assets/NeedsYouDrawer-CuNYJCJ0.js.map +0 -1
  450. package/dist/core/web/public/next/assets/NeedsYouDrawer-SkhvvdLb.css +0 -1
  451. package/dist/core/web/public/next/assets/NewChatDialog-B_BsS9pr.js +0 -3
  452. package/dist/core/web/public/next/assets/OnboardingFlow-CtCPpgoX.js +0 -2
  453. package/dist/core/web/public/next/assets/PreviewPane-Cx6RRwzM.js +0 -2
  454. package/dist/core/web/public/next/assets/PreviewPane-Cx6RRwzM.js.map +0 -1
  455. package/dist/core/web/public/next/assets/PreviewPane-WQJFjSXe.css +0 -1
  456. package/dist/core/web/public/next/assets/RailStatus-BWs6xevj.js +0 -2
  457. package/dist/core/web/public/next/assets/RailStatus-BWs6xevj.js.map +0 -1
  458. package/dist/core/web/public/next/assets/SeatSelector-DaUO-zoK.js +0 -3
  459. package/dist/core/web/public/next/assets/SessionSearch-B5aQ0BCM.js +0 -2
  460. package/dist/core/web/public/next/assets/SettingsSection-CuESA30a.js +0 -2
  461. package/dist/core/web/public/next/assets/SettingsSection-CuESA30a.js.map +0 -1
  462. package/dist/core/web/public/next/assets/Sidebar-DfD8MNZt.css +0 -1
  463. package/dist/core/web/public/next/assets/Sidebar-q11dtYZf.js +0 -3
  464. package/dist/core/web/public/next/assets/Sidebar-q11dtYZf.js.map +0 -1
  465. package/dist/core/web/public/next/assets/StepBand-B1W7rU70.js +0 -2
  466. package/dist/core/web/public/next/assets/StepBand-B1W7rU70.js.map +0 -1
  467. package/dist/core/web/public/next/assets/Swimlane-BR40WVcj.js +0 -2
  468. package/dist/core/web/public/next/assets/Swimlane-BR40WVcj.js.map +0 -1
  469. package/dist/core/web/public/next/assets/TerminalPane-CPKUTD9K.js +0 -7
  470. package/dist/core/web/public/next/assets/TerminalPane-CPKUTD9K.js.map +0 -1
  471. package/dist/core/web/public/next/assets/TerminalPane-CmE2QL-Q.css +0 -1
  472. package/dist/core/web/public/next/assets/UniverseConsoleApp-DKqAf-eD.js +0 -2
  473. package/dist/core/web/public/next/assets/UsageSection-B6fR3cru.js +0 -2
  474. package/dist/core/web/public/next/assets/UsageSection-B6fR3cru.js.map +0 -1
  475. package/dist/core/web/public/next/assets/UsageSection-DwgNOYvi.css +0 -1
  476. package/dist/core/web/public/next/assets/VerseConsoleApp-C0V221WL.css +0 -1
  477. package/dist/core/web/public/next/assets/VerseConsoleApp-bjARLPwN.js +0 -3
  478. package/dist/core/web/public/next/assets/VerseConsoleApp-bjARLPwN.js.map +0 -1
  479. package/dist/core/web/public/next/assets/Workspace-DQXMVDf7.css +0 -1
  480. package/dist/core/web/public/next/assets/Workspace-DtJb5tiM.js +0 -10
  481. package/dist/core/web/public/next/assets/Workspace-DtJb5tiM.js.map +0 -1
  482. package/dist/core/web/public/next/assets/actions-Bszsdpms.js +0 -2
  483. package/dist/core/web/public/next/assets/actions-Bszsdpms.js.map +0 -1
  484. package/dist/core/web/public/next/assets/actions-Dug8YIf0.css +0 -1
  485. package/dist/core/web/public/next/assets/capacity-strip-model-BR539Ci8.js +0 -2
  486. package/dist/core/web/public/next/assets/capacity-strip-model-BR539Ci8.js.map +0 -1
  487. package/dist/core/web/public/next/assets/charts-D4NaLaXA.js +0 -2
  488. package/dist/core/web/public/next/assets/charts-D4NaLaXA.js.map +0 -1
  489. package/dist/core/web/public/next/assets/colors-B-vHsX1S.js +0 -2
  490. package/dist/core/web/public/next/assets/colors-B-vHsX1S.js.map +0 -1
  491. package/dist/core/web/public/next/assets/command-catalog-s3W6Z96D.js +0 -2
  492. package/dist/core/web/public/next/assets/command-catalog-s3W6Z96D.js.map +0 -1
  493. package/dist/core/web/public/next/assets/context-model-Bto3LZn2.js +0 -2
  494. package/dist/core/web/public/next/assets/context-model-Bto3LZn2.js.map +0 -1
  495. package/dist/core/web/public/next/assets/context-queries-DVdSLrYy.js +0 -2
  496. package/dist/core/web/public/next/assets/context-queries-DVdSLrYy.js.map +0 -1
  497. package/dist/core/web/public/next/assets/context.module-B_k02HNU.js +0 -2
  498. package/dist/core/web/public/next/assets/context.module-B_k02HNU.js.map +0 -1
  499. package/dist/core/web/public/next/assets/dock-icons-oG8d7mNZ.js +0 -2
  500. package/dist/core/web/public/next/assets/dock-icons-oG8d7mNZ.js.map +0 -1
  501. package/dist/core/web/public/next/assets/dock-panes-BNTLvX7G.js +0 -2
  502. package/dist/core/web/public/next/assets/fleet-model-ClBbQ0Uj.js +0 -2
  503. package/dist/core/web/public/next/assets/fleet-model-ClBbQ0Uj.js.map +0 -1
  504. package/dist/core/web/public/next/assets/format-BNYWGJat.js +0 -2
  505. package/dist/core/web/public/next/assets/format-BNYWGJat.js.map +0 -1
  506. package/dist/core/web/public/next/assets/global-DVgMguLr.js +0 -2
  507. package/dist/core/web/public/next/assets/global-DVgMguLr.js.map +0 -1
  508. package/dist/core/web/public/next/assets/live-model-Dm6ITHvX.js +0 -2
  509. package/dist/core/web/public/next/assets/live-model-Dm6ITHvX.js.map +0 -1
  510. package/dist/core/web/public/next/assets/mind-B-lYfSUJ.css +0 -1
  511. package/dist/core/web/public/next/assets/mind.module-BzhAlg3e.js +0 -2
  512. package/dist/core/web/public/next/assets/mind.module-BzhAlg3e.js.map +0 -1
  513. package/dist/core/web/public/next/assets/mutations-C6E10SPX.js +0 -2
  514. package/dist/core/web/public/next/assets/primitives-DQvYikjm.js +0 -1
  515. package/dist/core/web/public/next/assets/seat-subscription-CrWOV4Qc.js +0 -2
  516. package/dist/core/web/public/next/assets/seat-subscription-CrWOV4Qc.js.map +0 -1
  517. package/dist/core/web/public/next/assets/slots-W8gkmdfE.js +0 -3
  518. package/dist/core/web/public/next/assets/surface-data-ZtCegYMQ.js +0 -2
  519. package/dist/core/web/public/next/assets/surface-data-ZtCegYMQ.js.map +0 -1
  520. package/dist/core/web/public/next/assets/tasks-model-CnYQzgxk.js +0 -2
  521. package/dist/core/web/public/next/assets/types-Dypu22dp.js +0 -3
  522. package/dist/core/web/public/next/assets/types-Dypu22dp.js.map +0 -1
  523. package/dist/core/web/public/next/assets/use-guarded-action-CO_aAsed.js +0 -2
  524. package/dist/core/web/public/next/assets/use-guarded-action-CO_aAsed.js.map +0 -1
  525. package/dist/core/web/public/next/assets/use-token-gate-DYA2-ALC.js +0 -2
  526. package/dist/core/web/public/next/assets/use-token-gate-DYA2-ALC.js.map +0 -1
  527. package/dist/core/web/public/next/assets/useChartWidth-B8E5mJgM.css +0 -1
  528. package/dist/core/web/public/next/assets/useChartWidth-MEXvDxDL.js +0 -2
  529. package/dist/core/web/public/next/assets/useChartWidth-MEXvDxDL.js.map +0 -1
  530. package/dist/core/web/public/next/assets/verse-model-E98kXngO.js +0 -2
  531. package/dist/core/web/public/next/assets/verse-model-E98kXngO.js.map +0 -1
  532. package/dist/core/web/public/next/assets/verse-store-BgKx_YGs.js +0 -2
  533. package/dist/core/web/public/next/assets/verse-store-BgKx_YGs.js.map +0 -1
  534. package/dist/core/web/public/next/assets/verse-ui-store-KTTKfv-T.js +0 -3
@@ -0,0 +1,654 @@
1
+ /**
2
+ * Seat capacity history (3.10.1) — a small rolling log of each paid seat's
3
+ * window usage, beside the latest-only snapshot:
4
+ *
5
+ * ~/.ashlr/routing/capacity.json latest snapshot (budget-store.ts)
6
+ * ~/.ashlr/routing/capacity-history.jsonl this file: one row per seat
7
+ * window per recorded sample
8
+ *
9
+ * WHY: Command's weekly burn-downs used to start empty on every page load —
10
+ * the readings lived only in the browser. The wire contract (row shape,
11
+ * route, response) is capacity-history-types.ts.
12
+ *
13
+ * WHO WRITES (each path never throws into its caller):
14
+ * - the daemon's capacity publisher, on every publish and on every check
15
+ * that finds the Verse server's snapshot fresh (daemon/capacity-publisher.ts);
16
+ * - the Verse server, after each budget read the UI polls and on a 60 s
17
+ * follow of its own publisher (capacity-history-api.ts) — so history keeps
18
+ * growing while the fleet is dark and no daemon runs.
19
+ * Both read the same snapshot, so they see the same observations; the rules
20
+ * below make a second recorder a no-op instead of a duplicate.
21
+ *
22
+ * RULES
23
+ * - A row carries the seat's `observedAt` (when the provider window was
24
+ * read), never the publish time: republishing a stale reading adds nothing,
25
+ * and a seat with no timestamp adds nothing (headroom.ts treats it as
26
+ * unknown usage too).
27
+ * - Flat-run compression: a row is written only when the value (or the
28
+ * window's reset) changed, or ≥ 10 min passed since that seat window's
29
+ * last row. A week of flat readings is ~1 000 rows per window, not 20 000.
30
+ * - Stable series: a row's window class is headroom.ts's, except that a
31
+ * Codex `*_primary` window already recorded as WEEKLY stays weekly for the
32
+ * rest of that reset period (historyWindowClass) — so a weekly-only
33
+ * primary does not jump to the session line in its last ~5 hours.
34
+ * - Bounded: rows older than 8 days are dropped, and the file is rewritten
35
+ * (atomic temp + rename, 0600) once it passes 2 MiB or its oldest row is a
36
+ * day past the keep window — so compaction runs about daily, not per append.
37
+ * Past the byte cap, older rows are THINNED per series (a low and a high
38
+ * reading per time slot) before any row is dropped, so every seat keeps
39
+ * its whole 8-day window; dropping the oldest rows is the last resort.
40
+ * - ASHLR_CAPACITY_HISTORY=0 turns EVERY recorder off (checked here in the
41
+ * store, so the daemon, the request path and the follow all honour it);
42
+ * the route still serves whatever was already recorded.
43
+ * - Readers are total: a corrupt or partial line (a writer that died
44
+ * mid-line) is skipped, and an append after one starts on a fresh line.
45
+ * - 0600 file in the 0700 routing directory, O_NOFOLLOW | O_NONBLOCK (a FIFO
46
+ * planted at the path is refused instead of hanging the process), one
47
+ * O_APPEND write per record batch. Paths re-resolve homedir() per call
48
+ * (budget-store.ts), so a relocated HOME in tests is always honoured.
49
+ *
50
+ * Known race, accepted: a compaction in one process can drop a row another
51
+ * process appended between the compaction's read and its rename. That costs
52
+ * one sample, once a day at most; the next sample re-records the value.
53
+ */
54
+ import { closeSync, constants as fsConstants, fchmodSync, fstatSync, openSync, readSync, writeSync } from 'node:fs';
55
+ import { dirname, join } from 'node:path';
56
+ import { ensurePrivateDirectory, writePrivateFileAtomic } from '../verse/preferences.js';
57
+ import { readCapacitySnapshot, routingDir } from './budget-store.js';
58
+ import { classifyWindow } from './headroom.js';
59
+ import { BUDGET_SEAT_ID_RE } from './policy.js';
60
+ export const CAPACITY_HISTORY_FILE = 'capacity-history.jsonl';
61
+ const MIN = 60_000;
62
+ const HOUR = 60 * MIN;
63
+ const DAY = 86_400_000;
64
+ /** A flat seat window still gets one row this often (so a reader can tell "flat" from "not watched"). */
65
+ export const HISTORY_FLAT_ROW_MS = 10 * MIN;
66
+ /** Rows younger than this are always kept (subject to the byte cap). */
67
+ export const HISTORY_KEEP_MS = 8 * DAY;
68
+ /** Past this size the file is compacted. */
69
+ export const HISTORY_MAX_BYTES = 2 * 1024 * 1024;
70
+ /** Compaction rewrites down to this, so the next byte compaction is days away, not one append away. */
71
+ export const HISTORY_COMPACT_TARGET_BYTES = Math.floor(HISTORY_MAX_BYTES * 0.75);
72
+ /**
73
+ * Byte compaction thins before it drops (3.10.1 review: a flat cut to the
74
+ * target evicted the start of EVERY seat's weekly window once a multi-seat
75
+ * setup passed ~16 series). Each step leaves rows newer than `rawMs`
76
+ * untouched and keeps, per series, at most the lowest and the highest reading
77
+ * in each `slotMs` slot of the older rows — a climb keeps its ends, a reset
78
+ * keeps its drop. Steps run in order until the file fits the target. Rough
79
+ * cost of 8 days per series: 30 min slots ≈ 85 KB, 2 h ≈ 22 KB, 6 h ≈ 8 KB,
80
+ * so even MAX_SEATS paid seats (128 series) fit at the last step. Slots are
81
+ * epoch-aligned, so re-thinning already-thinned rows keeps the same rows.
82
+ */
83
+ export const HISTORY_THIN_STEPS = [
84
+ { rawMs: DAY, slotMs: 30 * MIN },
85
+ { rawMs: DAY, slotMs: 2 * HOUR },
86
+ { rawMs: 6 * HOUR, slotMs: 2 * HOUR },
87
+ { rawMs: HOUR, slotMs: 6 * HOUR },
88
+ ];
89
+ /** Age compaction runs once the oldest row is this far past the keep window. */
90
+ const AGE_SLACK_MS = DAY;
91
+ /** How much of the file's end an append reads to find each series' last row. */
92
+ const TAIL_BYTES = 128 * 1024;
93
+ /** How much of the file's start an append reads to find the oldest row (age compaction). */
94
+ const HEAD_BYTES = 2048;
95
+ /** The most a reader loads (the file is compacted at 2 MiB; anything past this is not ours). */
96
+ const MAX_READ_BYTES = 4 * 1024 * 1024;
97
+ /** A row is ~120 bytes; a longer line was not written by us. */
98
+ const MAX_LINE_CHARS = 1024;
99
+ /** A reading stamped further ahead than this is a clock problem, not a sample. */
100
+ const FUTURE_SKEW_MS = 5 * MIN;
101
+ /** Codex reports its reset as a countdown, so the same reset can move by a second between reads. */
102
+ const RESET_JITTER_MS = MIN;
103
+ const MAX_SEATS = 64;
104
+ /** Response bounds: ≤ 32 series × ≤ 720 points (one per ~14 min over a week) — a few hundred KB at worst. */
105
+ export const HISTORY_MAX_SERIES = 32;
106
+ export const HISTORY_MAX_POINTS_PER_SERIES = 720;
107
+ const WINDOWS = ['session', 'weekly'];
108
+ const SOURCES = ['daemon', 'verse'];
109
+ const NO_FOLLOW = typeof fsConstants.O_NOFOLLOW === 'number' ? fsConstants.O_NOFOLLOW : 0;
110
+ /**
111
+ * O_NONBLOCK, as verse/fleet-history.ts: a blocking open() of a FIFO waits
112
+ * forever for the other end, and every open here is synchronous — on the
113
+ * Verse server's event loop or in the daemon's standing tick. Non-blocking, a
114
+ * read open of a FIFO returns at once (the fstat check then refuses it) and
115
+ * an append open without a reader fails with ENXIO. Regular files ignore it.
116
+ */
117
+ const NON_BLOCK = typeof fsConstants.O_NONBLOCK === 'number' ? fsConstants.O_NONBLOCK : 0;
118
+ /** True when ASHLR_CAPACITY_HISTORY=0: no recorder writes (the route still serves what exists). */
119
+ export function capacityHistoryDisabled(env = process.env) {
120
+ return env['ASHLR_CAPACITY_HISTORY'] === '0';
121
+ }
122
+ export function capacityHistoryPath() {
123
+ return join(routingDir(), CAPACITY_HISTORY_FILE);
124
+ }
125
+ /** Series identity: seat ids may contain `:` and `/` (BUDGET_SEAT_ID_RE), never `#`. */
126
+ export function historySeriesKey(seatId, window) {
127
+ return `${seatId}#${window}`;
128
+ }
129
+ /** Second precision keeps rows short; two reads in one second are one observation. */
130
+ function isoSeconds(ms) {
131
+ return new Date(Math.floor(ms / 1000) * 1000).toISOString().replace('.000Z', 'Z');
132
+ }
133
+ function isObject(value) {
134
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
135
+ }
136
+ function isIso(value) {
137
+ return typeof value === 'string' && value.length <= 40 && Number.isFinite(Date.parse(value));
138
+ }
139
+ // ---------------------------------------------------------------------------
140
+ // Rows
141
+ // ---------------------------------------------------------------------------
142
+ function resetMoved(a, b) {
143
+ if (a === null || b === null)
144
+ return a !== b;
145
+ return Math.abs(Date.parse(a) - Date.parse(b)) > RESET_JITTER_MS;
146
+ }
147
+ /**
148
+ * The series a window's reading is recorded under: headroom.ts's class, made
149
+ * STABLE for the one window whose class depends on the clock.
150
+ *
151
+ * headroom.ts calls a Codex `*_primary` window weekly only while its reset is
152
+ * more than ~5 h away (the primary is usually the 5-hour window, but some
153
+ * accounts report a weekly-only primary). Recorded as is, a weekly-only
154
+ * primary would move to the session series for the last ~5 h before its
155
+ * reset, splitting one physical window across two lines. So a primary the
156
+ * live classifier calls 'session' stays 'weekly' when this seat's newest
157
+ * weekly row carries the same reset instant (within the countdown jitter)
158
+ * and no window the classifier already calls weekly accounts for that reset
159
+ * — i.e. that primary IS the window the weekly line has been drawing. A
160
+ * window's reset instant is fixed for its life, so a real 5-hour window
161
+ * never inherits a weekly one's. The next period (reset ~7 days out) is
162
+ * weekly on its own. With no weekly row on file (first seen inside its last
163
+ * 5 h) there is no evidence, and the headroom class stands. Budget gating is
164
+ * unchanged: this only picks the history series.
165
+ */
166
+ export function historyWindowClass(seat, window, nowMs, weeklyReset) {
167
+ const cls = classifyWindow(seat.engine, window, nowMs);
168
+ if (cls !== 'session' || seat.engine !== 'codex' || !window.id.endsWith('_primary'))
169
+ return cls;
170
+ if (!weeklyReset || !window.resetsAt || resetMoved(window.resetsAt, weeklyReset))
171
+ return cls;
172
+ const explained = seat.windows.some((other) => other !== window && other.resetsAt !== null
173
+ && classifyWindow(seat.engine, other, nowMs) === 'weekly' && !resetMoved(other.resetsAt, weeklyReset));
174
+ return explained ? cls : 'weekly';
175
+ }
176
+ /**
177
+ * The highest reading among the seat's ACCOUNT windows of `cls` — exactly
178
+ * headroom.ts assessSeat's `sessionUsed` / `weeklyUsed` (same classifier,
179
+ * per-model windows excluded, null percent = no signal), so a recorded row
180
+ * is the number the budget view showed for that window at that moment. The
181
+ * one exception is the sticky weekly primary ({@link historyWindowClass}).
182
+ */
183
+ function peakWindow(seat, cls, nowMs, weeklyReset) {
184
+ let best = null;
185
+ for (const window of seat.windows) {
186
+ const used = window.usedPercent;
187
+ if (used === null || typeof used !== 'number' || !Number.isFinite(used))
188
+ continue;
189
+ if (historyWindowClass(seat, window, nowMs, weeklyReset) !== cls)
190
+ continue;
191
+ if (best === null || used > best.usedPercent)
192
+ best = window;
193
+ }
194
+ return best;
195
+ }
196
+ /** The rows one snapshot of `seats` would record (before compression). Pure. */
197
+ export function historyRowsFromSeats(seats, opts) {
198
+ const rows = [];
199
+ for (const seat of seats.slice(0, MAX_SEATS)) {
200
+ if (!isObject(seat) || seat.free || typeof seat.seatId !== 'string' || !BUDGET_SEAT_ID_RE.test(seat.seatId))
201
+ continue;
202
+ if (!Array.isArray(seat.windows))
203
+ continue;
204
+ // No timestamp, no row: an undated reading cannot be placed on a chart.
205
+ const observed = typeof seat.observedAt === 'string' ? Date.parse(seat.observedAt) : NaN;
206
+ if (!Number.isFinite(observed) || observed > opts.nowMs + FUTURE_SKEW_MS || observed < opts.nowMs - HISTORY_KEEP_MS)
207
+ continue;
208
+ const ts = isoSeconds(observed);
209
+ const weeklyReset = opts.weeklyResetBySeat?.get(seat.seatId);
210
+ for (const window of WINDOWS) {
211
+ const peak = peakWindow(seat, window, opts.nowMs, weeklyReset);
212
+ if (!peak)
213
+ continue;
214
+ const resetMs = peak.resetsAt ? Date.parse(peak.resetsAt) : NaN;
215
+ rows.push({
216
+ ts,
217
+ seat: seat.seatId,
218
+ window,
219
+ usedPct: Math.round(Math.min(100, Math.max(0, peak.usedPercent)) * 10) / 10,
220
+ resetsAt: Number.isFinite(resetMs) ? isoSeconds(resetMs) : null,
221
+ source: opts.source,
222
+ });
223
+ }
224
+ }
225
+ return rows;
226
+ }
227
+ /**
228
+ * Flat-run compression: record `row` after `last` (that series' newest row)
229
+ * only when it is a NEWER observation and its value or reset changed, or
230
+ * ≥ 10 min passed. An equal or older timestamp is an observation already
231
+ * recorded — by this process or the other recorder.
232
+ */
233
+ export function shouldRecordRow(last, row) {
234
+ if (!last)
235
+ return true;
236
+ const dt = Date.parse(row.ts) - Date.parse(last.ts);
237
+ if (!(dt > 0))
238
+ return false;
239
+ if (row.usedPct !== last.usedPct)
240
+ return true;
241
+ if (resetMoved(last.resetsAt, row.resetsAt))
242
+ return true;
243
+ return dt >= HISTORY_FLAT_ROW_MS;
244
+ }
245
+ function serializeRow(row) {
246
+ // resetsAt is omitted when unknown (every Claude row): ~15 bytes a row.
247
+ return JSON.stringify({
248
+ ts: row.ts,
249
+ seat: row.seat,
250
+ window: row.window,
251
+ usedPct: row.usedPct,
252
+ ...(row.resetsAt ? { resetsAt: row.resetsAt } : {}),
253
+ source: row.source,
254
+ });
255
+ }
256
+ /** One line → a validated row, or null (corrupt, partial, foreign). Never throws. */
257
+ export function parseHistoryLine(line) {
258
+ if (line.length === 0 || line.length > MAX_LINE_CHARS)
259
+ return null;
260
+ let raw;
261
+ try {
262
+ raw = JSON.parse(line);
263
+ }
264
+ catch {
265
+ return null;
266
+ }
267
+ if (!isObject(raw))
268
+ return null;
269
+ const { ts, seat, window, usedPct, resetsAt, source } = raw;
270
+ if (!isIso(ts))
271
+ return null;
272
+ if (typeof seat !== 'string' || !BUDGET_SEAT_ID_RE.test(seat))
273
+ return null;
274
+ if (typeof window !== 'string' || !WINDOWS.includes(window))
275
+ return null;
276
+ if (typeof usedPct !== 'number' || !Number.isFinite(usedPct) || usedPct < 0 || usedPct > 100)
277
+ return null;
278
+ if (resetsAt !== undefined && resetsAt !== null && !isIso(resetsAt))
279
+ return null;
280
+ if (typeof source !== 'string' || !SOURCES.includes(source))
281
+ return null;
282
+ return {
283
+ ts,
284
+ seat,
285
+ window: window,
286
+ usedPct,
287
+ resetsAt: typeof resetsAt === 'string' ? resetsAt : null,
288
+ source: source,
289
+ };
290
+ }
291
+ /** The first or last `maxBytes` of `file`; null when it is missing or not a regular file (a FIFO included). Never throws. */
292
+ function readChunk(file, maxBytes, where) {
293
+ let fd;
294
+ try {
295
+ fd = openSync(file, fsConstants.O_RDONLY | NO_FOLLOW | NON_BLOCK);
296
+ }
297
+ catch {
298
+ return null;
299
+ }
300
+ try {
301
+ const stat = fstatSync(fd);
302
+ if (!stat.isFile())
303
+ return null;
304
+ const size = stat.size;
305
+ const length = Math.min(size, maxBytes);
306
+ const position = where === 'tail' ? size - length : 0;
307
+ const buffer = Buffer.alloc(length);
308
+ let offset = 0;
309
+ while (offset < length) {
310
+ const n = readSync(fd, buffer, offset, length - offset, position + offset);
311
+ if (n <= 0)
312
+ break;
313
+ offset += n;
314
+ }
315
+ const bytes = buffer.subarray(0, offset);
316
+ return {
317
+ text: bytes.toString('utf8'),
318
+ size,
319
+ fromStart: position === 0,
320
+ endsWithNewline: size === 0 || (where === 'tail' && offset === length && bytes[offset - 1] === 0x0a),
321
+ };
322
+ }
323
+ catch {
324
+ return null;
325
+ }
326
+ finally {
327
+ try {
328
+ closeSync(fd);
329
+ }
330
+ catch { /* never throws */ }
331
+ }
332
+ }
333
+ function rowsOf(chunk) {
334
+ const lines = chunk.text.split('\n');
335
+ // A tail window starts mid-line; that fragment is not a row.
336
+ if (!chunk.fromStart)
337
+ lines.shift();
338
+ const rows = [];
339
+ for (const line of lines) {
340
+ const row = parseHistoryLine(line);
341
+ if (row)
342
+ rows.push(row);
343
+ }
344
+ return rows;
345
+ }
346
+ /**
347
+ * One O_APPEND write of `text`; creates the file 0600 and re-tightens a
348
+ * loosened mode. Anything but a regular file is refused: a FIFO without a
349
+ * reader fails the non-blocking open (ENXIO), one with a reader the fstat.
350
+ */
351
+ function appendPrivate(file, text) {
352
+ const fd = openSync(file, fsConstants.O_WRONLY | fsConstants.O_APPEND | fsConstants.O_CREAT | NO_FOLLOW | NON_BLOCK, 0o600);
353
+ try {
354
+ const stat = fstatSync(fd);
355
+ if (!stat.isFile())
356
+ throw new Error('capacity history is not a regular file');
357
+ if (typeof process.getuid === 'function' && stat.uid !== process.getuid()) {
358
+ throw new Error('capacity history is owned by another user');
359
+ }
360
+ if ((stat.mode & 0o777) !== 0o600)
361
+ fchmodSync(fd, 0o600);
362
+ const bytes = Buffer.from(text, 'utf8');
363
+ let offset = 0;
364
+ while (offset < bytes.length) {
365
+ const n = writeSync(fd, bytes, offset, bytes.length - offset);
366
+ if (n <= 0)
367
+ throw new Error('capacity history write made no progress');
368
+ offset += n;
369
+ }
370
+ }
371
+ finally {
372
+ closeSync(fd);
373
+ }
374
+ }
375
+ function byTime(a, b) {
376
+ return Date.parse(a.ts) - Date.parse(b.ts);
377
+ }
378
+ function totalBytes(entries) {
379
+ return entries.reduce((n, e) => n + e.bytes, 0);
380
+ }
381
+ /**
382
+ * One thinning step (HISTORY_THIN_STEPS): entries at or after `nowMs − rawMs`
383
+ * stay; each series' older entries keep only the first lowest and the first
384
+ * highest reading of every epoch-aligned `slotMs` slot, in time order — plus
385
+ * the series' own first and last entry, so thinning never shortens a line
386
+ * (the window's start is exactly what the byte cap used to cut).
387
+ * `entries` is in time order; so is the result.
388
+ */
389
+ function thinEntries(entries, nowMs, step) {
390
+ const rawFrom = nowMs - step.rawMs;
391
+ const keep = new Array(entries.length).fill(false);
392
+ const slots = new Map();
393
+ const ends = new Map();
394
+ entries.forEach((entry, i) => {
395
+ const end = ends.get(entry.key);
396
+ if (end)
397
+ end.last = i;
398
+ else
399
+ ends.set(entry.key, { first: i, last: i });
400
+ if (entry.t >= rawFrom) {
401
+ keep[i] = true;
402
+ return;
403
+ }
404
+ const id = `${entry.key}#${Math.floor(entry.t / step.slotMs)}`;
405
+ const slot = slots.get(id);
406
+ if (!slot) {
407
+ slots.set(id, { lo: i, hi: i });
408
+ return;
409
+ }
410
+ if (entry.row.usedPct < entries[slot.lo].row.usedPct)
411
+ slot.lo = i;
412
+ if (entry.row.usedPct > entries[slot.hi].row.usedPct)
413
+ slot.hi = i;
414
+ });
415
+ for (const { lo, hi } of slots.values()) {
416
+ keep[lo] = true;
417
+ keep[hi] = true;
418
+ }
419
+ for (const { first, last } of ends.values()) {
420
+ keep[first] = true;
421
+ keep[last] = true;
422
+ }
423
+ return entries.filter((_, i) => keep[i]);
424
+ }
425
+ /**
426
+ * Rewrite the file with rows younger than the keep window; duplicates (one
427
+ * observation recorded by both recorders) and unreadable lines go too. Over
428
+ * the compaction target, older rows are thinned per series
429
+ * (HISTORY_THIN_STEPS) so every seat keeps its whole window, and only if the
430
+ * coarsest step still does not fit are the oldest rows dropped. Atomic (temp
431
+ * + fsync + rename, 0600). Returns the rows kept. Throws on a storage failure.
432
+ */
433
+ export function compactCapacityHistory(file = capacityHistoryPath(), nowMs = Date.now()) {
434
+ const chunk = readChunk(file, MAX_READ_BYTES, 'tail');
435
+ if (!chunk)
436
+ return 0;
437
+ const cutoff = nowMs - HISTORY_KEEP_MS;
438
+ const seen = new Set();
439
+ let entries = rowsOf(chunk)
440
+ .filter((row) => Date.parse(row.ts) >= cutoff)
441
+ .sort(byTime)
442
+ .filter((row) => {
443
+ const id = `${historySeriesKey(row.seat, row.window)}#${row.ts}`;
444
+ if (seen.has(id))
445
+ return false;
446
+ seen.add(id);
447
+ return true;
448
+ })
449
+ .map((row) => {
450
+ const line = serializeRow(row);
451
+ return { row, t: Date.parse(row.ts), key: historySeriesKey(row.seat, row.window), line, bytes: Buffer.byteLength(line) + 1 };
452
+ });
453
+ let total = totalBytes(entries);
454
+ for (const step of HISTORY_THIN_STEPS) {
455
+ if (total <= HISTORY_COMPACT_TARGET_BYTES)
456
+ break;
457
+ entries = thinEntries(entries, nowMs, step);
458
+ total = totalBytes(entries);
459
+ }
460
+ // Last resort (a burst no thinning step can absorb): oldest first.
461
+ let drop = 0;
462
+ while (total > HISTORY_COMPACT_TARGET_BYTES && drop < entries.length) {
463
+ total -= entries[drop].bytes;
464
+ drop += 1;
465
+ }
466
+ const kept = entries.slice(drop).map((e) => e.line);
467
+ writePrivateFileAtomic(file, kept.length > 0 ? `${kept.join('\n')}\n` : '');
468
+ return kept.length;
469
+ }
470
+ function needsCompaction(file, sizeAfter, nowMs) {
471
+ if (sizeAfter > HISTORY_MAX_BYTES)
472
+ return true;
473
+ const head = readChunk(file, HEAD_BYTES, 'head');
474
+ if (!head || head.size === 0)
475
+ return false;
476
+ // Rows are appended in time order, so the first readable row is the oldest.
477
+ const lines = head.text.split('\n');
478
+ if (head.size > HEAD_BYTES)
479
+ lines.pop(); // the head window may end mid-line
480
+ for (const line of lines) {
481
+ const row = parseHistoryLine(line);
482
+ if (row)
483
+ return Date.parse(row.ts) < nowMs - HISTORY_KEEP_MS - AGE_SLACK_MS;
484
+ }
485
+ // The file opens with garbage (a torn write, a hand edit): rewrite it clean.
486
+ return true;
487
+ }
488
+ function errorText(err) {
489
+ const code = err?.code;
490
+ if (typeof code === 'string')
491
+ return code;
492
+ return err instanceof Error ? err.message : 'unknown error';
493
+ }
494
+ const NOTHING = Object.freeze({ appended: 0, compacted: false, error: null });
495
+ /**
496
+ * Record `seats` (one snapshot's readings) under the compression rule.
497
+ * NEVER THROWS: history is a convenience beside the budget gate, never a
498
+ * reason a publish or a budget read fails. Failures come back as `error`.
499
+ * A no-op under ASHLR_CAPACITY_HISTORY=0 — this is the one door every
500
+ * recorder (daemon, request path, follow) writes through.
501
+ */
502
+ export function appendCapacityHistory(seats, opts) {
503
+ if (capacityHistoryDisabled(opts.env))
504
+ return { ...NOTHING };
505
+ const nowMs = opts.nowMs ?? Date.now();
506
+ try {
507
+ // Cheap pre-check (no I/O): a snapshot with nothing recordable touches no file.
508
+ if (historyRowsFromSeats(seats, { nowMs, source: opts.source }).length === 0)
509
+ return { ...NOTHING };
510
+ const file = opts.file ?? capacityHistoryPath();
511
+ ensurePrivateDirectory(dirname(file));
512
+ const tail = readChunk(file, TAIL_BYTES, 'tail');
513
+ // Each series' newest row. A series quiet for longer than the tail
514
+ // window gets one extra row — harmless.
515
+ const last = new Map();
516
+ for (const row of tail ? rowsOf(tail) : []) {
517
+ const key = historySeriesKey(row.seat, row.window);
518
+ const prev = last.get(key);
519
+ if (!prev || Date.parse(row.ts) >= Date.parse(prev.ts))
520
+ last.set(key, row);
521
+ }
522
+ // Each seat's newest weekly reset keeps a weekly-only Codex primary on
523
+ // its weekly line through its last hours (historyWindowClass).
524
+ const weeklyResetBySeat = new Map();
525
+ for (const row of last.values()) {
526
+ if (row.window === 'weekly' && row.resetsAt)
527
+ weeklyResetBySeat.set(row.seat, row.resetsAt);
528
+ }
529
+ const rows = historyRowsFromSeats(seats, { nowMs, source: opts.source, weeklyResetBySeat });
530
+ const fresh = [];
531
+ for (const row of rows) {
532
+ const key = historySeriesKey(row.seat, row.window);
533
+ if (!shouldRecordRow(last.get(key), row))
534
+ continue;
535
+ fresh.push(row);
536
+ last.set(key, row);
537
+ }
538
+ if (fresh.length === 0)
539
+ return { ...NOTHING };
540
+ // After a torn last line, start on a fresh one so only the fragment is lost.
541
+ const separator = tail && tail.size > 0 && !tail.endsWithNewline ? '\n' : '';
542
+ const text = `${separator}${fresh.map(serializeRow).join('\n')}\n`;
543
+ appendPrivate(file, text);
544
+ let compacted = false;
545
+ if (needsCompaction(file, (tail?.size ?? 0) + Buffer.byteLength(text), nowMs)) {
546
+ compactCapacityHistory(file, nowMs);
547
+ compacted = true;
548
+ }
549
+ return { appended: fresh.length, compacted, error: null };
550
+ }
551
+ catch (err) {
552
+ return { appended: 0, compacted: false, error: errorText(err) };
553
+ }
554
+ }
555
+ /**
556
+ * Record a capacity snapshot — the one given, or (when `snapshot` is
557
+ * undefined) the one on disk. A missing or unreadable snapshot records
558
+ * nothing, and so does ASHLR_CAPACITY_HISTORY=0 (before any read). Never
559
+ * throws.
560
+ */
561
+ export function recordCapacityHistoryFromSnapshot(snapshot, source, opts = {}) {
562
+ if (capacityHistoryDisabled(opts.env))
563
+ return { ...NOTHING };
564
+ let snap = snapshot ?? null;
565
+ if (snapshot === undefined) {
566
+ try {
567
+ snap = readCapacitySnapshot(opts.snapshotFile);
568
+ }
569
+ catch {
570
+ snap = null;
571
+ }
572
+ }
573
+ if (!snap)
574
+ return { ...NOTHING };
575
+ return appendCapacityHistory(snap.seats, { source, nowMs: opts.nowMs, file: opts.file, env: opts.env });
576
+ }
577
+ /** Every readable row at or after `sinceMs`, in file order. Never throws. */
578
+ export function readCapacityHistory(opts = {}) {
579
+ try {
580
+ const chunk = readChunk(opts.file ?? capacityHistoryPath(), MAX_READ_BYTES, 'tail');
581
+ if (!chunk)
582
+ return [];
583
+ const since = opts.sinceMs ?? Number.NEGATIVE_INFINITY;
584
+ return rowsOf(chunk).filter((row) => Date.parse(row.ts) >= since);
585
+ }
586
+ catch {
587
+ return [];
588
+ }
589
+ }
590
+ /** Drop the interior points of every flat run: its first and last reading draw the same line. */
591
+ export function collapseFlatRuns(points) {
592
+ return points.filter((p, i) => i === 0 || i === points.length - 1 || p[1] !== points[i - 1][1] || p[1] !== points[i + 1][1]);
593
+ }
594
+ /** `max` points spread evenly over `points`, first and last always kept. */
595
+ function thinEvenly(points, max) {
596
+ if (points.length <= max)
597
+ return [...points];
598
+ const out = [];
599
+ let previous = -1;
600
+ for (let i = 0; i < max; i++) {
601
+ const index = Math.round((i * (points.length - 1)) / (max - 1));
602
+ if (index !== previous)
603
+ out.push(points[index]);
604
+ previous = index;
605
+ }
606
+ return out;
607
+ }
608
+ /** Group `rows` into bounded per-seat-window series for the last `days`. Pure. */
609
+ export function buildCapacityHistoryResponse(rows, opts) {
610
+ const sinceMs = opts.nowMs - opts.days * DAY;
611
+ const groups = new Map();
612
+ for (const row of rows) {
613
+ const t = Date.parse(row.ts);
614
+ if (!(t >= sinceMs) || t > opts.nowMs + FUTURE_SKEW_MS)
615
+ continue;
616
+ const key = historySeriesKey(row.seat, row.window);
617
+ let group = groups.get(key);
618
+ if (!group) {
619
+ group = { seatId: row.seat, window: row.window, rows: [] };
620
+ groups.set(key, group);
621
+ }
622
+ group.rows.push({ t, used: row.usedPct, resetsAt: row.resetsAt });
623
+ }
624
+ const keys = [...groups.keys()].sort();
625
+ let oldest = Number.POSITIVE_INFINITY;
626
+ const series = keys.slice(0, HISTORY_MAX_SERIES).map((key) => {
627
+ const group = groups.get(key);
628
+ // Stable sort, then one point per instant: both recorders may have seen
629
+ // the same observation; the later-written row wins.
630
+ const sorted = [...group.rows].sort((a, b) => a.t - b.t);
631
+ const unique = [];
632
+ for (const r of sorted) {
633
+ if (unique.length > 0 && unique[unique.length - 1].t === r.t)
634
+ unique[unique.length - 1] = r;
635
+ else
636
+ unique.push(r);
637
+ }
638
+ const collapsed = collapseFlatRuns(unique.map((r) => [r.t, r.used]));
639
+ const thinned = collapsed.length > HISTORY_MAX_POINTS_PER_SERIES;
640
+ const points = thinned ? thinEvenly(collapsed, HISTORY_MAX_POINTS_PER_SERIES) : collapsed;
641
+ oldest = Math.min(oldest, points[0][0]);
642
+ return { seatId: group.seatId, window: group.window, points, resetsAt: unique[unique.length - 1].resetsAt, thinned };
643
+ });
644
+ return {
645
+ v: 1,
646
+ generatedAt: new Date(opts.nowMs).toISOString(),
647
+ days: opts.days,
648
+ since: new Date(sinceMs).toISOString(),
649
+ oldestAt: Number.isFinite(oldest) ? new Date(oldest).toISOString() : null,
650
+ series,
651
+ truncated: keys.length > HISTORY_MAX_SERIES,
652
+ };
653
+ }
654
+ //# sourceMappingURL=capacity-history.js.map