@ashlr/hub 3.11.3 → 3.12.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 (558) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/README.md +44 -18
  3. package/dist/authority-surface.json +74 -59
  4. package/dist/build-identity.json +2 -2
  5. package/dist/cli/authority.d.ts +39 -0
  6. package/dist/cli/authority.js +222 -55
  7. package/dist/cli/authority.js.map +1 -1
  8. package/dist/cli/help.js +1 -1
  9. package/dist/cli/help.js.map +1 -1
  10. package/dist/cli/verse.d.ts +3 -0
  11. package/dist/cli/verse.js +10 -0
  12. package/dist/cli/verse.js.map +1 -1
  13. package/dist/core/authority/trust-roots.js +7 -1
  14. package/dist/core/authority/trust-roots.js.map +1 -1
  15. package/dist/core/authority/types.d.ts +2 -2
  16. package/dist/core/cloud/cloud-api.js +1 -1
  17. package/dist/core/cloud/cloud-api.js.map +1 -1
  18. package/dist/core/cloud/delivery-contract.d.ts +1 -1
  19. package/dist/core/cloud/delivery-contract.js +25 -15
  20. package/dist/core/cloud/delivery-contract.js.map +1 -1
  21. package/dist/core/cloud/store.js +6 -0
  22. package/dist/core/cloud/store.js.map +1 -1
  23. package/dist/core/cloud/tracker.d.ts +2 -0
  24. package/dist/core/cloud/tracker.js +140 -37
  25. package/dist/core/cloud/tracker.js.map +1 -1
  26. package/dist/core/cloud/types.d.ts +9 -1
  27. package/dist/core/cloud/types.js.map +1 -1
  28. package/dist/core/comms/dispatch.d.ts +5 -0
  29. package/dist/core/comms/dispatch.js +12 -1
  30. package/dist/core/comms/dispatch.js.map +1 -1
  31. package/dist/core/comms/requests.d.ts +27 -1
  32. package/dist/core/comms/requests.js +50 -1
  33. package/dist/core/comms/requests.js.map +1 -1
  34. package/dist/core/daemon/loop.d.ts +14 -0
  35. package/dist/core/daemon/loop.js +35 -0
  36. package/dist/core/daemon/loop.js.map +1 -1
  37. package/dist/core/fabric/claude-usage.js +23 -1
  38. package/dist/core/fabric/claude-usage.js.map +1 -1
  39. package/dist/core/fleet/dispatch-router.d.ts +7 -0
  40. package/dist/core/fleet/dispatch-router.js +4 -1
  41. package/dist/core/fleet/dispatch-router.js.map +1 -1
  42. package/dist/core/fleet/tick-hooks-live.d.ts +5 -1
  43. package/dist/core/fleet/tick-hooks-live.js +10 -1
  44. package/dist/core/fleet/tick-hooks-live.js.map +1 -1
  45. package/dist/core/local-runtime/llama/config.d.ts +14 -0
  46. package/dist/core/local-runtime/llama/config.js +20 -2
  47. package/dist/core/local-runtime/llama/config.js.map +1 -1
  48. package/dist/core/local-runtime/llama/process.d.ts +19 -0
  49. package/dist/core/local-runtime/llama/process.js +67 -17
  50. package/dist/core/local-runtime/llama/process.js.map +1 -1
  51. package/dist/core/local-runtime/llama/supervisor.js +14 -3
  52. package/dist/core/local-runtime/llama/supervisor.js.map +1 -1
  53. package/dist/core/observability/rollup.d.ts +12 -0
  54. package/dist/core/observability/rollup.js +37 -2
  55. package/dist/core/observability/rollup.js.map +1 -1
  56. package/dist/core/observability/usage-source.js +49 -1
  57. package/dist/core/observability/usage-source.js.map +1 -1
  58. package/dist/core/resources/connection-monitor.js +47 -4
  59. package/dist/core/resources/connection-monitor.js.map +1 -1
  60. package/dist/core/resources/engineering-mission-store.d.ts +1 -1
  61. package/dist/core/routing/headroom.js +7 -2
  62. package/dist/core/routing/headroom.js.map +1 -1
  63. package/dist/core/routing/router.d.ts +48 -0
  64. package/dist/core/routing/router.js +129 -13
  65. package/dist/core/routing/router.js.map +1 -1
  66. package/dist/core/run/best-of-n.d.ts +7 -0
  67. package/dist/core/run/best-of-n.js +3 -0
  68. package/dist/core/run/best-of-n.js.map +1 -1
  69. package/dist/core/run/harness-dispatch.d.ts +147 -0
  70. package/dist/core/run/harness-dispatch.js +234 -0
  71. package/dist/core/run/harness-dispatch.js.map +1 -0
  72. package/dist/core/run/orchestrator.js +3 -0
  73. package/dist/core/run/orchestrator.js.map +1 -1
  74. package/dist/core/run/provider-client.d.ts +8 -0
  75. package/dist/core/run/provider-client.js +4 -0
  76. package/dist/core/run/provider-client.js.map +1 -1
  77. package/dist/core/run/sandboxed-engine.d.ts +8 -0
  78. package/dist/core/run/sandboxed-engine.js +60 -7
  79. package/dist/core/run/sandboxed-engine.js.map +1 -1
  80. package/dist/core/types.d.ts +14 -0
  81. package/dist/core/types.js.map +1 -1
  82. package/dist/core/universe/builtins/preparation/manifest.json +1 -1
  83. package/dist/core/universe/builtins/preparation/preparation-bridge.mjs +188 -6
  84. package/dist/core/universe/builtins/preparation/preparation-verification-fixtures.mjs +187 -5
  85. package/dist/core/universe/firm-demo.d.ts +1 -1
  86. package/dist/core/universe/firm-graph.d.ts +2 -2
  87. package/dist/core/util/scrub.js +16 -3
  88. package/dist/core/util/scrub.js.map +1 -1
  89. package/dist/core/verse/accounts.d.ts +9 -1
  90. package/dist/core/verse/accounts.js +52 -11
  91. package/dist/core/verse/accounts.js.map +1 -1
  92. package/dist/core/verse/apps-api.d.ts +12 -0
  93. package/dist/core/verse/apps-api.js +22 -4
  94. package/dist/core/verse/apps-api.js.map +1 -1
  95. package/dist/core/verse/apps.js +22 -12
  96. package/dist/core/verse/apps.js.map +1 -1
  97. package/dist/core/verse/local-models.js +3 -7
  98. package/dist/core/verse/local-models.js.map +1 -1
  99. package/dist/core/verse/model-display-name.d.ts +34 -0
  100. package/dist/core/verse/model-display-name.js +125 -0
  101. package/dist/core/verse/model-display-name.js.map +1 -0
  102. package/dist/core/verse/seats.d.ts +11 -2
  103. package/dist/core/verse/seats.js +42 -18
  104. package/dist/core/verse/seats.js.map +1 -1
  105. package/dist/core/verse/transient-events.d.ts +21 -0
  106. package/dist/core/verse/transient-events.js +12 -0
  107. package/dist/core/verse/transient-events.js.map +1 -0
  108. package/dist/core/verse/types.d.ts +6 -13
  109. package/dist/core/verse/types.js +5 -36
  110. package/dist/core/verse/types.js.map +1 -1
  111. package/dist/core/web/public/next/assets/ActionMenu-B4-39f2S.js +2 -0
  112. package/dist/core/web/public/next/assets/{ActionMenu-FxXeRbPx.js.map → ActionMenu-B4-39f2S.js.map} +1 -1
  113. package/dist/core/web/public/next/assets/Advanced-B-LqYXvd.js +2 -0
  114. package/dist/core/web/public/next/assets/Advanced-B-LqYXvd.js.map +1 -0
  115. package/dist/core/web/public/next/assets/App-E2zCDRxm.js +7 -0
  116. package/dist/core/web/public/next/assets/App-E2zCDRxm.js.map +1 -0
  117. package/dist/core/web/public/next/assets/AppsSection-8wXPPhZb.js +2 -0
  118. package/dist/core/web/public/next/assets/AppsSection-8wXPPhZb.js.map +1 -0
  119. package/dist/core/web/public/next/assets/AreaTrend-BFimExYn.js +2 -0
  120. package/dist/core/web/public/next/assets/{AreaTrend-CDxrQU4b.js.map → AreaTrend-BFimExYn.js.map} +1 -1
  121. package/dist/core/web/public/next/assets/AutonomyOffState-B5eEkmiz.js +2 -0
  122. package/dist/core/web/public/next/assets/AutonomyOffState-B5eEkmiz.js.map +1 -0
  123. package/dist/core/web/public/next/assets/AutonomyOffState-DmbE71vI.css +1 -0
  124. package/dist/core/web/public/next/assets/AutonomySection-B46igJKR.js +2 -0
  125. package/dist/core/web/public/next/assets/{AutonomySection-DuQkHGD_.js.map → AutonomySection-B46igJKR.js.map} +1 -1
  126. package/dist/core/web/public/next/assets/BranchBar-BRkrEQGs.js +2 -0
  127. package/dist/core/web/public/next/assets/{BranchBar-CLsvOcyK.js.map → BranchBar-BRkrEQGs.js.map} +1 -1
  128. package/dist/core/web/public/next/assets/BudgetControl-T_RjPrw9.js +2 -0
  129. package/dist/core/web/public/next/assets/{BudgetControl-TL3FeZ1D.js.map → BudgetControl-T_RjPrw9.js.map} +1 -1
  130. package/dist/core/web/public/next/assets/{Button-HHXgoXGr.js → Button-BhO-WKPp.js} +2 -2
  131. package/dist/core/web/public/next/assets/{Button-HHXgoXGr.js.map → Button-BhO-WKPp.js.map} +1 -1
  132. package/dist/core/web/public/next/assets/CapacityStrip-CkFz5vq2.js +2 -0
  133. package/dist/core/web/public/next/assets/{CapacityStrip-qReu0RaF.js.map → CapacityStrip-CkFz5vq2.js.map} +1 -1
  134. package/dist/core/web/public/next/assets/{useChartWidth-BW6SwYIK.css → ChartFrame-BVuBe6RP.css} +1 -1
  135. package/dist/core/web/public/next/assets/ChartFrame-SygZ7B3x.js +2 -0
  136. package/dist/core/web/public/next/assets/ChartFrame-SygZ7B3x.js.map +1 -0
  137. package/dist/core/web/public/next/assets/ChatSection-D6WybBpB.js +3 -0
  138. package/dist/core/web/public/next/assets/ChatSection-D6WybBpB.js.map +1 -0
  139. package/dist/core/web/public/next/assets/CloudBudgetForm-Bd91iStN.js +2 -0
  140. package/dist/core/web/public/next/assets/CloudBudgetForm-Bd91iStN.js.map +1 -0
  141. package/dist/core/web/public/next/assets/CommandPalette-B6SgDJH-.js +2 -0
  142. package/dist/core/web/public/next/assets/CommandPalette-B6SgDJH-.js.map +1 -0
  143. package/dist/core/web/public/next/assets/CommandSection-CvAVd1w4.css +1 -0
  144. package/dist/core/web/public/next/assets/CommandSection-DgMGoepd.js +2 -0
  145. package/dist/core/web/public/next/assets/CommandSection-DgMGoepd.js.map +1 -0
  146. package/dist/core/web/public/next/assets/ConfirmDialog-Bv4hdK2T.js +2 -0
  147. package/dist/core/web/public/next/assets/{ConfirmDialog-DLrLKM0c.js.map → ConfirmDialog-Bv4hdK2T.js.map} +1 -1
  148. package/dist/core/web/public/next/assets/DeleteChatDialog-CH1Ix8Eh.js +2 -0
  149. package/dist/core/web/public/next/assets/DeleteChatDialog-CH1Ix8Eh.js.map +1 -0
  150. package/dist/core/web/public/next/assets/Dialog-BSsIFNqD.js +2 -0
  151. package/dist/core/web/public/next/assets/{Dialog-BS9Dxi3G.js.map → Dialog-BSsIFNqD.js.map} +1 -1
  152. package/dist/core/web/public/next/assets/DiffPane-BpNuJmth.js +2 -0
  153. package/dist/core/web/public/next/assets/{DiffPane-TOmUf3b2.js.map → DiffPane-BpNuJmth.js.map} +1 -1
  154. package/dist/core/web/public/next/assets/DiffViewer-CJarUvs0.js +2 -0
  155. package/dist/core/web/public/next/assets/{DiffViewer-BpH56302.js.map → DiffViewer-CJarUvs0.js.map} +1 -1
  156. package/dist/core/web/public/next/assets/DockHost-DW9q0NdR.js +2 -0
  157. package/dist/core/web/public/next/assets/DockHost-DW9q0NdR.js.map +1 -0
  158. package/dist/core/web/public/next/assets/{EmptyState-BqR5YAmf.js → EmptyState-DPrd2aak.js} +2 -2
  159. package/dist/core/web/public/next/assets/{EmptyState-BqR5YAmf.js.map → EmptyState-DPrd2aak.js.map} +1 -1
  160. package/dist/core/web/public/next/assets/{Epistemic-dhvDTwAZ.js → Epistemic-D7MxSmED.js} +2 -2
  161. package/dist/core/web/public/next/assets/{Epistemic-dhvDTwAZ.js.map → Epistemic-D7MxSmED.js.map} +1 -1
  162. package/dist/core/web/public/next/assets/FleetSection-BdZN6rGS.js +3 -0
  163. package/dist/core/web/public/next/assets/FleetSection-BdZN6rGS.js.map +1 -0
  164. package/dist/core/web/public/next/assets/Funnel-BeNQZWv2.js +2 -0
  165. package/dist/core/web/public/next/assets/{Funnel-D2u7Wlzc.js.map → Funnel-BeNQZWv2.js.map} +1 -1
  166. package/dist/core/web/public/next/assets/GearTray-CIPtzeIx.js +2 -0
  167. package/dist/core/web/public/next/assets/{GearTray-Cb2npoxM.js.map → GearTray-CIPtzeIx.js.map} +1 -1
  168. package/dist/core/web/public/next/assets/GrowthSection-iiQg6wvK.js +2 -0
  169. package/dist/core/web/public/next/assets/{GrowthSection-C5aDPs8B.js.map → GrowthSection-iiQg6wvK.js.map} +1 -1
  170. package/dist/core/web/public/next/assets/HandoffDialog-DrQ6ofuy.js +2 -0
  171. package/dist/core/web/public/next/assets/{HandoffDialog-BF3AYg-X.js.map → HandoffDialog-DrQ6ofuy.js.map} +1 -1
  172. package/dist/core/web/public/next/assets/Input-C0MQxEM6.js +2 -0
  173. package/dist/core/web/public/next/assets/{Input-B5dmGLZx.js.map → Input-C0MQxEM6.js.map} +1 -1
  174. package/dist/core/web/public/next/assets/LeaderCard-BRr3_yE-.js +2 -0
  175. package/dist/core/web/public/next/assets/LeaderCard-BRr3_yE-.js.map +1 -0
  176. package/dist/core/web/public/next/assets/MatrixHeatmap-DZvZeWXL.js +2 -0
  177. package/dist/core/web/public/next/assets/{MatrixHeatmap-BgEUs2Eu.js.map → MatrixHeatmap-DZvZeWXL.js.map} +1 -1
  178. package/dist/core/web/public/next/assets/McpSection-BRuCcTjT.js +2 -0
  179. package/dist/core/web/public/next/assets/{McpSection-DZkiOuoq.js.map → McpSection-BRuCcTjT.js.map} +1 -1
  180. package/dist/core/web/public/next/assets/MessageMarkdown-bRvD5nSc.js +3 -0
  181. package/dist/core/web/public/next/assets/{MessageMarkdown-BauY8ZTY.js.map → MessageMarkdown-bRvD5nSc.js.map} +1 -1
  182. package/dist/core/web/public/next/assets/{MessageMarkdownRenderer-DLBNLfsn.js → MessageMarkdownRenderer-FjjkPKA2.js} +4 -4
  183. package/dist/core/web/public/next/assets/{MessageMarkdownRenderer-DLBNLfsn.js.map → MessageMarkdownRenderer-FjjkPKA2.js.map} +1 -1
  184. package/dist/core/web/public/next/assets/{Meter-DNeocJnD.js → Meter-CFNLpwA-.js} +2 -2
  185. package/dist/core/web/public/next/assets/{Meter-DNeocJnD.js.map → Meter-CFNLpwA-.js.map} +1 -1
  186. package/dist/core/web/public/next/assets/MindSection-BTIiQS8P.js +2 -0
  187. package/dist/core/web/public/next/assets/MindSection-BTIiQS8P.js.map +1 -0
  188. package/dist/core/web/public/next/assets/MutationTokenDialog-T7gv3a9r.js +2 -0
  189. package/dist/core/web/public/next/assets/{MutationTokenDialog-mxrw0Yvy.js.map → MutationTokenDialog-T7gv3a9r.js.map} +1 -1
  190. package/dist/core/web/public/next/assets/NeedsYouDrawer-lYN4G_aM.js +2 -0
  191. package/dist/core/web/public/next/assets/{NeedsYouDrawer-CO-Balfp.js.map → NeedsYouDrawer-lYN4G_aM.js.map} +1 -1
  192. package/dist/core/web/public/next/assets/NeedsYouList-BgH8ezqf.js +2 -0
  193. package/dist/core/web/public/next/assets/{NeedsYouList-CzDZbzRD.js.map → NeedsYouList-BgH8ezqf.js.map} +1 -1
  194. package/dist/core/web/public/next/assets/NewChatDialog-Db5Xjrk8.js +3 -0
  195. package/dist/core/web/public/next/assets/NewChatDialog-Db5Xjrk8.js.map +1 -0
  196. package/dist/core/web/public/next/assets/OnboardingFlow-HUNQGQuU.css +1 -0
  197. package/dist/core/web/public/next/assets/OnboardingFlow-LoY-zuSe.js +2 -0
  198. package/dist/core/web/public/next/assets/OnboardingFlow-LoY-zuSe.js.map +1 -0
  199. package/dist/core/web/public/next/assets/OnboardingGate-C4VXn7BJ.js +3 -0
  200. package/dist/core/web/public/next/assets/OnboardingGate-C4VXn7BJ.js.map +1 -0
  201. package/dist/core/web/public/next/assets/PreviewPane-BPBbcROb.js +2 -0
  202. package/dist/core/web/public/next/assets/{PreviewPane-BS-CleCd.js.map → PreviewPane-BPBbcROb.js.map} +1 -1
  203. package/dist/core/web/public/next/assets/{ProviderLogo-C5mBg8i0.js → ProviderLogo-CT2cSfkg.js} +2 -2
  204. package/dist/core/web/public/next/assets/{ProviderLogo-C5mBg8i0.js.map → ProviderLogo-CT2cSfkg.js.map} +1 -1
  205. package/dist/core/web/public/next/assets/RailStatus-Vgl0GYtd.js +2 -0
  206. package/dist/core/web/public/next/assets/{RailStatus-cPRyOmrk.js.map → RailStatus-Vgl0GYtd.js.map} +1 -1
  207. package/dist/core/web/public/next/assets/{RefreshIndicator-CMwSCiz5.js → RefreshIndicator-CSyqpY_q.js} +2 -2
  208. package/dist/core/web/public/next/assets/{RefreshIndicator-CMwSCiz5.js.map → RefreshIndicator-CSyqpY_q.js.map} +1 -1
  209. package/dist/core/web/public/next/assets/{ResourcePoolConsoleApp-BFi1opsC.js → ResourcePoolConsoleApp-BX2nkdmZ.js} +4 -4
  210. package/dist/core/web/public/next/assets/{ResourcePoolConsoleApp-BFi1opsC.js.map → ResourcePoolConsoleApp-BX2nkdmZ.js.map} +1 -1
  211. package/dist/core/web/public/next/assets/ResourcesChrome-B2U2lO1H.js +3 -0
  212. package/dist/core/web/public/next/assets/ResourcesChrome-B2U2lO1H.js.map +1 -0
  213. package/dist/core/web/public/next/assets/ResourcesDrawer-BCFJ2Uq8.css +1 -0
  214. package/dist/core/web/public/next/assets/ResourcesDrawer-DlUKOjl9.js +2 -0
  215. package/dist/core/web/public/next/assets/ResourcesDrawer-DlUKOjl9.js.map +1 -0
  216. package/dist/core/web/public/next/assets/RouteErrorBoundary-BaC7YVzR.js +2 -0
  217. package/dist/core/web/public/next/assets/{RouteErrorBoundary-DYtwc2ja.js.map → RouteErrorBoundary-BaC7YVzR.js.map} +1 -1
  218. package/dist/core/web/public/next/assets/RunInCloudAction-D5PDHJPE.js +2 -0
  219. package/dist/core/web/public/next/assets/{RunInCloudAction-BEGEEM8O.js.map → RunInCloudAction-D5PDHJPE.js.map} +1 -1
  220. package/dist/core/web/public/next/assets/SeatSelector-Cg75LInq.js +3 -0
  221. package/dist/core/web/public/next/assets/{SeatSelector-CYHRR7Wp.js.map → SeatSelector-Cg75LInq.js.map} +1 -1
  222. package/dist/core/web/public/next/assets/Segmented-CametjLt.js +2 -0
  223. package/dist/core/web/public/next/assets/{Segmented-BE53BenI.js.map → Segmented-CametjLt.js.map} +1 -1
  224. package/dist/core/web/public/next/assets/Select-De52fghU.js +2 -0
  225. package/dist/core/web/public/next/assets/{Select-BwSGkHCS.js.map → Select-De52fghU.js.map} +1 -1
  226. package/dist/core/web/public/next/assets/SessionGate-CzlcNq3O.js +2 -0
  227. package/dist/core/web/public/next/assets/{SessionGate-e0dFJm9d.js.map → SessionGate-CzlcNq3O.js.map} +1 -1
  228. package/dist/core/web/public/next/assets/SessionInsightChip-Bk_Owa7u.js +2 -0
  229. package/dist/core/web/public/next/assets/{SessionInsightChip-CxlSyueJ.js.map → SessionInsightChip-Bk_Owa7u.js.map} +1 -1
  230. package/dist/core/web/public/next/assets/SessionSearch-C6C8DHN8.js +2 -0
  231. package/dist/core/web/public/next/assets/{SessionSearch-_yp7S2TP.js.map → SessionSearch-C6C8DHN8.js.map} +1 -1
  232. package/dist/core/web/public/next/assets/SettingsSection-mI9wQYZg.js +2 -0
  233. package/dist/core/web/public/next/assets/SettingsSection-mI9wQYZg.js.map +1 -0
  234. package/dist/core/web/public/next/assets/Sheet-CJhK9Dqv.js +2 -0
  235. package/dist/core/web/public/next/assets/{Sheet-DVP2Mgy6.js.map → Sheet-CJhK9Dqv.js.map} +1 -1
  236. package/dist/core/web/public/next/assets/ShortcutsOverlay-DDW-i9Fc.js +2 -0
  237. package/dist/core/web/public/next/assets/{ShortcutsOverlay-BcIcoClX.js.map → ShortcutsOverlay-DDW-i9Fc.js.map} +1 -1
  238. package/dist/core/web/public/next/assets/Sidebar-DT7ykaqS.js +3 -0
  239. package/dist/core/web/public/next/assets/Sidebar-DT7ykaqS.js.map +1 -0
  240. package/dist/core/web/public/next/assets/Slider-Bwd9HfXl.js +2 -0
  241. package/dist/core/web/public/next/assets/{Slider-BypUWjpH.js.map → Slider-Bwd9HfXl.js.map} +1 -1
  242. package/dist/core/web/public/next/assets/StatTile-DPZ5yyaU.js +2 -0
  243. package/dist/core/web/public/next/assets/StatTile-DPZ5yyaU.js.map +1 -0
  244. package/dist/core/web/public/next/assets/{StatusBadge-HCZp416_.js → StatusBadge-DHKRtttH.js} +2 -2
  245. package/dist/core/web/public/next/assets/{StatusBadge-HCZp416_.js.map → StatusBadge-DHKRtttH.js.map} +1 -1
  246. package/dist/core/web/public/next/assets/StepBand-DQykLkk_.js +2 -0
  247. package/dist/core/web/public/next/assets/{StepBand-Duz1PUes.js.map → StepBand-DQykLkk_.js.map} +1 -1
  248. package/dist/core/web/public/next/assets/Surface-D--LXgQm.js +2 -0
  249. package/dist/core/web/public/next/assets/Surface-D--LXgQm.js.map +1 -0
  250. package/dist/core/web/public/next/assets/Surface-e1z6GdZt.css +1 -0
  251. package/dist/core/web/public/next/assets/Swimlane-BzH6OCee.js +2 -0
  252. package/dist/core/web/public/next/assets/{Swimlane-DGcIcnNA.js.map → Swimlane-BzH6OCee.js.map} +1 -1
  253. package/dist/core/web/public/next/assets/{Switch-iveI-8NY.js → Switch-PMixU6b0.js} +2 -2
  254. package/dist/core/web/public/next/assets/{Switch-iveI-8NY.js.map → Switch-PMixU6b0.js.map} +1 -1
  255. package/dist/core/web/public/next/assets/{Tag-DH15CUJp.js → Tag-fordBsrJ.js} +2 -2
  256. package/dist/core/web/public/next/assets/{Tag-DH15CUJp.js.map → Tag-fordBsrJ.js.map} +1 -1
  257. package/dist/core/web/public/next/assets/TerminalPane-BSnGdUuF.js +7 -0
  258. package/dist/core/web/public/next/assets/TerminalPane-BSnGdUuF.js.map +1 -0
  259. package/dist/core/web/public/next/assets/UniverseConsoleApp-DtXFhAhw.js +2 -0
  260. package/dist/core/web/public/next/assets/{UniverseConsoleApp-C8yQ0AaR.js.map → UniverseConsoleApp-DtXFhAhw.js.map} +1 -1
  261. package/dist/core/web/public/next/assets/{UniverseView-_nPURPqe.js → UniverseView-sWm3pnTW.js} +3 -3
  262. package/dist/core/web/public/next/assets/{UniverseView-_nPURPqe.js.map → UniverseView-sWm3pnTW.js.map} +1 -1
  263. package/dist/core/web/public/next/assets/UsageSection-CiD1DbuF.js +3 -0
  264. package/dist/core/web/public/next/assets/UsageSection-CiD1DbuF.js.map +1 -0
  265. package/dist/core/web/public/next/assets/VerseConsoleApp-BCY5uSok.js +3 -0
  266. package/dist/core/web/public/next/assets/VerseConsoleApp-BCY5uSok.js.map +1 -0
  267. package/dist/core/web/public/next/assets/Workspace-BQSZFSeO.js +10 -0
  268. package/dist/core/web/public/next/assets/Workspace-BQSZFSeO.js.map +1 -0
  269. package/dist/core/web/public/next/assets/actions-BmIf9avl.css +1 -0
  270. package/dist/core/web/public/next/assets/actions-Ci6I4C0l.js +2 -0
  271. package/dist/core/web/public/next/assets/actions-Ci6I4C0l.js.map +1 -0
  272. package/dist/core/web/public/next/assets/apps-model-DlwnfqwJ.js +2 -0
  273. package/dist/core/web/public/next/assets/apps-model-DlwnfqwJ.js.map +1 -0
  274. package/dist/core/web/public/next/assets/authority-model-BFuPezSo.js +2 -0
  275. package/dist/core/web/public/next/assets/authority-model-BFuPezSo.js.map +1 -0
  276. package/dist/core/web/public/next/assets/binding-left-DZpq5sLf.js +2 -0
  277. package/dist/core/web/public/next/assets/binding-left-DZpq5sLf.js.map +1 -0
  278. package/dist/core/web/public/next/assets/{budget-queries-V3wcJVK_.js → budget-queries-DsAjH8ac.js} +2 -2
  279. package/dist/core/web/public/next/assets/{budget-queries-V3wcJVK_.js.map → budget-queries-DsAjH8ac.js.map} +1 -1
  280. package/dist/core/web/public/next/assets/capacity-strip-model-Dn1cNOhz.js +2 -0
  281. package/dist/core/web/public/next/assets/capacity-strip-model-Dn1cNOhz.js.map +1 -0
  282. package/dist/core/web/public/next/assets/charts-C_xJbJiw.js +2 -0
  283. package/dist/core/web/public/next/assets/charts-C_xJbJiw.js.map +1 -0
  284. package/dist/core/web/public/next/assets/charts-DhKTrQLw.css +1 -0
  285. package/dist/core/web/public/next/assets/clipboard-DkZdqlxf.js +2 -0
  286. package/dist/core/web/public/next/assets/clipboard-DkZdqlxf.js.map +1 -0
  287. package/dist/core/web/public/next/assets/cloud-D-HXms6q.css +1 -0
  288. package/dist/core/web/public/next/assets/cloud-model-CX407gPY.js +2 -0
  289. package/dist/core/web/public/next/assets/cloud-model-CX407gPY.js.map +1 -0
  290. package/dist/core/web/public/next/assets/cloud-queries-QAhpExlz.js +2 -0
  291. package/dist/core/web/public/next/assets/cloud-queries-QAhpExlz.js.map +1 -0
  292. package/dist/core/web/public/next/assets/cloud.module-DOP-N4Ch.js +2 -0
  293. package/dist/core/web/public/next/assets/cloud.module-DOP-N4Ch.js.map +1 -0
  294. package/dist/core/web/public/next/assets/command-catalog-CF0cQQac.js +2 -0
  295. package/dist/core/web/public/next/assets/command-catalog-CF0cQQac.js.map +1 -0
  296. package/dist/core/web/public/next/assets/context-model-Co4wh3SM.js +2 -0
  297. package/dist/core/web/public/next/assets/context-model-Co4wh3SM.js.map +1 -0
  298. package/dist/core/web/public/next/assets/context-model-DV1zCfAm.js +3 -0
  299. package/dist/core/web/public/next/assets/context-model-DV1zCfAm.js.map +1 -0
  300. package/dist/core/web/public/next/assets/{context-queries-CrPcHWTz.js → context-queries-CktFQqSS.js} +2 -2
  301. package/dist/core/web/public/next/assets/{context-queries-CrPcHWTz.js.map → context-queries-CktFQqSS.js.map} +1 -1
  302. package/dist/core/web/public/next/assets/{control-queries-CmgBgKV7.js → control-queries-DAvlh_YM.js} +2 -2
  303. package/dist/core/web/public/next/assets/{control-queries-CmgBgKV7.js.map → control-queries-DAvlh_YM.js.map} +1 -1
  304. package/dist/core/web/public/next/assets/copy-setup-CqRSfELB.js +2 -0
  305. package/dist/core/web/public/next/assets/copy-setup-CqRSfELB.js.map +1 -0
  306. package/dist/core/web/public/next/assets/dock-icons-BFuBbqJl.js +2 -0
  307. package/dist/core/web/public/next/assets/{dock-icons-CUh8dOxJ.js.map → dock-icons-BFuBbqJl.js.map} +1 -1
  308. package/dist/core/web/public/next/assets/fleet-model-Dfd5JyLR.js +2 -0
  309. package/dist/core/web/public/next/assets/fleet-model-Dfd5JyLR.js.map +1 -0
  310. package/dist/core/web/public/next/assets/fleet-queries-RtMTd5rR.js +2 -0
  311. package/dist/core/web/public/next/assets/fleet-queries-RtMTd5rR.js.map +1 -0
  312. package/dist/core/web/public/next/assets/{focus-trap-HtcoXeEq.js → focus-trap-BdrbWfC4.js} +2 -2
  313. package/dist/core/web/public/next/assets/{focus-trap-HtcoXeEq.js.map → focus-trap-BdrbWfC4.js.map} +1 -1
  314. package/dist/core/web/public/next/assets/format-Dk4Fmxax.js +2 -0
  315. package/dist/core/web/public/next/assets/format-Dk4Fmxax.js.map +1 -0
  316. package/dist/core/web/public/next/assets/{git-model-bk_RXh3y.js → git-model-_BnI_Ogh.js} +2 -2
  317. package/dist/core/web/public/next/assets/{git-model-bk_RXh3y.js.map → git-model-_BnI_Ogh.js.map} +1 -1
  318. package/dist/core/web/public/next/assets/global-CNNGMril.js +2 -0
  319. package/dist/core/web/public/next/assets/{global-oEl9Qj8u.js.map → global-CNNGMril.js.map} +1 -1
  320. package/dist/core/web/public/next/assets/{guarded-runners-LHLXmXIk.js → guarded-runners-DPh2d32e.js} +2 -2
  321. package/dist/core/web/public/next/assets/{guarded-runners-LHLXmXIk.js.map → guarded-runners-DPh2d32e.js.map} +1 -1
  322. package/dist/core/web/public/next/assets/icons-0haWy6nh.js +2 -0
  323. package/dist/core/web/public/next/assets/icons-0haWy6nh.js.map +1 -0
  324. package/dist/core/web/public/next/assets/{index-BVxOlseC.js → index-QesfXBsb.js} +3 -3
  325. package/dist/core/web/public/next/assets/{index-BVxOlseC.js.map → index-QesfXBsb.js.map} +1 -1
  326. package/dist/core/web/public/next/assets/live-model-De-q0ZFK.js +2 -0
  327. package/dist/core/web/public/next/assets/live-model-De-q0ZFK.js.map +1 -0
  328. package/dist/core/web/public/next/assets/local-model-C9xNi9fN.js +2 -0
  329. package/dist/core/web/public/next/assets/local-model-C9xNi9fN.js.map +1 -0
  330. package/dist/core/web/public/next/assets/mind.module-BrK2nFOL.js +2 -0
  331. package/dist/core/web/public/next/assets/{mind.module-gTGAuJt1.js.map → mind.module-BrK2nFOL.js.map} +1 -1
  332. package/dist/core/web/public/next/assets/mutations-DTCtKCn_.js +2 -0
  333. package/dist/core/web/public/next/assets/{mutations-C5S7okTW.js.map → mutations-DTCtKCn_.js.map} +1 -1
  334. package/dist/core/web/public/next/assets/nav-KmGX0CVz.js +2 -0
  335. package/dist/core/web/public/next/assets/{nav-NVtnuG7A.js.map → nav-KmGX0CVz.js.map} +1 -1
  336. package/dist/core/web/public/next/assets/{overnight-queries-DGm3qL1b.js → overnight-queries-mlO0xzsr.js} +2 -2
  337. package/dist/core/web/public/next/assets/{overnight-queries-DGm3qL1b.js.map → overnight-queries-mlO0xzsr.js.map} +1 -1
  338. package/dist/core/web/public/next/assets/primitives-D0Fb3TtS.js +1 -0
  339. package/dist/core/web/public/next/assets/{queries-CYisSAAB.js → queries-CyBE8nsW.js} +2 -2
  340. package/dist/core/web/public/next/assets/{queries-CYisSAAB.js.map → queries-CyBE8nsW.js.map} +1 -1
  341. package/dist/core/web/public/next/assets/reasoning-pref-CaoA4_Vl.js +2 -0
  342. package/dist/core/web/public/next/assets/{reasoning-pref-BUcFF_5G.js.map → reasoning-pref-CaoA4_Vl.js.map} +1 -1
  343. package/dist/core/web/public/next/assets/{reveal-anchor-D-tV8xau.js → reveal-anchor-BP1VqnPU.js} +2 -2
  344. package/dist/core/web/public/next/assets/{reveal-anchor-D-tV8xau.js.map → reveal-anchor-BP1VqnPU.js.map} +1 -1
  345. package/dist/core/web/public/next/assets/seat-subscription-C5Tvr0WQ.js +2 -0
  346. package/dist/core/web/public/next/assets/{seat-subscription-B-f9ViU2.js.map → seat-subscription-C5Tvr0WQ.js.map} +1 -1
  347. package/dist/core/web/public/next/assets/{sidebar-model-DQ-FyBHW.js → sidebar-model-B5Qk95k_.js} +2 -2
  348. package/dist/core/web/public/next/assets/{sidebar-model-DQ-FyBHW.js.map → sidebar-model-B5Qk95k_.js.map} +1 -1
  349. package/dist/core/web/public/next/assets/slots-DHKQDoE6.js +3 -0
  350. package/dist/core/web/public/next/assets/{slots-BhP8b8tf.js.map → slots-DHKQDoE6.js.map} +1 -1
  351. package/dist/core/web/public/next/assets/surface-data-CchClvHo.js +2 -0
  352. package/dist/core/web/public/next/assets/surface-data-CchClvHo.js.map +1 -0
  353. package/dist/core/web/public/next/assets/surface-prefetch-BWr0LBQn.js +2 -0
  354. package/dist/core/web/public/next/assets/surface-prefetch-BWr0LBQn.js.map +1 -0
  355. package/dist/core/web/public/next/assets/{tasks-model-BKDNqmmt.js → tasks-model-D6WFVULI.js} +2 -2
  356. package/dist/core/web/public/next/assets/{tasks-model-BKDNqmmt.js.map → tasks-model-D6WFVULI.js.map} +1 -1
  357. package/dist/core/web/public/next/assets/{terminal-icons-D2xe-aM1.js → terminal-icons-BvCvuXk2.js} +2 -2
  358. package/dist/core/web/public/next/assets/{terminal-icons-D2xe-aM1.js.map → terminal-icons-BvCvuXk2.js.map} +1 -1
  359. package/dist/core/web/public/next/assets/transient-events-nTLhMBND.js +2 -0
  360. package/dist/core/web/public/next/assets/transient-events-nTLhMBND.js.map +1 -0
  361. package/dist/core/web/public/next/assets/types-D5XOdyw8.js.map +1 -1
  362. package/dist/core/web/public/next/assets/{usage-queries-BZuAANlI.js → usage-queries-D1SU1t7r.js} +2 -2
  363. package/dist/core/web/public/next/assets/{usage-queries-BZuAANlI.js.map → usage-queries-D1SU1t7r.js.map} +1 -1
  364. package/dist/core/web/public/next/assets/{use-guarded-action-Cf4MeNBa.js → use-guarded-action-BZmBv7CJ.js} +2 -2
  365. package/dist/core/web/public/next/assets/{use-guarded-action-Cf4MeNBa.js.map → use-guarded-action-BZmBv7CJ.js.map} +1 -1
  366. package/dist/core/web/public/next/assets/{use-ticker-D9yi49my.js → use-ticker-CkJ4-0wU.js} +2 -2
  367. package/dist/core/web/public/next/assets/{use-ticker-D9yi49my.js.map → use-ticker-CkJ4-0wU.js.map} +1 -1
  368. package/dist/core/web/public/next/assets/{use-token-gate-DqrSXdX6.js → use-token-gate-CYcfk_GS.js} +2 -2
  369. package/dist/core/web/public/next/assets/{use-token-gate-DqrSXdX6.js.map → use-token-gate-CYcfk_GS.js.map} +1 -1
  370. package/dist/core/web/public/next/assets/useOnboarding-CujRS6PK.js +2 -0
  371. package/dist/core/web/public/next/assets/useOnboarding-CujRS6PK.js.map +1 -0
  372. package/dist/core/web/public/next/assets/useSeatsRefresh-BEaQdkZs.js +2 -0
  373. package/dist/core/web/public/next/assets/useSeatsRefresh-BEaQdkZs.js.map +1 -0
  374. package/dist/core/web/public/next/assets/useVerseTranscript-BQ0J6Xhx.js +2 -0
  375. package/dist/core/web/public/next/assets/{useVerseTranscript-CDYrrWOO.js.map → useVerseTranscript-BQ0J6Xhx.js.map} +1 -1
  376. package/dist/core/web/public/next/assets/verse-icons-DndgEgKS.js +2 -0
  377. package/dist/core/web/public/next/assets/verse-icons-DndgEgKS.js.map +1 -0
  378. package/dist/core/web/public/next/assets/verse-model-MMySehjj.js +2 -0
  379. package/dist/core/web/public/next/assets/verse-model-MMySehjj.js.map +1 -0
  380. package/dist/core/web/public/next/assets/verse-store-DNVRuiJL.js +2 -0
  381. package/dist/core/web/public/next/assets/verse-store-DNVRuiJL.js.map +1 -0
  382. package/dist/core/web/public/next/assets/warmup-CNEH_-be.js +3 -0
  383. package/dist/core/web/public/next/assets/{warmup-HG5vYbsN.js.map → warmup-CNEH_-be.js.map} +1 -1
  384. package/dist/core/web/public/next/assets/why-seat-model-jlDTwYSc.js +2 -0
  385. package/dist/core/web/public/next/assets/why-seat-model-jlDTwYSc.js.map +1 -0
  386. package/dist/core/web/public/next/assets/{workspace-model-CbhdPhei.js → workspace-model-Dukb2wwv.js} +2 -2
  387. package/dist/core/web/public/next/assets/{workspace-model-CbhdPhei.js.map → workspace-model-Dukb2wwv.js.map} +1 -1
  388. package/dist/core/web/public/next/index.html +1 -1
  389. package/dist/release-dependency-inventory.json +1 -1
  390. package/docs/README.md +2 -1
  391. package/package.json +1 -1
  392. package/dist/core/web/public/next/assets/ActionMenu-FxXeRbPx.js +0 -2
  393. package/dist/core/web/public/next/assets/Advanced-D_eS4472.js +0 -2
  394. package/dist/core/web/public/next/assets/Advanced-D_eS4472.js.map +0 -1
  395. package/dist/core/web/public/next/assets/App-Cj4zKbG3.js +0 -7
  396. package/dist/core/web/public/next/assets/App-Cj4zKbG3.js.map +0 -1
  397. package/dist/core/web/public/next/assets/AppsSection-Ddu_RCQE.js +0 -2
  398. package/dist/core/web/public/next/assets/AppsSection-Ddu_RCQE.js.map +0 -1
  399. package/dist/core/web/public/next/assets/AreaTrend-CDxrQU4b.js +0 -2
  400. package/dist/core/web/public/next/assets/AutonomySection-DuQkHGD_.js +0 -2
  401. package/dist/core/web/public/next/assets/BranchBar-CLsvOcyK.js +0 -2
  402. package/dist/core/web/public/next/assets/BudgetControl-TL3FeZ1D.js +0 -2
  403. package/dist/core/web/public/next/assets/BurnDown-sFXkUGdB.js +0 -2
  404. package/dist/core/web/public/next/assets/BurnDown-sFXkUGdB.js.map +0 -1
  405. package/dist/core/web/public/next/assets/CapacityStrip-qReu0RaF.js +0 -2
  406. package/dist/core/web/public/next/assets/ChatSection-DZuZfTaC.js +0 -3
  407. package/dist/core/web/public/next/assets/ChatSection-DZuZfTaC.js.map +0 -1
  408. package/dist/core/web/public/next/assets/CloudBudgetForm-DJbiT1wi.js +0 -2
  409. package/dist/core/web/public/next/assets/CloudBudgetForm-DJbiT1wi.js.map +0 -1
  410. package/dist/core/web/public/next/assets/CommandPalette-zYLFZRnj.js +0 -2
  411. package/dist/core/web/public/next/assets/CommandPalette-zYLFZRnj.js.map +0 -1
  412. package/dist/core/web/public/next/assets/CommandSection-rIeMK5Ch.js +0 -2
  413. package/dist/core/web/public/next/assets/CommandSection-rIeMK5Ch.js.map +0 -1
  414. package/dist/core/web/public/next/assets/ConfirmDialog-DLrLKM0c.js +0 -2
  415. package/dist/core/web/public/next/assets/Dialog-BS9Dxi3G.js +0 -2
  416. package/dist/core/web/public/next/assets/DiffPane-TOmUf3b2.js +0 -2
  417. package/dist/core/web/public/next/assets/DiffViewer-BpH56302.js +0 -2
  418. package/dist/core/web/public/next/assets/DockHost-DzkzR-HD.js +0 -2
  419. package/dist/core/web/public/next/assets/DockHost-DzkzR-HD.js.map +0 -1
  420. package/dist/core/web/public/next/assets/FleetSection-ViAb549H.js +0 -3
  421. package/dist/core/web/public/next/assets/FleetSection-ViAb549H.js.map +0 -1
  422. package/dist/core/web/public/next/assets/Funnel-D2u7Wlzc.js +0 -2
  423. package/dist/core/web/public/next/assets/GearTray-Cb2npoxM.js +0 -2
  424. package/dist/core/web/public/next/assets/GrowthSection-C5aDPs8B.js +0 -2
  425. package/dist/core/web/public/next/assets/HandoffDialog-BF3AYg-X.js +0 -2
  426. package/dist/core/web/public/next/assets/Input-B5dmGLZx.js +0 -2
  427. package/dist/core/web/public/next/assets/LeaderCard-DZrmjDbI.js +0 -2
  428. package/dist/core/web/public/next/assets/LeaderCard-DZrmjDbI.js.map +0 -1
  429. package/dist/core/web/public/next/assets/MatrixHeatmap-BgEUs2Eu.js +0 -2
  430. package/dist/core/web/public/next/assets/McpSection-DZkiOuoq.js +0 -2
  431. package/dist/core/web/public/next/assets/MessageMarkdown-BauY8ZTY.js +0 -3
  432. package/dist/core/web/public/next/assets/MindSection-BvJXFjyX.js +0 -2
  433. package/dist/core/web/public/next/assets/MindSection-BvJXFjyX.js.map +0 -1
  434. package/dist/core/web/public/next/assets/MutationTokenDialog-mxrw0Yvy.js +0 -2
  435. package/dist/core/web/public/next/assets/NeedsYouDrawer-CO-Balfp.js +0 -2
  436. package/dist/core/web/public/next/assets/NeedsYouList-CzDZbzRD.js +0 -2
  437. package/dist/core/web/public/next/assets/NewChatDialog-B8eJjlFf.js +0 -3
  438. package/dist/core/web/public/next/assets/NewChatDialog-B8eJjlFf.js.map +0 -1
  439. package/dist/core/web/public/next/assets/OnboardingFlow-Cij6KWat.js +0 -2
  440. package/dist/core/web/public/next/assets/OnboardingFlow-Cij6KWat.js.map +0 -1
  441. package/dist/core/web/public/next/assets/OnboardingFlow-DSpPj8UE.css +0 -1
  442. package/dist/core/web/public/next/assets/PreviewPane-BS-CleCd.js +0 -2
  443. package/dist/core/web/public/next/assets/RailStatus-cPRyOmrk.js +0 -2
  444. package/dist/core/web/public/next/assets/ResourcesChrome-BJCauW_t.js +0 -3
  445. package/dist/core/web/public/next/assets/ResourcesChrome-BJCauW_t.js.map +0 -1
  446. package/dist/core/web/public/next/assets/ResourcesDrawer-BDecg6nO.js +0 -2
  447. package/dist/core/web/public/next/assets/ResourcesDrawer-BDecg6nO.js.map +0 -1
  448. package/dist/core/web/public/next/assets/ResourcesDrawer-CSKIO_wZ.css +0 -1
  449. package/dist/core/web/public/next/assets/RouteErrorBoundary-DYtwc2ja.js +0 -2
  450. package/dist/core/web/public/next/assets/RunInCloudAction-BEGEEM8O.js +0 -2
  451. package/dist/core/web/public/next/assets/SeatSelector-CYHRR7Wp.js +0 -3
  452. package/dist/core/web/public/next/assets/Segmented-BE53BenI.js +0 -2
  453. package/dist/core/web/public/next/assets/Select-BwSGkHCS.js +0 -2
  454. package/dist/core/web/public/next/assets/SessionGate-e0dFJm9d.js +0 -2
  455. package/dist/core/web/public/next/assets/SessionInsightChip-CxlSyueJ.js +0 -2
  456. package/dist/core/web/public/next/assets/SessionSearch-_yp7S2TP.js +0 -2
  457. package/dist/core/web/public/next/assets/SettingsSection-wGnpWeGW.js +0 -2
  458. package/dist/core/web/public/next/assets/SettingsSection-wGnpWeGW.js.map +0 -1
  459. package/dist/core/web/public/next/assets/Sheet-DVP2Mgy6.js +0 -2
  460. package/dist/core/web/public/next/assets/ShortcutsOverlay-BcIcoClX.js +0 -2
  461. package/dist/core/web/public/next/assets/Sidebar-DjQOqPbm.js +0 -3
  462. package/dist/core/web/public/next/assets/Sidebar-DjQOqPbm.js.map +0 -1
  463. package/dist/core/web/public/next/assets/Slider-BypUWjpH.js +0 -2
  464. package/dist/core/web/public/next/assets/StepBand-Duz1PUes.js +0 -2
  465. package/dist/core/web/public/next/assets/Surface-B75lVfzm.js +0 -2
  466. package/dist/core/web/public/next/assets/Surface-B75lVfzm.js.map +0 -1
  467. package/dist/core/web/public/next/assets/Surface-DMca0gAe.css +0 -1
  468. package/dist/core/web/public/next/assets/Swimlane-DGcIcnNA.js +0 -2
  469. package/dist/core/web/public/next/assets/TerminalPane-MQT-veKZ.js +0 -7
  470. package/dist/core/web/public/next/assets/TerminalPane-MQT-veKZ.js.map +0 -1
  471. package/dist/core/web/public/next/assets/UniverseConsoleApp-C8yQ0AaR.js +0 -2
  472. package/dist/core/web/public/next/assets/UsageSection-CqxRGJ40.js +0 -2
  473. package/dist/core/web/public/next/assets/UsageSection-CqxRGJ40.js.map +0 -1
  474. package/dist/core/web/public/next/assets/VerseConsoleApp-DTjDpGCd.js +0 -3
  475. package/dist/core/web/public/next/assets/VerseConsoleApp-DTjDpGCd.js.map +0 -1
  476. package/dist/core/web/public/next/assets/Workspace-DfcFGzME.js +0 -10
  477. package/dist/core/web/public/next/assets/Workspace-DfcFGzME.js.map +0 -1
  478. package/dist/core/web/public/next/assets/actions-Ddfg2iLl.css +0 -1
  479. package/dist/core/web/public/next/assets/actions-tWevL9HV.js +0 -2
  480. package/dist/core/web/public/next/assets/actions-tWevL9HV.js.map +0 -1
  481. package/dist/core/web/public/next/assets/apps-model-CDFvmsQV.js +0 -2
  482. package/dist/core/web/public/next/assets/apps-model-CDFvmsQV.js.map +0 -1
  483. package/dist/core/web/public/next/assets/capacity-strip-model-BDbmQ3e3.js +0 -2
  484. package/dist/core/web/public/next/assets/capacity-strip-model-BDbmQ3e3.js.map +0 -1
  485. package/dist/core/web/public/next/assets/charts-CfAjuKMv.js +0 -2
  486. package/dist/core/web/public/next/assets/charts-CfAjuKMv.js.map +0 -1
  487. package/dist/core/web/public/next/assets/charts-uSX6xVYN.css +0 -1
  488. package/dist/core/web/public/next/assets/cloud-C1KPNRHC.css +0 -1
  489. package/dist/core/web/public/next/assets/cloud-queries-Br_r0UAz.js +0 -2
  490. package/dist/core/web/public/next/assets/cloud-queries-Br_r0UAz.js.map +0 -1
  491. package/dist/core/web/public/next/assets/cloud.module-ascz58c3.js +0 -2
  492. package/dist/core/web/public/next/assets/cloud.module-ascz58c3.js.map +0 -1
  493. package/dist/core/web/public/next/assets/command-bus-xYZoK9nQ.js +0 -2
  494. package/dist/core/web/public/next/assets/command-bus-xYZoK9nQ.js.map +0 -1
  495. package/dist/core/web/public/next/assets/command-catalog-Bb_PxC5w.js +0 -2
  496. package/dist/core/web/public/next/assets/command-catalog-Bb_PxC5w.js.map +0 -1
  497. package/dist/core/web/public/next/assets/composer-keys-su0g1h9o.js +0 -2
  498. package/dist/core/web/public/next/assets/composer-keys-su0g1h9o.js.map +0 -1
  499. package/dist/core/web/public/next/assets/context-model-BC-HOmPo.js +0 -2
  500. package/dist/core/web/public/next/assets/context-model-BC-HOmPo.js.map +0 -1
  501. package/dist/core/web/public/next/assets/context-model-CIBmSugV.js +0 -2
  502. package/dist/core/web/public/next/assets/context-model-CIBmSugV.js.map +0 -1
  503. package/dist/core/web/public/next/assets/dark-since-DOMvtB_G.js +0 -2
  504. package/dist/core/web/public/next/assets/dark-since-DOMvtB_G.js.map +0 -1
  505. package/dist/core/web/public/next/assets/dock-icons-CUh8dOxJ.js +0 -2
  506. package/dist/core/web/public/next/assets/dock-store-B2vlxqPu.js +0 -2
  507. package/dist/core/web/public/next/assets/dock-store-B2vlxqPu.js.map +0 -1
  508. package/dist/core/web/public/next/assets/fleet-model-7i-FbzKI.js +0 -2
  509. package/dist/core/web/public/next/assets/fleet-model-7i-FbzKI.js.map +0 -1
  510. package/dist/core/web/public/next/assets/fleet-queries-DzGoqq8X.js +0 -2
  511. package/dist/core/web/public/next/assets/fleet-queries-DzGoqq8X.js.map +0 -1
  512. package/dist/core/web/public/next/assets/format-BkWdOQDL.js +0 -2
  513. package/dist/core/web/public/next/assets/format-BkWdOQDL.js.map +0 -1
  514. package/dist/core/web/public/next/assets/global-oEl9Qj8u.js +0 -2
  515. package/dist/core/web/public/next/assets/guarded-action-OzqcPjmh.js +0 -3
  516. package/dist/core/web/public/next/assets/guarded-action-OzqcPjmh.js.map +0 -1
  517. package/dist/core/web/public/next/assets/icon-base-DvM1eI5V.js +0 -2
  518. package/dist/core/web/public/next/assets/icon-base-DvM1eI5V.js.map +0 -1
  519. package/dist/core/web/public/next/assets/icons-DEQa2rTx.js +0 -2
  520. package/dist/core/web/public/next/assets/icons-DEQa2rTx.js.map +0 -1
  521. package/dist/core/web/public/next/assets/live-model-bmsJgnYD.js +0 -2
  522. package/dist/core/web/public/next/assets/live-model-bmsJgnYD.js.map +0 -1
  523. package/dist/core/web/public/next/assets/local-model-DFyjKX0b.js +0 -2
  524. package/dist/core/web/public/next/assets/local-model-DFyjKX0b.js.map +0 -1
  525. package/dist/core/web/public/next/assets/mind.module-gTGAuJt1.js +0 -2
  526. package/dist/core/web/public/next/assets/mutations-C5S7okTW.js +0 -2
  527. package/dist/core/web/public/next/assets/nav-NVtnuG7A.js +0 -2
  528. package/dist/core/web/public/next/assets/preloaded-Cwf9rsnZ.js +0 -2
  529. package/dist/core/web/public/next/assets/preloaded-Cwf9rsnZ.js.map +0 -1
  530. package/dist/core/web/public/next/assets/primitives-DyCKYSBG.js +0 -1
  531. package/dist/core/web/public/next/assets/reasoning-pref-BUcFF_5G.js +0 -2
  532. package/dist/core/web/public/next/assets/seat-subscription-B-f9ViU2.js +0 -2
  533. package/dist/core/web/public/next/assets/section-visibility-Yctxu-if.js +0 -2
  534. package/dist/core/web/public/next/assets/section-visibility-Yctxu-if.js.map +0 -1
  535. package/dist/core/web/public/next/assets/slots-BhP8b8tf.js +0 -3
  536. package/dist/core/web/public/next/assets/surface-data-DTI7LjvH.js +0 -2
  537. package/dist/core/web/public/next/assets/surface-data-DTI7LjvH.js.map +0 -1
  538. package/dist/core/web/public/next/assets/surface-prefetch-CdUEBFrl.js +0 -2
  539. package/dist/core/web/public/next/assets/surface-prefetch-CdUEBFrl.js.map +0 -1
  540. package/dist/core/web/public/next/assets/useChartWidth-owwodNVz.js +0 -2
  541. package/dist/core/web/public/next/assets/useChartWidth-owwodNVz.js.map +0 -1
  542. package/dist/core/web/public/next/assets/useSeatsRefresh-DgFy-Ph4.js +0 -2
  543. package/dist/core/web/public/next/assets/useSeatsRefresh-DgFy-Ph4.js.map +0 -1
  544. package/dist/core/web/public/next/assets/useVerseTranscript-CDYrrWOO.js +0 -2
  545. package/dist/core/web/public/next/assets/verse-icons-F9VwX07_.js +0 -2
  546. package/dist/core/web/public/next/assets/verse-icons-F9VwX07_.js.map +0 -1
  547. package/dist/core/web/public/next/assets/verse-model-DyCwZF-M.js +0 -2
  548. package/dist/core/web/public/next/assets/verse-model-DyCwZF-M.js.map +0 -1
  549. package/dist/core/web/public/next/assets/verse-store-b_Lek_c5.js +0 -3
  550. package/dist/core/web/public/next/assets/verse-store-b_Lek_c5.js.map +0 -1
  551. package/dist/core/web/public/next/assets/verse-ui-store-62DxpVHS.js +0 -3
  552. package/dist/core/web/public/next/assets/verse-ui-store-62DxpVHS.js.map +0 -1
  553. package/dist/core/web/public/next/assets/viewport-nTubFCwf.js +0 -2
  554. package/dist/core/web/public/next/assets/viewport-nTubFCwf.js.map +0 -1
  555. package/dist/core/web/public/next/assets/warmup-HG5vYbsN.js +0 -3
  556. package/dist/core/web/public/next/assets/workbench-types-DzN-5trg.js +0 -2
  557. package/dist/core/web/public/next/assets/workbench-types-DzN-5trg.js.map +0 -1
  558. /package/dist/core/web/public/next/assets/{BurnDown-BuLMsJMx.css → StatTile-BuLMsJMx.css} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"file":"UsageSection-CqxRGJ40.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/usage/usage-model.ts","../../../../../../src/web-ui/routes/verse/usage/usage.module.css","../../../../../../src/web-ui/routes/verse/usage/WindowMeter.tsx","../../../../../../src/web-ui/routes/verse/usage/AccountCard.tsx","../../../../../../src/web-ui/routes/verse/usage/AccountDetail.tsx","../../../../../../src/web-ui/routes/verse/usage/CapacityFacts.tsx","../../../../../../src/web-ui/routes/verse/usage/EfficiencyPanel.tsx","../../../../../../src/web-ui/routes/verse/usage/LimitsPanel.tsx","../../../../../../src/web-ui/routes/verse/usage/series-model.ts","../../../../../../src/web-ui/routes/verse/usage/LocalCloudPanel.tsx","../../../../../../src/web-ui/routes/verse/usage/LocalModelsPanel.tsx","../../../../../../src/web-ui/routes/verse/usage/SeriesPanel.tsx","../../../../../../src/web-ui/routes/verse/usage/SpendPanel.tsx","../../../../../../src/web-ui/routes/verse/cloud/CloudCreditsPanel.tsx","../../../../../../src/web-ui/routes/verse/usage/accounts-model.ts","../../../../../../src/web-ui/routes/verse/sections/UsageSection.tsx"],"sourcesContent":["/**\n * routes/verse/usage/usage-model.ts — the honesty layer of the Usage section.\n *\n * Every number this section renders passes through here first, because the\n * hard problem of this surface is NOT drawing meters: it is knowing which\n * numbers are real. `GET /api/usage` collapses three different provenances\n * into one identical-looking `subscriptionWindow` shape (see\n * src/core/usage/frontier-usage.ts `buildEngineUsage`):\n *\n * 1. a REAL subscription-tracker reading (codex, parsed from its session\n * files) — `subWindow !== null`;\n * 2. a figure DERIVED from the dispatch ledger vs. a configured foundry\n * cap — taken only when `limitMax !== undefined && limitMax > 0`;\n * 3. genuinely nothing — `state: 'unknown', usedPct: 0`.\n *\n * (2) is the trap. For Claude — which has no local utilization signal at all\n * (`subscriptionUsage('claude')` returns null by design, and Ashlr never\n * proactively throttles it) — a configured cap makes `/api/usage` hand back\n * something like `{state:'active', usedPct: 35, windowLabel:'1d'}`. Rendered\n * as a window meter that reads \"Claude 35% of window used\", which is false.\n * And (3)'s `usedPct: 0` rendered as a bar reads \"0% used — plenty left\",\n * which is equally false.\n *\n * So this module establishes provenance before anything is called measured:\n *\n * - `ControlSnapshot.subscriptionUsage` is provenance-bearing: an entry\n * exists for codex only when `readCodexRateLimits()` actually succeeded,\n * and `hasData` is literally `windows.length > 0`. Claude's entry is\n * hard-coded `{windows: [], hasData: false}`. Grok has no entry at all.\n * A `hasData` entry is therefore proof of a real reading.\n * - `VerseSeat.health.windows` come from observations.json and are\n * PER-ACCOUNT, which is finer-grained than anything else available; a\n * non-null `usedPercent` there is a real observation.\n * - Failing both, a `/api/usage` entry can still be proven real by\n * elimination: branch (2) is unreachable without a configured limit, so\n * `state !== 'unknown' && limit === undefined` can ONLY have come from\n * the subscription tracker.\n * - Everything else is unknown, and says why in one line.\n *\n * Nothing here ever converts an unknown into 0, and nothing derived from the\n * dispatch ledger is ever presented as subscription utilization — that data\n * is real, but it belongs under \"Dispatch limits\", where it is labeled as\n * calls against a configured cap.\n *\n * Scope note: this module owns PROVENANCE (what may be called measured) and\n * the accounting projections (local/cloud split, dispatch limits, the daemon\n * tick spend series, the configured-caps narrowing). The account CARD model —\n * binding constraint, verdict, credits — lives in `accounts-model.ts`, which\n * calls `resolveWindowSignal` here for the fallback path rather than\n * re-deriving provenance a second time.\n *\n * Pure: no React, no I/O, no formatting of currency/percent (the chart\n * layer's `chartFormat` owns that).\n */\nimport type { ControlSnapshot, SourceQuality, VerseEngine, VerseSeat } from '../../../data/api-types.js';\nimport type { FrontierEngineUsage } from '../../../../core/usage/frontier-usage.js';\nimport { localDateKey } from '../autonomy/format.js';\nimport { calendarDayStart } from '../growth/calendar-day.js';\n\ntype SubscriptionEngineUsage = ControlSnapshot['subscriptionUsage'][number];\ntype ControlLimit = ControlSnapshot['limits'][number];\ntype ControlUsage = ControlSnapshot['usage'];\ntype DaemonObservation = ControlSnapshot['daemonObservation'];\n\n// ---------------------------------------------------------------------------\n// Engine identity\n// ---------------------------------------------------------------------------\n\n/**\n * One hue per provider (docs/VERSE-DESIGN-V2.md §2 \"Engine identity\"). Used\n * ONLY for the 2px seat marker and the window bar, never for text. Written\n * with a literal fallback so the section is correct before owner A lands the\n * tokens in design/tokens.css.\n */\nexport const ENGINE_COLOR: Record<VerseEngine, string> = {\n claude: 'var(--engine-claude, #c96442)',\n codex: 'var(--engine-codex, #10a37f)',\n grok: 'var(--engine-grok, #6b7280)',\n local: 'var(--engine-local, #7c5cff)',\n};\n\n// ---------------------------------------------------------------------------\n// Window signals\n// ---------------------------------------------------------------------------\n\n/** Exact copy for every \"we do not know\" case, exported so tests pin it. */\nexport const NO_SIGNAL_REASON: Partial<Record<VerseEngine, string>> = {\n claude:\n 'Claude publishes no local utilization signal, so there is no window percentage to read. Ashlr deliberately never throttles this seat on a guess.',\n // Grok is absent from frontier-usage.ts entirely, so /api/usage can never\n // carry it. Its real state comes from the per-account probe behind\n // /api/verse/accounts; this copy is only ever seen on the fallback roster.\n grok: 'Grok is absent from the per-engine usage snapshot, so this fallback roster has no window data for it. Its real state comes from the per-account probe.',\n};\n\nexport const AMBIGUOUS_REASON =\n 'The only figure available is derived from the dispatch ledger against a configured cap, not from the subscription itself. It is shown under Dispatch limits.';\n\nexport const GENERIC_NO_SIGNAL = 'No subscription window reading is reported for this engine.';\n\nexport const LOCAL_NOT_APPLICABLE =\n 'Local models have no subscription and no quota window — only whether the runtime is up.';\n\nexport type WindowTone = 'ok' | 'warn' | 'danger';\n\n/** Provenance of a measured window, shown to the operator as a source line. */\nexport type WindowSource = 'account-observation' | 'subscription-tracker';\n\nexport const WINDOW_SOURCE_LABEL: Record<WindowSource, string> = {\n 'account-observation': 'from this account’s observed windows',\n 'subscription-tracker': 'from the subscription tracker',\n};\n\nexport interface MeasuredWindow {\n id: string;\n label: string;\n /** 0–100, clamped. Never synthesized — only ever a real reading. */\n usedPct: number;\n /** Unix epoch SECONDS, matching SubscriptionUsageWindow.resetsAt. */\n resetsAt: number | null;\n tone: WindowTone;\n}\n\nexport type WindowSignal =\n | {\n kind: 'measured';\n source: WindowSource;\n /** 'engine' when the reading covers every account on this engine. */\n scope: 'account' | 'engine';\n windows: MeasuredWindow[];\n }\n | { kind: 'unknown'; reason: string }\n | { kind: 'not-applicable'; reason: string };\n\n/** `SourceQuality` shaped for <Epistemic/> so unknowns use the shared treatment. */\nexport function unknownQuality(reason: string): SourceQuality {\n return { sourceState: 'unknown', complete: false, reason };\n}\n\nexport function windowTone(usedPct: number): WindowTone {\n // Mirrors frontier-usage.ts: >= DEFAULT_MAX_PERCENT (90) exhausted, >= 80 near.\n if (usedPct >= 90) return 'danger';\n if (usedPct >= 80) return 'warn';\n return 'ok';\n}\n\nfunction clampPct(value: number): number {\n if (!Number.isFinite(value)) return 0;\n return Math.max(0, Math.min(100, value));\n}\n\nfunction toEpochSeconds(value: number | undefined | null): number | null {\n return typeof value === 'number' && Number.isFinite(value) ? value : null;\n}\n\nfunction measured(\n source: WindowSource,\n scope: 'account' | 'engine',\n windows: MeasuredWindow[],\n): WindowSignal {\n return { kind: 'measured', source, scope, windows };\n}\n\nfunction noSignal(engine: VerseEngine): WindowSignal {\n return { kind: 'unknown', reason: NO_SIGNAL_REASON[engine] ?? GENERIC_NO_SIGNAL };\n}\n\n/**\n * The one decision that keeps this surface honest. See the module header for\n * why each branch is ordered the way it is.\n */\nexport function resolveWindowSignal(input: {\n engine: VerseEngine;\n seat?: VerseSeat | undefined;\n subscription?: SubscriptionEngineUsage | undefined;\n frontier?: FrontierEngineUsage | undefined;\n /** >1 means a tracker reading covers several accounts, so scope is 'engine'. */\n engineSeatCount?: number;\n}): WindowSignal {\n const { engine, seat, subscription, frontier, engineSeatCount = 1 } = input;\n\n if (engine === 'local') return { kind: 'not-applicable', reason: LOCAL_NOT_APPLICABLE };\n\n // 1. Per-account observations are the finest-grained real reading we have.\n const observed = (seat?.health.windows ?? []).filter(\n (w): w is { id: string; usedPercent: number; resetsAt: string | null } =>\n typeof w.usedPercent === 'number' && Number.isFinite(w.usedPercent),\n );\n if (observed.length > 0) {\n return measured(\n 'account-observation',\n 'account',\n observed.map((w) => {\n const pct = clampPct(w.usedPercent);\n const parsed = w.resetsAt ? Date.parse(w.resetsAt) : Number.NaN;\n return {\n id: w.id,\n label: w.id,\n usedPct: pct,\n resetsAt: Number.isNaN(parsed) ? null : Math.round(parsed / 1000),\n tone: windowTone(pct),\n };\n }),\n );\n }\n\n // 2. A `hasData` subscription entry is proof the tracker actually read something.\n if (subscription && subscription.hasData && subscription.windows.length > 0) {\n return measured(\n 'subscription-tracker',\n engineSeatCount > 1 ? 'engine' : 'account',\n subscription.windows.map((w, i) => {\n const pct = clampPct(w.usedPercent);\n return {\n id: `${w.label}-${i}`,\n label: w.label,\n usedPct: pct,\n resetsAt: toEpochSeconds(w.resetsAt),\n tone: windowTone(pct),\n };\n }),\n );\n }\n\n // 3. An explicit `hasData: false` entry is an explicit \"no signal\" (claude).\n if (subscription && !subscription.hasData) return noSignal(engine);\n\n if (frontier && frontier.subscriptionWindow.state !== 'unknown') {\n // 4. Proof by elimination: frontier-usage's derived branch is unreachable\n // without a configured limit, so a stated window with no limit can only\n // have come from the subscription tracker.\n if (frontier.limit === undefined) {\n const pct = clampPct(frontier.subscriptionWindow.usedPct);\n return measured('subscription-tracker', engineSeatCount > 1 ? 'engine' : 'account', [\n {\n id: frontier.subscriptionWindow.windowLabel ?? 'window',\n label: frontier.subscriptionWindow.windowLabel ?? 'window',\n usedPct: pct,\n resetsAt: toEpochSeconds(frontier.subscriptionWindow.resetsAt),\n tone: windowTone(pct),\n },\n ]);\n }\n // 5. A limit is configured, so the figure may be ledger-derived. Ambiguous\n // is not good enough for a meter.\n return { kind: 'unknown', reason: AMBIGUOUS_REASON };\n }\n\n // 6. state === 'unknown' (usedPct is a placeholder 0) or no entry at all.\n return noSignal(engine);\n}\n\n// ---------------------------------------------------------------------------\n// Local vs cloud split\n// ---------------------------------------------------------------------------\n\nexport interface ProviderSlice {\n provider: string;\n tier: 'local' | 'cloud';\n tokens: number;\n costUsd: number;\n sharePct: number;\n}\n\nexport interface LocalCloudSplit {\n window: string;\n totalTokens: number;\n totalCostUsd: number;\n /** Money NOT spent because the work ran locally. */\n localSavingsUsd: number;\n localTokens: number;\n cloudTokens: number;\n localCostUsd: number;\n cloudCostUsd: number;\n byProvider: ProviderSlice[];\n /** True when the window carries no activity at all — an empty state, not a zero. */\n empty: boolean;\n}\n\nexport function buildLocalCloudSplit(usage: ControlUsage | undefined): LocalCloudSplit | null {\n if (!usage) return null;\n const byProvider: ProviderSlice[] = (usage.byProvider ?? []).map((p) => ({\n provider: p.provider,\n tier: p.tier,\n tokens: p.tokens,\n costUsd: p.costUsd,\n sharePct: p.sharePct,\n }));\n const sum = (tier: 'local' | 'cloud', field: 'tokens' | 'costUsd'): number =>\n byProvider.filter((p) => p.tier === tier).reduce((acc, p) => acc + (p[field] || 0), 0);\n\n return {\n window: usage.window,\n totalTokens: usage.totalTokens,\n totalCostUsd: usage.totalCostUsd,\n localSavingsUsd: usage.localSavingsUsd,\n localTokens: sum('local', 'tokens'),\n cloudTokens: sum('cloud', 'tokens'),\n localCostUsd: sum('local', 'costUsd'),\n cloudCostUsd: sum('cloud', 'costUsd'),\n byProvider: [...byProvider].sort((a, b) => b.tokens - a.tokens),\n empty: byProvider.length === 0 && usage.totalTokens === 0,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Dispatch-ledger usage against configured foundry limits\n// ---------------------------------------------------------------------------\n\nexport interface UsageLimitRow {\n id: string;\n backend: string;\n window: string;\n max: number;\n /** null when the limit is configured but no ledger reading is available. */\n used: number | null;\n standing: ControlLimit['standing'] | 'unknown';\n usedPct: number | null;\n /** True when only the configured cap is known, with no usage behind it. */\n configuredOnly: boolean;\n}\n\n/**\n * `/api/control`'s `limits` already pairs each configured foundry limit with\n * its ledger reading. Owner B's `/api/verse/control` adds the CONFIGURED caps,\n * which may include an engine the control snapshot has not reported on — those\n * are surfaced as configured-with-no-reading rather than dropped or zeroed.\n */\nexport function buildLimitRows(\n limits: readonly ControlLimit[] | undefined,\n configured: readonly ConfiguredFoundryLimit[] | undefined,\n): UsageLimitRow[] {\n const rows: UsageLimitRow[] = [];\n const seen = new Set<string>();\n for (const l of limits ?? []) {\n const key = `${l.backend}:${l.window}`;\n seen.add(key);\n const usedPct = l.max > 0 ? clampPct((l.used / l.max) * 100) : null;\n rows.push({\n id: key,\n backend: l.backend,\n window: l.window,\n max: l.max,\n used: l.used,\n standing: l.standing,\n usedPct,\n configuredOnly: false,\n });\n }\n for (const c of configured ?? []) {\n const key = `${c.engine}:${c.window}`;\n if (seen.has(key)) continue;\n seen.add(key);\n rows.push({\n id: key,\n backend: c.engine,\n window: c.window,\n max: c.max,\n used: null,\n standing: 'unknown',\n usedPct: null,\n configuredOnly: true,\n });\n }\n return rows.sort((a, b) => a.backend.localeCompare(b.backend) || a.window.localeCompare(b.window));\n}\n\n// ---------------------------------------------------------------------------\n// Per-day spend series\n// ---------------------------------------------------------------------------\n\nexport interface SpendDay {\n /** YYYY-MM-DD — the viewer's LOCAL calendar day, the calendar the chart and table label in. */\n day: string;\n /** null = no tick retained for this day, NOT a measured zero. */\n usd: number | null;\n}\n\nexport type SpendSeries =\n | { available: true; days: SpendDay[]; tickCount: number; caveat: string }\n | { available: false; reason: string };\n\nexport const SERIES_UNAVAILABLE_NO_LEDGER =\n 'No per-day series is available: the sources this view reads carry aggregate spend only, not a dated history.';\n\n/**\n * The only dated spend history reachable from the three endpoints this section\n * reads is `ControlSnapshot.daemonObservation.ticks`, where each tick carries\n * `ts` and `spentUsd`. It is real, but partial — the ledger is capped and it\n * records the autonomous loop only — so the caveat says so, days inside the\n * covered span with no retained tick stay `null` (a visible break, never a\n * fabricated zero), and anything under two days is refused as \"not a series\".\n */\nexport function buildDailySpendSeries(observation: DaemonObservation | undefined): SpendSeries {\n if (!observation) return { available: false, reason: SERIES_UNAVAILABLE_NO_LEDGER };\n if (observation.sourceQuality?.sourceState !== 'healthy') {\n return {\n available: false,\n reason: `No per-day series: the daemon ledger is ${observation.sourceQuality?.sourceState ?? 'unavailable'}${\n observation.sourceQuality?.reason ? ` (${observation.sourceQuality.reason})` : ''\n }.`,\n };\n }\n const ticks = observation.ticks;\n if (!ticks || ticks.length === 0) return { available: false, reason: SERIES_UNAVAILABLE_NO_LEDGER };\n\n const byDay = new Map<string, number>();\n for (const t of ticks) {\n const ms = Date.parse(t.ts);\n if (Number.isNaN(ms)) continue;\n // Bucketed by the viewer's LOCAL day — the same calendar every day axis\n // uses (growth/calendar-day) — so a tick at 8 PM on the 23rd in Denver\n // counts toward the 23rd, not the UTC 24th.\n const day = localDateKey(new Date(ms));\n byDay.set(day, (byDay.get(day) ?? 0) + (Number.isFinite(t.spentUsd) ? t.spentUsd : 0));\n }\n if (byDay.size < 2) {\n return {\n available: false,\n reason: `No per-day series: only ${byDay.size} day${byDay.size === 1 ? '' : 's'} of daemon ticks is retained, which is not a trend.`,\n };\n }\n\n const sorted = [...byDay.keys()].sort();\n const first = sorted[0] as string;\n const last = sorted[sorted.length - 1] as string;\n const days: SpendDay[] = [];\n // Walk LOCAL calendar days (a DST day is 23 or 25 hours, never a skipped or doubled day).\n const end = calendarDayStart(last);\n for (let at = new Date(calendarDayStart(first)); at.getTime() <= end; at = new Date(at.getFullYear(), at.getMonth(), at.getDate() + 1)) {\n const day = localDateKey(at);\n days.push({ day, usd: byDay.has(day) ? (byDay.get(day) as number) : null });\n }\n return {\n available: true,\n days,\n tickCount: ticks.length,\n caveat: `From the last ${ticks.length} recorded daemon ticks. The tick ledger is capped and records the autonomous loop only — interactive chat turns are not in it, and a gap is a day with no retained tick, not a measured zero.`,\n };\n}\n\n// ---------------------------------------------------------------------------\n// GET /api/verse/control — defensive projection\n// ---------------------------------------------------------------------------\n\nexport interface ConfiguredFoundryLimit {\n engine: string;\n window: string;\n max: number;\n}\n\nexport interface VerseControlProjection {\n available: boolean;\n reason: string | null;\n dailyBudgetUsd: number | null;\n subscriptionMaxPercent: number | null;\n todaySpentUsd: number | null;\n /**\n * The ledger day `todaySpentUsd` was counted for (`YYYY-MM-DD`), or null\n * when the source carries no date. The daemon writes the figure once a day\n * and leaves it there, so without this a stale day renders as today's spend.\n */\n todaySpentDate: string | null;\n foundryLimits: ConfiguredFoundryLimit[];\n}\n\nconst UNAVAILABLE_PROJECTION: VerseControlProjection = {\n available: false,\n reason: null,\n dailyBudgetUsd: null,\n subscriptionMaxPercent: null,\n todaySpentUsd: null,\n todaySpentDate: null,\n foundryLimits: [],\n};\n\nfunction record(value: unknown): Record<string, unknown> | null {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n}\n\nfunction readNumber(source: Record<string, unknown> | null, keys: readonly string[]): number | null {\n if (!source) return null;\n for (const key of keys) {\n const v = source[key];\n if (typeof v === 'number' && Number.isFinite(v)) return v;\n }\n return null;\n}\n\n/**\n * Narrow `GET /api/verse/control` down to the four figures this section needs.\n *\n * The authoritative shape is `VerseControlSnapshot` in\n * `src/core/verse/control-types.ts`, and the field paths below now match it\n * exactly (`caps.*`, `spend.todayUsd`). It still narrows STRUCTURALLY rather\n * than casting to that type, because `usage-queries.ts` deliberately hands\n * this function a non-throwing wrapper's `raw` body: the route can be absent\n * (no --allow-dispatch) or degraded, and a degraded panel is the designed\n * state here, not an exception. The legacy root-level spend spellings are\n * kept as a fallback ONLY behind the contract path, so a server that predates\n * the `spend` block still renders a figure instead of \"unknown\".\n */\nexport function projectVerseControl(raw: unknown, reason: string | null = null): VerseControlProjection {\n const root = record(raw);\n if (!root) return { ...UNAVAILABLE_PROJECTION, reason };\n\n const caps = record(root['caps']) ?? root;\n const daemon = record(root['daemon']);\n const spend = record(root['spend']);\n\n const foundryLimits: ConfiguredFoundryLimit[] = [];\n const rawLimits = caps['foundryLimits'];\n if (Array.isArray(rawLimits)) {\n for (const entry of rawLimits) {\n const e = record(entry);\n if (!e) continue;\n const engine = typeof e['engine'] === 'string' ? e['engine'] : null;\n const max = readNumber(e, ['max']);\n if (engine === null || max === null) continue;\n foundryLimits.push({\n engine,\n window: typeof e['window'] === 'string' ? e['window'] : '1d',\n max,\n });\n }\n }\n\n return {\n available: true,\n reason,\n dailyBudgetUsd: readNumber(caps, ['dailyBudgetUsd']),\n subscriptionMaxPercent: readNumber(caps, ['subscriptionMaxPercent']),\n // Contract path first: VerseControlSnapshot.spend.todayUsd is the one the\n // server actually sends, and it is null (not 0) when the ledger is\n // unreadable — so a present-but-null `spend` block must NOT fall through\n // to the daemon observation and report a stale number as today's spend.\n todaySpentUsd: spend\n ? readNumber(spend, ['todayUsd'])\n : readNumber(root, ['todaySpentUsd', 'todaySpendUsd', 'spendTodayUsd']) ??\n readNumber(daemon, ['todaySpentUsd']),\n // Only the contract path carries a date. A legacy server's root-level\n // spelling has none, and null means \"cannot be checked\", not \"today\".\n todaySpentDate: spend && typeof spend['todayDate'] === 'string' ? spend['todayDate'] : null,\n foundryLimits,\n };\n}\n\nexport function unavailableVerseControl(reason: string): VerseControlProjection {\n return { ...UNAVAILABLE_PROJECTION, reason };\n}\n","/**\n * routes/verse/usage/usage.module.css — Usage section styling.\n *\n * Follows docs/VERSE-DESIGN-V2.md: monochrome ground, separation by 1px\n * hairlines and whitespace (no shadows, no nested rounded boxes), engine hue\n * used ONLY for a 2px marker and a window bar, numerals in the display face.\n * Density comes from --density-pad with a fallback so the section is correct\n * before owner A lands the density tokens.\n */\n\n.section {\n display: flex;\n flex-direction: column;\n min-height: 0;\n height: 100%;\n background: var(--bg-canvas);\n}\n\n/* 48px header strip, hairline bottom border, ghost controls only. */\n.header {\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--space-3);\n /* DESIGN-V2 §4: header strips are --strip-height, and the token is what the\n desktop shell's inset maths is written against. */\n height: var(--strip-height);\n padding: 0 var(--space-5);\n border-bottom: 1px solid var(--border-subtle);\n}\n\n.headerTitle {\n font-family: var(--font-display);\n font-size: var(--text-md-size);\n font-weight: var(--font-weight-semibold);\n letter-spacing: var(--tracking-display, -0.02em);\n color: var(--text-primary);\n}\n\n.headerMeta {\n display: flex;\n align-items: center;\n gap: var(--space-3);\n min-width: 0;\n font-size: var(--text-xs-size);\n color: var(--text-tertiary);\n}\n\n.ghostButton {\n min-height: var(--control-h-sm);\n padding: 0 var(--space-3);\n border: 1px solid transparent;\n border-radius: var(--radius-sm);\n background: transparent;\n color: var(--text-secondary);\n font-size: var(--text-xs-size);\n font-weight: var(--font-weight-medium);\n cursor: pointer;\n}\n\n.ghostButton:hover {\n background: var(--bg-hover);\n color: var(--text-primary);\n}\n\n.scroll {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n padding: var(--space-5) var(--space-5) var(--space-12);\n scrollbar-gutter: stable;\n}\n\n.panel {\n padding-block: var(--space-5);\n}\n\n.panel + .panel {\n border-top: 1px solid var(--border-subtle);\n}\n\n.panelHead {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: var(--space-3);\n margin-bottom: var(--space-4);\n}\n\n/* Display face, like every other uppercase micro-label: appearance-store.ts\n implements the Display-font setting by writing --font-display on <html>, so\n a label that names --font-ui explicitly opts OUT of the operator's choice\n and the Usage panel titles stopped moving while the Settings ones did. */\n.panelTitle {\n font-family: var(--font-display);\n font-size: var(--text-2xs-size, 11px);\n font-weight: var(--font-weight-semibold);\n letter-spacing: var(--tracking-label, 0.06em);\n text-transform: uppercase;\n color: var(--text-tertiary);\n}\n\n.panelNote {\n font-size: var(--text-xs-size);\n color: var(--text-tertiary);\n max-width: 48ch;\n text-align: right;\n}\n\n.muted {\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line);\n color: var(--text-tertiary);\n max-width: 72ch;\n}\n\n/*\n * The server's own caveats about how to read the meters below. They sit on the\n * panel surface (not a hover or press ground), where --text-tertiary measures\n * 4.83:1 light / 5.47:1 dark — above the body floor. The 2px left rule is the\n * language's marker for an aside, reused here rather than a bordered box.\n */\n.noteList {\n display: flex;\n flex-direction: column;\n gap: var(--space-1);\n margin: var(--space-2) 0 0;\n padding: 0 0 0 var(--space-3);\n border-left: 2px solid var(--border-subtle);\n list-style: none;\n}\n\n/* Numerals: display face, tabular so meters and columns line up. */\n.num {\n font-family: var(--font-display);\n font-variant-numeric: tabular-nums;\n letter-spacing: var(--tracking-display, -0.02em);\n color: var(--text-primary);\n}\n\n.tiles {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));\n gap: var(--space-3);\n}\n\n/* ── Account cards ─────────────────────────────────────────────────────── */\n\n.cards {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));\n gap: var(--space-3);\n}\n\n.card {\n position: relative;\n padding: var(--density-pad, var(--space-3)) var(--space-4);\n padding-left: calc(var(--space-4) + 2px);\n border: 1px solid var(--border-subtle);\n border-radius: var(--radius-md);\n background: var(--bg-surface);\n}\n\n/* The 2px engine marker — the only place an engine hue is allowed. */\n.card::before {\n content: '';\n position: absolute;\n inset-block: -1px;\n inset-inline-start: -1px;\n width: 2px;\n border-start-start-radius: var(--radius-md);\n border-end-start-radius: var(--radius-md);\n background: var(--engine-color, var(--border-strong));\n}\n\n.cardHead {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--space-2);\n min-width: 0;\n}\n\n/* The account name is the card head's label (a control): it wraps rather\n than cutting \"Cash Margin Partners\" off mid-word. */\n.cardLabel {\n font-family: var(--font-display);\n font-size: var(--text-sm-size);\n font-weight: var(--font-weight-medium);\n letter-spacing: var(--tracking-display, -0.02em);\n color: var(--text-primary);\n min-width: 0;\n overflow-wrap: anywhere;\n text-align: left;\n}\n\n.cardMeta {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-1);\n margin-top: var(--space-1);\n font-size: var(--text-xs-size);\n color: var(--text-tertiary);\n}\n\n.cardFigures {\n display: grid;\n grid-template-columns: repeat(3, minmax(0, 1fr));\n gap: var(--space-2);\n margin-top: var(--space-3);\n padding-top: var(--space-3);\n border-top: 1px solid var(--border-subtle);\n}\n\n.figure {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.figureLabel {\n font-family: var(--font-display);\n font-size: var(--text-2xs-size, 11px);\n letter-spacing: var(--tracking-label, 0.06em);\n text-transform: uppercase;\n color: var(--text-tertiary);\n}\n\n.figureValue {\n font-family: var(--font-display);\n font-variant-numeric: tabular-nums;\n font-size: var(--text-sm-size);\n color: var(--text-primary);\n}\n\n/* ── Window meters ─────────────────────────────────────────────────────── */\n\n.windows {\n display: flex;\n flex-direction: column;\n gap: var(--space-3);\n margin-top: var(--space-3);\n}\n\n.windowHead {\n display: flex;\n align-items: baseline;\n justify-content: space-between;\n gap: var(--space-2);\n margin-bottom: var(--space-1);\n font-size: var(--text-xs-size);\n color: var(--text-secondary);\n}\n\n.windowPct {\n font-family: var(--font-display);\n font-variant-numeric: tabular-nums;\n color: var(--text-primary);\n}\n\n.windowReset {\n margin-top: var(--space-1);\n /* Prose, not a micro-label: tokens.css sets the body floor at 12px and\n reserves --text-2xs for uppercase labels and keyboard hints. */\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n color: var(--text-tertiary);\n}\n\n/* The unfilled half is --meter-track, not --bg-active: see the token's note\n in tokens.css. At --bg-active this track was 1.22:1 against the card in\n light and 1.20:1 in dark, so the remaining capacity — the whole point of a\n window meter — was invisible and only the fill could be read. */\n.track {\n position: relative;\n height: 4px;\n border-radius: var(--radius-full);\n background: var(--meter-track);\n overflow: hidden;\n}\n\n.fill {\n height: 100%;\n border-radius: inherit;\n background: var(--engine-color, var(--accent-500));\n transition: width var(--duration-base, 180ms) var(--ease-decelerate);\n}\n\n.track[data-tone='warn'] .fill {\n background: var(--status-warning-solid);\n}\n\n.track[data-tone='danger'] .fill {\n background: var(--status-danger-solid);\n}\n\n/*\n * Unknown is NOT a track. A filled track at 0% reads \"plenty left\" and a\n * track at 100% reads \"exhausted\"; both are lies when there is no signal. A\n * dashed rule reads as absence, and it is paired with the Epistemic pill and\n * a one-line reason so the state is never carried by styling alone.\n */\n/* --text-tertiary, not --border-strong at 0.8 opacity. This dashed rule is\n the designed representation of ABSENCE (see above), which makes it a border\n carrying meaning under DESIGN-V2 §6's 3:1 floor; composited it measured\n 1.34:1 light / 1.47:1 dark. --border-strong is deliberately held to the\n 1.1:1 hairline floor in tokens-contrast.test.ts, which is right for a\n structural divider and wrong for this. --text-tertiary measures 4.83:1\n light / 5.47:1 dark and reads as \"absent\" rather than \"structural\". */\n.unknownRule {\n height: 0;\n margin-block: var(--space-1) 0;\n border: 0;\n border-top: 2px dashed var(--text-tertiary);\n}\n\n.signalRow {\n display: flex;\n align-items: center;\n gap: var(--space-2);\n flex-wrap: wrap;\n}\n\n.reason {\n margin-top: var(--space-2);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n color: var(--text-tertiary);\n max-width: 60ch;\n}\n\n.sourceLine {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-1);\n margin-top: var(--space-1);\n /* Prose, not a micro-label: tokens.css sets the body floor at 12px and\n reserves --text-2xs for uppercase labels and keyboard hints. */\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n color: var(--text-tertiary);\n}\n\n/* ── Split / limits ────────────────────────────────────────────────────── */\n\n.split {\n display: flex;\n flex-direction: column;\n gap: var(--space-2);\n margin-bottom: var(--space-4);\n}\n\n.splitRow {\n display: grid;\n grid-template-columns: 72px minmax(0, 1fr) auto;\n align-items: center;\n gap: var(--space-3);\n font-size: var(--text-xs-size);\n color: var(--text-secondary);\n}\n\n.splitBar {\n height: 4px;\n border-radius: var(--radius-full);\n background: var(--bg-active);\n overflow: hidden;\n}\n\n.splitFill {\n height: 100%;\n border-radius: inherit;\n background: var(--split-color, var(--accent-500));\n}\n\n.limitList {\n display: flex;\n flex-direction: column;\n}\n\n.limitRow {\n display: grid;\n grid-template-columns: minmax(0, 1fr) 128px auto;\n align-items: center;\n gap: var(--space-3);\n padding-block: var(--space-2);\n min-height: var(--density-row, 32px);\n}\n\n.limitRow + .limitRow {\n border-top: 1px solid var(--border-subtle);\n}\n\n.limitName {\n display: flex;\n align-items: center;\n gap: var(--space-2);\n min-width: 0;\n font-size: var(--text-sm-size);\n color: var(--text-primary);\n}\n\n.limitWindow {\n font-size: var(--text-xs-size);\n color: var(--text-tertiary);\n}\n\n.limitValue {\n font-family: var(--font-display);\n font-variant-numeric: tabular-nums;\n font-size: var(--text-sm-size);\n color: var(--text-primary);\n text-align: right;\n white-space: nowrap;\n}\n\n/* ── Verdict + binding constraint ──────────────────────────────────────── */\n\n/*\n * The verdict sentence is the card's argument in one line, so it sits directly\n * under the identity row at body weight — not as a caption. It is always\n * paired with the StatusBadge above it (glyph + text), never carried by color.\n */\n.verdictDetail {\n margin-top: var(--space-2);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n color: var(--text-secondary);\n max-width: 60ch;\n}\n\n.bindingLabel {\n font-family: var(--font-display);\n display: block;\n margin-top: var(--space-3);\n font-size: var(--text-2xs-size, 11px);\n letter-spacing: var(--tracking-label, 0.06em);\n text-transform: uppercase;\n color: var(--text-tertiary);\n}\n\n.windowBlock {\n min-width: 0;\n}\n\n.windowBlock + .windowBlock {\n margin-top: var(--space-3);\n}\n\n/* The binding window gets the weight; the others stay deliberately quieter. */\n.windowBlockLead {\n margin-top: var(--space-2);\n}\n\n.windowBlockLead .windowHead {\n font-size: var(--text-sm-size);\n color: var(--text-primary);\n}\n\n.windowBlockLead .track {\n height: 6px;\n}\n\n.windowFlag {\n font-family: var(--font-display);\n font-size: var(--text-xs-size);\n color: var(--status-danger-fg, var(--text-primary));\n}\n\n/* ── Credits + actions ─────────────────────────────────────────────────── */\n\n.creditsRow {\n display: grid;\n grid-template-columns: auto minmax(0, 1fr);\n align-items: baseline;\n gap: var(--space-2) var(--space-3);\n margin-top: var(--space-3);\n padding-top: var(--space-3);\n border-top: 1px solid var(--border-subtle);\n}\n\n.creditsRow > .reason {\n grid-column: 1 / -1;\n margin-top: 0;\n}\n\n.actionBlock {\n margin-top: var(--space-3);\n padding-top: var(--space-3);\n border-top: 1px solid var(--border-subtle);\n}\n\n.command,\n.commandInline {\n font-family: var(--font-mono);\n font-size: var(--text-xs-size);\n color: var(--text-primary);\n background: var(--bg-code, var(--bg-active));\n border: 1px solid var(--border-subtle);\n border-radius: var(--radius-xs);\n padding: 1px 6px;\n}\n\n.command {\n display: inline-block;\n margin-top: var(--space-1);\n}\n\n.negative {\n color: var(--status-danger-fg, var(--text-primary));\n}\n\n/* ── Series panel ──────────────────────────────────────────────────────── */\n\n.segmented {\n display: inline-flex;\n border: 1px solid var(--border-default);\n border-radius: var(--radius-sm);\n overflow: hidden;\n}\n\n.segment {\n min-height: var(--control-h-xs);\n padding: 0 var(--space-3);\n border: 0;\n background: transparent;\n color: var(--text-secondary);\n font-family: var(--font-display);\n font-variant-numeric: tabular-nums;\n font-size: var(--text-xs-size);\n cursor: pointer;\n}\n\n.segment + .segment {\n border-left: 1px solid var(--border-subtle);\n}\n\n.segment:hover {\n background: var(--bg-hover);\n color: var(--text-primary);\n}\n\n.segment[aria-pressed='true'] {\n background: var(--bg-selected);\n color: var(--text-primary);\n}\n\n/* The one place an INSET ring is right: .segmented clips with\n `overflow: hidden`, so the global outward --shadow-focus-ring would be cut\n off. It is silenced here so exactly one ring paints. */\n.segment:focus-visible {\n outline: 2px solid var(--border-focus);\n outline-offset: -2px;\n box-shadow: none;\n}\n\n.charts {\n display: flex;\n flex-direction: column;\n gap: var(--space-5);\n margin-top: var(--space-4);\n}\n\n/*\n * The local-model table is genuinely wide (eight independent facts per model).\n * Per the responsive rule, a table may exceed the measure only inside its own\n * horizontal scroll container, so the page body never scrolls sideways.\n */\n.tableScroll {\n overflow-x: auto;\n scrollbar-gutter: stable;\n}\n\n/* ── States ────────────────────────────────────────────────────────────── */\n\n\n.stateBlock {\n padding: var(--space-6) var(--space-4);\n border: 1px solid var(--border-subtle);\n border-radius: var(--radius-md);\n background: var(--bg-surface);\n max-width: 72ch;\n}\n\n.stateTitle {\n font-family: var(--font-display);\n font-size: var(--text-md-size);\n font-weight: var(--font-weight-semibold);\n letter-spacing: var(--tracking-display, -0.02em);\n color: var(--text-primary);\n margin-bottom: var(--space-2);\n}\n\n.stateBody {\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line);\n color: var(--text-secondary);\n}\n\n.stateActions {\n margin-top: var(--space-4);\n}\n\n.skeletonGrid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));\n gap: var(--space-3);\n}\n\n/* Guarded: appearance-store.ts writes data-motion=\"full\" so an operator can\n opt out of the OS preference, and every other animated surface here honours\n it. */\n@media (prefers-reduced-motion: reduce) {\n :root:not([data-motion=\"full\"]) .fill {\n transition: none;\n }\n}\n\n@media (max-width: 900px) {\n .cards,\n .skeletonGrid {\n grid-template-columns: 1fr;\n }\n\n .limitRow {\n grid-template-columns: minmax(0, 1fr) auto;\n }\n\n .limitRow > .track {\n display: none;\n }\n\n .panelNote {\n text-align: left;\n }\n}\n\n/* ---- desktop shell (see desktop/README.md \"Desktop shell contract\") -----\n * In the Tauri window the OS title bar overlays the top 48px and the macOS\n * traffic lights float over the top-LEFT 92px of the WINDOW. This strip does\n * not start at the window's left edge — the 56px rail does — so the inset it\n * owes is the overlap, never the full 92px. Both vars are absent in a\n * browser, where the expression floors to 0px and the layout is unchanged. */\n.header {\n padding-left: max(\n var(--space-5),\n calc(var(--app-traffic-light-inset, 0px) - var(--rail-width, 56px))\n );\n}\n\n/* ── Capacity strip ────────────────────────────────────────────────────────\n *\n * The first thing on the screen and the only thing that has to be readable in\n * under two seconds. It is NOT a card: hairline bottom rule and whitespace\n * (DESIGN-V2 §1.2), no ground of its own, so it reads as the head of the page\n * rather than as one more panel competing with the cards below it.\n */\n\n.capacity {\n padding-bottom: var(--space-5);\n border-bottom: 1px solid var(--border-subtle);\n}\n\n.capacityHeadline {\n font-family: var(--font-display);\n font-size: var(--text-md-size);\n line-height: var(--text-md-line);\n letter-spacing: var(--tracking-display, -0.02em);\n color: var(--text-primary);\n max-width: 78ch;\n}\n\n/* No capacity at all is the one state worth a tonal shift — and it is still\n paired with the sentence itself, never carried by color. */\n.capacityHeadline[data-empty='true'] {\n color: var(--status-warning-fg, var(--text-primary));\n}\n\n.chips {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-2);\n margin-top: var(--space-3);\n}\n\n.chip {\n position: relative;\n display: inline-flex;\n align-items: center;\n gap: var(--space-2);\n min-height: var(--control-h-sm);\n padding: 0 var(--space-3) 0 calc(var(--space-3) + 2px);\n border: 1px solid var(--border-subtle);\n border-radius: var(--radius-sm);\n background: var(--bg-surface);\n color: var(--text-secondary);\n font-size: var(--text-xs-size);\n text-align: left;\n}\n\nbutton.chip {\n cursor: pointer;\n}\n\nbutton.chip:hover {\n background: var(--bg-hover);\n}\n\nbutton.chip[aria-pressed='true'] {\n background: var(--bg-selected);\n border-color: var(--border-default);\n}\n\n/* The 2px engine marker, same language as the card's leading edge. */\n.chip::before {\n content: '';\n position: absolute;\n inset-block: -1px;\n inset-inline-start: -1px;\n width: 2px;\n border-start-start-radius: var(--radius-sm);\n border-end-start-radius: var(--radius-sm);\n background: var(--engine-color, var(--border-strong));\n}\n\n.chipLabel {\n font-family: var(--font-display);\n font-weight: var(--font-weight-medium);\n letter-spacing: var(--tracking-display, -0.02em);\n color: var(--text-primary);\n}\n\n/* State is a WORD, never a color alone (DESIGN-V2 §6). The tint is a second\n channel on top of it, not the channel. Display face, like every other\n uppercase micro-label, so the Display-font setting reaches it too. */\n.chipState {\n font-family: var(--font-display);\n font-size: var(--text-2xs-size, 11px);\n letter-spacing: var(--tracking-label, 0.06em);\n text-transform: uppercase;\n color: var(--text-tertiary);\n}\n\n.chip[data-capacity='ready'] .chipState {\n color: var(--status-success-fg, var(--text-secondary));\n}\n\n.chip[data-capacity='tight'] .chipState {\n color: var(--status-warning-fg, var(--text-secondary));\n}\n\n.chip[data-capacity='blocked'] .chipState {\n color: var(--status-danger-fg, var(--text-secondary));\n}\n\n.chipPct {\n font-family: var(--font-display);\n font-variant-numeric: tabular-nums;\n color: var(--text-primary);\n}\n\n.capacityFacts {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));\n gap: var(--space-3) var(--space-5);\n margin-top: var(--space-4);\n}\n\n.capacityFact > dd {\n margin: 2px 0 0;\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n color: var(--text-secondary);\n}\n\n.capacityMuted {\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n color: var(--text-tertiary);\n}\n\n.proseResets {\n margin-top: var(--space-4);\n}\n\n.visuallyHidden {\n position: absolute;\n width: 1px;\n height: 1px;\n margin: -1px;\n padding: 0;\n overflow: hidden;\n clip: rect(0 0 0 0);\n clip-path: inset(50%);\n white-space: nowrap;\n border: 0;\n}\n\n/* ── Card trigger + detail view ───────────────────────────────────────── */\n\n/*\n * The card head IS the control. It resets the button ground entirely so the\n * card still reads as a card, and takes the focus ring from the global\n * treatment rather than inventing one.\n */\n.cardTrigger {\n width: 100%;\n padding: 0;\n border: 0;\n background: transparent;\n font: inherit;\n color: inherit;\n text-align: left;\n cursor: pointer;\n}\n\n.cardTrigger:hover .cardLabel {\n text-decoration: underline;\n text-underline-offset: 3px;\n}\n\n.cardChevron {\n font-family: var(--font-display);\n font-size: var(--text-sm-size);\n color: var(--text-tertiary);\n margin-left: var(--space-2);\n}\n\n/*\n * Selection, in both themes. `--bg-surface-raised` IS `--bg-surface` in light\n * (#ffffff both), so the previous treatment's background half was a literal\n * no-op there and the only cue was a hairline stepping from `--border-subtle`\n * to `--border-strong`: 1.18:1 → 1.45:1, a change an operator with low vision\n * cannot see at all. Two channels now, both of which move in light AND dark:\n * the accent border (6.24:1 light / 3.99:1 dark on the card ground, already\n * pinned above 3:1 by the token suite) and `--bg-selected`, the system's own\n * selected ground (1.22:1 / 1.24:1 — symmetric, unlike raised).\n *\n * Colour is not the only carrier: `.cardTrigger` is a real button and reports\n * the same state through `aria-expanded`.\n */\n.card[data-selected='true'] {\n border-color: var(--accent-500);\n background: var(--bg-selected);\n}\n\n.detail {\n margin-top: var(--space-4);\n padding: var(--space-4);\n border: 1px solid var(--border-default);\n border-radius: var(--radius-md);\n background: var(--bg-surface);\n}\n\n.detailHead {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: var(--space-3);\n}\n\n.detailTitle {\n font-family: var(--font-display);\n font-size: var(--text-md-size);\n font-weight: var(--font-weight-semibold);\n letter-spacing: var(--tracking-display, -0.02em);\n color: var(--text-primary);\n}\n\n.detailGrid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));\n gap: var(--space-5);\n margin-top: var(--space-4);\n}\n\n.detailColumn {\n min-width: 0;\n}\n\n.evidenceList {\n display: flex;\n flex-direction: column;\n gap: var(--space-2);\n margin-top: var(--space-2);\n}\n\n.evidenceRow {\n display: grid;\n grid-template-columns: 110px minmax(0, 1fr);\n gap: var(--space-3);\n align-items: baseline;\n}\n\n.evidenceValue {\n margin: 0;\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n color: var(--text-secondary);\n min-width: 0;\n overflow-wrap: anywhere;\n}\n\n/* ── Local panel additions ─────────────────────────────────────────────── */\n\n.figureTile {\n display: flex;\n flex-direction: column;\n gap: 2px;\n padding: var(--space-3);\n border: 1px solid var(--border-subtle);\n border-radius: var(--radius-md);\n background: var(--bg-surface);\n min-width: 0;\n}\n\n.figureBig {\n font-family: var(--font-display);\n font-variant-numeric: tabular-nums;\n font-size: var(--text-lg-size);\n letter-spacing: var(--tracking-display, -0.02em);\n color: var(--text-primary);\n}\n\n.figureCaption {\n /* Prose, not a micro-label: tokens.css sets the body floor at 12px and\n reserves --text-2xs for uppercase labels and keyboard hints. */\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n color: var(--text-tertiary);\n}\n\n.panelActions {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-3);\n margin: var(--space-4) 0 var(--space-3);\n}\n\n/*\n * The GPU/CPU split, as two segments of one bar. Two hues and a text label,\n * because \"split\" is exactly the state where a single-color bar would look\n * like a percentage of something else.\n */\n.placement {\n display: inline-flex;\n align-items: center;\n gap: var(--space-2);\n min-width: 0;\n}\n\n.placementBar {\n display: inline-flex;\n width: 64px;\n height: 4px;\n border-radius: var(--radius-full);\n overflow: hidden;\n background: var(--bg-active);\n flex: none;\n}\n\n.placementGpu,\n.placementCpu {\n display: block;\n height: 100%;\n background: var(--split-color, var(--accent-500));\n}\n\n.placementText {\n /* Prose, not a micro-label: tokens.css sets the body floor at 12px and\n reserves --text-2xs for uppercase labels and keyboard hints. */\n font-size: var(--text-xs-size);\n color: var(--text-tertiary);\n white-space: nowrap;\n}\n\n/*\n * The staleness banner. It is deliberately loud in text and quiet in chrome:\n * the fact that matters is the sentence, and a warning-tinted box would push\n * a retained-but-valid reading toward reading as an error.\n */\n.staleNotice {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: var(--space-2);\n margin: var(--space-2) 0 var(--space-3);\n padding-left: var(--space-3);\n border-left: 2px solid var(--status-warning-solid, var(--border-strong));\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n color: var(--text-secondary);\n max-width: 72ch;\n}\n\n.staleFlag {\n font-family: var(--font-display);\n font-size: var(--text-2xs-size, 11px);\n letter-spacing: var(--tracking-label, 0.06em);\n text-transform: uppercase;\n color: var(--status-warning-fg, var(--text-primary));\n}\n\n/*\n * Chart chrome, raised locally rather than in the shared chart tokens.\n *\n * A gridline carries meaning: it is what an eye reads a value against, so\n * DESIGN-V2 §6's 3:1 floor applies to it. The default `--chart-grid` is\n * `--border-subtle`, and the previous fix here moved it to `--border-default`\n * with `--chart-axis` on `--border-strong` — but those are ALL hairline tokens,\n * which design/tokens-contrast.test.ts pins to a 1.1 \"not invisible\" floor and\n * documents as deliberately exempt from 3:1. Measured against ChartContainer's\n * `--bg-surface` ground that swap went 1.14:1 → 1.31:1 in dark; the axis\n * reached 1.66:1 dark / 1.45:1 light. Still effectively invisible on near-black.\n *\n * `--text-tertiary` is the right source: tokens-contrast.test.ts already pins\n * it as a meaning-carrying non-text token at 4.83:1 light / 5.47:1 dark on\n * `--bg-surface` — the same argument `.unknownRule` above makes.\n *\n * The grid is a SHARE of that token so a rule per gridline does not overpower\n * the series — but the share has to stay above the floor it is claiming, and\n * 45% did not: it measured 1.83:1 light / 2.06:1 dark, barely better than the\n * `--border-default` it replaced, under a comment asserting it cleared 3:1.\n * Nothing caught that because the suite could only measure the TOKEN, not the\n * mix. 80% measures 3.29:1 / 3.92:1, still visibly recessive against the\n * full-strength axis, and `design/contrast.ts` now parses `color-mix` so the\n * two values below are asserted from this file rather than argued for here.\n */\n.charts {\n --chart-grid: color-mix(in srgb, var(--text-tertiary) 80%, transparent);\n --chart-axis: var(--text-tertiary);\n --chart-tooltip-border: var(--border-strong);\n}\n\n@media (max-width: 900px) {\n .evidenceRow {\n grid-template-columns: 1fr;\n gap: 0;\n }\n\n .detailGrid {\n grid-template-columns: 1fr;\n }\n}\n","/**\n * routes/verse/usage/WindowMeter.tsx — one quota window, rendered so that a\n * glancing reader cannot misread it.\n *\n * Four visually distinct outcomes, and no two of them look alike:\n *\n * measured → a real bar, a real percentage, and the provider's own\n * reset text VERBATIM (Claude's reset is prose, not a\n * timestamp, and is never turned into a countdown).\n * limit reached → a full bar in the danger tone labelled \"limit reached\".\n * The upstream writes a SENTINEL 100 for this, so no\n * percentage is printed and no numeric value is announced\n * to assistive tech — it is a flag, not a measurement.\n * unknown → the shared <Epistemic/> unknown treatment plus a dashed\n * rule (absence), and a one-line reason. NEVER a bar:\n * an empty bar reads \"plenty left\" and a full one reads\n * \"exhausted\", and both are lies when there is no signal.\n * not applicable → a plain sentence.\n *\n * `prominent` is the binding constraint — the window with the highest used\n * percent, which is the one that actually blocks work.\n */\nimport type { ReactNode } from 'react';\nimport { Epistemic } from '../../../components/primitives/Epistemic.js';\nimport type { WindowView } from './accounts-model.js';\nimport { percentText } from './capacity-strip-model.js';\nimport { unknownQuality } from './usage-model.js';\nimport styles from './usage.module.css';\n\nexport function WindowMeter({\n view,\n ariaPrefix,\n prominent = false,\n}: {\n view: WindowView;\n /** Account label, so every meter has a unique accessible name. */\n ariaPrefix: string;\n prominent?: boolean;\n}): ReactNode {\n const name = `${ariaPrefix} ${view.label}`;\n\n if (view.limitReached) {\n return (\n <div className={prominent ? styles.windowBlockLead : styles.windowBlock}>\n <div className={styles.windowHead}>\n <span>{view.label}</span>\n <span className={styles.windowFlag}>limit reached</span>\n </div>\n <div\n className={styles.track}\n data-tone=\"danger\"\n role=\"img\"\n aria-label={`${name}: the provider flagged this window as rate-limited, so no percentage is shown`}\n >\n <div className={styles.fill} style={{ width: '100%' }} />\n </div>\n {view.resetText ? <p className={styles.windowReset}>{view.resetText}</p> : null}\n </div>\n );\n }\n\n if (view.usedPct === null) {\n return (\n <div className={prominent ? styles.windowBlockLead : styles.windowBlock}>\n <div className={styles.windowHead}>\n <span>{view.label}</span>\n <Epistemic quality={unknownQuality('No percentage was reported for this window.')} label={name}>\n {null}\n </Epistemic>\n </div>\n <hr className={styles.unknownRule} aria-hidden=\"true\" />\n </div>\n );\n }\n\n const pct = Math.round(view.usedPct);\n return (\n <div className={prominent ? styles.windowBlockLead : styles.windowBlock}>\n <div className={styles.windowHead}>\n <span>{view.label}</span>\n <span className={styles.windowPct}>{percentText(view.usedPct)}</span>\n </div>\n <div\n className={styles.track}\n data-tone={view.tone}\n role=\"meter\"\n aria-label={`${name} used`}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={pct}\n aria-valuetext={`${percentText(view.usedPct)} used${view.resetText ? `, ${view.resetText}` : ''}`}\n >\n <div className={styles.fill} style={{ width: `${pct}%` }} />\n </div>\n {view.resetText ? <p className={styles.windowReset}>{view.resetText}</p> : null}\n </div>\n );\n}\n","/**\n * routes/verse/usage/AccountCard.tsx — one account, answering one question:\n * can I use this right now, and what will it cost me.\n *\n * Layout order is the argument:\n * 1. the VERDICT, as a badge with text (never color alone);\n * 2. the BINDING window — the constraint that actually blocks work, given\n * the full-width treatment, because Claude's weekly per-model window sat\n * at 100% while its all-models window read 58% and leading with 58%\n * would be a lie of emphasis;\n * 3. the other windows, compact, so the detail is there without competing;\n * 4. credits and plan, which for Codex are INDEPENDENT of the window — a\n * 100%-used week with a spendable balance is not blocked, and this card\n * must not let it read that way;\n * 5. an action when there is one (signed out → reconnect).\n *\n * Identity is the 2px engine marker on the leading edge — the only\n * engine-hued element on the card (docs/VERSE-DESIGN-V2.md §2).\n *\n * The card HEAD is the control that opens the detail view. Making the whole\n * <article> clickable would have meant either a div with an onClick and no\n * keyboard path, or a <button> wrapping the window meters — and a `role=meter`\n * inside a button is not a thing assistive tech can make sense of. A real\n * button spanning the label and the verdict badge is a large target, is\n * reachable by keyboard for free, and carries `aria-expanded`/`aria-controls`\n * so the relationship to the detail region is announced rather than implied.\n */\nimport type { CSSProperties, ReactNode } from 'react';\nimport { StatusBadge, type Tone } from '../../../components/primitives/StatusBadge.js';\nimport { ENGINE_LABEL } from '../verse-model.js';\nimport type { AccountCardModel, AccountVerdictState } from './accounts-model.js';\nimport { WindowMeter } from './WindowMeter.js';\nimport styles from './usage.module.css';\n\nconst VERDICT_TONE: Record<AccountVerdictState, Tone> = {\n available: 'success',\n credits: 'success',\n tight: 'warning',\n exhausted: 'danger',\n 'signed-out': 'warning',\n 'probe-unsupported': 'warning',\n unknown: 'unknown',\n};\n\nfunction CreditsRow({ credits }: { credits: AccountCardModel['credits'] }): ReactNode {\n if (!credits) return null;\n const value = credits.unlimited\n ? 'unlimited'\n : credits.balance !== null\n ? credits.balanceValue !== null\n ? credits.balanceValue.toLocaleString('en-US', { maximumFractionDigits: 2 })\n : credits.balance\n : null;\n\n return (\n <div className={styles.creditsRow}>\n <span className={styles.figureLabel}>Credits</span>\n <span className={styles.num} title={credits.balance ?? undefined}>\n {value ?? 'not reported'}\n </span>\n <p className={styles.reason}>\n Credits are a separate pool from the window above — a fully used window does not stop a\n spendable balance from being spent. The provider gives a bare number, not a currency, so it is\n shown as reported.\n </p>\n </div>\n );\n}\n\nexport function AccountCard({\n card,\n onOpen,\n expanded = false,\n triggerId,\n detailId,\n}: {\n card: AccountCardModel;\n /** Omitted when there is nothing to open — the head then stays inert text. */\n onOpen?: ((id: string) => void) | undefined;\n expanded?: boolean;\n triggerId?: string | undefined;\n detailId?: string | undefined;\n}): ReactNode {\n const engineStyle = { '--engine-color': card.color } as CSSProperties;\n const showReconnect = card.verdict.state === 'signed-out';\n const openable = onOpen !== undefined && card.hasDetail;\n\n const head = (\n <>\n <span className={styles.cardLabel}>{card.label}</span>\n <StatusBadge status={card.verdict.state} tone={VERDICT_TONE[card.verdict.state]}>\n {card.verdict.headline}\n </StatusBadge>\n </>\n );\n\n return (\n <article\n className={styles.card}\n style={engineStyle}\n aria-label={`${card.label} usage`}\n data-selected={expanded ? 'true' : undefined}\n >\n {openable ? (\n <button\n type=\"button\"\n id={triggerId}\n className={`${styles.cardHead} ${styles.cardTrigger}`}\n aria-expanded={expanded}\n {...(detailId ? { 'aria-controls': detailId } : {})}\n onClick={() => onOpen(card.id)}\n >\n {head}\n <span className={styles.cardChevron} aria-hidden=\"true\">\n {expanded ? '\\u2212' : '+'}\n </span>\n </button>\n ) : (\n <div className={styles.cardHead}>{head}</div>\n )}\n\n <div className={styles.cardMeta}>\n <span>{ENGINE_LABEL[card.engine]}</span>\n <span aria-hidden=\"true\">·</span>\n <span>{card.plan ? `${card.plan} plan` : 'plan not reported'}</span>\n </div>\n\n <p className={styles.verdictDetail}>{card.verdict.detail}</p>\n {card.verdict.code ? (\n /* The verbatim probe/collector code, kept as evidence and as the thing\n to search for — but never as the card's sentence. */\n <p className={styles.sourceLine}>\n Probe reason <code className={styles.commandInline}>{card.verdict.code}</code>\n </p>\n ) : null}\n\n {card.binding ? (\n <>\n <span className={styles.bindingLabel}>Binding constraint</span>\n <WindowMeter view={card.binding} ariaPrefix={card.label} prominent />\n </>\n ) : null}\n\n {card.others.length > 0 ? (\n <div className={styles.windows}>\n {card.others.map((w) => (\n <WindowMeter key={w.id} view={w} ariaPrefix={card.label} />\n ))}\n </div>\n ) : null}\n\n <CreditsRow credits={card.credits} />\n\n {showReconnect ? (\n <div className={styles.actionBlock}>\n {card.reconnectCommand ? (\n <>\n <span className={styles.figureLabel}>Reconnect</span>\n <code className={styles.command}>{card.reconnectCommand}</code>\n </>\n ) : (\n <p className={styles.reason}>\n Sign this account back in through its own provider CLI under its pinned profile.\n Ashlr does not print that invocation here, because the pinned-profile launcher path is\n never allowed onto a surface. <code className={styles.commandInline}>ashlr resources</code>{' '}\n shows the connection state once it is back.\n </p>\n )}\n </div>\n ) : null}\n\n {card.sourceNote ? <p className={styles.sourceLine}>{card.sourceNote}</p> : null}\n </article>\n );\n}\n","/**\n * routes/verse/usage/AccountDetail.tsx — one account, in full, on demand.\n *\n * The card answers \"can I use this\". This answers \"why, exactly\" — and it is\n * a separate surface rather than more card because the card must stay\n * readable in a glance and this is deliberately dense.\n *\n * What it shows that the card does not:\n * - EVERY window, not just the binding one, each with its own reset signal;\n * - the plan and, for Codex, the credit balance as a fact independent of\n * the window;\n * - the PROBE EVIDENCE — connection state, authentication, the monitor's\n * health verdict, the verbatim machine code, and when the reading was\n * taken. None of that is a measurement; all of it is why a measurement is\n * or is not there.\n *\n * WHAT IT DELIBERATELY DOES NOT SHOW: a history. No source this section reads\n * retains a per-account time series — `/api/verse/accounts` is a point-in-time\n * snapshot and `/api/verse/usage-series` is roster-wide with no per-account\n * breakdown — so the panel says that in one line instead of drawing a\n * one-point \"trend\" or back-filling a shape nobody measured.\n */\nimport { useEffect, useRef, type ReactNode } from 'react';\nimport { StatusBadge, type Tone } from '../../../components/primitives/StatusBadge.js';\nimport { relativePhrase } from '../context/context-model.js';\nimport { ENGINE_LABEL } from '../verse-model.js';\nimport type { AccountCardModel, AccountVerdictState } from './accounts-model.js';\nimport { WindowMeter } from './WindowMeter.js';\nimport styles from './usage.module.css';\n\nconst VERDICT_TONE: Record<AccountVerdictState, Tone> = {\n available: 'success',\n credits: 'success',\n tight: 'warning',\n exhausted: 'danger',\n 'signed-out': 'warning',\n 'probe-unsupported': 'warning',\n unknown: 'unknown',\n};\n\nexport const NO_HISTORY_NOTE =\n 'No per-account history is retained by any source this view reads: the accounts route is a point-in-time snapshot and the usage series carries no per-account breakdown. A trend is not drawn from one reading.';\n\n/**\n * Claude's health is `unknown` BY CONSTRUCTION (docs/VERSE-TELEMETRY-V2.md),\n * so rendering it as a fault would invent a problem. Every provider's\n * `unknown` is described as \"not reported\" for the same reason.\n */\nfunction healthSentence(health: string | null, provider: string): string {\n if (health === null) return 'The source behind this card reports no health verdict at all.';\n if (health === 'unknown') {\n return provider === 'claude'\n ? 'Health reads unknown, which is how this provider always reads — the probe has no health channel for it. It is not a fault.'\n : 'Health reads unknown: the monitor took no verdict on this account.';\n }\n return `Monitor health: ${health}.`;\n}\n\nfunction EvidenceRow({ label, children }: { label: string; children: ReactNode }): ReactNode {\n return (\n <div className={styles.evidenceRow}>\n <dt className={styles.figureLabel}>{label}</dt>\n <dd className={styles.evidenceValue}>{children}</dd>\n </div>\n );\n}\n\nexport function AccountDetail({\n card,\n onClose,\n headingId,\n}: {\n card: AccountCardModel;\n onClose: () => void;\n /** Ties the region back to the card's own trigger for assistive tech. */\n headingId: string;\n}): ReactNode {\n const { evidence } = card;\n const credits = card.credits;\n\n // Move focus to the heading when this opens, and again when the selection\n // moves to a different account.\n //\n // The trigger is a card in a wrapping grid, so the panel it reveals is never\n // the next thing in reading order and is often off-screen entirely. Leaving\n // focus on the card meant a keyboard or screen-reader operator pressed Enter,\n // was told \"expanded\", and then had to tab through the rest of the grid to\n // reach what they opened. `aria-controls` alone does not move anyone; only a\n // small minority of assistive tech offers to follow it.\n //\n // Keyed on `card.id`, not on every render: the 30s poll rebuilds this model\n // in place, and re-focusing on each one would yank focus out from under\n // whatever the operator was reading inside the panel.\n const headingRef = useRef<HTMLHeadingElement>(null);\n useEffect(() => {\n headingRef.current?.focus();\n }, [card.id]);\n\n return (\n <section className={styles.detail} aria-labelledby={headingId}>\n <div className={styles.detailHead}>\n <div>\n {/* tabIndex -1: a focus target for the effect above, not a tab stop. */}\n <h4 id={headingId} ref={headingRef} tabIndex={-1} className={styles.detailTitle}>\n {card.label}\n </h4>\n <div className={styles.cardMeta}>\n <span>{ENGINE_LABEL[card.engine]}</span>\n <span aria-hidden=\"true\">·</span>\n <span>{card.plan ? `${card.plan} plan` : 'plan not reported'}</span>\n <span aria-hidden=\"true\">·</span>\n <StatusBadge status={card.verdict.state} tone={VERDICT_TONE[card.verdict.state]}>\n {card.verdict.headline}\n </StatusBadge>\n </div>\n </div>\n <button type=\"button\" className={styles.ghostButton} onClick={onClose}>\n Close\n </button>\n </div>\n\n <p className={styles.verdictDetail}>{card.verdict.detail}</p>\n\n <div className={styles.detailGrid}>\n <div className={styles.detailColumn}>\n <span className={styles.figureLabel}>\n All windows ({card.allWindows.length})\n </span>\n {card.allWindows.length === 0 ? (\n <p className={styles.reason}>\n This account reported no windows at all. That is an absent reading, not a set of\n windows at zero.\n </p>\n ) : (\n <div className={styles.windows}>\n {card.allWindows.map((w, i) => (\n <WindowMeter\n key={w.id}\n view={w}\n ariaPrefix={card.label}\n prominent={i === 0}\n />\n ))}\n </div>\n )}\n {card.allWindows.some((w) => !w.measured) ? (\n <p className={styles.reason}>\n At least one window above carries a provider FLAG rather than a measurement, so no\n percentage is printed for it. A flagged limit and a measured 100% are different facts.\n </p>\n ) : null}\n </div>\n\n <div className={styles.detailColumn}>\n <span className={styles.figureLabel}>Probe evidence</span>\n <dl className={styles.evidenceList}>\n <EvidenceRow label=\"Connection\">{evidence.state}</EvidenceRow>\n <EvidenceRow label=\"Authentication\">{evidence.authentication}</EvidenceRow>\n <EvidenceRow label=\"Health\">{healthSentence(evidence.health, card.engine)}</EvidenceRow>\n <EvidenceRow label=\"Observed\">\n {evidence.observedAt === null ? (\n <span className={styles.capacityMuted}>\n no observation timestamp was reported\n </span>\n ) : (\n <span className={styles.num} title={new Date(evidence.observedAt).toLocaleString()}>\n {relativePhrase(evidence.observedAt) ?? new Date(evidence.observedAt).toLocaleString()}\n </span>\n )}\n </EvidenceRow>\n <EvidenceRow label=\"Probe reason\">\n {evidence.reasonCode === null ? (\n <span className={styles.capacityMuted}>none reported</span>\n ) : (\n <code className={styles.commandInline}>{evidence.reasonCode}</code>\n )}\n </EvidenceRow>\n {evidence.unsupported ? (\n <EvidenceRow label=\"Version pin\">\n <code className={styles.commandInline}>{evidence.unsupported.code}</code>\n {evidence.unsupported.pinnedVersion ? (\n <>\n {' '}\n pinned to <span className={styles.num}>{evidence.unsupported.pinnedVersion}</span>\n . A one-line constant bump, not an outage.\n </>\n ) : null}\n </EvidenceRow>\n ) : null}\n </dl>\n\n {credits ? (\n <div className={styles.creditsRow}>\n <span className={styles.figureLabel}>Credits</span>\n <span className={styles.num} title={credits.balance ?? undefined}>\n {credits.unlimited\n ? 'unlimited'\n : credits.balanceValue !== null\n ? credits.balanceValue.toLocaleString('en-US', { maximumFractionDigits: 2 })\n : (credits.balance ?? 'not reported')}\n </span>\n <p className={styles.reason}>\n A separate pool from every window above. The provider gives a bare number, not a\n currency, so it is shown as reported.\n </p>\n </div>\n ) : null}\n\n {evidence.notes.length > 0 ? (\n <>\n <span className={styles.figureLabel}>Provider notes</span>\n <ul className={styles.noteList}>\n {evidence.notes.map((n) => (\n <li key={n} className={styles.capacityMuted}>\n {n}\n </li>\n ))}\n </ul>\n </>\n ) : null}\n </div>\n </div>\n\n <p className={styles.sourceLine}>{NO_HISTORY_NOTE}</p>\n </section>\n );\n}\n","/**\n * routes/verse/usage/CapacityFacts.tsx — the Usage screen's machine-wide\n * facts under the shared capacity strip: when the nearest window resets, how\n * much local memory is free, and how many local models can drive a session.\n *\n * Split out of the pre-3.10 CapacityStrip when the per-seat half became the\n * ONE shared `CapacityStrip` (SPEC-310C §4). These three facts need the\n * Usage-only reads (`/api/verse/accounts`, `/api/verse/local-models`), so\n * they stay here rather than weighing down every surface that mounts the strip.\n *\n * Honesty rules, unchanged:\n * - a countdown is only ever computed from a machine-readable `resetsAt`,\n * against a LIVE clock (the model is memoized on the account data, so a\n * duration baked into it would freeze);\n * - a reset in the past is \"predates the rollover\", never a negative count;\n * - Claude's reset is provider prose, printed verbatim under its own heading;\n * - local headroom is unknown unless both the resident total and the budget\n * are known.\n */\nimport type { ReactNode } from 'react';\nimport { useEffect, useMemo, useState } from 'react';\nimport { describeResetAt } from '../../../../core/verse/seat-readiness.js';\nimport type { CapacityOverview } from './capacity-model.js';\nimport { formatUntil, nextResetAt } from './capacity-model.js';\nimport { formatBytes } from './local-model.js';\nimport styles from './usage.module.css';\n\nfunction useNow(active: boolean, intervalMs = 30_000): number {\n const [now, setNow] = useState(() => Date.now());\n useEffect(() => {\n if (!active) return;\n const id = setInterval(() => setNow(Date.now()), intervalMs);\n return () => clearInterval(id);\n }, [active, intervalMs]);\n return now;\n}\n\nexport function CapacityFacts({ overview }: { overview: CapacityOverview }): ReactNode {\n // Re-select against the live clock, not against the `overdue` flag frozen\n // into the model: the soonest reset changes as time passes, and the account\n // payload that would rebuild the model may be byte-identical for hours.\n const nowMs = useNow(overview.resets.length > 0);\n const reset = useMemo(() => nextResetAt(overview.resets, nowMs), [overview.resets, nowMs]);\n const untilMs = reset === null ? 0 : reset.atMs - nowMs;\n const overdue = untilMs <= 0;\n\n const local = overview.local;\n\n return (\n <section className={styles.capacity} aria-label=\"Resets and local headroom\">\n <dl className={styles.capacityFacts}>\n <div className={styles.capacityFact}>\n <dt className={styles.figureLabel}>Nearest reset</dt>\n <dd>\n {reset === null ? (\n <span className={styles.capacityMuted}>\n No seat reported a dated reset. That is an absent timestamp, not \"never\".\n </span>\n ) : overdue ? (\n <span className={styles.capacityMuted}>\n <span className={styles.num}>{reset.seatLabel}</span> · {reset.windowLabel} was due to\n reset {describeResetAt(new Date(reset.atMs).toISOString(), nowMs)} — this reading predates the rollover.\n </span>\n ) : (\n <>\n <span className={styles.num}>{formatUntil(untilMs)}</span>{' '}\n <span className={styles.capacityMuted}>\n · {reset.seatLabel} {reset.windowLabel}, resets{' '}\n {describeResetAt(new Date(reset.atMs).toISOString(), nowMs)}\n </span>\n </>\n )}\n </dd>\n </div>\n\n <div className={styles.capacityFact}>\n <dt className={styles.figureLabel}>Local headroom</dt>\n <dd>\n {local === null ? (\n <span className={styles.capacityMuted}>No local source answered.</span>\n ) : !local.reachable ? (\n <span className={styles.capacityMuted}>\n The local runtime did not answer this probe, so headroom is unknown — not zero, and\n not full.\n </span>\n ) : local.headroomBytes === null ? (\n <span className={styles.capacityMuted}>\n Either the resident total or the machine budget was not reported, so headroom cannot\n be computed.\n </span>\n ) : (\n <>\n <span className={styles.num}>{formatBytes(local.headroomBytes)}</span>{' '}\n <span className={styles.capacityMuted}>\n free of {formatBytes(local.memoryBudgetBytes)} · {local.residentCount} resident,{' '}\n {local.installedCount} installed\n </span>\n </>\n )}\n </dd>\n </div>\n\n <div className={styles.capacityFact}>\n <dt className={styles.figureLabel}>Agentic locally</dt>\n <dd>\n {local === null || !local.reachable ? (\n <span className={styles.capacityMuted}>unknown</span>\n ) : (\n <>\n <span className={styles.num}>{local.agenticCount}</span>{' '}\n <span className={styles.capacityMuted}>\n of {local.installedCount} installed models can drive a session\n {local.unknownToolCount > 0\n ? `; ${local.unknownToolCount} did not report a capability list`\n : ''}\n </span>\n </>\n )}\n </dd>\n </div>\n </dl>\n\n {overview.proseResets.length > 0 ? (\n <div className={styles.proseResets}>\n <span className={styles.figureLabel}>Resets reported as text</span>\n <ul className={styles.noteList}>\n {overview.proseResets.map((r) => (\n <li key={`${r.seatLabel}-${r.windowLabel}-${r.text}`} className={styles.capacityMuted}>\n {r.seatLabel} · {r.windowLabel} — {r.text}\n </li>\n ))}\n </ul>\n <p className={styles.capacityMuted}>\n These providers publish a sentence rather than a timestamp, so it is shown exactly as\n given and never turned into a countdown.\n </p>\n </div>\n ) : null}\n </section>\n );\n}\n","/**\n * routes/verse/usage/EfficiencyPanel.tsx — context efficiency per seat, across\n * every chat on this machine (V3.9, docs/VERSE-CONTEXT.md).\n *\n * The Usage section answers \"which account can I use, and what will it cost\".\n * Past the quota windows, the biggest lever on that cost is how each seat's\n * chats use their context: a chat that re-reads its prompt from cache pays a\n * fraction of one that re-reads it at full price, and a chat that keeps\n * compacting is carrying more than its budget holds. So each seat gets its\n * aggregate cache-hit ratio and compaction count — computed in the browser\n * from the session records the console already has. No request, no spend, no\n * new server state.\n *\n * Honesty rules (all enforced in context-model.ts, stated here once):\n * - ratios are computed from SUMMED tokens, never averaged per chat;\n * - \"none reported\" is not 0%: a provider that reported no cache activity\n * (Ollama) has made no claim either way;\n * - an upper-bound occupancy (codex before its rollout is read) is shown \"≤\";\n * - a seat with no chats has no row — an empty table is not a seat at 0%.\n */\nimport type { ReactNode } from 'react';\nimport { TableView, chartFormat, type TableColumn } from '../../../components/charts/index.js';\nimport { percentText } from '../autonomy/format.js';\nimport { formatTokens } from '../verse-store.js';\nimport { ENGINE_LABEL } from '../verse-model.js';\nimport { formatRatio, type SeatEfficiencyRow } from './context-model.js';\nimport styles from './usage.module.css';\n\nfunction fullestText(row: SeatEfficiencyRow): string {\n const f = row.fullest;\n if (f === null) return '—';\n const size = `${f.exact ? '' : '≤'}${formatTokens(f.tokens)}`;\n if (f.window === null) return size;\n const share = (f.tokens / f.window) * 100;\n // The one percent rule up to the window (\"99%\", never a rounded \"100%\" that\n // reads as full); past it, the real overflow (\"112%\") rather than a clamp.\n return `${size} / ${formatTokens(f.window)} · ${share <= 100 ? percentText(share) : chartFormat.formatPercent(share / 100)}`;\n}\n\nconst COLUMNS: TableColumn<SeatEfficiencyRow>[] = [\n {\n key: 'seat',\n label: 'Seat',\n render: (r) => (\n <>\n {r.label}\n <span className={styles.limitWindow}>\n {` · ${ENGINE_LABEL[r.engine]}`}\n {r.retired ? ' · no longer connected' : ''}\n </span>\n </>\n ),\n },\n { key: 'chats', label: 'Chats', numeric: true, render: (r) => chartFormat.formatCompact(r.sessions) },\n { key: 'turns', label: 'Turns', numeric: true, render: (r) => chartFormat.formatCompact(r.turns) },\n { key: 'prompt', label: 'Prompt tokens', numeric: true, render: (r) => formatTokens(r.promptTokens) },\n {\n key: 'hit',\n label: 'Cache hit',\n numeric: true,\n render: (r) => (r.cacheHitRatio !== null ? formatRatio(r.cacheHitRatio) : r.promptTokens > 0 ? 'none reported' : '—'),\n },\n { key: 'compactions', label: 'Compactions', numeric: true, render: (r) => chartFormat.formatCompact(r.compactions) },\n {\n key: 'expansive',\n label: 'Expansive chats',\n numeric: true,\n render: (r) => chartFormat.formatCompact(r.expansiveSessions),\n },\n { key: 'fullest', label: 'Fullest context', numeric: true, render: (r) => fullestText(r) },\n];\n\nexport function EfficiencyPanel({\n rows,\n unavailableReason,\n}: {\n rows: readonly SeatEfficiencyRow[];\n /** Why the chat list could not be read; null when it was. */\n unavailableReason: string | null;\n}): ReactNode {\n return (\n <section className={styles.panel} aria-labelledby=\"verse-usage-efficiency\">\n <div className={styles.panelHead}>\n <h3 id=\"verse-usage-efficiency\" className={styles.panelTitle}>\n Context efficiency\n </h3>\n <p className={styles.panelNote}>\n Per seat, across every chat on this machine. Cache hit is the share of prompt tokens served\n from the provider&apos;s cache — the higher it is, the less each turn re-reads at full price.\n Compactions are the CLI summarizing a context that outgrew its budget.\n </p>\n </div>\n\n {unavailableReason !== null ? (\n <p className={styles.muted}>{unavailableReason}</p>\n ) : rows.length === 0 ? (\n <p className={styles.muted}>\n No chats yet, so there is nothing to measure — this is an empty history, not a seat at 0%.\n Start a chat on any seat and its context use shows up here.\n </p>\n ) : (\n <div className={styles.tableScroll}>\n <TableView\n caption=\"Context efficiency per seat: chats, turns, prompt tokens, cache-hit ratio, compactions, expansive chats and the fullest context\"\n columns={COLUMNS}\n rows={[...rows]}\n rowKey={(r) => r.seatId}\n />\n </div>\n )}\n\n <p className={styles.sourceLine}>\n Computed in this browser from each chat&apos;s recorded totals — no extra request, no spend.\n &ldquo;None reported&rdquo; means the provider reported no cache activity, not a 0% hit rate; a\n figure marked &le; is an upper bound. Compactions are counted from Verse 3.9 on; earlier ones\n were not recorded.\n </p>\n </section>\n );\n}\n","/**\n * routes/verse/usage/LimitsPanel.tsx — dispatch-ledger usage against each\n * configured foundry limit.\n *\n * This is where the ledger-derived numbers belong, and they are labeled as\n * what they are: calls counted against a cap the operator configured, NOT\n * subscription utilization. A limit that owner B's /api/verse/control reports\n * as configured but for which /api/control has no reading renders as\n * \"configured · no reading\" with no bar — the same rule the window meters\n * follow.\n */\nimport type { ReactNode } from 'react';\nimport { StatusBadge, type Tone } from '../../../components/primitives/StatusBadge.js';\nimport { chartFormat } from '../../../components/charts/index.js';\nimport type { UsageLimitRow } from './usage-model.js';\nimport styles from './usage.module.css';\n\nfunction standingTone(standing: UsageLimitRow['standing']): Tone {\n switch (standing) {\n case 'ok':\n return 'success';\n case 'warn':\n return 'warning';\n case 'over':\n return 'danger';\n case 'unlimited':\n return 'neutral';\n default:\n return 'unknown';\n }\n}\n\nexport function LimitsPanel({\n rows,\n capsNote,\n}: {\n rows: readonly UsageLimitRow[];\n capsNote: string | null;\n}): ReactNode {\n return (\n <section className={styles.panel} aria-labelledby=\"verse-usage-limits\">\n <div className={styles.panelHead}>\n <h3 id=\"verse-usage-limits\" className={styles.panelTitle}>\n Dispatch limits\n </h3>\n <p className={styles.panelNote}>\n Calls recorded in the dispatch ledger against each configured foundry cap. This is not\n subscription utilization.\n </p>\n </div>\n\n {capsNote ? <p className={styles.muted}>{capsNote}</p> : null}\n\n {rows.length === 0 ? (\n <p className={styles.muted}>\n No foundry limits are configured, so dispatches are uncapped on this machine. Nothing here is\n being throttled.\n </p>\n ) : (\n <div className={styles.limitList}>\n {rows.map((row) => (\n <div key={row.id} className={styles.limitRow}>\n <span className={styles.limitName}>\n {row.backend}\n <span className={styles.limitWindow}>per {row.window}</span>\n <StatusBadge status={row.standing} tone={standingTone(row.standing)}>\n {row.standing === 'unknown' ? 'no reading' : row.standing}\n </StatusBadge>\n </span>\n {row.usedPct === null ? (\n <hr className={styles.unknownRule} aria-hidden=\"true\" />\n ) : (\n <div\n className={styles.track}\n data-tone={row.usedPct >= 100 ? 'danger' : row.usedPct >= 80 ? 'warn' : 'ok'}\n role=\"meter\"\n aria-label={`${row.backend} dispatches against its ${row.window} cap`}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={Math.round(row.usedPct)}\n >\n <div className={styles.fill} style={{ width: `${Math.round(row.usedPct)}%` }} />\n </div>\n )}\n <span className={styles.limitValue}>\n {row.used === null\n ? `configured ${chartFormat.formatCompact(row.max)}`\n : `${chartFormat.formatCompact(row.used)} / ${chartFormat.formatCompact(row.max)}`}\n </span>\n </div>\n ))}\n </div>\n )}\n </section>\n );\n}\n","/**\n * routes/verse/usage/series-model.ts — the daily token/spend series, shaped\n * for the chart primitives.\n *\n * `GET /api/verse/usage-series` returns `DailyUsage[]` straight off\n * `buildRollup(window, cfg).byDay`, which every current backend consumer\n * computes and then throws away. Charting it is the cheapest honest win on\n * this surface — but three of its columns are not what a glancing reader\n * would assume, so each one is labelled at the point of display:\n *\n * - `estCostUsd` is ESTIMATED from a static price table in the repo. It is\n * not a bill, not a quote, and will not match a provider invoice.\n * - `cacheRead` / `cacheWrite` are HARDCODED 0 for Codex upstream. A window\n * with Codex traffic therefore understates cache activity, and Codex's\n * cache economics are not comparable to Claude's. Where no day in the\n * window carries a rate at all, the chart is refused rather than drawn as\n * a flat 0% line.\n * - A day with no rollup row is a GAP (`null`), not a measured zero. The\n * chart primitives break the line at a null by contract, so nothing here\n * back-fills.\n *\n * Pure: no React, no I/O.\n */\nimport type { Series, SeriesPoint } from '../../../components/charts/index.js';\nimport type { DailyUsage, SeriesWindow, UsageSeries } from './usage-contract.js';\nimport { calendarDayStart } from '../growth/calendar-day.js';\n\nexport const COST_ESTIMATE_NOTE =\n 'Cost is ESTIMATED from a static price table in this repo, not billed. It will not match a provider invoice.';\n\nexport const CACHE_CAVEAT =\n 'Codex reports cacheRead and cacheWrite as a hardcoded 0 upstream, so any window containing Codex traffic understates cache activity — its cache economics are not comparable to Claude’s.';\n\nexport const LOCAL_SAVINGS_NOTE =\n 'A flat heuristic of $3 per 1M local tokens, not a quote and not a measured price.';\n\nexport const SERIES_TOO_THIN =\n 'Fewer than two days in this window carry a rollup row, which is not a trend.';\n\n/**\n * Why there is no per-day local/cloud line, stated where the chart would be.\n *\n * `GET /api/verse/usage-series` returns `buildRollup(window, cfg).byDay`, and\n * `DailyUsage` has no per-engine or per-tier columns at all — the tier split\n * exists only in `/api/control`'s `usage.byProvider`, which is a single\n * AGGREGATE for its window with no dates on it. Splitting the daily totals by\n * the aggregate's ratio would draw a smooth, plausible, entirely invented\n * pair of lines. So the chart is refused and the aggregate is shown instead,\n * under its own window, labelled as an aggregate.\n */\nexport const LOCAL_CLOUD_SERIES_UNAVAILABLE =\n 'The daily rollup carries no per-engine or local/cloud columns, and the only tier split available is a single aggregate with no dates on it. Apportioning the daily totals by that aggregate\\u2019s ratio would invent a shape nobody measured, so no per-day split is drawn — the aggregate below is the real figure.';\n\nexport type SeriesProjection =\n | { available: true; series: Series[]; days: DailyUsage[] }\n | { available: false; reason: string };\n\n/** Days that carry at least one non-null reading for `pick`. */\nfunction knownCount(days: readonly DailyUsage[], pick: (d: DailyUsage) => number | null): number {\n return days.reduce((acc, d) => acc + (pick(d) === null ? 0 : 1), 0);\n}\n\nfunction points(days: readonly DailyUsage[], pick: (d: DailyUsage) => number | null): SeriesPoint[] {\n // Each day at LOCAL midnight (growth/calendar-day): the chart kit labels x in\n // local time, so a UTC-midnight stamp read \"Sep 23\" for the \"2026-09-24\"\n // row west of UTC while the table under the same card said \"Sep 24\".\n return days.map((d) => ({ x: calendarDayStart(d.day), y: pick(d) }));\n}\n\nexport interface SeriesTotals {\n tokensIn: number;\n tokensOut: number;\n estCostUsd: number;\n sessions: number;\n /** Days actually present in the window — the denominator behind any average. */\n dayCount: number;\n}\n\nexport function totalsFor(days: readonly DailyUsage[]): SeriesTotals {\n return days.reduce<SeriesTotals>(\n (acc, d) => ({\n tokensIn: acc.tokensIn + d.tokensIn,\n tokensOut: acc.tokensOut + d.tokensOut,\n estCostUsd: acc.estCostUsd + d.estCostUsd,\n sessions: acc.sessions + d.sessions,\n dayCount: acc.dayCount + 1,\n }),\n { tokensIn: 0, tokensOut: 0, estCostUsd: 0, sessions: 0, dayCount: 0 },\n );\n}\n\n/** Tokens in and out as two named series — never stacked, never summed away. */\nexport function buildTokenSeries(series: UsageSeries | null): SeriesProjection {\n if (!series) return { available: false, reason: 'No usage series has been loaded.' };\n if (series.days.length < 2) return { available: false, reason: SERIES_TOO_THIN };\n return {\n available: true,\n days: series.days,\n series: [\n { id: 'tokensIn', label: 'Tokens in', points: points(series.days, (d) => d.tokensIn) },\n { id: 'tokensOut', label: 'Tokens out', points: points(series.days, (d) => d.tokensOut) },\n ],\n };\n}\n\nexport function buildSpendSeries(series: UsageSeries | null): SeriesProjection {\n if (!series) return { available: false, reason: 'No usage series has been loaded.' };\n if (series.days.length < 2) return { available: false, reason: SERIES_TOO_THIN };\n return {\n available: true,\n days: series.days,\n series: [\n { id: 'estCostUsd', label: 'Estimated spend', points: points(series.days, (d) => d.estCostUsd) },\n ],\n };\n}\n\n/**\n * Cache hit rate, only where the provider actually gave one. A window in which\n * NO day carries a rate is refused outright — drawing it would put a flat 0%\n * line on screen that a glancing reader would take for \"the cache never hits\",\n * when the truth is \"nothing reported a rate\".\n */\nexport function buildCacheSeries(series: UsageSeries | null): SeriesProjection {\n if (!series) return { available: false, reason: 'No usage series has been loaded.' };\n const known = knownCount(series.days, (d) => d.cacheHitRate);\n if (known === 0) {\n return {\n available: false,\n reason:\n 'No day in this window reported a cache hit rate, so there is nothing to plot. This is an absent signal, not a 0% hit rate.',\n };\n }\n if (known < 2) {\n return {\n available: false,\n reason: `Only ${known} day in this window reported a cache hit rate, which is not a trend.`,\n };\n }\n return {\n available: true,\n days: series.days,\n series: [\n { id: 'cacheHitRate', label: 'Cache hit rate', points: points(series.days, (d) => d.cacheHitRate) },\n ],\n };\n}\n\n/**\n * Cache READ and WRITE token counts, which are a different fact from the hit\n * RATE: a day can have a healthy rate on tiny volume. Refused outright when no\n * day reports either column, because a flat pair of zero lines would read as\n * \"the cache did nothing\" when the truth is \"nothing was reported\".\n */\nexport function buildCacheTokenSeries(series: UsageSeries | null): SeriesProjection {\n if (!series) return { available: false, reason: 'No usage series has been loaded.' };\n const known =\n knownCount(series.days, (d) => d.cacheRead) + knownCount(series.days, (d) => d.cacheWrite);\n if (known === 0) {\n return {\n available: false,\n reason:\n 'No day in this window reported cache read or write tokens, so there is nothing to plot. This is an absent signal, not zero cache activity.',\n };\n }\n if (series.days.length < 2) return { available: false, reason: SERIES_TOO_THIN };\n return {\n available: true,\n days: series.days,\n series: [\n { id: 'cacheRead', label: 'Cache read', points: points(series.days, (d) => d.cacheRead) },\n { id: 'cacheWrite', label: 'Cache write', points: points(series.days, (d) => d.cacheWrite) },\n ],\n };\n}\n\nexport interface SeriesAverages {\n /** Per RECORDED day, not per calendar day — the denominator is stated. */\n tokensInPerDay: number | null;\n tokensOutPerDay: number | null;\n estCostUsdPerDay: number | null;\n /** The busiest recorded day, for \"what does a heavy day cost me\". */\n peakCostDay: { day: string; usd: number } | null;\n}\n\n/**\n * Averages over the days that actually carry a row. Dividing by the window\n * length instead would understate every figure by however many days the\n * rollup has no data for, which is the difference between \"I spend $4 a day\"\n * and \"I spend $4 on the days I work\".\n */\nexport function averagesFor(days: readonly DailyUsage[]): SeriesAverages {\n if (days.length === 0) {\n return {\n tokensInPerDay: null,\n tokensOutPerDay: null,\n estCostUsdPerDay: null,\n peakCostDay: null,\n };\n }\n const totals = totalsFor(days);\n const peak = days.reduce((best, d) => (d.estCostUsd > best.estCostUsd ? d : best));\n return {\n tokensInPerDay: totals.tokensIn / days.length,\n tokensOutPerDay: totals.tokensOut / days.length,\n estCostUsdPerDay: totals.estCostUsd / days.length,\n peakCostDay: { day: peak.day, usd: peak.estCostUsd },\n };\n}\n\n/** Sparkline input for a stat tile: gaps preserved as nulls. */\nexport function sparklinePoints(\n series: UsageSeries | null,\n pick: (d: DailyUsage) => number | null,\n): (number | null)[] | undefined {\n if (!series || series.days.length < 2) return undefined;\n return series.days.map(pick);\n}\n\nexport const WINDOW_LABEL: Record<SeriesWindow, string> = {\n '7d': 'Last 7 days',\n '30d': 'Last 30 days',\n};\n","/**\n * routes/verse/usage/LocalCloudPanel.tsx — where the period's work actually\n * ran, and what running it locally did NOT cost.\n *\n * `localSavingsUsd` is framed as money not spent rather than as revenue or a\n * balance, because that is exactly what it is: an estimate of what the same\n * local tokens would have cost at cloud list price. The bar chart is single-\n * hue (nominal providers never get a value ramp) and ships the table twin\n * that ChartContainer expects.\n */\nimport type { CSSProperties, ReactNode } from 'react';\nimport {\n BarChart,\n ChartContainer,\n Legend,\n StatTile,\n TableView,\n chartFormat,\n seriesColor,\n type TableColumn,\n} from '../../../components/charts/index.js';\nimport { percentText } from '../autonomy/format.js';\nimport { COST_ESTIMATE_NOTE } from './series-model.js';\nimport type { LocalCloudSplit, ProviderSlice } from './usage-model.js';\nimport styles from './usage.module.css';\n\nconst LOCAL_COLOR = seriesColor(0);\nconst CLOUD_COLOR = seriesColor(1);\n\nconst COLUMNS: TableColumn<ProviderSlice>[] = [\n { key: 'provider', label: 'Provider', render: (r) => r.provider },\n { key: 'tier', label: 'Tier', render: (r) => r.tier },\n { key: 'tokens', label: 'Tokens', numeric: true, render: (r) => chartFormat.formatCompact(r.tokens) },\n { key: 'cost', label: 'Cost', numeric: true, render: (r) => chartFormat.formatUsd(r.costUsd) },\n { key: 'share', label: 'Share', numeric: true, render: (r) => percentText(r.sharePct) },\n];\n\nfunction SplitRow({ label, tokens, total, color }: { label: string; tokens: number; total: number; color: string }): ReactNode {\n const share = total > 0 ? (tokens / total) * 100 : 0;\n const pct = Math.round(share);\n return (\n <div className={styles.splitRow}>\n <span>{label}</span>\n <div\n className={styles.splitBar}\n role=\"meter\"\n aria-label={`${label} share of tokens`}\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={pct}\n >\n <div className={styles.splitFill} style={{ width: `${pct}%`, '--split-color': color } as CSSProperties} />\n </div>\n <span className={styles.num}>\n {chartFormat.formatCompact(tokens)} · {percentText(share)}\n </span>\n </div>\n );\n}\n\nexport function LocalCloudPanel({\n split,\n savingsNote,\n}: {\n split: LocalCloudSplit;\n /**\n * The estimate disclosure for `localSavingsUsd`. It is a flat heuristic with\n * the constant inlined in control.ts, so the caption says so at the point of\n * display rather than letting a dollar figure imply a measured price.\n */\n savingsNote?: string;\n}): ReactNode {\n const totalTokens = split.localTokens + split.cloudTokens;\n const chartData = split.byProvider.map((p) => ({ label: p.provider, value: p.tokens }));\n\n return (\n <section className={styles.panel} aria-labelledby=\"verse-usage-split\">\n <div className={styles.panelHead}>\n <h3 id=\"verse-usage-split\" className={styles.panelTitle}>\n Local vs cloud · {split.window}\n </h3>\n </div>\n\n <div className={styles.tiles}>\n <StatTile\n label=\"Not spent (ran locally)\"\n value={<span className={styles.num}>{chartFormat.formatUsd(split.localSavingsUsd)}</span>}\n caption={`Estimated cloud list price of the ${split.window} local tokens. ${\n savingsNote ?? 'A heuristic, not a quote.'\n }`}\n />\n {/* Two things this tile used to get wrong, and both mattered.\n (1) NOT BILLED: the figure is `rollup.totals.estCostUsd` — the same\n static price-table estimate SeriesPanel labels \"Estimated spend\" —\n so captioning it \"Billed\" invited planning a month around it.\n (2) NOT CLOUD: `totalCostUsd` is the rollup total across every\n model, local included. `cloudCostUsd` is the cloud-only figure and\n is what this tile claims to show. */}\n <StatTile\n label={`Estimated cloud spend · ${split.window}`}\n value={<span className={styles.num}>{chartFormat.formatUsd(split.cloudCostUsd)}</span>}\n caption={COST_ESTIMATE_NOTE}\n />\n <StatTile\n label={`Tokens · ${split.window}`}\n value={<span className={styles.num}>{chartFormat.formatCompact(split.totalTokens)}</span>}\n caption=\"Local and cloud combined\"\n />\n </div>\n\n {split.empty ? (\n <p className={styles.muted} style={{ marginTop: 'var(--space-4)' }}>\n No provider activity recorded in this window. Choose a longer window, or run a chat turn and it\n appears here.\n </p>\n ) : (\n <>\n <div className={styles.split} style={{ marginTop: 'var(--space-4)' }}>\n <SplitRow label=\"Local\" tokens={split.localTokens} total={totalTokens} color={LOCAL_COLOR} />\n <SplitRow label=\"Cloud\" tokens={split.cloudTokens} total={totalTokens} color={CLOUD_COLOR} />\n </div>\n <Legend\n items={[\n { label: 'Local', color: LOCAL_COLOR, kind: 'swatch' },\n { label: 'Cloud', color: CLOUD_COLOR, kind: 'swatch' },\n ]}\n />\n <ChartContainer\n title=\"Tokens by provider\"\n description={`Share of the ${split.window} window`}\n empty={chartData.length === 0}\n emptyMessage=\"No provider rows in this window.\"\n table={\n <TableView\n caption=\"Tokens and cost by provider\"\n columns={COLUMNS}\n rows={split.byProvider}\n rowKey={(r) => r.provider}\n />\n }\n >\n <BarChart\n data={chartData}\n orientation=\"horizontal\"\n height={Math.max(120, chartData.length * 34)}\n formatValue={(v) => chartFormat.formatCompact(v)}\n ariaLabel={`Tokens by provider over the ${split.window} window`}\n />\n </ChartContainer>\n </>\n )}\n </section>\n );\n}\n","/**\n * routes/verse/usage/LocalModelsPanel.tsx — local availability as a\n * first-class capacity surface, not a list of installed files.\n *\n * A local seat has no subscription and no quota, so the honest analogue of a\n * meter is RESIDENT BYTES AGAINST THE MACHINE'S MEMORY BUDGET: that is what\n * decides whether a model can answer right now. Around it sit the facts the\n * old surface fetched and discarded (docs/VERSE-TELEMETRY-V2.md):\n *\n * - resident vs installed, as counts AND as a memory chart, because \"12\n * models installed\" and \"nothing loaded\" are compatible and only one of\n * them is about capacity;\n * - the GPU/CPU split from `size_vram` / `placement`, drawn as a two-segment\n * bar: a model that half-spilled to the CPU is usable but slow, and that\n * is a fact to see before picking the seat, not mid-turn;\n * - the keep-alive countdown from `expires_at`, which ticks;\n * - and the hard gate: whether the model advertises `tools`. A model without\n * it CANNOT drive an agentic session at any speed, so it is marked in the\n * row, counted in the summary, and filterable — not buried in a column.\n *\n * `capabilities: null` is rendered as unknown, never as \"no tools\": refusing\n * to answer and answering \"no\" are different facts.\n *\n * STALENESS (V2.1): when a runtime probe times out the server serves the last\n * known-good report with `stale: true` and `staleForMs`. That is the right\n * call — a timeout is \"no answer yet\", not \"the runtime is gone\" — but it\n * obliges this panel to say the numbers are N seconds old, in words, above\n * everything they describe.\n */\nimport type { CSSProperties, ReactNode } from 'react';\nimport { useEffect, useMemo, useState } from 'react';\nimport { Epistemic } from '../../../components/primitives/Epistemic.js';\nimport { StatusBadge, type Tone } from '../../../components/primitives/StatusBadge.js';\nimport {\n BarChart,\n ChartContainer,\n TableView,\n chartFormat,\n seriesColor,\n type TableColumn,\n} from '../../../components/charts/index.js';\nimport type { ServingRuntimeSnapshot } from '../autonomy/fleet-contract.js';\nimport { runtimeCapacity } from '../autonomy/fleet-model.js';\nimport { percentText } from '../autonomy/format.js';\nimport type { AccountVerdictState, LocalCardModel } from './accounts-model.js';\nimport {\n formatAge,\n formatBytes,\n formatContext,\n formatCountdown,\n localStaleness,\n type LocalModelRow,\n type LocalModelsView,\n type LocalStaleness,\n} from './local-model.js';\nimport { unknownQuality } from './usage-model.js';\nimport styles from './usage.module.css';\n\nconst VERDICT_TONE: Record<AccountVerdictState, Tone> = {\n available: 'success',\n credits: 'success',\n tight: 'warning',\n exhausted: 'danger',\n 'signed-out': 'warning',\n 'probe-unsupported': 'warning',\n unknown: 'unknown',\n};\n\nconst GPU_COLOR = seriesColor(0);\nconst CPU_COLOR = seriesColor(5);\n\n/**\n * A keep-alive countdown that does not tick is worse than no countdown, so\n * this re-renders while (and only while) something is actually expiring.\n * 5s is slow enough to be invisible work and fast enough that the number on\n * screen is never meaningfully wrong.\n */\nfunction useNow(active: boolean, intervalMs = 5000): number {\n const [now, setNow] = useState(() => Date.now());\n useEffect(() => {\n if (!active) return;\n const id = setInterval(() => setNow(Date.now()), intervalMs);\n return () => clearInterval(id);\n }, [active, intervalMs]);\n return now;\n}\n\n/**\n * The keep-alive countdown, derived from the expiry INSTANT against a live\n * clock. The row's `expiresInMs` was computed when `buildLocalModelsView` ran\n * and is frozen inside that memo, so rendering it would show the same number\n * until the local-models payload itself changed — a stopped clock with a\n * second hand painted on.\n */\nfunction KeepAliveCell({ row }: { row: LocalModelRow }): ReactNode {\n const at = row.resident ? row.expiresAtMs : null;\n const now = useNow(at !== null);\n if (at === null) return '—';\n return formatCountdown(at - now);\n}\n\n/**\n * The agentic gate, rendered so it cannot be skimmed past: a danger-toned\n * badge with the words \"no tools\", not a quiet cell. The unknown case gets the\n * shared Epistemic treatment instead, because the runtime declining to answer\n * is not the model saying no.\n */\nfunction ToolsCell({ row }: { row: LocalModelRow }): ReactNode {\n if (row.tools === 'unknown') {\n return (\n <Epistemic\n quality={unknownQuality('The runtime did not report a capability list for this model.')}\n label={`${row.name} tool support`}\n >\n {null}\n </Epistemic>\n );\n }\n return row.tools === 'supported' ? (\n <StatusBadge status=\"agentic\" tone=\"success\">\n tools\n </StatusBadge>\n ) : (\n <StatusBadge status=\"no-tools\" tone=\"danger\">\n no tools\n </StatusBadge>\n );\n}\n\n/**\n * `sizeBytes` is NOT a residency figure for an unloaded model: core's\n * `local-models.ts` sets it to `live?.sizeBytes ?? tag.sizeBytes`, and\n * `tag.sizeBytes` is the ON-DISK size from `/api/tags`. Under this column's\n * old \"Resident size\" header, a machine with nothing resident and twelve\n * installed models showed a multi-GB figure on every row — tens of gigabytes\n * that read as memory in use when the true resident total was zero, which is\n * the exact \"can I run this now\" question this panel exists to answer. The\n * header is now \"Size\" and the State column carries residency; the tooltip\n * says which figure this is for this row.\n */\nfunction SizeCell({ row }: { row: LocalModelRow }): ReactNode {\n if (row.sizeBytes === null) return <span>—</span>;\n const provenance = row.resident\n ? 'Resident size reported by the runtime.'\n : 'On-disk size; this model is not resident, so it is using no memory.';\n return (\n <span title={provenance}>\n {formatBytes(row.sizeBytes)}\n {row.resident && row.memoryPct !== null ? ` · ${percentText(row.memoryPct)} of machine` : ''}\n </span>\n );\n}\n\n/**\n * The GPU/CPU split as a two-segment bar.\n *\n * Only a RESIDENT model has a placement — an installed one is on disk and\n * occupies neither. An unreported split draws nothing rather than assuming\n * \"all GPU\", which is the flattering guess and the wrong one.\n */\nfunction PlacementCell({ row }: { row: LocalModelRow }): ReactNode {\n if (!row.resident) return <span className={styles.capacityMuted}>not resident</span>;\n if (row.gpuPct === null) {\n return (\n <Epistemic\n quality={unknownQuality('The runtime reported no VRAM split for this resident model.')}\n label={`${row.name} placement`}\n >\n {null}\n </Epistemic>\n );\n }\n const gpu = Math.round(row.gpuPct);\n return (\n <span className={styles.placement}>\n <span\n className={styles.placementBar}\n role=\"img\"\n aria-label={`${row.name}: ${percentText(row.gpuPct)} of resident bytes on GPU, ${percentText(100 - row.gpuPct)} on CPU`}\n >\n <span\n className={styles.placementGpu}\n style={{ width: `${gpu}%`, '--split-color': GPU_COLOR } as CSSProperties}\n />\n <span\n className={styles.placementCpu}\n style={{ width: `${100 - gpu}%`, '--split-color': CPU_COLOR } as CSSProperties}\n />\n </span>\n <span className={styles.placementText}>\n {row.placement === 'unknown' ? `${percentText(row.gpuPct)} GPU` : `${row.placement} · ${percentText(row.gpuPct)} GPU`}\n </span>\n </span>\n );\n}\n\nfunction ContextCell({ row }: { row: LocalModelRow }): ReactNode {\n if (row.nativeContext === null && row.configuredContext === null) return <span>—</span>;\n if (!row.contextTruncated) return <span>{formatContext(row.nativeContext ?? row.configuredContext)}</span>;\n return (\n <span title={`Native context is ${formatContext(row.nativeContext)}; Ashlr runs this seat at ${formatContext(row.configuredContext)}.`}>\n {`${formatContext(row.configuredContext)} of ${formatContext(row.nativeContext)}`}\n </span>\n );\n}\n\nconst COLUMNS: TableColumn<LocalModelRow>[] = [\n { key: 'name', label: 'Model', render: (r) => r.name },\n {\n key: 'state',\n label: 'State',\n render: (r) =>\n r.resident ? (\n <StatusBadge status=\"resident\" tone=\"success\">\n resident\n </StatusBadge>\n ) : (\n <StatusBadge status=\"installed\" tone=\"neutral\">\n installed\n </StatusBadge>\n ),\n },\n { key: 'tools', label: 'Agentic', render: (r) => <ToolsCell row={r} /> },\n { key: 'size', label: 'Size', numeric: true, render: (r) => <SizeCell row={r} /> },\n { key: 'placement', label: 'Placement', render: (r) => <PlacementCell row={r} /> },\n { key: 'params', label: 'Params', numeric: true, render: (r) => r.parameterSize ?? '—' },\n { key: 'quant', label: 'Quant', render: (r) => r.quantization ?? '—' },\n { key: 'context', label: 'Context', numeric: true, render: (r) => <ContextCell row={r} /> },\n { key: 'keepalive', label: 'Keep-alive', numeric: true, render: (r) => <KeepAliveCell row={r} /> },\n];\n\n/**\n * The staleness sentence. It says the age in words, names the runtimes, and\n * states outright that this is the last KNOWN-GOOD reading rather than a fresh\n * one — which is the difference between a number an operator can act on and\n * one that quietly misleads.\n */\nexport function StaleNotice({ staleness }: { staleness: LocalStaleness }): ReactNode {\n if (!staleness.stale) return null;\n return (\n <p className={styles.staleNotice} role=\"status\">\n <span className={styles.staleFlag}>last known-good</span> Every local figure below is the last\n known-good reading from {formatAge(staleness.staleForMs)} ago\n {staleness.runtimes.length > 0 ? ` (${staleness.runtimes.join(', ')})` : ''}, not a fresh\n probe: the runtime did not answer in time and the server kept the previous report rather than\n erasing it.\n </p>\n );\n}\n\nexport function LocalCard({\n card,\n staleness,\n}: {\n card: LocalCardModel;\n staleness?: LocalStaleness | undefined;\n}): ReactNode {\n const engineStyle = { '--engine-color': card.color } as CSSProperties;\n const pct = card.usedPct === null ? null : Math.round(card.usedPct);\n const pctText = card.usedPct === null ? null : percentText(card.usedPct);\n\n return (\n <article className={styles.card} style={engineStyle} aria-label=\"Local usage\">\n <div className={styles.cardHead}>\n <span className={styles.cardLabel}>Local</span>\n <StatusBadge status={card.verdict.state} tone={VERDICT_TONE[card.verdict.state]}>\n {card.verdict.headline}\n </StatusBadge>\n </div>\n\n <div className={styles.cardMeta}>\n <span>Ollama</span>\n <span aria-hidden=\"true\">·</span>\n <span>no subscription, no quota, no bill</span>\n </div>\n\n {staleness?.stale ? <StaleNotice staleness={staleness} /> : null}\n\n <p className={styles.verdictDetail}>{card.verdict.detail}</p>\n {card.verdict.code ? (\n /* The runtime's verbatim probe code, kept as evidence beside the\n sentence rather than standing in for it — same treatment an account\n card gives a collector code. */\n <p className={styles.sourceLine}>\n Probe reason <code className={styles.commandInline}>{card.verdict.code}</code>\n </p>\n ) : null}\n\n <span className={styles.bindingLabel}>Memory budget</span>\n {pct === null ? (\n <div className={styles.windowBlockLead}>\n <div className={styles.windowHead}>\n <span>Resident against machine memory</span>\n <Epistemic\n quality={unknownQuality(\n 'Either the resident size or the machine memory budget was not reported, so no share can be computed.',\n )}\n label=\"local memory budget\"\n >\n {null}\n </Epistemic>\n </div>\n <hr className={styles.unknownRule} aria-hidden=\"true\" />\n </div>\n ) : (\n <div className={styles.windowBlockLead}>\n <div className={styles.windowHead}>\n <span>Resident against machine memory</span>\n <span className={styles.windowPct}>{pctText}</span>\n </div>\n <div\n className={styles.track}\n data-tone={card.tone}\n role=\"meter\"\n aria-label=\"Local resident models against machine memory budget\"\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={pct}\n aria-valuetext={`${formatBytes(card.residentBytes)} of ${formatBytes(card.memoryBudgetBytes)} resident`}\n >\n <div className={styles.fill} style={{ width: `${pct}%` }} />\n </div>\n <p className={styles.windowReset}>\n {formatBytes(card.residentBytes)} of {formatBytes(card.memoryBudgetBytes)}\n </p>\n </div>\n )}\n\n <p className={styles.sourceLine}>\n {card.residentCount} resident · {card.installedCount} installed\n </p>\n </article>\n );\n}\n\n/**\n * The concurrency note.\n *\n * Residency and concurrency are different questions, and this panel answers\n * only the first. A model can be resident, fit entirely in VRAM, advertise\n * tools — and still be servable to exactly one agent at a time, because that\n * is a property of the RUNTIME, not the model. Measured on this machine\n * (docs/LOCAL-FLEET.md), four concurrent Qwen3.8 requests to Ollama returned\n * staggered four seconds apart while the same weights on llama-server returned\n * together.\n *\n * So the panel states the boundary rather than letting a full \"Resident now\"\n * tile imply a fleet. When the caller hands it the serving runtime it prints\n * the real figure; when it does not, it says where the answer lives instead of\n * quoting a number it has no source for.\n */\nfunction ConcurrencyNote({ serving }: { serving: ServingRuntimeSnapshot | null | undefined }): ReactNode {\n if (serving === undefined) {\n return (\n <p className={styles.sourceLine}>\n Residency is not concurrency. How many local agents can run at once is decided by the serving\n runtime, not by these models — a resident model can still be served to one agent at a time.\n The serving runtime and its real slot count are in Autonomy.\n </p>\n );\n }\n const capacity = runtimeCapacity(serving);\n return (\n <p className={styles.sourceLine}>\n <strong>{capacity.headline}.</strong> {capacity.detail}\n </p>\n );\n}\n\nexport function LocalModelsPanel({\n view,\n serving,\n}: {\n view: LocalModelsView | null;\n /**\n * The serving runtime, when the host has it. `undefined` means this caller\n * does not supply one — which is rendered as \"the answer is in Autonomy\",\n * never as a concurrency of zero or one.\n */\n serving?: ServingRuntimeSnapshot | null;\n}): ReactNode {\n const [agenticOnly, setAgenticOnly] = useState(false);\n // The keep-alive countdown subscribes to the clock in its own cell\n // (`KeepAliveCell`), where the value is actually derived — re-rendering the\n // whole panel around a frozen number achieved nothing.\n\n const staleness = useMemo(() => localStaleness(view?.runtimes ?? []), [view]);\n\n // The filter hides models that CANNOT drive a session. It deliberately keeps\n // the `unknown` ones: hiding a model because its runtime declined to answer\n // would turn an unanswered question into a verdict.\n const rows = useMemo(\n () => (agenticOnly ? (view?.rows ?? []).filter((r) => r.tools !== 'unsupported') : (view?.rows ?? [])),\n [view, agenticOnly],\n );\n\n const residentRows = useMemo(() => rows.filter((r) => r.resident && r.sizeBytes !== null), [rows]);\n\n return (\n <section className={styles.panel} aria-labelledby=\"verse-usage-local\">\n <div className={styles.panelHead}>\n <h3 id=\"verse-usage-local\" className={styles.panelTitle}>\n Local availability\n </h3>\n <p className={styles.panelNote}>\n Resident models answer immediately. A model without tool support cannot drive an agentic\n session at all, however much memory is free.\n </p>\n </div>\n\n <ConcurrencyNote serving={serving} />\n\n <StaleNotice staleness={staleness} />\n\n {view === null ? (\n <p className={styles.muted}>\n No local-model source answered, so neither resident nor installed models can be listed. This\n is a missing source, not an empty machine. Start Ollama (<code className={styles.commandInline}>ollama serve</code>)\n or llama-server, and this fills in on the next check.\n </p>\n ) : !view.reachable ? (\n /* `view.reason` is a machine code, not a sentence. It is shown as\n evidence after the sentence rather than being the whole panel. */\n <p className={styles.muted}>\n No local runtime answered this probe, so nothing about local models can be read. That is an\n unanswered probe, not a report that no models are installed. Start Ollama\n (<code className={styles.commandInline}>ollama serve</code>) or llama-server, then check again.\n {view.reason ? (\n <>\n {' '}\n Probe reason <code className={styles.commandInline}>{view.reason}</code>.\n </>\n ) : null}\n </p>\n ) : view.rows.length === 0 ? (\n <p className={styles.muted}>\n The local runtime answered and reports no installed models. Pull one to give Ashlr a local\n seat.\n </p>\n ) : (\n <>\n <div className={styles.tiles}>\n <StatFigure\n label=\"Resident now\"\n value={String(view.rows.filter((r) => r.resident).length)}\n caption={\n view.residentBytes === null\n ? 'At least one resident model reported no size, so the total is withheld rather than understated.'\n : `${formatBytes(view.residentBytes)} in memory`\n }\n />\n <StatFigure\n label=\"Installed\"\n value={String(view.rows.length)}\n caption=\"On disk; the first turn on one of these pays a load\"\n />\n <StatFigure\n label=\"Can drive a session\"\n value={String(view.agenticCount)}\n caption={\n view.unknownToolCount > 0\n ? `${view.nonAgenticCount} cannot; ${view.unknownToolCount} did not report a capability list`\n : `${view.nonAgenticCount} cannot drive one`\n }\n />\n <StatFigure\n label=\"Machine memory\"\n value={\n view.memoryBudgetBytes === null ? 'unknown' : formatBytes(view.memoryBudgetBytes)\n }\n caption={\n view.freeMemoryBytes === null\n ? 'The machine reported no free-memory figure.'\n : `${formatBytes(view.freeMemoryBytes)} reported free by the OS`\n }\n />\n </div>\n\n <div className={styles.panelActions}>\n <button\n type=\"button\"\n className={styles.segment}\n aria-pressed={agenticOnly}\n onClick={() => setAgenticOnly((v) => !v)}\n >\n Hide models that cannot drive a session\n </button>\n {view.nonAgenticCount > 0 ? (\n <span className={styles.capacityMuted}>\n {view.nonAgenticCount} of {view.rows.length} installed models cannot drive an agentic\n session.\n </span>\n ) : null}\n </div>\n\n <div className={styles.tableScroll}>\n <TableView\n caption=\"Local models: residency, tool support, size, placement, parameters, quantization, context and keep-alive\"\n columns={COLUMNS}\n rows={rows}\n rowKey={(r) => `${r.runtime ?? 'runtime'}:${r.name}`}\n />\n </div>\n\n <div className={styles.charts}>\n <ChartContainer\n title=\"Resident memory by model\"\n description=\"What is actually in memory right now\"\n caveat=\"Only models the runtime reports as resident WITH a size appear here. An installed model occupies no memory and is not a bar at zero.\"\n empty={residentRows.length === 0}\n emptyMessage=\"Nothing is resident, so there is no memory in use to chart. That is an idle machine, not a zero reading.\"\n table={\n <TableView\n caption=\"Resident size per model\"\n columns={[\n { key: 'name', label: 'Model', render: (r: LocalModelRow) => r.name },\n {\n key: 'size',\n label: 'Resident',\n numeric: true,\n render: (r: LocalModelRow) => formatBytes(r.sizeBytes),\n },\n ]}\n rows={residentRows}\n rowKey={(r) => r.name}\n />\n }\n >\n <BarChart\n data={residentRows.map((r) => ({ label: r.name, value: r.sizeBytes }))}\n orientation=\"horizontal\"\n height={Math.max(120, residentRows.length * 34)}\n formatValue={(v) => formatBytes(v)}\n ariaLabel=\"Resident memory by local model\"\n />\n </ChartContainer>\n </div>\n\n {view.runtimes.length > 0 ? (\n <ul className={styles.noteList}>\n {view.runtimes.map((r) => (\n <li key={r.runtime} className={styles.capacityMuted}>\n {r.runtime}:{' '}\n {r.reachable\n ? `${r.modelCount} model${r.modelCount === 1 ? '' : 's'} reported`\n : 'did not answer'}\n {r.stale ? ` · retained reading, ${formatAge(r.staleForMs)} old` : ''}\n {r.reason ? ' · ' : ''}\n {r.reason ? <code className={styles.commandInline}>{r.reason}</code> : null}\n </li>\n ))}\n </ul>\n ) : null}\n\n {view.notes.length > 0 ? (\n <ul className={styles.noteList}>\n {view.notes.map((n) => (\n <li key={n} className={styles.capacityMuted}>\n {n}\n </li>\n ))}\n </ul>\n ) : null}\n\n <p className={styles.sourceLine}>\n Sizes and the GPU share come from the runtime&apos;s own resident report; a model with no\n reported VRAM split shows no placement bar rather than being drawn as fully on GPU.{' '}\n {chartFormat.formatCompact(view.rows.length)} models installed.\n </p>\n </>\n )}\n </section>\n );\n}\n\n/**\n * A local figure tile. Deliberately NOT `StatTile`: that primitive is built\n * around a sparkline and a delta, and there is no local time series to put in\n * one — a tile with an empty trend slot invites the eye to look for a trend\n * that does not exist.\n */\nfunction StatFigure({\n label,\n value,\n caption,\n}: {\n label: string;\n value: string;\n caption: string;\n}): ReactNode {\n return (\n <div className={styles.figureTile}>\n <span className={styles.figureLabel}>{label}</span>\n <span className={styles.figureBig}>{value}</span>\n <span className={styles.figureCaption}>{caption}</span>\n </div>\n );\n}\n","/**\n * routes/verse/usage/SeriesPanel.tsx — token output and spend over time.\n *\n * The series comes from `buildRollup(window, cfg).byDay`, which the backend\n * has always computed and always discarded. Three honesty rules travel with\n * it and are stated AT THE POINT OF DISPLAY, not in a footnote:\n *\n * - the spend chart is titled \"Estimated spend\" and carries the static\n * price-table caveat, because no part of this figure is billed;\n * - the cache chart carries the Codex caveat (its cacheRead/cacheWrite are\n * hardcoded 0 upstream, so the two providers are not comparable) and is\n * REFUSED entirely when no day reported a rate — a flat 0% line would\n * read as \"the cache never hits\";\n * - a day with no rollup row is a gap, and the chart primitives break the\n * line at a null by contract.\n *\n * Charts are the existing primitives only — no new chart code, no library.\n */\nimport type { ReactNode } from 'react';\nimport {\n ChartContainer,\n LineChart,\n StatTile,\n TableView,\n chartFormat,\n type TableColumn,\n} from '../../../components/charts/index.js';\nimport { formatWholePercent } from '../autonomy/format.js';\nimport type { DailyUsage, SeriesWindow, UsageSeries } from './usage-contract.js';\nimport {\n CACHE_CAVEAT,\n COST_ESTIMATE_NOTE,\n LOCAL_CLOUD_SERIES_UNAVAILABLE,\n WINDOW_LABEL,\n averagesFor,\n buildCacheSeries,\n buildCacheTokenSeries,\n buildSpendSeries,\n buildTokenSeries,\n sparklinePoints,\n totalsFor,\n} from './series-model.js';\nimport styles from './usage.module.css';\n\nconst WINDOWS: readonly SeriesWindow[] = ['7d', '30d'];\n\nconst TOKEN_COLUMNS: TableColumn<DailyUsage>[] = [\n { key: 'day', label: 'Day', render: (r) => chartFormat.formatDayLabel(r.day) },\n { key: 'in', label: 'Tokens in', numeric: true, render: (r) => chartFormat.formatCompact(r.tokensIn) },\n { key: 'out', label: 'Tokens out', numeric: true, render: (r) => chartFormat.formatCompact(r.tokensOut) },\n { key: 'sessions', label: 'Sessions', numeric: true, render: (r) => chartFormat.formatCompact(r.sessions) },\n];\n\nconst SPEND_COLUMNS: TableColumn<DailyUsage>[] = [\n { key: 'day', label: 'Day', render: (r) => chartFormat.formatDayLabel(r.day) },\n {\n key: 'cost',\n label: 'Estimated spend',\n numeric: true,\n render: (r) => chartFormat.formatUsd(r.estCostUsd),\n },\n];\n\nconst CACHE_TOKEN_COLUMNS: TableColumn<DailyUsage>[] = [\n { key: 'day', label: 'Day', render: (r) => chartFormat.formatDayLabel(r.day) },\n {\n key: 'read',\n label: 'Cache read',\n numeric: true,\n render: (r) => (r.cacheRead === null ? 'not reported' : chartFormat.formatCompact(r.cacheRead)),\n },\n {\n key: 'write',\n label: 'Cache write',\n numeric: true,\n render: (r) => (r.cacheWrite === null ? 'not reported' : chartFormat.formatCompact(r.cacheWrite)),\n },\n];\n\nconst CACHE_COLUMNS: TableColumn<DailyUsage>[] = [\n { key: 'day', label: 'Day', render: (r) => chartFormat.formatDayLabel(r.day) },\n {\n key: 'rate',\n label: 'Cache hit rate',\n numeric: true,\n // \"<1%\" for a sliver of hits, never \"0%\" (the app-wide rule).\n render: (r) => (r.cacheHitRate === null ? 'not reported' : formatWholePercent(r.cacheHitRate)),\n },\n {\n key: 'read',\n label: 'Cache read',\n numeric: true,\n render: (r) => (r.cacheRead === null ? 'not reported' : chartFormat.formatCompact(r.cacheRead)),\n },\n];\n\nexport function SeriesPanel({\n series,\n window,\n onWindowChange,\n unavailableReason,\n loading,\n}: {\n series: UsageSeries | null;\n window: SeriesWindow;\n onWindowChange: (next: SeriesWindow) => void;\n /** Non-null when the route could not be read at all. */\n unavailableReason: string | null;\n loading: boolean;\n}): ReactNode {\n const totals = series ? totalsFor(series.days) : null;\n const averages = series ? averagesFor(series.days) : null;\n const tokens = buildTokenSeries(series);\n const spend = buildSpendSeries(series);\n const cache = buildCacheSeries(series);\n const cacheTokens = buildCacheTokenSeries(series);\n\n return (\n <section className={styles.panel} aria-labelledby=\"verse-usage-series\">\n <div className={styles.panelHead}>\n <h3 id=\"verse-usage-series\" className={styles.panelTitle}>\n Token output and spend\n </h3>\n <div className={styles.segmented} role=\"group\" aria-label=\"Series window\">\n {WINDOWS.map((w) => (\n <button\n key={w}\n type=\"button\"\n className={styles.segment}\n aria-pressed={w === window}\n onClick={() => onWindowChange(w)}\n >\n {w}\n </button>\n ))}\n </div>\n </div>\n\n {unavailableReason ? (\n <p className={styles.muted}>\n {unavailableReason} No token or spend series can be drawn, and none is invented in its place.\n </p>\n ) : loading && series === null ? (\n <p className={styles.muted} aria-busy=\"true\">\n Loading the {WINDOW_LABEL[window].toLowerCase()} rollup…\n </p>\n ) : series === null || series.days.length === 0 ? (\n <p className={styles.muted}>\n The rollup for {WINDOW_LABEL[window].toLowerCase()} came back with no days in it. That is an\n empty window, not a zero.\n </p>\n ) : (\n <>\n <div className={styles.tiles}>\n <StatTile\n label={`Tokens in · ${window}`}\n value={<span className={styles.num}>{chartFormat.formatCompact(totals?.tokensIn ?? 0)}</span>}\n caption={`Across ${totals?.dayCount ?? 0} recorded days`}\n trend={sparklinePoints(series, (d) => d.tokensIn)}\n trendLabel=\"Tokens in per day\"\n />\n <StatTile\n label={`Tokens out · ${window}`}\n value={<span className={styles.num}>{chartFormat.formatCompact(totals?.tokensOut ?? 0)}</span>}\n caption=\"What the models actually produced\"\n trend={sparklinePoints(series, (d) => d.tokensOut)}\n trendLabel=\"Tokens out per day\"\n />\n <StatTile\n label={`Estimated spend · ${window}`}\n value={<span className={styles.num}>{chartFormat.formatUsd(totals?.estCostUsd ?? 0)}</span>}\n caption=\"Estimated from a static price table — not billed\"\n trend={sparklinePoints(series, (d) => d.estCostUsd)}\n trendLabel=\"Estimated spend per day\"\n />\n <StatTile\n label={`Sessions · ${window}`}\n value={<span className={styles.num}>{chartFormat.formatCompact(totals?.sessions ?? 0)}</span>}\n caption=\"Rollup rows, not billed calls\"\n trend={sparklinePoints(series, (d) => d.sessions)}\n trendLabel=\"Sessions per day\"\n />\n {/* Averages are per RECORDED day, never per calendar day: dividing\n by the window length would understate every figure by however\n many days the rollup has no row for. */}\n <StatTile\n label=\"Estimated spend per active day\"\n value={\n <span className={styles.num}>\n {averages?.estCostUsdPerDay === null || averages === null\n ? 'unknown'\n : chartFormat.formatUsd(averages.estCostUsdPerDay)}\n </span>\n }\n caption={`Across the ${totals?.dayCount ?? 0} days that carry a rollup row — not the ${window} calendar span`}\n />\n <StatTile\n label=\"Heaviest day\"\n value={\n <span className={styles.num}>\n {averages?.peakCostDay ? chartFormat.formatUsd(averages.peakCostDay.usd) : 'unknown'}\n </span>\n }\n caption={\n averages?.peakCostDay\n ? `${chartFormat.formatDayLabel(averages.peakCostDay.day)} — estimated, not billed`\n : 'No day in this window carries a cost row.'\n }\n />\n </div>\n\n <div className={styles.charts}>\n <ChartContainer\n title=\"Tokens per day\"\n description={WINDOW_LABEL[window]}\n empty={!tokens.available}\n emptyMessage={tokens.available ? '' : tokens.reason}\n table={\n <TableView\n caption=\"Tokens in and out per day\"\n columns={TOKEN_COLUMNS}\n rows={series.days}\n rowKey={(r) => r.day}\n />\n }\n >\n {tokens.available ? (\n <LineChart\n series={tokens.series}\n formatX={(x) => chartFormat.formatTimeLabel(x)}\n formatY={(y) => chartFormat.formatCompact(y)}\n ariaLabel={`Tokens in and out per day over ${WINDOW_LABEL[window].toLowerCase()}`}\n />\n ) : null}\n </ChartContainer>\n\n <ChartContainer\n title=\"Estimated spend per day\"\n description={WINDOW_LABEL[window]}\n caveat={COST_ESTIMATE_NOTE}\n empty={!spend.available}\n emptyMessage={spend.available ? '' : spend.reason}\n table={\n <TableView\n caption=\"Estimated spend per day\"\n columns={SPEND_COLUMNS}\n rows={series.days}\n rowKey={(r) => r.day}\n />\n }\n >\n {spend.available ? (\n <LineChart\n series={spend.series}\n area\n formatX={(x) => chartFormat.formatTimeLabel(x)}\n formatY={(y) => chartFormat.formatUsd(y)}\n ariaLabel={`Estimated spend per day over ${WINDOW_LABEL[window].toLowerCase()}`}\n />\n ) : null}\n </ChartContainer>\n\n <ChartContainer\n title=\"Cache hit rate\"\n description={WINDOW_LABEL[window]}\n caveat={CACHE_CAVEAT}\n empty={!cache.available}\n emptyMessage={cache.available ? '' : cache.reason}\n table={\n cache.available ? (\n <TableView\n caption=\"Cache hit rate per day\"\n columns={CACHE_COLUMNS}\n rows={series.days}\n rowKey={(r) => r.day}\n />\n ) : undefined\n }\n >\n {cache.available ? (\n <LineChart\n series={cache.series}\n formatX={(x) => chartFormat.formatTimeLabel(x)}\n formatY={(y) => chartFormat.formatPercent(y)}\n ariaLabel={`Cache hit rate per day over ${WINDOW_LABEL[window].toLowerCase()}`}\n />\n ) : null}\n </ChartContainer>\n\n <ChartContainer\n title=\"Cache read and write tokens\"\n description={WINDOW_LABEL[window]}\n caveat={CACHE_CAVEAT}\n empty={!cacheTokens.available}\n emptyMessage={cacheTokens.available ? '' : cacheTokens.reason}\n table={\n cacheTokens.available ? (\n <TableView\n caption=\"Cache read and write tokens per day\"\n columns={CACHE_TOKEN_COLUMNS}\n rows={series.days}\n rowKey={(r) => r.day}\n />\n ) : undefined\n }\n >\n {cacheTokens.available ? (\n <LineChart\n series={cacheTokens.series}\n formatX={(x) => chartFormat.formatTimeLabel(x)}\n formatY={(y) => chartFormat.formatCompact(y)}\n ariaLabel={`Cache read and write tokens per day over ${WINDOW_LABEL[window].toLowerCase()}`}\n />\n ) : null}\n </ChartContainer>\n\n {/* The local/cloud split has no dated source. Refusing the chart\n out loud, in the place the chart would occupy, is the honest\n answer — see LOCAL_CLOUD_SERIES_UNAVAILABLE. */}\n <ChartContainer\n title=\"Local vs cloud per day\"\n description={WINDOW_LABEL[window]}\n empty\n emptyMessage={LOCAL_CLOUD_SERIES_UNAVAILABLE}\n >\n {null}\n </ChartContainer>\n </div>\n\n {series.caveats.length > 0 ? (\n <ul className={styles.noteList}>\n {series.caveats.map((c) => (\n <li key={c} className={styles.capacityMuted}>\n {c}\n </li>\n ))}\n </ul>\n ) : null}\n </>\n )}\n </section>\n );\n}\n","/**\n * routes/verse/usage/SpendPanel.tsx — spend today and, when the data supports\n * one, spend per day.\n *\n * The only dated spend history any of this section's sources carries is the\n * daemon tick ledger. It is real but partial, so it renders with its caveat\n * attached and with gaps left as gaps. When it cannot support a trend the\n * panel says the series is unavailable and shows the aggregate — it never\n * draws a flat line out of one data point.\n */\nimport type { ReactNode } from 'react';\nimport { ChartContainer, LineChart, StatTile, TableView, chartFormat, type TableColumn } from '../../../components/charts/index.js';\nimport { isCurrentLedgerDay } from '../autonomy/format.js';\nimport { calendarDayStart } from '../growth/calendar-day.js';\nimport type { SpendDay, SpendSeries } from './usage-model.js';\nimport styles from './usage.module.css';\n\nconst COLUMNS: TableColumn<SpendDay>[] = [\n { key: 'day', label: 'Day', render: (r) => chartFormat.formatDayLabel(r.day) },\n {\n key: 'usd',\n label: 'Spend',\n numeric: true,\n render: (r) => (r.usd === null ? 'no tick retained' : chartFormat.formatUsd(r.usd)),\n },\n];\n\nexport function SpendPanel({\n series,\n todaySpentUsd,\n todaySpentDate,\n dailyBudgetUsd,\n showSeries = true,\n}: {\n series: SpendSeries;\n todaySpentUsd: number | null;\n /**\n * The ledger day `todaySpentUsd` belongs to, or null when the source has\n * none. The daemon writes the figure once a day and leaves it, so a\n * `todaySpentDate` that is not the viewer's local today says nothing about\n * today and must not be rendered under that word (DESIGN-V2 §6: unknown is\n * not blank and not zero).\n */\n todaySpentDate: string | null;\n dailyBudgetUsd: number | null;\n /**\n * False when the real per-day series (GET /api/verse/usage-series) is on\n * screen already. The daemon tick ledger covers the autonomous loop only and\n * is capped, so next to the full rollup it is a narrower second line about\n * the same money — worth keeping as the fallback, not worth double-drawing.\n */\n showSeries?: boolean;\n}): ReactNode {\n const stale = todaySpentDate !== null && !isCurrentLedgerDay(todaySpentDate);\n const spentToday = stale ? null : todaySpentUsd;\n const budgetCaption = stale\n ? `Nothing recorded today — the last ledger day is ${chartFormat.formatDayLabel(todaySpentDate)}`\n : dailyBudgetUsd === null\n ? 'Configured daily budget unavailable'\n : dailyBudgetUsd === 0\n ? 'Daily budget is 0 — the loop is stopped'\n : `of a ${chartFormat.formatUsd(dailyBudgetUsd)} daily budget`;\n\n return (\n <section className={styles.panel} aria-labelledby=\"verse-usage-spend\">\n <div className={styles.panelHead}>\n <h3 id=\"verse-usage-spend\" className={styles.panelTitle}>\n Spend\n </h3>\n </div>\n\n <div className={styles.tiles}>\n <StatTile\n label=\"Spend today\"\n value={\n <span className={styles.num}>\n {spentToday === null ? 'unknown' : chartFormat.formatUsd(spentToday)}\n </span>\n }\n caption={budgetCaption}\n />\n </div>\n\n {!showSeries ? (\n <p className={styles.sourceLine}>\n Per-day spend is charted above from the full usage rollup. The daemon tick ledger is not\n drawn again here.\n </p>\n ) : (\n <div style={{ marginTop: 'var(--space-4)' }}>\n {series.available ? (\n <ChartContainer\n title=\"Spend per day\"\n description=\"Autonomous loop, from the daemon tick ledger\"\n caveat={series.caveat}\n table={\n <TableView\n caption=\"Spend per day from the daemon tick ledger\"\n columns={COLUMNS}\n rows={series.days}\n rowKey={(r) => r.day}\n />\n }\n >\n <LineChart\n series={[\n {\n id: 'spend',\n label: 'Spend',\n // Local midnight of each ledger day (growth/calendar-day), so\n // the axis and tooltip name the same day as the table below.\n points: series.days.map((d) => ({ x: calendarDayStart(d.day), y: d.usd })),\n },\n ]}\n area\n formatX={(x) => chartFormat.formatTimeLabel(x)}\n formatY={(y) => chartFormat.formatUsd(y)}\n ariaLabel=\"Autonomous loop spend per day\"\n />\n </ChartContainer>\n ) : (\n <ChartContainer title=\"Spend per day\" empty emptyMessage={series.reason}>\n {null}\n </ChartContainer>\n )}\n </div>\n )}\n </section>\n );\n}\n","/**\n * routes/verse/cloud/CloudCreditsPanel.tsx — \"Cloud credits\" in Usage (3.11\n * unit C3; mounted by sections/UsageSection.tsx). The same estimate and the\n * same budget fields as Command's Cloud card (CloudBudgetForm), laid out as\n * a Usage panel: this is where the operator calibrates the estimate after\n * checking the real balance on claude.ai.\n *\n * Renders nothing while the first read is out and nothing on a server\n * without the cloud lane (404) — Usage has many panels, and \"not in this\n * build\" is not worth one of them. Any other failure says so in the panel.\n */\nimport { CLOUD_BALANCE_URL, type CloudBudgetUpdate } from '../../../../core/cloud/types.js';\nimport { IconExternalLink } from '../../../components/primitives/icons.js';\nimport { Meter } from '../../../components/primitives/Meter.js';\nimport { useQuery, useRefetch } from '../../../data/hooks.js';\nimport { tidyProse } from '../autonomy/format.js';\nimport { ActionStatus, useSurfaceActions } from '../command/actions.js';\nimport { usePollWhileVisible } from '../shell/section-visibility.js';\nimport usage from '../usage/usage.module.css';\nimport { CloudBudgetForm } from './CloudBudgetForm.js';\nimport { creditsMeter, gateText, sessionsLine } from './cloud-model.js';\nimport { CLOUD_POLL_MS, cloudQuery, updateCloudBudget } from './cloud-queries.js';\nimport styles from './cloud.module.css';\n\nexport function CloudCreditsPanel({ now = Date.now() }: { now?: number }) {\n const read = useQuery(cloudQuery, { freshMs: 15_000 });\n const refetch = useRefetch(cloudQuery);\n usePollWhileVisible(refetch, CLOUD_POLL_MS);\n const actions = useSurfaceActions();\n\n if (!read.data) return null;\n if (!read.data.available) return null;\n const overview = read.data.value;\n const view = overview?.budget ?? null;\n const meter = view ? creditsMeter(view) : null;\n const refused = view ? gateText(view.canLaunch, 'The cloud budget does not allow another launch right now.') : null;\n\n const save = (update: CloudBudgetUpdate) => actions.act(() => updateCloudBudget(update), 'Change the cloud budget.');\n\n return (\n <section className={usage.panel} aria-labelledby=\"verse-usage-cloud-credits\">\n <div className={usage.panelHead}>\n <h3 id=\"verse-usage-cloud-credits\" className={usage.panelTitle}>\n Cloud credits\n </h3>\n <p className={usage.panelNote}>\n What Claude Code cloud sessions launched by Verse have cost, as an estimate, and the limits Verse keeps them inside.\n </p>\n </div>\n {!view || !meter ? (\n <p className={styles.muted}>{read.data.reason ?? 'The cloud lane did not answer.'}</p>\n ) : (\n <div className={styles.body}>\n <ActionStatus actions={actions} />\n <Meter\n value={meter.value}\n max={meter.max}\n label=\"Credits remaining\"\n valueText={meter.text}\n tone={meter.tone}\n aria-label={`Estimated cloud credits remaining: ${meter.text}, ${meter.usedText}`}\n />\n <p className={styles.estimateNote}>\n {tidyProse(view.estimateNote, now)}{' '}\n <a className={styles.link} href={CLOUD_BALANCE_URL} target=\"_blank\" rel=\"noreferrer noopener\" aria-label=\"Check the real balance on claude.ai\">\n Check usage on claude.ai <IconExternalLink width={12} height={12} aria-hidden=\"true\" />\n </a>\n </p>\n {meter.warning ? <p className={styles.notice} data-tone=\"warning\" role=\"note\">{meter.warning}</p> : null}\n <p className={styles.facts}>{sessionsLine(view, now)}</p>\n {refused ? <p className={styles.notice} data-tone=\"warning\" role=\"note\">New launches are paused: {refused}</p> : null}\n <CloudBudgetForm idPrefix=\"usage-cloud-budget\" budget={view.budget} busy={actions.busy} disabled={actions.readOnly} onSave={save} />\n </div>\n )}\n {actions.dialogs}\n </section>\n );\n}\n","/**\n * routes/verse/usage/accounts-model.ts — the \"can I use this account right\n * now\" decision, in one pure module.\n *\n * This view exists to answer ONE question at a glance, so this module turns\n * each account into a single verdict plus the evidence behind it. The rules\n * are not cosmetic; each one comes from a fact in docs/VERSE-TELEMETRY-V2.md\n * that a naive meter would get wrong:\n *\n * 1. THE BINDING WINDOW LEADS. An account is blocked by its *worst* window,\n * not its average and not its first. Claude's weekly per-model window sat\n * at 100% while all-models read 58% — showing 58% would be a lie of\n * emphasis. The binding window is the headline; the others are secondary.\n * 2. CREDITS ARE NOT THE WINDOW. A Codex account at 100% of its weekly window\n * with a spendable credit balance is USABLE. `verdict` therefore has a\n * distinct `credits` state, and it never reads as blocked.\n * 3. SIGNED OUT IS AN ACTION, NOT A ZERO. A signed-out account has no\n * measurement at all. It renders as an actionable state, never as a 0%\n * meter and never as a bare \"unknown\".\n * 4. THE SENTINEL 100 IS A FLAG. `rateLimitReachedType` is written upstream\n * as 100, which is not a measurement. It reads \"limit reached\", never\n * \"100% used\".\n * 5. A VERSION-PINNED PROBE THAT FAILS CLOSED SAYS SO. Claude's probe is\n * pinned; when it reports `usage-version-unsupported` the fix is a\n * one-line constant bump, and a silent \"unknown\" would hide it.\n *\n * Nothing here converts an absent reading into 0, and nothing invents a\n * number the provider did not give.\n *\n * Pure: no React, no I/O, no currency/percent formatting (chartFormat owns\n * that).\n */\nimport { describeResetAt } from '../../../../core/verse/seat-readiness.js';\nimport { percentText } from '../autonomy/format.js';\nimport type { ControlSnapshot, VerseBootstrap, VerseEngine } from '../../../data/api-types.js';\nimport type { FrontierUsage } from '../../../../core/usage/frontier-usage.js';\nimport type { Account, AccountWindow, LocalModelsSnapshot } from './usage-contract.js';\nimport { ENGINE_COLOR, resolveWindowSignal, WINDOW_SOURCE_LABEL, windowTone, type WindowTone } from './usage-model.js';\n\n// ---------------------------------------------------------------------------\n// Windows\n// ---------------------------------------------------------------------------\n\nexport interface WindowView {\n id: string;\n label: string;\n /** 0–100, or null when there is no reading. NEVER a substituted 0. */\n usedPct: number | null;\n tone: WindowTone;\n /**\n * Verbatim provider prose, rendered as-is and never turned into a countdown;\n * or, when the provider gave only an instant, that instant in local time\n * (\"resets Fri 11:46 PM\") — never the raw ISO string.\n */\n resetText: string | null;\n /**\n * The MACHINE-READABLE reset instant (ISO), when the provider gave one.\n *\n * Claude's is structurally always null — its reset is prose in `resetText`\n * and may never be turned into a countdown — so this is the only field a\n * countdown may ever be computed from, and the capacity strip keeps the two\n * channels apart for exactly that reason.\n */\n resetsAt: string | null;\n /** True when the provider flagged the limit rather than measuring a percent. */\n limitReached: boolean;\n /** False when the percent behind this window is a sentinel, not a reading. */\n measured: boolean;\n}\n\n/** Human names for the window ids the probes actually emit. */\nconst WINDOW_LABELS: Record<string, string> = {\n five_hour: 'Session · rolling 5h',\n seven_day: 'Week · all models',\n seven_day_sonnet: 'Week · Sonnet',\n seven_day_opus: 'Week · Opus',\n seven_day_fable: 'Week · Fable',\n codex: 'Week · Codex',\n primary: 'Primary window',\n secondary: 'Secondary window',\n};\n\nexport function windowLabel(w: AccountWindow): string {\n if (w.label) return w.label;\n const known = WINDOW_LABELS[w.id];\n if (known) return known;\n const perModel = /^seven_day_(.+)$/.exec(w.id);\n if (perModel) return `Week · ${perModel[1]}`;\n return w.id;\n}\n\n/** \"resets Fri 11:46 PM\" for a machine instant; null when it does not parse (a raw ISO string is never printed). */\nfunction instantResetText(iso: string | null, now: number): string | null {\n const when = describeResetAt(iso, now);\n return when === null ? null : `resets ${when}`;\n}\n\nexport function toWindowView(w: AccountWindow, now: number = Date.now()): WindowView {\n const reset = w.resetDescription ?? instantResetText(w.resetsAt, now);\n return {\n id: w.id,\n label: windowLabel(w),\n // A flagged limit is not a measurement, so it carries no percentage.\n usedPct: w.limitReached ? null : w.usedPercent,\n tone: w.limitReached ? 'danger' : w.usedPercent === null ? 'ok' : windowTone(w.usedPercent),\n resetText: reset,\n resetsAt: w.resetsAt,\n limitReached: w.limitReached,\n measured: w.measured,\n };\n}\n\n/**\n * The window that actually blocks work: the highest measured percent, with a\n * flagged limit outranking every measurement. The server computes this too;\n * we verify rather than trust, because a `binding` that is not one of\n * `windows` would silently desynchronize the headline from the detail.\n */\nexport function bindingWindow(account: Account): AccountWindow | null {\n const candidates = account.windows;\n const flagged = candidates.find((w) => w.limitReached);\n if (flagged) return flagged;\n\n const measured = candidates.filter((w) => w.usedPercent !== null);\n const computed =\n measured.length === 0\n ? null\n : measured.reduce((worst, w) => ((w.usedPercent ?? 0) > (worst.usedPercent ?? 0) ? w : worst));\n\n const served = account.binding;\n if (served) {\n // The server's `binding` is `{id, usedPercent, limitReached}` on the wire\n // (core `VerseAccountRecord['binding']`) — it carries NO label, no\n // `resetsAt` and no `nativeReport.resetDescription`. Returning it directly\n // dropped the reset line from the one meter the doc says must lead, and\n // for Claude that IS the entire reset signal: `resetsAt` is null by\n // construction and docs/VERSE-TELEMETRY-V2.md:133 requires the provider's\n // prose be rendered verbatim. AccountCard then filters the full window out\n // of `others` by id, so the prose appeared nowhere on the card. Resolve\n // the id back to this account's own full window; the server's CHOICE is\n // still honoured, only its stripped shape is not.\n const full = candidates.find((w) => w.id === served.id) ?? null;\n if (full) {\n if (served.limitReached || full.limitReached) return full;\n if (computed === null) return full;\n if ((served.usedPercent ?? -1) >= (computed.usedPercent ?? -1)) return full;\n }\n }\n return computed;\n}\n\n// ---------------------------------------------------------------------------\n// Verdict — the two-second answer\n// ---------------------------------------------------------------------------\n\nexport type AccountVerdictState =\n | 'available'\n | 'tight'\n | 'credits'\n | 'exhausted'\n | 'signed-out'\n | 'probe-unsupported'\n | 'unknown';\n\nexport interface AccountVerdict {\n state: AccountVerdictState;\n /** Short headline, e.g. \"Usable now\" — paired with a glyph, never color alone. */\n headline: string;\n /** One sentence of evidence. Always names WHY. Never a machine code. */\n detail: string;\n /**\n * The verbatim probe/collector code behind `detail`, on the states where\n * that code EXPLAINS an absent measurement (signed out, version-pinned, no\n * reading). It is shown as a secondary, clearly-machine line — never as the\n * sentence. Null on a state that HAS a reading, where the code would be\n * noise (\"probe-observed\") rather than evidence.\n */\n code: string | null;\n}\n\n/**\n * Plain-language copy for the machine-readable codes that actually reach this\n * surface.\n *\n * `reason` is a machine code BY CONTRACT on the producing side — core's\n * `VerseAccountRecord.reason` is documented \"Machine-readable probe reason,\n * verbatim. Never rewritten into prose\" — and this module used to render it as\n * the card's one sentence of evidence, so on a degraded collector every card\n * read headline \"No reading\", detail \"connection-monitor-stopped\". That tells\n * Mason nothing about what to do. The code is kept (it is the thing to search\n * for), but it is never the body text.\n *\n * Codes are matched exactly; anything unlisted falls through to the branch's\n * own prose rather than being printed raw.\n */\nexport const REASON_COPY: Record<string, string> = {\n 'connection-monitor-stopped':\n 'Native polling stopped after a metadata sample could not confirm its process cleanup, so these readings are frozen and no new ones are being taken. Restarting `ashlr verse` begins a new collection generation.',\n 'collector-unavailable':\n 'This server is not collecting native metadata, so nothing here is a live reading.',\n 'collector-not-running':\n 'No account collector is running in this server, so these cards fall back to whatever shared evidence exists.',\n 'collector-owned':\n 'Another collector (`ashlr resource-console`) owns the exclusive metadata lease, so Verse is reading its shared evidence rather than probing.',\n 'collector-start-failed':\n 'The metadata collectors could not be started in this server, so no probe has run.',\n 'connection-polling-paused':\n 'Native polling is paused because no client has asked for account data recently; it resumes on the next request.',\n 'connection-not-checked':\n 'No probe has run for this account yet in this server.',\n 'connection-probe-unavailable':\n 'The probe for this account did not return a usable result, so there is no measurement to show.',\n 'accounts-pool-unavailable':\n 'This accounts root has no readable pool or bindings, so there is nothing to probe.',\n 'accounts-collection-not-configured':\n 'Native account collection is not configured for this accounts root.',\n 'usage-version-unsupported':\n 'The usage probe is pinned to a specific provider build and failed closed on the installed one. That is a version pin, not an outage.',\n 'usage-account-changed':\n 'The account behind this profile changed between two reads, so the reading was discarded rather than attributed to the wrong account.',\n 'probe-account-unavailable':\n 'The pinned profile answered but carries no usable account identity — it is not authenticated.',\n 'probe-account-unsupported':\n 'The pinned profile is authenticated by a method this probe does not accept, so no reading was taken.',\n 'probe-account-changed':\n 'The account behind this pinned profile changed mid-probe, so the reading was discarded.',\n 'probe-account-hint-mismatch':\n 'The pinned profile is signed in as a different account than this seat expects.',\n 'probe-native-unavailable':\n 'The provider CLI for this pinned profile could not be run, so no reading was taken.',\n 'probe-native-exit-failed':\n 'The provider CLI for this pinned profile exited without a usable result.',\n 'probe-provider-error':\n 'The provider CLI returned an error instead of account metadata.',\n 'probe-protocol-unsupported':\n 'The installed provider CLI does not speak the metadata protocol this probe requires.',\n 'probe-quota-invalid':\n 'The provider returned a quota shape this probe does not recognise, so nothing was accepted as a reading.',\n 'probe-timed-out':\n 'The metadata probe for this account timed out before it returned anything.',\n};\n\n/** Prose for a code, or the branch's own sentence. NEVER the raw code. */\nexport function reasonSentence(reason: string | null, fallback: string): string {\n if (reason === null) return fallback;\n return REASON_COPY[reason] ?? fallback;\n}\n\n/** Ordering rank: what Mason can use comes first. */\nconst VERDICT_RANK: Record<AccountVerdictState, number> = {\n available: 0,\n credits: 1,\n tight: 2,\n exhausted: 3,\n 'signed-out': 4,\n 'probe-unsupported': 5,\n unknown: 6,\n};\n\nconst TIGHT_AT = 80;\nconst FULL_AT = 100;\n\nexport function creditsSpendable(credits: Account['credits']): boolean {\n if (!credits) return false;\n if (credits.unlimited) return true;\n if (!credits.hasCredits) return false;\n return credits.balanceValue !== null && credits.balanceValue > 0;\n}\n\nfunction describeCredits(credits: NonNullable<Account['credits']>): string {\n if (credits.unlimited) return 'credits are unlimited on this plan';\n return `a credit balance of ${credits.balance ?? 'an unreported amount'} is still spendable`;\n}\n\nexport function accountVerdict(account: Account, binding: AccountWindow | null): AccountVerdict {\n if (account.authentication === 'signed-out' || account.state === 'signed-out') {\n return {\n state: 'signed-out',\n headline: 'Signed out',\n detail: reasonSentence(\n account.reason,\n 'The probe reached this account’s pinned profile but it is not authenticated, so there is nothing to measure.',\n ),\n code: account.reason,\n };\n }\n\n if (account.unsupported) {\n return {\n state: 'probe-unsupported',\n headline: 'Probe version-pinned',\n detail: `The usage probe failed closed with ${account.unsupported.code}${\n account.unsupported.pinnedVersion ? `; it is pinned to ${account.unsupported.pinnedVersion}` : ''\n }. This is a version pin, not an outage — no window can be read until the pin is bumped.`,\n code: account.unsupported.code,\n };\n }\n\n const spendable = creditsSpendable(account.credits);\n\n if (binding === null || (binding.usedPercent === null && !binding.limitReached)) {\n if (spendable && account.credits) {\n return {\n state: 'credits',\n headline: 'Usable on credits',\n detail: `No window reading reached this surface, but ${describeCredits(account.credits)}.`,\n code: account.reason,\n };\n }\n return {\n state: 'unknown',\n headline: 'No reading',\n detail: reasonSentence(\n account.reason,\n 'No window percentage reached this surface for this account, so nothing here is a measurement.',\n ),\n code: account.reason,\n };\n }\n\n const pct = binding.usedPercent;\n const exhausted = binding.limitReached || (pct !== null && pct >= FULL_AT);\n const label = windowLabel(binding);\n\n if (exhausted) {\n if (spendable && account.credits) {\n return {\n state: 'credits',\n headline: 'Usable on credits',\n detail: `${label} is ${\n binding.limitReached ? 'reported as limit reached' : 'fully used'\n }, but ${describeCredits(account.credits)} — credits are independent of the window, so this account is not blocked.`,\n code: null,\n };\n }\n return {\n state: 'exhausted',\n headline: binding.limitReached ? 'Limit reached' : 'Window exhausted',\n detail: binding.limitReached\n ? `The provider flagged ${label} as rate-limited. That flag is a denial, not a measurement, so no percentage is shown.`\n : `${label} is at ${percentText(pct as number)} — it is the binding constraint on this account.`,\n code: null,\n };\n }\n\n if ((pct as number) >= TIGHT_AT) {\n return {\n state: 'tight',\n headline: 'Running tight',\n detail: `${label} is the binding constraint at ${percentText(pct as number)}.`,\n code: null,\n };\n }\n\n return {\n state: 'available',\n headline: 'Usable now',\n detail: `${label} is the binding constraint at ${percentText(pct as number)}.`,\n code: null,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Card model\n// ---------------------------------------------------------------------------\n\nexport interface AccountCardModel {\n id: string;\n label: string;\n engine: VerseEngine;\n color: string;\n plan: string | null;\n verdict: AccountVerdict;\n /**\n * Every window this account reported, binding first, for the detail view.\n * The card itself still leads with `binding` and quiets `others`; this is\n * the same data in one list so the detail view never re-derives an order.\n */\n allWindows: WindowView[];\n /** Probe evidence, shown in the detail view rather than on the card face. */\n evidence: AccountEvidence;\n /** The binding window, already viewified. Null when nothing was measured. */\n binding: WindowView | null;\n /** Every other window, in the order the provider reported them. */\n others: WindowView[];\n credits: Account['credits'];\n /** Safe-to-print command, or null. Never a launcher invocation. */\n reconnectCommand: string | null;\n observedAt: string | null;\n /** Sort rank; lower is more usable. */\n rank: number;\n /** True when this card has anything worth opening a detail view for. */\n hasDetail: boolean;\n /**\n * Where these windows came from, when that is not simply \"this account's own\n * probe\" — e.g. an engine-wide subscription-tracker reading shared by two\n * Codex accounts. Null when the reading is per-account by construction.\n */\n sourceNote: string | null;\n}\n\n/**\n * What a probe actually told us, kept off the card face and shown in the\n * detail view. None of it is a measurement; all of it is why a measurement is\n * or is not there, which is the question a card's verdict raises.\n */\nexport interface AccountEvidence {\n state: Account['state'];\n authentication: Account['authentication'];\n /**\n * The monitor's health verdict. Claude's is `unknown` BY CONSTRUCTION\n * (docs/VERSE-TELEMETRY-V2.md) and the detail view says so rather than\n * drawing it as a fault.\n */\n health: string | null;\n /** The verbatim machine code. Evidence, never prose. */\n reasonCode: string | null;\n observedAt: string | null;\n /** The server's plain-language facts for this account. */\n notes: string[];\n unsupported: Account['unsupported'];\n}\n\nexport function buildAccountCard(account: Account, sourceNote: string | null = null): AccountCardModel {\n const binding = bindingWindow(account);\n const verdict = accountVerdict(account, binding);\n const engine: VerseEngine = account.provider;\n const others = account.windows.filter((w) => w.id !== binding?.id).map((w) => toWindowView(w));\n const bindingView = binding ? toWindowView(binding) : null;\n const evidence: AccountEvidence = {\n state: account.state,\n authentication: account.authentication,\n health: account.health,\n reasonCode: account.reason,\n observedAt: account.observedAt,\n notes: account.notes,\n unsupported: account.unsupported,\n };\n return {\n id: account.id,\n label: account.label,\n engine,\n color: ENGINE_COLOR[engine],\n plan: account.planType,\n verdict,\n allWindows: bindingView ? [bindingView, ...others] : others,\n evidence,\n hasDetail:\n account.windows.length > 0 ||\n account.notes.length > 0 ||\n account.credits !== null ||\n account.reason !== null,\n binding: bindingView,\n others,\n credits: account.credits,\n reconnectCommand: account.reconnectCommand,\n observedAt: account.observedAt,\n rank: VERDICT_RANK[verdict.state],\n sourceNote,\n };\n}\n\n/**\n * The server's plain-language caveats, deduplicated across accounts.\n *\n * These are per-account on the wire, but the same sentence is emitted for both\n * Codex accounts (and for every Claude window), so rendering them per card\n * would print the same fact three times. They belong to the panel, not the\n * card — they explain how to read every meter on it.\n */\nexport function collectAccountNotes(snapshot: { accounts: Account[] } | null): string[] {\n if (!snapshot) return [];\n const seen = new Set<string>();\n for (const account of snapshot.accounts) {\n for (const note of account.notes) seen.add(note);\n }\n return [...seen];\n}\n\n/** Most usable first; ties keep a stable alphabetical order so cards do not shuffle. */\nexport function buildAccountCards(snapshot: { accounts: Account[] } | null): AccountCardModel[] {\n if (!snapshot) return [];\n return snapshot.accounts\n .map((account) => buildAccountCard(account))\n .sort((a, b) => a.rank - b.rank || a.label.localeCompare(b.label));\n}\n\n// ---------------------------------------------------------------------------\n// Local availability as an account card\n// ---------------------------------------------------------------------------\n\nexport interface LocalCardModel {\n /** Resident models, i.e. what can answer with no load delay. */\n residentCount: number;\n installedCount: number;\n residentBytes: number | null;\n memoryBudgetBytes: number | null;\n /** Resident bytes against the machine budget — the local analogue of a meter. */\n usedPct: number | null;\n tone: WindowTone;\n verdict: AccountVerdict;\n color: string;\n /** Same rank scale as an account card, so local sorts into the same grid. */\n rank: number;\n}\n\nexport function buildLocalCard(snapshot: LocalModelsSnapshot | null): LocalCardModel | null {\n if (!snapshot) return null;\n const resident = snapshot.models.filter((m) => m.loaded);\n // Mirrors `buildLocalModelsView` in local-model.ts, deliberately: a resident\n // model with no reported size makes the TOTAL unknown. The old reduce\n // skipped those and still returned a sum, so with three resident models of\n // which one reported no size this meter drew a bar that under-read — and\n // understating a memory figure is exactly the quiet lie this surface\n // refuses. `usedPct` already degrades to null, which LocalCard renders as\n // the dashed unknown rule.\n //\n // An UNREACHABLE runtime is the other way to have no resident models, and it\n // is not the same fact as an idle one. The runtime never answered, so what\n // is resident is unknown — rendering that as `0` drew a real 0% meter and\n // the words \"0 MB of 128 GB\" under a card that had just said it could not\n // reach the runtime at all, which reads as a measurement. `null` sends it\n // through the same dashed unknown rule every other unreadable figure uses.\n const residentBytes = !snapshot.reachable\n ? null\n : resident.length === 0\n ? 0\n : resident.some((m) => m.sizeBytes === null)\n ? null\n : resident.reduce((acc, m) => acc + (m.sizeBytes ?? 0), 0);\n const budget = snapshot.memoryBudgetBytes;\n const usedPct =\n residentBytes !== null && budget !== null && budget > 0\n ? Math.max(0, Math.min(100, (residentBytes / budget) * 100))\n : null;\n\n // `snapshot.reason` is a MACHINE CODE by contract on the producing side\n // (`ollama-unreachable`, `lmstudio-probe-failed`) — never prose. Putting it\n // straight into `detail` made the card's only sentence the string\n // `ollama-unreachable`, which tells an operator nothing about what to do and\n // is the one thing on the card that looks like a diagnosis. It rides along\n // as `code` instead, exactly as a signed-out account's probe code does, and\n // the sentence says what happened in plain language.\n const verdict: AccountVerdict = !snapshot.reachable\n ? {\n state: 'unknown',\n headline: 'Runtime unreachable',\n detail:\n 'No local runtime answered, so neither resident nor installed models can be listed. This is an unanswered probe, not a report that the machine is empty.',\n code: snapshot.reason,\n }\n : resident.length > 0\n ? {\n state: 'available',\n headline: 'Resident now',\n detail: `${resident.length} model${resident.length === 1 ? '' : 's'} already in memory — no load delay, no quota, no bill.`,\n code: null,\n }\n : snapshot.models.length > 0\n ? {\n state: 'tight',\n headline: 'Installed, not loaded',\n detail: `${snapshot.models.length} model${\n snapshot.models.length === 1 ? ' is' : 's are'\n } installed but nothing is resident, so the first turn pays a load.`,\n code: null,\n }\n : {\n state: 'unknown',\n headline: 'No models installed',\n detail: 'The runtime is reachable but reports no installed models.',\n code: null,\n };\n\n return {\n residentCount: resident.length,\n installedCount: snapshot.models.length,\n residentBytes,\n memoryBudgetBytes: budget,\n usedPct,\n tone: usedPct === null ? 'ok' : windowTone(usedPct),\n verdict,\n color: ENGINE_COLOR.local,\n rank: VERDICT_RANK[verdict.state],\n };\n}\n\n// ---------------------------------------------------------------------------\n// Fallback: the same card model, built from the pre-V2 sources\n// ---------------------------------------------------------------------------\n//\n// `/api/verse/accounts` is the real source and is per-account by construction.\n// When it is absent (a server that predates it, or one that could not acquire\n// the quota-refresh lease), this surface still has to answer the question, so\n// it falls back to the seat roster plus the per-ENGINE snapshots — and it says\n// so, because those are coarser: two Codex accounts share one engine row, and\n// a reading that covers both is labelled engine-wide rather than pinned to one\n// card. `resolveWindowSignal` carries the full provenance logic (see\n// usage-model.ts); this adapter only reshapes its output so both paths render\n// through one card component instead of two divergent ones.\n\nexport const FALLBACK_SOURCE_NOTE =\n 'Per-account probes are unavailable on this server, so these cards are derived from the seat roster and the per-engine snapshots.';\n\nfunction seatAccount(input: {\n seat: VerseBootstrap['seats'][number];\n control: ControlSnapshot | undefined;\n frontier: FrontierUsage | undefined;\n engineSeatCount: number;\n}): { account: Account; sourceNote: string | null } | null {\n const { seat, control, frontier, engineSeatCount } = input;\n if (seat.engine === 'local') return null; // Local has its own panel and its own physics.\n\n const subscription = control?.subscriptionUsage?.find((e) => String(e.engine) === seat.engine);\n const engineUsage = frontier?.engines.find((e) => String(e.engine) === seat.engine);\n const signal = resolveWindowSignal({\n engine: seat.engine,\n seat,\n subscription,\n frontier: engineUsage,\n engineSeatCount,\n });\n\n const windows: AccountWindow[] =\n signal.kind === 'measured'\n ? signal.windows.map((w) => ({\n id: w.id,\n label: w.label,\n usedPercent: w.usedPct,\n resetsAt: w.resetsAt === null ? null : new Date(w.resetsAt * 1000).toISOString(),\n resetDescription: null,\n limitReached: false,\n // `resolveWindowSignal` only ever emits a REAL reading (see\n // usage-model.ts): every branch that could be ledger-derived or a\n // placeholder returns `unknown` instead. So a window that reaches\n // here is measured by construction.\n measured: true,\n }))\n : [];\n\n const account: Account = {\n id: seat.id,\n label: seat.label,\n provider: seat.engine,\n state: signal.kind === 'measured' ? 'observed' : 'unavailable',\n authentication: 'unknown',\n // The coarse fallback sources carry no health verdict at all. Null is\n // \"not reported\"; inventing 'healthy' here would be a claim nothing made.\n health: null,\n planType: subscription?.plan ?? null,\n observedAt: seat.health.observedAt,\n windows,\n binding: null,\n credits: null,\n reason: signal.kind === 'measured' ? null : signal.reason,\n unsupported: null,\n reconnectCommand: null,\n notes: [],\n };\n\n const sourceNote =\n signal.kind === 'measured'\n ? `${WINDOW_SOURCE_LABEL[signal.source]}${\n signal.scope === 'engine' ? ' · engine-wide, shared by every account on this engine' : ''\n }`\n : null;\n\n return { account, sourceNote };\n}\n\nexport function buildFallbackAccountCards(input: {\n bootstrap: VerseBootstrap | undefined;\n control: ControlSnapshot | undefined;\n frontier: FrontierUsage | undefined;\n}): AccountCardModel[] {\n const seats = input.bootstrap?.seats ?? [];\n const perEngineCount = new Map<string, number>();\n for (const seat of seats) perEngineCount.set(seat.engine, (perEngineCount.get(seat.engine) ?? 0) + 1);\n\n return seats\n .map((seat) =>\n seatAccount({\n seat,\n control: input.control,\n frontier: input.frontier,\n engineSeatCount: perEngineCount.get(seat.engine) ?? 1,\n }),\n )\n .filter((entry): entry is { account: Account; sourceNote: string | null } => entry !== null)\n .map((entry) => buildAccountCard(entry.account, entry.sourceNote))\n .sort((a, b) => a.rank - b.rank || a.label.localeCompare(b.label));\n}\n","/**\n * routes/verse/sections/UsageSection.tsx — the Usage rail section\n * (docs/VERSE-CONTRACT-V2.md). Takes no props, per the shell contract; every\n * read is cache-backed so switching rails is instant.\n *\n * This view exists to answer ONE question at a glance: WHICH ACCOUNT CAN I\n * ACTUALLY USE RIGHT NOW, AND WHAT WILL IT COST ME. Everything is ordered\n * against that: account cards first, each led by its binding constraint and\n * sorted most-usable-first; then local availability; then the token and spend\n * series; then the accounting panels.\n *\n * Sources, in priority order:\n * GET /api/verse/accounts per-account state, windows, credits, plan\n * GET /api/verse/local-models resident vs installed, VRAM split, tools\n * GET /api/verse/usage-series DailyUsage[] behind every chart here\n * GET /api/control local/cloud split, localSavingsUsd, limits\n * GET /api/verse/control configured caps + today's spend\n * GET /api/usage per-engine frontier usage (fallback + limits)\n * GET /api/verse/bootstrap the seat roster (fallback roster only)\n *\n * V3.9 adds one panel computed entirely in the browser: CONTEXT EFFICIENCY\n * per seat (cache-hit ratio, compactions, the fullest context), aggregated\n * from the session records `bootstrap` already carries — no new route, no\n * spend (usage/context-model.ts `seatEfficiency`).\n *\n * The first three are owner T's and are landing in parallel. When they are\n * absent this section degrades to the pre-V2 sources through ONE card model\n * (see accounts-model.ts `buildFallbackAccountCards`) and says so in a banner\n * — it never renders two different card designs, and it never silently\n * presents coarser data as if it were per-account.\n *\n * Every honesty decision lives in the model modules, not here.\n */\nimport type { CSSProperties, ReactNode } from 'react';\nimport { Fragment, useCallback, useEffect, useMemo, useState } from 'react';\nimport { ApiError } from '../../../data/client.js';\nimport { useQuery, useRefetch, useRefresh } from '../../../data/hooks.js';\nimport { controlSnapshotQuery } from '../../../data/queries.js';\nimport { SkeletonCardGrid, SkeletonLine } from '../../../components/primitives/Skeleton.js';\nimport { StatTile, chartFormat } from '../../../components/charts/index.js';\nimport { verseBootstrapQuery } from '../verse-queries.js';\nimport { AccountCard } from '../usage/AccountCard.js';\nimport { AccountDetail } from '../usage/AccountDetail.js';\nimport { CapacityFacts } from '../usage/CapacityFacts.js';\nimport { CapacityStrip, useCapacityData } from '../usage/CapacityStrip.js';\nimport { EfficiencyPanel } from '../usage/EfficiencyPanel.js';\nimport { seatEfficiency } from '../usage/context-model.js';\nimport { LimitsPanel } from '../usage/LimitsPanel.js';\nimport { LocalCloudPanel } from '../usage/LocalCloudPanel.js';\nimport { LocalCard, LocalModelsPanel } from '../usage/LocalModelsPanel.js';\nimport { SeriesPanel } from '../usage/SeriesPanel.js';\nimport { SpendPanel } from '../usage/SpendPanel.js';\nimport { CloudCreditsPanel } from '../cloud/CloudCreditsPanel.js';\nimport {\n frontierUsageQuery,\n usageSeriesQuery,\n verseAccountsQuery,\n verseControlQuery,\n verseLocalModelsQuery,\n} from '../usage/usage-queries.js';\nimport {\n FALLBACK_SOURCE_NOTE,\n buildAccountCards,\n buildFallbackAccountCards,\n buildLocalCard,\n collectAccountNotes,\n} from '../usage/accounts-model.js';\nimport { buildLocalModelsView, localStaleness } from '../usage/local-model.js';\nimport { buildCapacityOverview } from '../usage/capacity-model.js';\nimport {\n projectAccountsSnapshot,\n projectLocalModels,\n projectUsageSeries,\n type SeriesWindow,\n} from '../usage/usage-contract.js';\nimport {\n buildDailySpendSeries,\n buildLimitRows,\n buildLocalCloudSplit,\n projectVerseControl,\n unavailableVerseControl,\n} from '../usage/usage-model.js';\nimport { LOCAL_SAVINGS_NOTE } from '../usage/series-model.js';\nimport styles from '../usage/usage.module.css';\n\nfunction isUnauthorized(err: Error | undefined): boolean {\n return err instanceof ApiError && err.status === 401;\n}\n\nfunction StateBlock({\n title,\n body,\n action,\n}: {\n title: string;\n body: string;\n action?: ReactNode;\n}): ReactNode {\n return (\n <div className={styles.stateBlock} role=\"status\">\n <p className={styles.stateTitle}>{title}</p>\n <p className={styles.stateBody}>{body}</p>\n {action ? <div className={styles.stateActions}>{action}</div> : null}\n </div>\n );\n}\n\n/**\n * How often the probe-spawning reads re-run while this section is on screen.\n *\n * Matches the collector's own cycle: reading faster cannot surface anything\n * newer, and each read costs a handful of short-lived process spawns (zero\n * tokens, zero paid quota — see docs/VERSE-TELEMETRY-V2.md).\n */\nconst USAGE_POLL_MS = 30_000;\n\n/**\n * The account detail spans the whole card row it sits in.\n *\n * Module scope so it is one frozen object rather than a fresh literal per\n * render, and inline rather than a new class because `usage.module.css` is not\n * this change's to edit — `.cards` is already\n * `repeat(auto-fit, minmax(280px, 1fr))`, and `1 / -1` spans it at every width\n * with no stylesheet rule to keep in sync.\n */\nconst DETAIL_ROW: CSSProperties = { gridColumn: '1 / -1' };\n\n/**\n * Re-read on an interval, but only while the document is actually visible.\n *\n * Accounts and local models have no server-side change signal to ride — there\n * is no SSE event that means \"a provider's window moved\" — so without this the\n * whole section was a mount-only snapshot: a Usage screen left open while the\n * loop worked overnight showed the capacity it had at mount, looking live.\n * Gating on visibility keeps a backgrounded window from spawning probes\n * forever, and `useRefetch` coalesces with any read already in flight.\n */\nfunction useVisiblePoll(refetch: () => void, intervalMs: number): void {\n useEffect(() => {\n let id: ReturnType<typeof setInterval> | null = null;\n const stop = (): void => {\n if (id !== null) clearInterval(id);\n id = null;\n };\n const sync = (): void => {\n const visible = typeof document === 'undefined' || document.visibilityState === 'visible';\n if (visible && id === null) id = setInterval(refetch, intervalMs);\n else if (!visible) stop();\n };\n sync();\n document.addEventListener('visibilitychange', sync);\n return () => {\n document.removeEventListener('visibilitychange', sync);\n stop();\n };\n }, [refetch, intervalMs]);\n}\n\nexport function UsageSection(): ReactNode {\n const [seriesWindow, setSeriesWindow] = useState<SeriesWindow>('7d');\n /** Which account card has its detail view open. Null = none. */\n const [selectedAccountId, setSelectedAccountId] = useState<string | null>(null);\n\n const accounts = useQuery(verseAccountsQuery);\n const localModels = useQuery(verseLocalModelsQuery);\n const seriesRead = useQuery(usageSeriesQuery(seriesWindow));\n const frontier = useQuery(frontierUsageQuery);\n const control = useQuery(controlSnapshotQuery);\n const verseControl = useQuery(verseControlQuery);\n const bootstrap = useQuery(verseBootstrapQuery);\n\n const refetchAccounts = useRefresh(verseAccountsQuery);\n const refetchLocalModels = useRefresh(verseLocalModelsQuery);\n const refetchSeries = useRefresh(usageSeriesQuery(seriesWindow));\n const refetchFrontier = useRefresh(frontierUsageQuery);\n const refetchControl = useRefresh(controlSnapshotQuery);\n const refetchVerseControl = useRefresh(verseControlQuery);\n const refetchBootstrap = useRefresh(verseBootstrapQuery);\n\n // Live without a server signal. Kept to the two reads that actually go stale\n // on their own; everything else rides the daemon SSE event (data/sse.ts) or\n // the Refresh button.\n const pollAccounts = useRefetch(verseAccountsQuery);\n const pollLocalModels = useRefetch(verseLocalModelsQuery);\n useVisiblePoll(pollAccounts, USAGE_POLL_MS);\n useVisiblePoll(pollLocalModels, USAGE_POLL_MS);\n\n const refreshAll = (): void => {\n refetchAccounts();\n refetchLocalModels();\n refetchSeries();\n refetchFrontier();\n refetchControl();\n refetchVerseControl();\n refetchBootstrap();\n };\n\n // ---- projections -------------------------------------------------------\n\n const accountsSnapshot = useMemo(\n () => (accounts.data?.available ? projectAccountsSnapshot(accounts.data.raw) : null),\n [accounts.data],\n );\n const localSnapshot = useMemo(\n () => (localModels.data?.available ? projectLocalModels(localModels.data.raw) : null),\n [localModels.data],\n );\n const series = useMemo(\n () => (seriesRead.data?.available ? projectUsageSeries(seriesRead.data.raw, seriesWindow) : null),\n [seriesRead.data, seriesWindow],\n );\n\n const caps = useMemo(\n () =>\n verseControl.data\n ? verseControl.data.available\n ? projectVerseControl(verseControl.data.raw, verseControl.data.reason)\n : unavailableVerseControl(verseControl.data.reason ?? 'Configured caps unavailable.')\n : unavailableVerseControl('Configured caps not loaded yet.'),\n [verseControl.data],\n );\n\n // The real roster when owner T's route answered; otherwise the same card\n // model built from the coarser pre-V2 sources, with a banner saying so.\n const usingFallbackRoster = accountsSnapshot === null;\n const cards = useMemo(\n () =>\n accountsSnapshot\n ? buildAccountCards(accountsSnapshot)\n : buildFallbackAccountCards({\n bootstrap: bootstrap.data,\n control: control.data,\n frontier: frontier.data,\n }),\n [accountsSnapshot, bootstrap.data, control.data, frontier.data],\n );\n\n const localView = useMemo(() => buildLocalModelsView(localSnapshot), [localSnapshot]);\n const localCard = useMemo(() => buildLocalCard(localSnapshot), [localSnapshot]);\n\n // The server's own caveats about how to read these meters. Deduplicated and\n // shown once for the panel rather than repeated on every card that carries\n // the same sentence.\n const accountNotes = useMemo(() => collectAccountNotes(accountsSnapshot), [accountsSnapshot]);\n\n // The local seat competes for the same attention as the cloud accounts —\n // when it is resident and they are exhausted, it IS the answer — so it sorts\n // into the same grid on the same rank scale rather than being parked last.\n const gridCards = useMemo(() => {\n const entries: Array<\n { key: string; rank: number; label: string } & (\n | { kind: 'account'; card: (typeof cards)[number] }\n | { kind: 'local'; card: NonNullable<typeof localCard> }\n )\n > = cards.map((card) => ({ key: card.id, rank: card.rank, label: card.label, kind: 'account', card }));\n if (localCard) entries.push({ key: 'local', rank: localCard.rank, label: 'Local', kind: 'local', card: localCard });\n return entries.sort((a, b) => a.rank - b.rank || a.label.localeCompare(b.label));\n }, [cards, localCard]);\n\n // The two-second answer, over the same card models the grid renders — so\n // the strip and the cards can never disagree about a seat's state.\n const capacity = useMemo(\n () => buildCapacityOverview({ cards, localCard, localView }),\n [cards, localCard, localView],\n );\n\n const localStale = useMemo(() => localStaleness(localView?.runtimes ?? []), [localView]);\n\n // The shared strip speaks in SEAT ids; the account cards below are keyed by\n // ACCOUNT id. A seat opens its card's detail only when that card exists.\n const capacitySeats = useCapacityData();\n const cardIds = useMemo(() => new Set(cards.map((c) => c.id)), [cards]);\n const seatAccount = useMemo(\n () => new Map(capacitySeats.seats.map((seat) => [seat.id, seat.accountId])),\n [capacitySeats.seats],\n );\n const selectedSeatId = useMemo(() => {\n if (selectedAccountId === null) return null;\n for (const [seatId, accountId] of seatAccount) if (accountId === selectedAccountId) return seatId;\n return null;\n }, [seatAccount, selectedAccountId]);\n const selectSeat = useCallback((seatId: string) => {\n const accountId = seatAccount.get(seatId) ?? seatId;\n if (cardIds.has(accountId)) setSelectedAccountId((current) => (current === accountId ? null : accountId));\n }, [seatAccount, cardIds]);\n\n // The selection is held as an ID, never as a card object: a refresh rebuilds\n // every model, and a captured card would keep rendering readings the next\n // poll already replaced. The detail renders from the card the grid is holding\n // at that moment, so an account that disappears simply takes its panel with\n // it.\n const toggleAccount = (id: string): void => {\n setSelectedAccountId((current) => (current === id ? null : id));\n };\n\n /**\n * Close the detail and hand focus back to the card that opened it.\n *\n * Without this, dismissing the panel from its own Close button dropped focus\n * onto `<body>` — the element under the cursor ceases to exist — and the next\n * Tab restarted at the top of the document. A disclosure must return focus to\n * its trigger; closing by clicking the card again already does, because the\n * trigger is what was clicked.\n */\n const closeAccount = useCallback((): void => {\n // Read the id from the closure, not inside the updater: a state updater\n // must stay pure (StrictMode calls it twice), and the trigger is still\n // mounted at this point either way.\n const id = selectedAccountId;\n setSelectedAccountId(null);\n if (id !== null && typeof document !== 'undefined') {\n document.getElementById(`verse-account-trigger-${id}`)?.focus();\n }\n }, [selectedAccountId]);\n\n // Per-seat context efficiency, from the session records bootstrap already\n // carries. Held back (with the reason) when the chat list never arrived:\n // an empty table there would read \"no chats\" when the truth is \"not read\".\n const efficiencyRows = useMemo(\n () => seatEfficiency(bootstrap.data?.sessions ?? [], bootstrap.data?.seats ?? []),\n [bootstrap.data],\n );\n const efficiencyUnavailable = bootstrap.data\n ? null\n : bootstrap.status === 'error'\n ? `The chat list could not be read${bootstrap.error?.message ? ` (${bootstrap.error.message})` : ''}, so efficiency cannot be computed.`\n : 'Reading the chat list…';\n\n const split = useMemo(() => buildLocalCloudSplit(control.data?.usage), [control.data]);\n const limitRows = useMemo(\n () => buildLimitRows(control.data?.limits, caps.foundryLimits),\n [control.data, caps.foundryLimits],\n );\n const daemonSeries = useMemo(\n () => buildDailySpendSeries(control.data?.daemonObservation),\n [control.data],\n );\n\n // Gate the legacy fallback on AVAILABILITY, not on nullness: when the\n // contract's `spend` block is present, `todayUsd` is null — never 0 — for an\n // unreadable ledger, and a `??` here would print a different snapshot's\n // number under the word \"today\".\n const todaySpentUsd = caps.available ? caps.todaySpentUsd : (control.data?.daemon.todaySpentUsd ?? null);\n const todaySpentDate = caps.available ? caps.todaySpentDate : null;\n\n // ---- surface states ----------------------------------------------------\n\n const unauthorized =\n isUnauthorized(accounts.error) ||\n isUnauthorized(localModels.error) ||\n isUnauthorized(seriesRead.error) ||\n isUnauthorized(frontier.error) ||\n isUnauthorized(control.error) ||\n isUnauthorized(bootstrap.error);\n\n // Only a total loss of BOTH aggregate sources is a dead section: the new\n // routes are optional by construction, so their absence is degradation.\n const bothFailed =\n !unauthorized &&\n frontier.status === 'error' &&\n control.status === 'error' &&\n frontier.data === undefined &&\n control.data === undefined;\n\n const firstLoad =\n !unauthorized &&\n !bothFailed &&\n accounts.data === undefined &&\n frontier.data === undefined &&\n control.data === undefined &&\n (accounts.status === 'loading' ||\n accounts.status === 'idle' ||\n frontier.status === 'loading' ||\n control.status === 'loading' ||\n frontier.status === 'idle' ||\n control.status === 'idle');\n\n const refreshing =\n accounts.status === 'refreshing' ||\n frontier.status === 'refreshing' ||\n control.status === 'refreshing';\n\n const generatedAt =\n accountsSnapshot?.sampledAt ?? frontier.data?.generatedAt ?? control.data?.ts ?? null;\n\n return (\n <section className={styles.section} aria-label=\"Usage\">\n <header className={styles.header} data-app-region=\"drag\">\n <h2 className={styles.headerTitle}>Usage</h2>\n <div className={styles.headerMeta}>\n {generatedAt ? (\n <span>\n {refreshing ? 'refreshing · ' : ''}\n as of {new Date(generatedAt).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}\n </span>\n ) : null}\n <button type=\"button\" className={styles.ghostButton} onClick={refreshAll}>\n Refresh\n </button>\n </div>\n </header>\n\n <div className={styles.scroll}>\n {unauthorized ? (\n <StateBlock\n title=\"Read session expired\"\n body=\"Usage data needs an authenticated read session. Unlock the console with the read token ashlr verse printed, then refresh.\"\n action={\n <button type=\"button\" className={styles.ghostButton} onClick={refreshAll}>\n Try again\n </button>\n }\n />\n ) : bothFailed ? (\n <StateBlock\n title=\"Usage sources unreachable\"\n body={`Neither /api/usage nor /api/control answered. ${control.error?.message ?? frontier.error?.message ?? ''}`.trim()}\n action={\n <button type=\"button\" className={styles.ghostButton} onClick={refreshAll}>\n Retry\n </button>\n }\n />\n ) : firstLoad ? (\n <div aria-busy=\"true\">\n <SkeletonLine width=\"30%\" />\n <div className={styles.skeletonGrid} style={{ marginTop: 'var(--space-4)' }}>\n <SkeletonCardGrid count={5} />\n </div>\n </div>\n ) : (\n <>\n {/*\n The ONE capacity view every surface shares (SPEC-310C §4),\n from the seat roster, A2 health and A9 budget. A seat name\n opens its account card's detail when there is a card for it.\n */}\n <CapacityStrip\n seats={capacitySeats.seats}\n health={capacitySeats.health}\n budget={capacitySeats.budget}\n selectedSeatId={selectedSeatId}\n onSelectSeat={selectSeat}\n />\n <CapacityFacts overview={capacity} />\n\n <section className={styles.panel} aria-labelledby=\"verse-usage-accounts\">\n <div className={styles.panelHead}>\n <h3 id=\"verse-usage-accounts\" className={styles.panelTitle}>\n Accounts\n </h3>\n <p className={styles.panelNote}>\n Ordered by what you can use right now. Each card leads with its binding constraint —\n the window with the highest used percent, because that is what blocks work.\n </p>\n </div>\n\n {usingFallbackRoster && accounts.data && !accounts.data.available ? (\n <p className={styles.muted}>\n {accounts.data.reason} {FALLBACK_SOURCE_NOTE}\n </p>\n ) : null}\n {accountsSnapshot?.collectorNote ? (\n <p className={styles.muted}>{accountsSnapshot.collectorNote}</p>\n ) : null}\n {accountNotes.length > 0 ? (\n <ul className={styles.noteList}>\n {accountNotes.map((note) => (\n <li key={note} className={styles.muted}>\n {note}\n </li>\n ))}\n </ul>\n ) : null}\n\n {cards.length === 0 && localCard === null ? (\n <p className={styles.muted}>\n No accounts and no local runtime were reported. Connect an account or start Ollama,\n then refresh — this is an empty roster, not a set of accounts at zero.\n </p>\n ) : (\n <>\n <div className={styles.cards}>\n {gridCards.map((entry) => {\n if (entry.kind !== 'account') {\n return <LocalCard key={entry.key} card={entry.card} staleness={localStale} />;\n }\n const open = selectedAccountId === entry.key;\n return (\n <Fragment key={entry.key}>\n <AccountCard\n card={entry.card}\n onOpen={toggleAccount}\n expanded={open}\n triggerId={`verse-account-trigger-${entry.key}`}\n detailId={`verse-account-detail-${entry.key}`}\n />\n {/*\n The detail belongs BESIDE the card it explains.\n Rendered after the whole grid it opened up to four\n rows below the thing clicked, frequently off-screen,\n with nothing connecting the two on the page — the\n grid is `auto-fit minmax(280px, 1fr)`, so at a wide\n window the card that was clicked and the panel that\n answered could be a screen apart. Spanning the full\n row in place keeps it under its own card at every\n width, and needs no new rule in the stylesheet.\n */}\n {open ? (\n <div id={`verse-account-detail-${entry.key}`} style={DETAIL_ROW}>\n <AccountDetail\n card={entry.card}\n headingId={`verse-account-heading-${entry.key}`}\n onClose={closeAccount}\n />\n </div>\n ) : null}\n </Fragment>\n );\n })}\n </div>\n </>\n )}\n </section>\n\n <LocalModelsPanel view={localView} />\n\n <SeriesPanel\n series={series}\n window={seriesWindow}\n onWindowChange={setSeriesWindow}\n unavailableReason={\n seriesRead.data && !seriesRead.data.available ? seriesRead.data.reason : null\n }\n loading={seriesRead.status === 'loading' || seriesRead.status === 'idle'}\n />\n\n <EfficiencyPanel rows={efficiencyRows} unavailableReason={efficiencyUnavailable} />\n\n {split ? (\n <LocalCloudPanel split={split} savingsNote={LOCAL_SAVINGS_NOTE} />\n ) : (\n <section className={styles.panel} aria-labelledby=\"verse-usage-split-missing\">\n <div className={styles.panelHead}>\n <h3 id=\"verse-usage-split-missing\" className={styles.panelTitle}>\n Local vs cloud\n </h3>\n </div>\n <div className={styles.tiles}>\n <StatTile\n label=\"Not spent (ran locally)\"\n value={<span className={styles.num}>unknown</span>}\n caption=\"/api/control did not answer, so the split is unavailable\"\n />\n </div>\n </section>\n )}\n\n {/* 3.11: Claude Code cloud sessions' estimated credits and their budget. */}\n <CloudCreditsPanel />\n\n <LimitsPanel rows={limitRows} capsNote={caps.available ? null : caps.reason} />\n\n <SpendPanel\n series={daemonSeries}\n todaySpentUsd={todaySpentUsd}\n todaySpentDate={todaySpentDate}\n dailyBudgetUsd={caps.dailyBudgetUsd}\n // The real per-day spend chart lives in the series panel above.\n // The daemon tick ledger is only worth drawing when that series\n // could not be read at all — otherwise it is a narrower, capped\n // second line about the same money.\n showSeries={series === null}\n />\n\n {caps.available && caps.subscriptionMaxPercent !== null ? (\n <p className={styles.muted}>\n Subscription throttle threshold is{' '}\n <span className={styles.num}>\n {chartFormat.formatPercent(caps.subscriptionMaxPercent / 100)}\n </span>\n . It only applies to engines that publish a real window reading — no seat is ever\n throttled on a guess.\n </p>\n ) : null}\n </>\n )}\n </div>\n </section>\n );\n}\n"],"mappings":"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"}