@ashlr/hub 3.10.1 → 3.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (342) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/README.md +343 -82
  3. package/dist/authority-surface.json +69 -9
  4. package/dist/build-identity.json +2 -2
  5. package/dist/cli/cloud.d.ts +39 -0
  6. package/dist/cli/cloud.js +448 -0
  7. package/dist/cli/cloud.js.map +1 -0
  8. package/dist/cli/completions.js +4 -0
  9. package/dist/cli/completions.js.map +1 -1
  10. package/dist/cli/help.js +2 -0
  11. package/dist/cli/help.js.map +1 -1
  12. package/dist/cli/index.d.ts +1 -0
  13. package/dist/cli/index.js +10 -0
  14. package/dist/cli/index.js.map +1 -1
  15. package/dist/core/cloud/backlog.d.ts +17 -0
  16. package/dist/core/cloud/backlog.js +177 -0
  17. package/dist/core/cloud/backlog.js.map +1 -0
  18. package/dist/core/cloud/budget.d.ts +19 -0
  19. package/dist/core/cloud/budget.js +99 -0
  20. package/dist/core/cloud/budget.js.map +1 -0
  21. package/dist/core/cloud/checkout.d.ts +41 -0
  22. package/dist/core/cloud/checkout.js +168 -0
  23. package/dist/core/cloud/checkout.js.map +1 -0
  24. package/dist/core/cloud/cloud-api.d.ts +86 -0
  25. package/dist/core/cloud/cloud-api.js +599 -0
  26. package/dist/core/cloud/cloud-api.js.map +1 -0
  27. package/dist/core/cloud/delivery-contract.d.ts +25 -0
  28. package/dist/core/cloud/delivery-contract.js +138 -0
  29. package/dist/core/cloud/delivery-contract.js.map +1 -0
  30. package/dist/core/cloud/improvement-backlog.d.ts +11 -0
  31. package/dist/core/cloud/improvement-backlog.js +26 -0
  32. package/dist/core/cloud/improvement-backlog.js.map +1 -0
  33. package/dist/core/cloud/launcher.d.ts +68 -0
  34. package/dist/core/cloud/launcher.js +312 -0
  35. package/dist/core/cloud/launcher.js.map +1 -0
  36. package/dist/core/cloud/service.d.ts +51 -0
  37. package/dist/core/cloud/service.js +215 -0
  38. package/dist/core/cloud/service.js.map +1 -0
  39. package/dist/core/cloud/store.d.ts +41 -0
  40. package/dist/core/cloud/store.js +278 -0
  41. package/dist/core/cloud/store.js.map +1 -0
  42. package/dist/core/cloud/tracker.d.ts +30 -0
  43. package/dist/core/cloud/tracker.js +152 -0
  44. package/dist/core/cloud/tracker.js.map +1 -0
  45. package/dist/core/cloud/types.d.ts +233 -0
  46. package/dist/core/cloud/types.js +73 -0
  47. package/dist/core/cloud/types.js.map +1 -0
  48. package/dist/core/verse/activity-api.d.ts +3 -1
  49. package/dist/core/verse/activity-api.js +16 -1
  50. package/dist/core/verse/activity-api.js.map +1 -1
  51. package/dist/core/verse/activity.d.ts +7 -0
  52. package/dist/core/verse/activity.js +23 -0
  53. package/dist/core/verse/activity.js.map +1 -1
  54. package/dist/core/verse/verse-api.d.ts +1 -1
  55. package/dist/core/verse/verse-api.js +2 -0
  56. package/dist/core/verse/verse-api.js.map +1 -1
  57. package/dist/core/vision/leader-cloud.d.ts +63 -0
  58. package/dist/core/vision/leader-cloud.js +134 -0
  59. package/dist/core/vision/leader-cloud.js.map +1 -0
  60. package/dist/core/vision/leader.d.ts +6 -0
  61. package/dist/core/vision/leader.js +12 -1
  62. package/dist/core/vision/leader.js.map +1 -1
  63. package/dist/core/web/public/next/assets/{ActionMenu-BBB7VYjz.js → ActionMenu-CQvNJvHY.js} +2 -2
  64. package/dist/core/web/public/next/assets/{ActionMenu-BBB7VYjz.js.map → ActionMenu-CQvNJvHY.js.map} +1 -1
  65. package/dist/core/web/public/next/assets/Advanced-DEM93sKI.js +2 -0
  66. package/dist/core/web/public/next/assets/Advanced-DEM93sKI.js.map +1 -0
  67. package/dist/core/web/public/next/assets/{App-CbDCLAxn.js → App-CimXmK0L.js} +2 -2
  68. package/dist/core/web/public/next/assets/{App-CbDCLAxn.js.map → App-CimXmK0L.js.map} +1 -1
  69. package/dist/core/web/public/next/assets/AppsSection-D6U-dSj6.js +2 -0
  70. package/dist/core/web/public/next/assets/AppsSection-D6U-dSj6.js.map +1 -0
  71. package/dist/core/web/public/next/assets/{AreaTrend-BgnK0wAy.js → AreaTrend-LD9lCPkT.js} +2 -2
  72. package/dist/core/web/public/next/assets/{AreaTrend-BgnK0wAy.js.map → AreaTrend-LD9lCPkT.js.map} +1 -1
  73. package/dist/core/web/public/next/assets/AutonomySection-3V9pUyxm.js +2 -0
  74. package/dist/core/web/public/next/assets/{AutonomySection-BF5UCsMv.js.map → AutonomySection-3V9pUyxm.js.map} +1 -1
  75. package/dist/core/web/public/next/assets/{BranchBar-nfSb59Kv.js → BranchBar-U8UdpfEB.js} +2 -2
  76. package/dist/core/web/public/next/assets/{BranchBar-nfSb59Kv.js.map → BranchBar-U8UdpfEB.js.map} +1 -1
  77. package/dist/core/web/public/next/assets/{BudgetControl-BESM12dO.js → BudgetControl-DOTlMSmW.js} +2 -2
  78. package/dist/core/web/public/next/assets/{BudgetControl-BESM12dO.js.map → BudgetControl-DOTlMSmW.js.map} +1 -1
  79. package/dist/core/web/public/next/assets/{BurnDown-D1AfskPT.js → BurnDown-x4PWH9JF.js} +2 -2
  80. package/dist/core/web/public/next/assets/{BurnDown-D1AfskPT.js.map → BurnDown-x4PWH9JF.js.map} +1 -1
  81. package/dist/core/web/public/next/assets/{Button-Cr_qkQEc.js → Button-DYv_KKxr.js} +2 -2
  82. package/dist/core/web/public/next/assets/{Button-Cr_qkQEc.js.map → Button-DYv_KKxr.js.map} +1 -1
  83. package/dist/core/web/public/next/assets/{CapacityStrip-DqqYnLek.js → CapacityStrip-C667yQe8.js} +2 -2
  84. package/dist/core/web/public/next/assets/{CapacityStrip-DqqYnLek.js.map → CapacityStrip-C667yQe8.js.map} +1 -1
  85. package/dist/core/web/public/next/assets/{ChatSection-DoqjyVoj.js → ChatSection-CCcIPpOq.js} +3 -3
  86. package/dist/core/web/public/next/assets/{ChatSection-DoqjyVoj.js.map → ChatSection-CCcIPpOq.js.map} +1 -1
  87. package/dist/core/web/public/next/assets/CloudBudgetForm-DJeJvBEu.js +2 -0
  88. package/dist/core/web/public/next/assets/CloudBudgetForm-DJeJvBEu.js.map +1 -0
  89. package/dist/core/web/public/next/assets/{CommandPalette-lLV-OR63.js → CommandPalette-FiD4N8XD.js} +2 -2
  90. package/dist/core/web/public/next/assets/{CommandPalette-lLV-OR63.js.map → CommandPalette-FiD4N8XD.js.map} +1 -1
  91. package/dist/core/web/public/next/assets/CommandSection-DN8KwH-X.js +2 -0
  92. package/dist/core/web/public/next/assets/CommandSection-DN8KwH-X.js.map +1 -0
  93. package/dist/core/web/public/next/assets/{DiffPane-BVxhK-cy.js → DiffPane-DLJ3gGGK.js} +2 -2
  94. package/dist/core/web/public/next/assets/{DiffPane-BVxhK-cy.js.map → DiffPane-DLJ3gGGK.js.map} +1 -1
  95. package/dist/core/web/public/next/assets/{DiffViewer-yCdw9J-Y.js → DiffViewer-B7NWPjIO.js} +2 -2
  96. package/dist/core/web/public/next/assets/{DiffViewer-yCdw9J-Y.js.map → DiffViewer-B7NWPjIO.js.map} +1 -1
  97. package/dist/core/web/public/next/assets/{DockHost-BZReKwos.js → DockHost-DvR-hPhZ.js} +2 -2
  98. package/dist/core/web/public/next/assets/{DockHost-BZReKwos.js.map → DockHost-DvR-hPhZ.js.map} +1 -1
  99. package/dist/core/web/public/next/assets/{EmptyState-D1GDxVZy.js → EmptyState-DhNgDDrF.js} +2 -2
  100. package/dist/core/web/public/next/assets/{EmptyState-D1GDxVZy.js.map → EmptyState-DhNgDDrF.js.map} +1 -1
  101. package/dist/core/web/public/next/assets/{Epistemic-DRp4dBfB.js → Epistemic-uARPnx9x.js} +2 -2
  102. package/dist/core/web/public/next/assets/{Epistemic-DRp4dBfB.js.map → Epistemic-uARPnx9x.js.map} +1 -1
  103. package/dist/core/web/public/next/assets/FleetSection-D_zRBCub.js +3 -0
  104. package/dist/core/web/public/next/assets/FleetSection-D_zRBCub.js.map +1 -0
  105. package/dist/core/web/public/next/assets/{Funnel-zvDj3He4.js → Funnel-CL8uHONq.js} +2 -2
  106. package/dist/core/web/public/next/assets/{Funnel-zvDj3He4.js.map → Funnel-CL8uHONq.js.map} +1 -1
  107. package/dist/core/web/public/next/assets/{GearTray-CkviqjYr.js → GearTray-C7k4l_BW.js} +2 -2
  108. package/dist/core/web/public/next/assets/{GearTray-CkviqjYr.js.map → GearTray-C7k4l_BW.js.map} +1 -1
  109. package/dist/core/web/public/next/assets/{GrowthSection-Bg5sW0jI.js → GrowthSection-DwdNSGj8.js} +2 -2
  110. package/dist/core/web/public/next/assets/{GrowthSection-Bg5sW0jI.js.map → GrowthSection-DwdNSGj8.js.map} +1 -1
  111. package/dist/core/web/public/next/assets/{HandoffDialog-DcPj1ri9.js → HandoffDialog-FPVOqOMN.js} +2 -2
  112. package/dist/core/web/public/next/assets/{HandoffDialog-DcPj1ri9.js.map → HandoffDialog-FPVOqOMN.js.map} +1 -1
  113. package/dist/core/web/public/next/assets/{Input-Ci7TD96x.js → Input-B9-VLcHS.js} +2 -2
  114. package/dist/core/web/public/next/assets/{Input-Ci7TD96x.js.map → Input-B9-VLcHS.js.map} +1 -1
  115. package/dist/core/web/public/next/assets/{LeaderCard-BSFTlMRF.js → LeaderCard-4R0BhDzT.js} +2 -2
  116. package/dist/core/web/public/next/assets/{LeaderCard-BSFTlMRF.js.map → LeaderCard-4R0BhDzT.js.map} +1 -1
  117. package/dist/core/web/public/next/assets/{MatrixHeatmap-DojKZe9L.js → MatrixHeatmap-DiuushcS.js} +2 -2
  118. package/dist/core/web/public/next/assets/{MatrixHeatmap-DojKZe9L.js.map → MatrixHeatmap-DiuushcS.js.map} +1 -1
  119. package/dist/core/web/public/next/assets/McpSection-CJ__OJKl.js +2 -0
  120. package/dist/core/web/public/next/assets/{McpSection-CvcYu1X_.js.map → McpSection-CJ__OJKl.js.map} +1 -1
  121. package/dist/core/web/public/next/assets/{MessageMarkdown-BrLCrb73.js → MessageMarkdown-qWKyJvAQ.js} +3 -3
  122. package/dist/core/web/public/next/assets/{MessageMarkdown-BrLCrb73.js.map → MessageMarkdown-qWKyJvAQ.js.map} +1 -1
  123. package/dist/core/web/public/next/assets/{MessageMarkdownRenderer-CjmdBw2p.js → MessageMarkdownRenderer-x05TrsrW.js} +2 -2
  124. package/dist/core/web/public/next/assets/{MessageMarkdownRenderer-CjmdBw2p.js.map → MessageMarkdownRenderer-x05TrsrW.js.map} +1 -1
  125. package/dist/core/web/public/next/assets/{Meter-DTHbmhQg.js → Meter-D-hncpkO.js} +2 -2
  126. package/dist/core/web/public/next/assets/{Meter-DTHbmhQg.js.map → Meter-D-hncpkO.js.map} +1 -1
  127. package/dist/core/web/public/next/assets/{MindSection-DcO9fmYe.js → MindSection-BjXHkQPS.js} +2 -2
  128. package/dist/core/web/public/next/assets/{MindSection-DcO9fmYe.js.map → MindSection-BjXHkQPS.js.map} +1 -1
  129. package/dist/core/web/public/next/assets/{MutationTokenDialog-Cqn2uPV6.js → MutationTokenDialog-SkRxqV_I.js} +2 -2
  130. package/dist/core/web/public/next/assets/{MutationTokenDialog-Cqn2uPV6.js.map → MutationTokenDialog-SkRxqV_I.js.map} +1 -1
  131. package/dist/core/web/public/next/assets/{NeedsYouDrawer-hiTINupk.js → NeedsYouDrawer-rSd1ZHAR.js} +2 -2
  132. package/dist/core/web/public/next/assets/{NeedsYouDrawer-hiTINupk.js.map → NeedsYouDrawer-rSd1ZHAR.js.map} +1 -1
  133. package/dist/core/web/public/next/assets/{NeedsYouList-B4Z37Phx.js → NeedsYouList-CG-nB1tr.js} +2 -2
  134. package/dist/core/web/public/next/assets/{NeedsYouList-B4Z37Phx.js.map → NeedsYouList-CG-nB1tr.js.map} +1 -1
  135. package/dist/core/web/public/next/assets/{NewChatDialog-utSckh7C.js → NewChatDialog-BeDQ1eW3.js} +2 -2
  136. package/dist/core/web/public/next/assets/{NewChatDialog-utSckh7C.js.map → NewChatDialog-BeDQ1eW3.js.map} +1 -1
  137. package/dist/core/web/public/next/assets/{OnboardingFlow-7N3YSUHN.js → OnboardingFlow-CkTZtt-m.js} +2 -2
  138. package/dist/core/web/public/next/assets/{OnboardingFlow-7N3YSUHN.js.map → OnboardingFlow-CkTZtt-m.js.map} +1 -1
  139. package/dist/core/web/public/next/assets/{PreviewPane-CqzkaAjG.js → PreviewPane-kzbbSK4u.js} +2 -2
  140. package/dist/core/web/public/next/assets/{PreviewPane-CqzkaAjG.js.map → PreviewPane-kzbbSK4u.js.map} +1 -1
  141. package/dist/core/web/public/next/assets/RailStatus-D-t2gPae.js +2 -0
  142. package/dist/core/web/public/next/assets/{RailStatus-sZhApA8k.js.map → RailStatus-D-t2gPae.js.map} +1 -1
  143. package/dist/core/web/public/next/assets/{RefreshIndicator-C1uQIegT.js → RefreshIndicator-BLnr9IOM.js} +2 -2
  144. package/dist/core/web/public/next/assets/{RefreshIndicator-C1uQIegT.js.map → RefreshIndicator-BLnr9IOM.js.map} +1 -1
  145. package/dist/core/web/public/next/assets/{ResourcePoolConsoleApp-DXjjV6Sh.js → ResourcePoolConsoleApp-BeG0gBif.js} +2 -2
  146. package/dist/core/web/public/next/assets/{ResourcePoolConsoleApp-DXjjV6Sh.js.map → ResourcePoolConsoleApp-BeG0gBif.js.map} +1 -1
  147. package/dist/core/web/public/next/assets/ResourcesChrome-B3Z3O98t.css +1 -0
  148. package/dist/core/web/public/next/assets/ResourcesChrome-BzV6bkIa.js +3 -0
  149. package/dist/core/web/public/next/assets/ResourcesChrome-BzV6bkIa.js.map +1 -0
  150. package/dist/core/web/public/next/assets/ResourcesDrawer-CSKIO_wZ.css +1 -0
  151. package/dist/core/web/public/next/assets/ResourcesDrawer-o4ILHdep.js +2 -0
  152. package/dist/core/web/public/next/assets/ResourcesDrawer-o4ILHdep.js.map +1 -0
  153. package/dist/core/web/public/next/assets/{RouteErrorBoundary-D1LZxQjN.js → RouteErrorBoundary-C5SxA2Dg.js} +2 -2
  154. package/dist/core/web/public/next/assets/{RouteErrorBoundary-D1LZxQjN.js.map → RouteErrorBoundary-C5SxA2Dg.js.map} +1 -1
  155. package/dist/core/web/public/next/assets/RunInCloudAction-C3LBp7C4.js +2 -0
  156. package/dist/core/web/public/next/assets/RunInCloudAction-C3LBp7C4.js.map +1 -0
  157. package/dist/core/web/public/next/assets/{SeatSelector-CT92PqM_.js → SeatSelector-DpvvbjNm.js} +2 -2
  158. package/dist/core/web/public/next/assets/{SeatSelector-CT92PqM_.js.map → SeatSelector-DpvvbjNm.js.map} +1 -1
  159. package/dist/core/web/public/next/assets/{Segmented-BMvq-FfD.js → Segmented-BL40udoO.js} +2 -2
  160. package/dist/core/web/public/next/assets/{Segmented-BMvq-FfD.js.map → Segmented-BL40udoO.js.map} +1 -1
  161. package/dist/core/web/public/next/assets/{Select-DkdeoSQn.js → Select-FWLnAw_j.js} +2 -2
  162. package/dist/core/web/public/next/assets/{Select-DkdeoSQn.js.map → Select-FWLnAw_j.js.map} +1 -1
  163. package/dist/core/web/public/next/assets/{SessionInsightChip-CwlakUYU.js → SessionInsightChip-CWye87Ju.js} +2 -2
  164. package/dist/core/web/public/next/assets/{SessionInsightChip-CwlakUYU.js.map → SessionInsightChip-CWye87Ju.js.map} +1 -1
  165. package/dist/core/web/public/next/assets/{SessionSearch-DFByh2NZ.js → SessionSearch-YvCHFUuN.js} +2 -2
  166. package/dist/core/web/public/next/assets/{SessionSearch-DFByh2NZ.js.map → SessionSearch-YvCHFUuN.js.map} +1 -1
  167. package/dist/core/web/public/next/assets/{SettingsSection-DgSaHFK4.js → SettingsSection-Dr18upeE.js} +2 -2
  168. package/dist/core/web/public/next/assets/{SettingsSection-DgSaHFK4.js.map → SettingsSection-Dr18upeE.js.map} +1 -1
  169. package/dist/core/web/public/next/assets/{Sheet-C7APkGPt.js → Sheet-DZKcQXQg.js} +2 -2
  170. package/dist/core/web/public/next/assets/{Sheet-C7APkGPt.js.map → Sheet-DZKcQXQg.js.map} +1 -1
  171. package/dist/core/web/public/next/assets/{ShortcutsOverlay-ZPyXUS_I.js → ShortcutsOverlay-BpDimdPq.js} +2 -2
  172. package/dist/core/web/public/next/assets/{ShortcutsOverlay-ZPyXUS_I.js.map → ShortcutsOverlay-BpDimdPq.js.map} +1 -1
  173. package/dist/core/web/public/next/assets/{Sidebar-Chsgazmk.js → Sidebar-BoBzBEFX.js} +3 -3
  174. package/dist/core/web/public/next/assets/{Sidebar-Chsgazmk.js.map → Sidebar-BoBzBEFX.js.map} +1 -1
  175. package/dist/core/web/public/next/assets/{Slider-B0kjW7cd.js → Slider-DUMo9HDD.js} +2 -2
  176. package/dist/core/web/public/next/assets/{Slider-B0kjW7cd.js.map → Slider-DUMo9HDD.js.map} +1 -1
  177. package/dist/core/web/public/next/assets/{StatusBadge-wv4e6f8b.js → StatusBadge-BwnBNFQr.js} +2 -2
  178. package/dist/core/web/public/next/assets/{StatusBadge-wv4e6f8b.js.map → StatusBadge-BwnBNFQr.js.map} +1 -1
  179. package/dist/core/web/public/next/assets/{StepBand-Db8WPw8J.js → StepBand-PDXMIlRk.js} +2 -2
  180. package/dist/core/web/public/next/assets/{StepBand-Db8WPw8J.js.map → StepBand-PDXMIlRk.js.map} +1 -1
  181. package/dist/core/web/public/next/assets/{Surface-BkDrQ4t3.js → Surface-B3TZVoER.js} +2 -2
  182. package/dist/core/web/public/next/assets/{Surface-BkDrQ4t3.js.map → Surface-B3TZVoER.js.map} +1 -1
  183. package/dist/core/web/public/next/assets/{Swimlane-Dcve56cP.js → Swimlane-DR4OgON_.js} +2 -2
  184. package/dist/core/web/public/next/assets/{Swimlane-Dcve56cP.js.map → Swimlane-DR4OgON_.js.map} +1 -1
  185. package/dist/core/web/public/next/assets/{Switch-DamlpSMY.js → Switch-CcR5Llk5.js} +2 -2
  186. package/dist/core/web/public/next/assets/{Switch-DamlpSMY.js.map → Switch-CcR5Llk5.js.map} +1 -1
  187. package/dist/core/web/public/next/assets/{Tag-Cs4tudBN.js → Tag-_-K1h7Hk.js} +2 -2
  188. package/dist/core/web/public/next/assets/{Tag-Cs4tudBN.js.map → Tag-_-K1h7Hk.js.map} +1 -1
  189. package/dist/core/web/public/next/assets/{TerminalPane-BDkKFych.js → TerminalPane-_1aH4ndN.js} +2 -2
  190. package/dist/core/web/public/next/assets/{TerminalPane-BDkKFych.js.map → TerminalPane-_1aH4ndN.js.map} +1 -1
  191. package/dist/core/web/public/next/assets/{UniverseConsoleApp-BE72VyBL.js → UniverseConsoleApp-BUsq-inZ.js} +2 -2
  192. package/dist/core/web/public/next/assets/{UniverseConsoleApp-BE72VyBL.js.map → UniverseConsoleApp-BUsq-inZ.js.map} +1 -1
  193. package/dist/core/web/public/next/assets/{UniverseView-BbmYY2P4.js → UniverseView-Dogy_dsB.js} +2 -2
  194. package/dist/core/web/public/next/assets/{UniverseView-BbmYY2P4.js.map → UniverseView-Dogy_dsB.js.map} +1 -1
  195. package/dist/core/web/public/next/assets/UsageSection-DiX_dTyo.js +2 -0
  196. package/dist/core/web/public/next/assets/UsageSection-DiX_dTyo.js.map +1 -0
  197. package/dist/core/web/public/next/assets/VerseConsoleApp-Cxqr-3qc.css +1 -0
  198. package/dist/core/web/public/next/assets/VerseConsoleApp-WVeyJnW7.js +3 -0
  199. package/dist/core/web/public/next/assets/VerseConsoleApp-WVeyJnW7.js.map +1 -0
  200. package/dist/core/web/public/next/assets/Workspace-BbxZHwQd.js +10 -0
  201. package/dist/core/web/public/next/assets/Workspace-BbxZHwQd.js.map +1 -0
  202. package/dist/core/web/public/next/assets/{actions-BnjZy8a-.js → actions-s2lfm_5k.js} +2 -2
  203. package/dist/core/web/public/next/assets/{actions-BnjZy8a-.js.map → actions-s2lfm_5k.js.map} +1 -1
  204. package/dist/core/web/public/next/assets/apps-model-CDFvmsQV.js +2 -0
  205. package/dist/core/web/public/next/assets/apps-model-CDFvmsQV.js.map +1 -0
  206. package/dist/core/web/public/next/assets/{budget-queries-Cp6vO7FH.js → budget-queries-wUshcovN.js} +2 -2
  207. package/dist/core/web/public/next/assets/{budget-queries-Cp6vO7FH.js.map → budget-queries-wUshcovN.js.map} +1 -1
  208. package/dist/core/web/public/next/assets/{capacity-strip-model-9-Yb211u.js → capacity-strip-model-Bj_9ztzs.js} +2 -2
  209. package/dist/core/web/public/next/assets/{capacity-strip-model-9-Yb211u.js.map → capacity-strip-model-Bj_9ztzs.js.map} +1 -1
  210. package/dist/core/web/public/next/assets/{charts-BmbKhjqw.js → charts-CMSgAUKn.js} +2 -2
  211. package/dist/core/web/public/next/assets/{charts-BmbKhjqw.js.map → charts-CMSgAUKn.js.map} +1 -1
  212. package/dist/core/web/public/next/assets/cloud-C1KPNRHC.css +1 -0
  213. package/dist/core/web/public/next/assets/cloud-queries-CnV1yaNG.js +2 -0
  214. package/dist/core/web/public/next/assets/cloud-queries-CnV1yaNG.js.map +1 -0
  215. package/dist/core/web/public/next/assets/cloud.module-CiwatLj3.js +2 -0
  216. package/dist/core/web/public/next/assets/cloud.module-CiwatLj3.js.map +1 -0
  217. package/dist/core/web/public/next/assets/{command-bus-DHJJLWh8.js → command-bus-DqimKCUY.js} +2 -2
  218. package/dist/core/web/public/next/assets/{command-bus-DHJJLWh8.js.map → command-bus-DqimKCUY.js.map} +1 -1
  219. package/dist/core/web/public/next/assets/command-catalog-BdtDH93o.js +2 -0
  220. package/dist/core/web/public/next/assets/command-catalog-BdtDH93o.js.map +1 -0
  221. package/dist/core/web/public/next/assets/{composer-keys-CYz4U4Bg.js → composer-keys-DBRymxQn.js} +2 -2
  222. package/dist/core/web/public/next/assets/{composer-keys-CYz4U4Bg.js.map → composer-keys-DBRymxQn.js.map} +1 -1
  223. package/dist/core/web/public/next/assets/{context-model-DeJ28uSZ.js → context-model-Dwd49-dp.js} +2 -2
  224. package/dist/core/web/public/next/assets/{context-model-DeJ28uSZ.js.map → context-model-Dwd49-dp.js.map} +1 -1
  225. package/dist/core/web/public/next/assets/{context-model-BGznyHNQ.js → context-model-MT17V86_.js} +2 -2
  226. package/dist/core/web/public/next/assets/{context-model-BGznyHNQ.js.map → context-model-MT17V86_.js.map} +1 -1
  227. package/dist/core/web/public/next/assets/{context-queries-_mEgy4eg.js → context-queries-xVKIeynP.js} +2 -2
  228. package/dist/core/web/public/next/assets/{context-queries-_mEgy4eg.js.map → context-queries-xVKIeynP.js.map} +1 -1
  229. package/dist/core/web/public/next/assets/{control-queries-C4TG8blN.js → control-queries-DOZR-D8G.js} +2 -2
  230. package/dist/core/web/public/next/assets/{control-queries-C4TG8blN.js.map → control-queries-DOZR-D8G.js.map} +1 -1
  231. package/dist/core/web/public/next/assets/{dock-icons-BB7Fi6hT.js → dock-icons-8EtARwUm.js} +2 -2
  232. package/dist/core/web/public/next/assets/{dock-icons-BB7Fi6hT.js.map → dock-icons-8EtARwUm.js.map} +1 -1
  233. package/dist/core/web/public/next/assets/dock-panes-UKS-mXhr.js +2 -0
  234. package/dist/core/web/public/next/assets/{dock-panes-mnIwSpRp.js.map → dock-panes-UKS-mXhr.js.map} +1 -1
  235. package/dist/core/web/public/next/assets/{dock-store-CdHQRP8s.js → dock-store-BA1cHOYA.js} +2 -2
  236. package/dist/core/web/public/next/assets/{dock-store-CdHQRP8s.js.map → dock-store-BA1cHOYA.js.map} +1 -1
  237. package/dist/core/web/public/next/assets/{fleet-model-B4FKC7fH.js → fleet-model-CNe8Wh-s.js} +2 -2
  238. package/dist/core/web/public/next/assets/{fleet-model-B4FKC7fH.js.map → fleet-model-CNe8Wh-s.js.map} +1 -1
  239. package/dist/core/web/public/next/assets/fleet-queries-BSdRlUwJ.js +2 -0
  240. package/dist/core/web/public/next/assets/fleet-queries-BSdRlUwJ.js.map +1 -0
  241. package/dist/core/web/public/next/assets/{format-lW58rL2y.js → format-B8DAVcn2.js} +2 -2
  242. package/dist/core/web/public/next/assets/{format-lW58rL2y.js.map → format-B8DAVcn2.js.map} +1 -1
  243. package/dist/core/web/public/next/assets/{git-model-DaGw1SzS.js → git-model-CivuBY_D.js} +2 -2
  244. package/dist/core/web/public/next/assets/{git-model-DaGw1SzS.js.map → git-model-CivuBY_D.js.map} +1 -1
  245. package/dist/core/web/public/next/assets/{global-DG1fmn4y.js → global-Di2PUgj4.js} +2 -2
  246. package/dist/core/web/public/next/assets/{global-DG1fmn4y.js.map → global-Di2PUgj4.js.map} +1 -1
  247. package/dist/core/web/public/next/assets/{guarded-action--lguLXfz.js → guarded-action-CvOHcqyH.js} +2 -2
  248. package/dist/core/web/public/next/assets/{guarded-action--lguLXfz.js.map → guarded-action-CvOHcqyH.js.map} +1 -1
  249. package/dist/core/web/public/next/assets/{icons-YPgbel-I.js → icons-B_yuAgdN.js} +2 -2
  250. package/dist/core/web/public/next/assets/{icons-YPgbel-I.js.map → icons-B_yuAgdN.js.map} +1 -1
  251. package/dist/core/web/public/next/assets/{index-Dk8R-3a7.js → index-oAAq8XJa.js} +3 -3
  252. package/dist/core/web/public/next/assets/{index-Dk8R-3a7.js.map → index-oAAq8XJa.js.map} +1 -1
  253. package/dist/core/web/public/next/assets/{live-model-44wEU6I8.js → live-model-DCw_IFRI.js} +2 -2
  254. package/dist/core/web/public/next/assets/{live-model-44wEU6I8.js.map → live-model-DCw_IFRI.js.map} +1 -1
  255. package/dist/core/web/public/next/assets/local-model-DFyjKX0b.js +2 -0
  256. package/dist/core/web/public/next/assets/local-model-DFyjKX0b.js.map +1 -0
  257. package/dist/core/web/public/next/assets/{mind.module-BOABBdi_.js → mind.module-vnuJcwvD.js} +2 -2
  258. package/dist/core/web/public/next/assets/{mind.module-BOABBdi_.js.map → mind.module-vnuJcwvD.js.map} +1 -1
  259. package/dist/core/web/public/next/assets/{mutations-DjXM3IDg.js → mutations-Dpsql5t7.js} +2 -2
  260. package/dist/core/web/public/next/assets/{mutations-DjXM3IDg.js.map → mutations-Dpsql5t7.js.map} +1 -1
  261. package/dist/core/web/public/next/assets/{overnight-queries-Be_eossf.js → overnight-queries-X-44Gsw5.js} +2 -2
  262. package/dist/core/web/public/next/assets/{overnight-queries-Be_eossf.js.map → overnight-queries-X-44Gsw5.js.map} +1 -1
  263. package/dist/core/web/public/next/assets/primitives-BDIcUvob.js +1 -0
  264. package/dist/core/web/public/next/assets/{queries-CYEVCq5r.js → queries-BA4rNGD-.js} +2 -2
  265. package/dist/core/web/public/next/assets/{queries-CYEVCq5r.js.map → queries-BA4rNGD-.js.map} +1 -1
  266. package/dist/core/web/public/next/assets/{reasoning-pref-a_ZP6GzU.js → reasoning-pref-B9-DJUXP.js} +2 -2
  267. package/dist/core/web/public/next/assets/{reasoning-pref-a_ZP6GzU.js.map → reasoning-pref-B9-DJUXP.js.map} +1 -1
  268. package/dist/core/web/public/next/assets/{seat-subscription-CRigL-GE.js → seat-subscription-CH6fW4fJ.js} +2 -2
  269. package/dist/core/web/public/next/assets/{seat-subscription-CRigL-GE.js.map → seat-subscription-CH6fW4fJ.js.map} +1 -1
  270. package/dist/core/web/public/next/assets/{section-visibility-u7q-Q9AA.js → section-visibility-qFqc_d4Z.js} +2 -2
  271. package/dist/core/web/public/next/assets/{section-visibility-u7q-Q9AA.js.map → section-visibility-qFqc_d4Z.js.map} +1 -1
  272. package/dist/core/web/public/next/assets/{sidebar-model-i4WRuQ6j.js → sidebar-model-M1GaQU5l.js} +2 -2
  273. package/dist/core/web/public/next/assets/{sidebar-model-i4WRuQ6j.js.map → sidebar-model-M1GaQU5l.js.map} +1 -1
  274. package/dist/core/web/public/next/assets/{slots-CV9ZuLQU.js → slots-Ds9ZIqUL.js} +3 -3
  275. package/dist/core/web/public/next/assets/{slots-CV9ZuLQU.js.map → slots-Ds9ZIqUL.js.map} +1 -1
  276. package/dist/core/web/public/next/assets/{surface-data-DLvmUX9z.js → surface-data-J52iIGMD.js} +2 -2
  277. package/dist/core/web/public/next/assets/{surface-data-DLvmUX9z.js.map → surface-data-J52iIGMD.js.map} +1 -1
  278. package/dist/core/web/public/next/assets/surface-prefetch-CgZ-LEJK.js +2 -0
  279. package/dist/core/web/public/next/assets/surface-prefetch-CgZ-LEJK.js.map +1 -0
  280. package/dist/core/web/public/next/assets/{tasks-model-DWs5u9RO.js → tasks-model-ent8f0jZ.js} +2 -2
  281. package/dist/core/web/public/next/assets/{tasks-model-DWs5u9RO.js.map → tasks-model-ent8f0jZ.js.map} +1 -1
  282. package/dist/core/web/public/next/assets/{terminal-icons-Ct9cZsEK.js → terminal-icons-DJTK7QpR.js} +2 -2
  283. package/dist/core/web/public/next/assets/{terminal-icons-Ct9cZsEK.js.map → terminal-icons-DJTK7QpR.js.map} +1 -1
  284. package/dist/core/web/public/next/assets/types-D5XOdyw8.js +2 -0
  285. package/dist/core/web/public/next/assets/types-D5XOdyw8.js.map +1 -0
  286. package/dist/core/web/public/next/assets/{usage-queries-CI_y9oWZ.js → usage-queries-Bn8ccqyN.js} +2 -2
  287. package/dist/core/web/public/next/assets/{usage-queries-CI_y9oWZ.js.map → usage-queries-Bn8ccqyN.js.map} +1 -1
  288. package/dist/core/web/public/next/assets/{use-guarded-action-DVCtLzSo.js → use-guarded-action-C2HlSzkz.js} +2 -2
  289. package/dist/core/web/public/next/assets/{use-guarded-action-DVCtLzSo.js.map → use-guarded-action-C2HlSzkz.js.map} +1 -1
  290. package/dist/core/web/public/next/assets/{use-ticker-C3LQ2IYs.js → use-ticker-BNc1H4ZC.js} +2 -2
  291. package/dist/core/web/public/next/assets/{use-ticker-C3LQ2IYs.js.map → use-ticker-BNc1H4ZC.js.map} +1 -1
  292. package/dist/core/web/public/next/assets/{use-token-gate-B5gOFkeH.js → use-token-gate-B3IJL6bf.js} +2 -2
  293. package/dist/core/web/public/next/assets/{use-token-gate-B5gOFkeH.js.map → use-token-gate-B3IJL6bf.js.map} +1 -1
  294. package/dist/core/web/public/next/assets/{useActivity-C3R1Sudh.js → useActivity-Bk3XgXjL.js} +2 -2
  295. package/dist/core/web/public/next/assets/{useActivity-C3R1Sudh.js.map → useActivity-Bk3XgXjL.js.map} +1 -1
  296. package/dist/core/web/public/next/assets/{useChartWidth-0APW0BR3.js → useChartWidth-lZ9PrQn0.js} +2 -2
  297. package/dist/core/web/public/next/assets/{useChartWidth-0APW0BR3.js.map → useChartWidth-lZ9PrQn0.js.map} +1 -1
  298. package/dist/core/web/public/next/assets/{useSeatsRefresh-BN8bso-n.js → useSeatsRefresh-CG4jczeL.js} +2 -2
  299. package/dist/core/web/public/next/assets/{useSeatsRefresh-BN8bso-n.js.map → useSeatsRefresh-CG4jczeL.js.map} +1 -1
  300. package/dist/core/web/public/next/assets/{verse-model-yHPwjf-7.js → verse-model-D7NZQFAR.js} +2 -2
  301. package/dist/core/web/public/next/assets/{verse-model-yHPwjf-7.js.map → verse-model-D7NZQFAR.js.map} +1 -1
  302. package/dist/core/web/public/next/assets/{verse-queries-2PxoBISm.js → verse-queries-DvIJcn6Z.js} +2 -2
  303. package/dist/core/web/public/next/assets/{verse-queries-2PxoBISm.js.map → verse-queries-DvIJcn6Z.js.map} +1 -1
  304. package/dist/core/web/public/next/assets/{verse-store-DHTuZpYa.js → verse-store-DjBWj04q.js} +2 -2
  305. package/dist/core/web/public/next/assets/{verse-store-DHTuZpYa.js.map → verse-store-DjBWj04q.js.map} +1 -1
  306. package/dist/core/web/public/next/assets/verse-ui-store-zafyzXKD.js +3 -0
  307. package/dist/core/web/public/next/assets/{verse-ui-store-Dy4HuDBV.js.map → verse-ui-store-zafyzXKD.js.map} +1 -1
  308. package/dist/core/web/public/next/assets/{viewport-DDoJ_xVq.js → viewport-BEqGUoTA.js} +2 -2
  309. package/dist/core/web/public/next/assets/{viewport-DDoJ_xVq.js.map → viewport-BEqGUoTA.js.map} +1 -1
  310. package/dist/core/web/public/next/assets/warmup-BR6pxAKs.js +3 -0
  311. package/dist/core/web/public/next/assets/{warmup-BsL2LdR-.js.map → warmup-BR6pxAKs.js.map} +1 -1
  312. package/dist/core/web/public/next/assets/{workspace-model-Dd3LmIym.js → workspace-model-D_tWD5Wt.js} +2 -2
  313. package/dist/core/web/public/next/assets/{workspace-model-Dd3LmIym.js.map → workspace-model-D_tWD5Wt.js.map} +1 -1
  314. package/dist/core/web/public/next/index.html +1 -1
  315. package/dist/release-dependency-inventory.json +1 -1
  316. package/package.json +1 -1
  317. package/dist/core/web/public/next/assets/Advanced-xVYFAeA8.js +0 -2
  318. package/dist/core/web/public/next/assets/Advanced-xVYFAeA8.js.map +0 -1
  319. package/dist/core/web/public/next/assets/AppsSection-B5HWJi9I.js +0 -2
  320. package/dist/core/web/public/next/assets/AppsSection-B5HWJi9I.js.map +0 -1
  321. package/dist/core/web/public/next/assets/AutonomySection-BF5UCsMv.js +0 -2
  322. package/dist/core/web/public/next/assets/CommandSection-fiZ4DJpM.js +0 -2
  323. package/dist/core/web/public/next/assets/CommandSection-fiZ4DJpM.js.map +0 -1
  324. package/dist/core/web/public/next/assets/FleetSection-rPLy_NPo.js +0 -3
  325. package/dist/core/web/public/next/assets/FleetSection-rPLy_NPo.js.map +0 -1
  326. package/dist/core/web/public/next/assets/McpSection-CvcYu1X_.js +0 -2
  327. package/dist/core/web/public/next/assets/RailStatus-sZhApA8k.js +0 -2
  328. package/dist/core/web/public/next/assets/UsageSection-DsC5WmLk.js +0 -2
  329. package/dist/core/web/public/next/assets/UsageSection-DsC5WmLk.js.map +0 -1
  330. package/dist/core/web/public/next/assets/VerseConsoleApp-CXJWDiEM.css +0 -1
  331. package/dist/core/web/public/next/assets/VerseConsoleApp-Dq_hREXs.js +0 -3
  332. package/dist/core/web/public/next/assets/VerseConsoleApp-Dq_hREXs.js.map +0 -1
  333. package/dist/core/web/public/next/assets/Workspace-CKvVEPFq.js +0 -10
  334. package/dist/core/web/public/next/assets/Workspace-CKvVEPFq.js.map +0 -1
  335. package/dist/core/web/public/next/assets/command-catalog-s3W6Z96D.js +0 -2
  336. package/dist/core/web/public/next/assets/command-catalog-s3W6Z96D.js.map +0 -1
  337. package/dist/core/web/public/next/assets/dock-panes-mnIwSpRp.js +0 -2
  338. package/dist/core/web/public/next/assets/primitives-Dl3SEQvh.js +0 -1
  339. package/dist/core/web/public/next/assets/surface-prefetch-Ct2JwXvL.js +0 -2
  340. package/dist/core/web/public/next/assets/surface-prefetch-Ct2JwXvL.js.map +0 -1
  341. package/dist/core/web/public/next/assets/verse-ui-store-Dy4HuDBV.js +0 -3
  342. package/dist/core/web/public/next/assets/warmup-BsL2LdR-.js +0 -3
@@ -1 +1 @@
1
- {"version":3,"file":"verse-model-yHPwjf-7.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/verse-model.ts"],"sourcesContent":["/**\n * routes/verse/verse-model.ts — small pure helpers shared by the Verse\n * components (labels, grouping, health → tone). No React, no I/O.\n */\nimport type { VerseEngine, VerseModelOption, VerseProject, VerseSeat, VerseSeatHealth, VerseSession } from '../../data/api-types.js';\nimport type { VerseContextMode, VerseWindowSource } from '../../../core/verse/types.js';\nimport type { Tone } from '../../components/primitives/StatusBadge.js';\n// context-math is PURE and browser-safe by contract (its only import is\n// type-only), so a value import here does not drag node into the bundle.\nimport { budgetFor, canonicalModelId, claudeAutocompactFlag, reconcileAutoCompactAt } from '../../../core/verse/context-math.js';\nimport { usedPercentText } from './percent-text.js';\n\nexport const ENGINE_ORDER: readonly VerseEngine[] = ['claude', 'codex', 'grok', 'local'];\n\nexport const ENGINE_LABEL: Record<VerseEngine, string> = {\n claude: 'Claude',\n codex: 'Codex',\n grok: 'Grok',\n local: 'Local',\n};\n\nexport function isVerseEngine(value: string): value is VerseEngine {\n return (ENGINE_ORDER as readonly string[]).includes(value);\n}\n\nexport function projectName(path: string, projects: readonly VerseProject[] = []): string {\n const known = projects.find((p) => p.path === path);\n if (known) return known.name;\n return path.split(/[\\\\/]/).filter(Boolean).at(-1) ?? path;\n}\n\nexport function seatById(seats: readonly VerseSeat[], seatId: string): VerseSeat | undefined {\n return seats.find((s) => s.id === seatId);\n}\n\nexport function seatLabel(seats: readonly VerseSeat[], session: Pick<VerseSession, 'seatId' | 'engine'>): string {\n return seatById(seats, session.seatId)?.label ?? ENGINE_LABEL[session.engine];\n}\n\nexport function modelLabel(seats: readonly VerseSeat[], session: Pick<VerseSession, 'seatId' | 'model'>): string {\n const seat = seatById(seats, session.seatId);\n return seat?.models.find((m) => m.id === session.model)?.label ?? session.model;\n}\n\n/**\n * The seat's catalog entry for a session's model. Exact id first; then the\n * canonical form, because a session created before the alias fix stores\n * `claude-opus-5.5` while today's catalog lists `claude-opus-5-5` (context-math\n * `VERSE_MODEL_ID_ALIASES`) — the record keeps its id, the lookup must not miss.\n */\nexport function modelOptionFor(seats: readonly VerseSeat[], session: Pick<VerseSession, 'seatId' | 'model'>): VerseModelOption | null {\n const seat = seatById(seats, session.seatId);\n if (!seat) return null;\n const exact = seat.models.find((m) => m.id === session.model);\n if (exact) return exact;\n const canonical = canonicalModelId(session.model);\n return seat.models.find((m) => canonicalModelId(m.id) === canonical) ?? null;\n}\n\n/** Everything the meter, the composer's cost hint and the advice banners read. */\nexport interface SessionContextBudget {\n /** Live occupancy as stored — UNCLAMPED; only the drawing clamps. */\n contextTokens: number;\n contextWindow: number | null;\n autoCompactAt: number | null;\n /** False when `contextTokens` is an upper bound (codex before its rollout is read). */\n exact: boolean;\n /** Where `contextWindow` came from; null when nothing on the record says. */\n source: VerseWindowSource | null;\n mode: VerseContextMode;\n /** The catalog option the session's model maps to on its seat, when listed. */\n option: VerseModelOption | null;\n}\n\nfunction positive(value: number | null | undefined): number | null {\n return typeof value === 'number' && Number.isFinite(value) && value > 0 ? value : null;\n}\n\n/**\n * The window a session is measured against, and where it compacts.\n *\n * Precedence (docs/VERSE-CONTEXT.md, \"honesty rules\"):\n *\n * 0. LOCAL — the window STORED on the record, whatever its source. Verse\n * SETS a local seat's window: the claude adapter passes the stored\n * `usage.contextWindow` as `CLAUDE_CODE_MAX_CONTEXT_TOKENS`, and the\n * engine refreshes that stored value from live discovery before each\n * turn. The seat's CURRENT option can differ (another dispatch lane,\n * another resident num_ctx), and drawing it measured the chat against a\n * window the CLI was never told — \"past the 66k window\" for a chat the\n * CLI compacts at 229k. The meter and the CLI must quote one number.\n * 1. RUNTIME — the CLI reported the window for this session's last turn\n * (`usage.contextWindowSource === 'runtime'`). Nothing outranks what the\n * CLI said it is actually running with (e.g. Claude Code clamping a 1M\n * model to 200k when long-context credit runs out).\n * 2. CATALOG — the seat's CURRENT option for the session's model, in the\n * session's mode. Current rather than stored so a corrected catalog (a\n * fixed window table, a mode switch) shows up without waiting for a turn.\n * 3. STORED — whatever the record carries (every pre-3.9 session).\n * 4. The seat's default window, marked `fallback`.\n *\n * A compaction point is only ever DERIVED from a window it belongs to: a\n * runtime window without a stored point is reconciled with context-math's\n * per-engine formula, never paired with a catalog point for another window.\n */\nexport function sessionContextBudget(\n seats: readonly VerseSeat[],\n session: Pick<VerseSession, 'seatId' | 'model' | 'usage' | 'engine' | 'contextMode'>,\n): SessionContextBudget {\n const usage = session.usage;\n // No UI-side legacy rule: the engine materialises a pre-3.9 Claude\n // record's mode (and its budget) on startup and on every touch, so every\n // record reaching the browser already names the mode it runs in.\n const mode: VerseContextMode = session.contextMode ?? 'standard';\n const option = modelOptionFor(seats, session);\n const base = {\n contextTokens: typeof usage.contextTokens === 'number' && Number.isFinite(usage.contextTokens) ? Math.max(0, usage.contextTokens) : 0,\n exact: usage.contextTokensExact !== false,\n mode,\n option,\n };\n const catalog = budgetFor(option, mode);\n\n const stored = positive(usage.contextWindow);\n if (stored !== null && (session.engine === 'local' || usage.contextWindowSource === 'runtime')) {\n const storedPoint = positive(usage.autoCompactAt ?? null);\n const autoCompactAt = storedPoint ?? reconcileAutoCompactAt({\n engine: session.engine,\n runtimeWindow: stored,\n // A local window is the whole budget (no --autocompact); pairing it\n // with the seat's current option would borrow another window's point.\n budget: session.engine === 'local' ? null : catalog,\n autocompactWindow: session.engine === 'claude' ? claudeAutocompactFlag(option, mode) : null,\n maxOutputTokens: option?.maxOutputTokens ?? null,\n });\n const source = session.engine === 'local' ? usage.contextWindowSource ?? null : 'runtime';\n return { ...base, contextWindow: stored, autoCompactAt, source };\n }\n if (catalog) {\n return { ...base, contextWindow: catalog.contextWindow, autoCompactAt: catalog.autoCompactAt, source: option?.windowSource ?? 'fallback' };\n }\n if (stored !== null) {\n return { ...base, contextWindow: stored, autoCompactAt: positive(usage.autoCompactAt ?? null), source: usage.contextWindowSource ?? null };\n }\n const seatWindow = positive(seatById(seats, session.seatId)?.contextWindow ?? null);\n return { ...base, contextWindow: seatWindow, autoCompactAt: null, source: seatWindow !== null ? 'fallback' : null };\n}\n\n/** Context window for a session — see {@link sessionContextBudget} for the precedence. */\nexport function contextWindowFor(\n seats: readonly VerseSeat[],\n session: Pick<VerseSession, 'seatId' | 'model' | 'usage' | 'engine' | 'contextMode'>,\n): number | null {\n return sessionContextBudget(seats, session).contextWindow;\n}\n\n/** Plain words for a window's provenance — the meter's tooltip and the resources panel share them. */\nexport const WINDOW_SOURCE_TEXT: Record<VerseWindowSource, string> = {\n runtime: 'reported by the CLI on the last turn',\n 'provider-catalog': \"from this seat's own model catalog\",\n 'cli-catalog': \"from the pinned CLI's built-in model table\",\n documented: \"from the provider's published model table\",\n fallback: 'a default estimate — the CLI has not reported the real window yet',\n};\n\n/**\n * The same provenance, per engine. On a LOCAL seat nothing is \"reported by\n * the CLI\": Verse measures the window from the model server (llama-server\n * slot, Ollama residency/defaults) and TELLS Claude Code to use it, so the\n * sentence names both halves.\n */\nexport function windowSourceText(source: VerseWindowSource, engine: VerseEngine | null | undefined): string {\n if (engine !== 'local') return WINDOW_SOURCE_TEXT[source];\n const from = source === 'runtime' ? 'measured from the local model server'\n : source === 'fallback' ? 'a default estimate — the model server did not report one'\n : WINDOW_SOURCE_TEXT[source];\n return `${from}; Verse passes this window to Claude Code for this chat`;\n}\n\n/**\n * The one sentence about Codex's surcharge above its standard window, for\n * every surface that prices Expansive on codex (the mode menu, the\n * \"Expansive could help\" chip, the new-chat mode selector, the handoff\n * dialog). Worded as REPORTED because that is all it is: the sources\n * docs/VERSE-CONTEXT.md §2.3 cites say GPT-5.6-class requests above 272k\n * count about 2× against plan limits, and Verse has no reading of its own\n * that confirms the multiplier. It multiplies the size ratio the copy quotes\n * (the ratio of the two compaction points), which is why it says \"twice that\".\n */\nexport const CODEX_EXPANSIVE_METERING_NOTE =\n 'OpenAI reportedly also counts requests above 272k tokens at about 2× against plan limits, so a turn near the expansive limit may cost roughly twice that.';\n\n/** The first model on a seat that can actually run (skips ones listed with an `unavailableReason`). */\nexport function firstRunnableModel(seat: VerseSeat): VerseModelOption | null {\n return seat.models.find((m) => !m.unavailableReason) ?? null;\n}\n\nexport function healthTone(state: VerseSeatHealth['state']): Tone {\n switch (state) {\n case 'ready':\n return 'success';\n case 'degraded':\n return 'warning';\n case 'unavailable':\n return 'danger';\n default:\n return 'unknown';\n }\n}\n\nexport function seatUnavailableReason(seat: VerseSeat): string | null {\n if (seat.health.state !== 'unavailable') return null;\n return seat.health.summary ?? 'seat unavailable';\n}\n\n// ---------------------------------------------------------------------------\n// Seat capacity — \"which account can I actually use right now\", at the point\n// the choice is made\n// ---------------------------------------------------------------------------\n\n/**\n * The four answers a picker needs. Same vocabulary as the Usage section's\n * `CapacityClass` so the two surfaces never use different words for one state.\n */\nexport type SeatCapacityClass = 'ready' | 'tight' | 'blocked' | 'unread';\n\n/** Word, never colour alone (DESIGN-V2 §6). */\nexport const SEAT_CAPACITY_WORD: Record<SeatCapacityClass, string> = {\n ready: 'usable',\n tight: 'tight',\n blocked: 'blocked',\n unread: 'no reading',\n};\n\n/** Above this share of the binding window a seat is worth flagging. */\nconst TIGHT_PERCENT = 85;\n\nexport interface SeatCapacityNote {\n cls: SeatCapacityClass;\n /**\n * The binding window's percent when it is a real measurement. Null for an\n * unread seat AND at the 100 ceiling, where the upstream value may be the\n * provider's \"limit reached\" sentinel rather than a reading\n * (docs/VERSE-TELEMETRY-V2.md) — and \"limit reached\" is true under either.\n */\n usedPercent: number | null;\n /** One short phrase for an option label, a pill title, a menu row. */\n text: string;\n}\n\n/** `seven_day_fable` → `weekly (fable)`; `five_hour` → `5-hour`. */\nexport function seatWindowLabel(id: string): string {\n const known: Record<string, string> = {\n five_hour: '5-hour window',\n seven_day: 'weekly window',\n codex: 'weekly window',\n };\n if (known[id]) return known[id];\n const perModel = /^seven_day_(.+)$/.exec(id);\n if (perModel) return `weekly ${perModel[1]!.replace(/_/g, ' ')} window`;\n return `${id.replace(/_/g, ' ')} window`;\n}\n\n/**\n * What a seat's own health says about whether a turn sent to it will land.\n *\n * This exists because the seat picker showed NOTHING: it annotated an option\n * only when `health.state === 'unavailable'`, and Claude's `health` is\n * `unknown` by construction (docs/VERSE-TELEMETRY-V2.md). So a Claude seat\n * whose binding weekly window reads 100% used appeared as an ordinary,\n * enabled, unannotated choice, and the exhaustion was discovered at turn time\n * — exactly the failure the Usage section was built to prevent.\n *\n * A `blocked` seat is MARKED, never disabled: a used-up window can coexist\n * with a spendable credit balance, so refusing the choice would be a stronger\n * claim than the data supports.\n */\nexport function seatCapacity(seat: VerseSeat): SeatCapacityNote {\n const reason = seatUnavailableReason(seat);\n if (reason !== null) return { cls: 'blocked', usedPercent: null, text: reason };\n\n const measured = 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 // No window reported a number. That is an unanswered question, not a zero —\n // an empty meter would read \"plenty left\".\n if (measured.length === 0) return { cls: 'unread', usedPercent: null, text: 'no capacity reading' };\n\n const binding = measured.reduce((a, b) => (b.usedPercent > a.usedPercent ? b : a));\n const pct = Math.max(0, Math.min(100, binding.usedPercent));\n const where = seatWindowLabel(binding.id);\n if (pct >= 100) return { cls: 'blocked', usedPercent: null, text: `${where} limit reached` };\n return {\n cls: pct >= TIGHT_PERCENT ? 'tight' : 'ready',\n usedPercent: pct,\n text: `${usedPercentText(pct)} of ${where} used`,\n };\n}\n\n/** Seats grouped in the fixed engine order; empty engines are omitted. */\nexport function groupSeats(seats: readonly VerseSeat[]): Array<{ engine: VerseEngine; seats: VerseSeat[] }> {\n return ENGINE_ORDER.map((engine) => ({ engine, seats: seats.filter((s) => s.engine === engine) })).filter((g) => g.seats.length > 0);\n}\n\nexport interface SessionGroup {\n projectPath: string;\n name: string;\n enrolled: boolean;\n sessions: VerseSession[];\n}\n\n/** Sidebar grouping: by project, most recently touched project first, sessions newest first. */\nexport function groupSessions(sessions: readonly VerseSession[], projects: readonly VerseProject[], query = ''): SessionGroup[] {\n const q = query.trim().toLowerCase();\n const filtered = q\n ? sessions.filter((s) =>\n s.title.toLowerCase().includes(q) ||\n s.projectPath.toLowerCase().includes(q) ||\n s.model.toLowerCase().includes(q) ||\n s.seatId.toLowerCase().includes(q))\n : [...sessions];\n const byProject = new Map<string, VerseSession[]>();\n for (const s of filtered) {\n const list = byProject.get(s.projectPath) ?? [];\n list.push(s);\n byProject.set(s.projectPath, list);\n }\n const groups: SessionGroup[] = [];\n for (const [projectPath, list] of byProject) {\n list.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));\n groups.push({\n projectPath,\n name: projectName(projectPath, projects),\n enrolled: projects.find((p) => p.path === projectPath)?.enrolled ?? false,\n sessions: list,\n });\n }\n groups.sort((a, b) => b.sessions[0]!.updatedAt.localeCompare(a.sessions[0]!.updatedAt));\n return groups;\n}\n\nexport function formatElapsed(ms: number): string {\n if (!Number.isFinite(ms) || ms < 0) return '0s';\n const s = Math.floor(ms / 1000);\n if (s < 60) return `${s}s`;\n const m = Math.floor(s / 60);\n if (m < 60) return `${m}m ${s % 60}s`;\n const h = Math.floor(m / 60);\n return `${h}h ${m % 60}m`;\n}\n\nexport function formatDuration(ms: number): string {\n if (!Number.isFinite(ms) || ms < 0) return '—';\n if (ms < 1000) return `${Math.round(ms)}ms`;\n if (ms < 60_000) return `${(ms / 1000).toFixed(1)}s`;\n return formatElapsed(ms);\n}\n\n/**\n * Sidebar rows carry a right-aligned relative time. Short by design — the\n * row has ~5ch for it — and it degrades to a date rather than \"412d\".\n * `now` is injectable so the format is testable without faking the clock.\n */\nexport function formatRelative(iso: string, now: number = Date.now()): string {\n const then = Date.parse(iso);\n if (!Number.isFinite(then)) return '';\n const seconds = Math.round((now - then) / 1000);\n if (seconds < 0) return 'now';\n if (seconds < 60) return 'now';\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h`;\n const days = Math.floor(hours / 24);\n if (days < 7) return `${days}d`;\n return new Date(then).toLocaleDateString([], { month: 'short', day: 'numeric' });\n}\n\nexport function formatClock(iso: string): string {\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return '';\n return d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });\n}\n\n/** One-line description of a tool call for a collapsed card header. */\nexport function summarizeToolInput(input: unknown): string {\n if (input === null || input === undefined) return '';\n if (typeof input === 'string') return truncate(input, 96);\n if (typeof input !== 'object') return truncate(String(input), 96);\n const record = input as Record<string, unknown>;\n const preferred = ['command', 'cmd', 'file_path', 'path', 'pattern', 'query', 'url', 'description', 'prompt', 'text'];\n for (const key of preferred) {\n const v = record[key];\n if (typeof v === 'string' && v.trim()) return truncate(v.trim().replace(/\\s+/g, ' '), 96);\n }\n const keys = Object.keys(record);\n if (keys.length === 0) return '';\n const first = record[keys[0]!];\n const rendered = typeof first === 'string' ? first : JSON.stringify(first);\n return truncate(`${keys[0]}: ${rendered ?? ''}`.replace(/\\s+/g, ' '), 96);\n}\n\nexport function truncate(value: string, max: number): string {\n return value.length > max ? `${value.slice(0, max - 1)}…` : value;\n}\n\n/** Pretty JSON for tool cards; falls back to String() for non-serializable input. */\nexport function prettyJson(value: unknown): string {\n if (typeof value === 'string') return value;\n try {\n return JSON.stringify(value, null, 2) ?? '';\n } catch {\n return String(value);\n }\n}\n\n/**\n * Accepts POSIX/Windows absolute paths and `~/...`. The server rewrites the\n * home directory as `~` in every outbound payload (sanitizePublicJson) and\n * expands it again on the way in, so a `~/` project from bootstrap is valid.\n */\nexport function isAbsolutePath(value: string): boolean {\n return /^(?:\\/|~(?:\\/|$)|[a-zA-Z]:[\\\\/]|\\\\\\\\)/.test(value) &&\n ![...value].some((c) => c.charCodeAt(0) < 32 || (c.charCodeAt(0) >= 127 && c.charCodeAt(0) <= 159));\n}\n\n/**\n * Seat pill text: \"<seat> · <model>\", collapsing to just the seat when the\n * model label is already contained in it (local seats expose one model whose\n * name is the seat name), so the pill never reads \"Qwen3-Coder · Qwen3-Coder\".\n */\nexport function seatPillLabel(seats: readonly VerseSeat[], ref: Pick<VerseSession, 'seatId' | 'engine' | 'model'>): string {\n const seat = seatLabel(seats, ref);\n const model = modelLabel(seats, ref);\n if (!model || seat.toLowerCase().includes(model.toLowerCase())) return seat;\n return `${seat} · ${model}`;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"verse-model-D7NZQFAR.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/verse-model.ts"],"sourcesContent":["/**\n * routes/verse/verse-model.ts — small pure helpers shared by the Verse\n * components (labels, grouping, health → tone). No React, no I/O.\n */\nimport type { VerseEngine, VerseModelOption, VerseProject, VerseSeat, VerseSeatHealth, VerseSession } from '../../data/api-types.js';\nimport type { VerseContextMode, VerseWindowSource } from '../../../core/verse/types.js';\nimport type { Tone } from '../../components/primitives/StatusBadge.js';\n// context-math is PURE and browser-safe by contract (its only import is\n// type-only), so a value import here does not drag node into the bundle.\nimport { budgetFor, canonicalModelId, claudeAutocompactFlag, reconcileAutoCompactAt } from '../../../core/verse/context-math.js';\nimport { usedPercentText } from './percent-text.js';\n\nexport const ENGINE_ORDER: readonly VerseEngine[] = ['claude', 'codex', 'grok', 'local'];\n\nexport const ENGINE_LABEL: Record<VerseEngine, string> = {\n claude: 'Claude',\n codex: 'Codex',\n grok: 'Grok',\n local: 'Local',\n};\n\nexport function isVerseEngine(value: string): value is VerseEngine {\n return (ENGINE_ORDER as readonly string[]).includes(value);\n}\n\nexport function projectName(path: string, projects: readonly VerseProject[] = []): string {\n const known = projects.find((p) => p.path === path);\n if (known) return known.name;\n return path.split(/[\\\\/]/).filter(Boolean).at(-1) ?? path;\n}\n\nexport function seatById(seats: readonly VerseSeat[], seatId: string): VerseSeat | undefined {\n return seats.find((s) => s.id === seatId);\n}\n\nexport function seatLabel(seats: readonly VerseSeat[], session: Pick<VerseSession, 'seatId' | 'engine'>): string {\n return seatById(seats, session.seatId)?.label ?? ENGINE_LABEL[session.engine];\n}\n\nexport function modelLabel(seats: readonly VerseSeat[], session: Pick<VerseSession, 'seatId' | 'model'>): string {\n const seat = seatById(seats, session.seatId);\n return seat?.models.find((m) => m.id === session.model)?.label ?? session.model;\n}\n\n/**\n * The seat's catalog entry for a session's model. Exact id first; then the\n * canonical form, because a session created before the alias fix stores\n * `claude-opus-5.5` while today's catalog lists `claude-opus-5-5` (context-math\n * `VERSE_MODEL_ID_ALIASES`) — the record keeps its id, the lookup must not miss.\n */\nexport function modelOptionFor(seats: readonly VerseSeat[], session: Pick<VerseSession, 'seatId' | 'model'>): VerseModelOption | null {\n const seat = seatById(seats, session.seatId);\n if (!seat) return null;\n const exact = seat.models.find((m) => m.id === session.model);\n if (exact) return exact;\n const canonical = canonicalModelId(session.model);\n return seat.models.find((m) => canonicalModelId(m.id) === canonical) ?? null;\n}\n\n/** Everything the meter, the composer's cost hint and the advice banners read. */\nexport interface SessionContextBudget {\n /** Live occupancy as stored — UNCLAMPED; only the drawing clamps. */\n contextTokens: number;\n contextWindow: number | null;\n autoCompactAt: number | null;\n /** False when `contextTokens` is an upper bound (codex before its rollout is read). */\n exact: boolean;\n /** Where `contextWindow` came from; null when nothing on the record says. */\n source: VerseWindowSource | null;\n mode: VerseContextMode;\n /** The catalog option the session's model maps to on its seat, when listed. */\n option: VerseModelOption | null;\n}\n\nfunction positive(value: number | null | undefined): number | null {\n return typeof value === 'number' && Number.isFinite(value) && value > 0 ? value : null;\n}\n\n/**\n * The window a session is measured against, and where it compacts.\n *\n * Precedence (docs/VERSE-CONTEXT.md, \"honesty rules\"):\n *\n * 0. LOCAL — the window STORED on the record, whatever its source. Verse\n * SETS a local seat's window: the claude adapter passes the stored\n * `usage.contextWindow` as `CLAUDE_CODE_MAX_CONTEXT_TOKENS`, and the\n * engine refreshes that stored value from live discovery before each\n * turn. The seat's CURRENT option can differ (another dispatch lane,\n * another resident num_ctx), and drawing it measured the chat against a\n * window the CLI was never told — \"past the 66k window\" for a chat the\n * CLI compacts at 229k. The meter and the CLI must quote one number.\n * 1. RUNTIME — the CLI reported the window for this session's last turn\n * (`usage.contextWindowSource === 'runtime'`). Nothing outranks what the\n * CLI said it is actually running with (e.g. Claude Code clamping a 1M\n * model to 200k when long-context credit runs out).\n * 2. CATALOG — the seat's CURRENT option for the session's model, in the\n * session's mode. Current rather than stored so a corrected catalog (a\n * fixed window table, a mode switch) shows up without waiting for a turn.\n * 3. STORED — whatever the record carries (every pre-3.9 session).\n * 4. The seat's default window, marked `fallback`.\n *\n * A compaction point is only ever DERIVED from a window it belongs to: a\n * runtime window without a stored point is reconciled with context-math's\n * per-engine formula, never paired with a catalog point for another window.\n */\nexport function sessionContextBudget(\n seats: readonly VerseSeat[],\n session: Pick<VerseSession, 'seatId' | 'model' | 'usage' | 'engine' | 'contextMode'>,\n): SessionContextBudget {\n const usage = session.usage;\n // No UI-side legacy rule: the engine materialises a pre-3.9 Claude\n // record's mode (and its budget) on startup and on every touch, so every\n // record reaching the browser already names the mode it runs in.\n const mode: VerseContextMode = session.contextMode ?? 'standard';\n const option = modelOptionFor(seats, session);\n const base = {\n contextTokens: typeof usage.contextTokens === 'number' && Number.isFinite(usage.contextTokens) ? Math.max(0, usage.contextTokens) : 0,\n exact: usage.contextTokensExact !== false,\n mode,\n option,\n };\n const catalog = budgetFor(option, mode);\n\n const stored = positive(usage.contextWindow);\n if (stored !== null && (session.engine === 'local' || usage.contextWindowSource === 'runtime')) {\n const storedPoint = positive(usage.autoCompactAt ?? null);\n const autoCompactAt = storedPoint ?? reconcileAutoCompactAt({\n engine: session.engine,\n runtimeWindow: stored,\n // A local window is the whole budget (no --autocompact); pairing it\n // with the seat's current option would borrow another window's point.\n budget: session.engine === 'local' ? null : catalog,\n autocompactWindow: session.engine === 'claude' ? claudeAutocompactFlag(option, mode) : null,\n maxOutputTokens: option?.maxOutputTokens ?? null,\n });\n const source = session.engine === 'local' ? usage.contextWindowSource ?? null : 'runtime';\n return { ...base, contextWindow: stored, autoCompactAt, source };\n }\n if (catalog) {\n return { ...base, contextWindow: catalog.contextWindow, autoCompactAt: catalog.autoCompactAt, source: option?.windowSource ?? 'fallback' };\n }\n if (stored !== null) {\n return { ...base, contextWindow: stored, autoCompactAt: positive(usage.autoCompactAt ?? null), source: usage.contextWindowSource ?? null };\n }\n const seatWindow = positive(seatById(seats, session.seatId)?.contextWindow ?? null);\n return { ...base, contextWindow: seatWindow, autoCompactAt: null, source: seatWindow !== null ? 'fallback' : null };\n}\n\n/** Context window for a session — see {@link sessionContextBudget} for the precedence. */\nexport function contextWindowFor(\n seats: readonly VerseSeat[],\n session: Pick<VerseSession, 'seatId' | 'model' | 'usage' | 'engine' | 'contextMode'>,\n): number | null {\n return sessionContextBudget(seats, session).contextWindow;\n}\n\n/** Plain words for a window's provenance — the meter's tooltip and the resources panel share them. */\nexport const WINDOW_SOURCE_TEXT: Record<VerseWindowSource, string> = {\n runtime: 'reported by the CLI on the last turn',\n 'provider-catalog': \"from this seat's own model catalog\",\n 'cli-catalog': \"from the pinned CLI's built-in model table\",\n documented: \"from the provider's published model table\",\n fallback: 'a default estimate — the CLI has not reported the real window yet',\n};\n\n/**\n * The same provenance, per engine. On a LOCAL seat nothing is \"reported by\n * the CLI\": Verse measures the window from the model server (llama-server\n * slot, Ollama residency/defaults) and TELLS Claude Code to use it, so the\n * sentence names both halves.\n */\nexport function windowSourceText(source: VerseWindowSource, engine: VerseEngine | null | undefined): string {\n if (engine !== 'local') return WINDOW_SOURCE_TEXT[source];\n const from = source === 'runtime' ? 'measured from the local model server'\n : source === 'fallback' ? 'a default estimate — the model server did not report one'\n : WINDOW_SOURCE_TEXT[source];\n return `${from}; Verse passes this window to Claude Code for this chat`;\n}\n\n/**\n * The one sentence about Codex's surcharge above its standard window, for\n * every surface that prices Expansive on codex (the mode menu, the\n * \"Expansive could help\" chip, the new-chat mode selector, the handoff\n * dialog). Worded as REPORTED because that is all it is: the sources\n * docs/VERSE-CONTEXT.md §2.3 cites say GPT-5.6-class requests above 272k\n * count about 2× against plan limits, and Verse has no reading of its own\n * that confirms the multiplier. It multiplies the size ratio the copy quotes\n * (the ratio of the two compaction points), which is why it says \"twice that\".\n */\nexport const CODEX_EXPANSIVE_METERING_NOTE =\n 'OpenAI reportedly also counts requests above 272k tokens at about 2× against plan limits, so a turn near the expansive limit may cost roughly twice that.';\n\n/** The first model on a seat that can actually run (skips ones listed with an `unavailableReason`). */\nexport function firstRunnableModel(seat: VerseSeat): VerseModelOption | null {\n return seat.models.find((m) => !m.unavailableReason) ?? null;\n}\n\nexport function healthTone(state: VerseSeatHealth['state']): Tone {\n switch (state) {\n case 'ready':\n return 'success';\n case 'degraded':\n return 'warning';\n case 'unavailable':\n return 'danger';\n default:\n return 'unknown';\n }\n}\n\nexport function seatUnavailableReason(seat: VerseSeat): string | null {\n if (seat.health.state !== 'unavailable') return null;\n return seat.health.summary ?? 'seat unavailable';\n}\n\n// ---------------------------------------------------------------------------\n// Seat capacity — \"which account can I actually use right now\", at the point\n// the choice is made\n// ---------------------------------------------------------------------------\n\n/**\n * The four answers a picker needs. Same vocabulary as the Usage section's\n * `CapacityClass` so the two surfaces never use different words for one state.\n */\nexport type SeatCapacityClass = 'ready' | 'tight' | 'blocked' | 'unread';\n\n/** Word, never colour alone (DESIGN-V2 §6). */\nexport const SEAT_CAPACITY_WORD: Record<SeatCapacityClass, string> = {\n ready: 'usable',\n tight: 'tight',\n blocked: 'blocked',\n unread: 'no reading',\n};\n\n/** Above this share of the binding window a seat is worth flagging. */\nconst TIGHT_PERCENT = 85;\n\nexport interface SeatCapacityNote {\n cls: SeatCapacityClass;\n /**\n * The binding window's percent when it is a real measurement. Null for an\n * unread seat AND at the 100 ceiling, where the upstream value may be the\n * provider's \"limit reached\" sentinel rather than a reading\n * (docs/VERSE-TELEMETRY-V2.md) — and \"limit reached\" is true under either.\n */\n usedPercent: number | null;\n /** One short phrase for an option label, a pill title, a menu row. */\n text: string;\n}\n\n/** `seven_day_fable` → `weekly (fable)`; `five_hour` → `5-hour`. */\nexport function seatWindowLabel(id: string): string {\n const known: Record<string, string> = {\n five_hour: '5-hour window',\n seven_day: 'weekly window',\n codex: 'weekly window',\n };\n if (known[id]) return known[id];\n const perModel = /^seven_day_(.+)$/.exec(id);\n if (perModel) return `weekly ${perModel[1]!.replace(/_/g, ' ')} window`;\n return `${id.replace(/_/g, ' ')} window`;\n}\n\n/**\n * What a seat's own health says about whether a turn sent to it will land.\n *\n * This exists because the seat picker showed NOTHING: it annotated an option\n * only when `health.state === 'unavailable'`, and Claude's `health` is\n * `unknown` by construction (docs/VERSE-TELEMETRY-V2.md). So a Claude seat\n * whose binding weekly window reads 100% used appeared as an ordinary,\n * enabled, unannotated choice, and the exhaustion was discovered at turn time\n * — exactly the failure the Usage section was built to prevent.\n *\n * A `blocked` seat is MARKED, never disabled: a used-up window can coexist\n * with a spendable credit balance, so refusing the choice would be a stronger\n * claim than the data supports.\n */\nexport function seatCapacity(seat: VerseSeat): SeatCapacityNote {\n const reason = seatUnavailableReason(seat);\n if (reason !== null) return { cls: 'blocked', usedPercent: null, text: reason };\n\n const measured = 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 // No window reported a number. That is an unanswered question, not a zero —\n // an empty meter would read \"plenty left\".\n if (measured.length === 0) return { cls: 'unread', usedPercent: null, text: 'no capacity reading' };\n\n const binding = measured.reduce((a, b) => (b.usedPercent > a.usedPercent ? b : a));\n const pct = Math.max(0, Math.min(100, binding.usedPercent));\n const where = seatWindowLabel(binding.id);\n if (pct >= 100) return { cls: 'blocked', usedPercent: null, text: `${where} limit reached` };\n return {\n cls: pct >= TIGHT_PERCENT ? 'tight' : 'ready',\n usedPercent: pct,\n text: `${usedPercentText(pct)} of ${where} used`,\n };\n}\n\n/** Seats grouped in the fixed engine order; empty engines are omitted. */\nexport function groupSeats(seats: readonly VerseSeat[]): Array<{ engine: VerseEngine; seats: VerseSeat[] }> {\n return ENGINE_ORDER.map((engine) => ({ engine, seats: seats.filter((s) => s.engine === engine) })).filter((g) => g.seats.length > 0);\n}\n\nexport interface SessionGroup {\n projectPath: string;\n name: string;\n enrolled: boolean;\n sessions: VerseSession[];\n}\n\n/** Sidebar grouping: by project, most recently touched project first, sessions newest first. */\nexport function groupSessions(sessions: readonly VerseSession[], projects: readonly VerseProject[], query = ''): SessionGroup[] {\n const q = query.trim().toLowerCase();\n const filtered = q\n ? sessions.filter((s) =>\n s.title.toLowerCase().includes(q) ||\n s.projectPath.toLowerCase().includes(q) ||\n s.model.toLowerCase().includes(q) ||\n s.seatId.toLowerCase().includes(q))\n : [...sessions];\n const byProject = new Map<string, VerseSession[]>();\n for (const s of filtered) {\n const list = byProject.get(s.projectPath) ?? [];\n list.push(s);\n byProject.set(s.projectPath, list);\n }\n const groups: SessionGroup[] = [];\n for (const [projectPath, list] of byProject) {\n list.sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));\n groups.push({\n projectPath,\n name: projectName(projectPath, projects),\n enrolled: projects.find((p) => p.path === projectPath)?.enrolled ?? false,\n sessions: list,\n });\n }\n groups.sort((a, b) => b.sessions[0]!.updatedAt.localeCompare(a.sessions[0]!.updatedAt));\n return groups;\n}\n\nexport function formatElapsed(ms: number): string {\n if (!Number.isFinite(ms) || ms < 0) return '0s';\n const s = Math.floor(ms / 1000);\n if (s < 60) return `${s}s`;\n const m = Math.floor(s / 60);\n if (m < 60) return `${m}m ${s % 60}s`;\n const h = Math.floor(m / 60);\n return `${h}h ${m % 60}m`;\n}\n\nexport function formatDuration(ms: number): string {\n if (!Number.isFinite(ms) || ms < 0) return '—';\n if (ms < 1000) return `${Math.round(ms)}ms`;\n if (ms < 60_000) return `${(ms / 1000).toFixed(1)}s`;\n return formatElapsed(ms);\n}\n\n/**\n * Sidebar rows carry a right-aligned relative time. Short by design — the\n * row has ~5ch for it — and it degrades to a date rather than \"412d\".\n * `now` is injectable so the format is testable without faking the clock.\n */\nexport function formatRelative(iso: string, now: number = Date.now()): string {\n const then = Date.parse(iso);\n if (!Number.isFinite(then)) return '';\n const seconds = Math.round((now - then) / 1000);\n if (seconds < 0) return 'now';\n if (seconds < 60) return 'now';\n const minutes = Math.floor(seconds / 60);\n if (minutes < 60) return `${minutes}m`;\n const hours = Math.floor(minutes / 60);\n if (hours < 24) return `${hours}h`;\n const days = Math.floor(hours / 24);\n if (days < 7) return `${days}d`;\n return new Date(then).toLocaleDateString([], { month: 'short', day: 'numeric' });\n}\n\nexport function formatClock(iso: string): string {\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return '';\n return d.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });\n}\n\n/** One-line description of a tool call for a collapsed card header. */\nexport function summarizeToolInput(input: unknown): string {\n if (input === null || input === undefined) return '';\n if (typeof input === 'string') return truncate(input, 96);\n if (typeof input !== 'object') return truncate(String(input), 96);\n const record = input as Record<string, unknown>;\n const preferred = ['command', 'cmd', 'file_path', 'path', 'pattern', 'query', 'url', 'description', 'prompt', 'text'];\n for (const key of preferred) {\n const v = record[key];\n if (typeof v === 'string' && v.trim()) return truncate(v.trim().replace(/\\s+/g, ' '), 96);\n }\n const keys = Object.keys(record);\n if (keys.length === 0) return '';\n const first = record[keys[0]!];\n const rendered = typeof first === 'string' ? first : JSON.stringify(first);\n return truncate(`${keys[0]}: ${rendered ?? ''}`.replace(/\\s+/g, ' '), 96);\n}\n\nexport function truncate(value: string, max: number): string {\n return value.length > max ? `${value.slice(0, max - 1)}…` : value;\n}\n\n/** Pretty JSON for tool cards; falls back to String() for non-serializable input. */\nexport function prettyJson(value: unknown): string {\n if (typeof value === 'string') return value;\n try {\n return JSON.stringify(value, null, 2) ?? '';\n } catch {\n return String(value);\n }\n}\n\n/**\n * Accepts POSIX/Windows absolute paths and `~/...`. The server rewrites the\n * home directory as `~` in every outbound payload (sanitizePublicJson) and\n * expands it again on the way in, so a `~/` project from bootstrap is valid.\n */\nexport function isAbsolutePath(value: string): boolean {\n return /^(?:\\/|~(?:\\/|$)|[a-zA-Z]:[\\\\/]|\\\\\\\\)/.test(value) &&\n ![...value].some((c) => c.charCodeAt(0) < 32 || (c.charCodeAt(0) >= 127 && c.charCodeAt(0) <= 159));\n}\n\n/**\n * Seat pill text: \"<seat> · <model>\", collapsing to just the seat when the\n * model label is already contained in it (local seats expose one model whose\n * name is the seat name), so the pill never reads \"Qwen3-Coder · Qwen3-Coder\".\n */\nexport function seatPillLabel(seats: readonly VerseSeat[], ref: Pick<VerseSession, 'seatId' | 'engine' | 'model'>): string {\n const seat = seatLabel(seats, ref);\n const model = modelLabel(seats, ref);\n if (!model || seat.toLowerCase().includes(model.toLowerCase())) return seat;\n return `${seat} · ${model}`;\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{D as e,P as t,at as n,l as r,s as i,u as a}from"./global-DG1fmn4y.js";import{a as o,g as s,o as c}from"./workbench-types-DzN-5trg.js";var l=`verse-bootstrap`,u=`verse-sessions`,d={key:l,fetch:e=>r(`/api/verse/bootstrap`,e)},f={key:u,fetch:e=>r(`/api/verse/sessions`,e)};function p(e,t=``){return`/api/verse/sessions/${encodeURIComponent(e)}${t}`}function m(e,t){return r(p(e),t)}var h=class extends Error{constructor(){super(`Unlock actions with the mutation token before chatting.`),this.name=`VerseMutationLockedError`}};async function g(n,r){let i=e();if(!i)throw new h;let o=await a(n,r,i);return t(),o}function _(){n(u),n(l)}async function v(e){let t=await g(`/api/verse/sessions`,e);return _(),t}async function y(e,t){let r={text:t},i=await g(p(e,`/turns`),r);return n(u),i}async function b(e){await g(p(e,`/cancel`),{}),n(u)}async function x(e){await g(p(e,`/delete`),{}),_()}async function S(e,t){let r=await g(p(e,`/rename`),{title:t});return n(u),r}var C=`verse-workspaces`,w=`verse-autonomy-scope`,T={key:C,fetch:e=>r(`/api/verse/workspaces`,e)},E={key:w,fetch:e=>r(`/api/verse/autonomy-scope`,e)};function D(e,t){return r(p(e,`/roots`),t)}function O(){n(C),n(w),n(l)}async function k(e){let t=await g(`/api/verse/workspaces`,e);return O(),t}async function A(e,t){let n=await g(`/api/verse/workspaces/${encodeURIComponent(e)}/update`,t);return O(),n}async function j(e){await g(`/api/verse/workspaces/${encodeURIComponent(e)}/delete`,{}),O()}async function M(e,t){await g(`/api/verse/workspaces/priority`,{path:e,priority:t}),O()}async function N(e){await g(`/api/verse/workspaces/focus`,{sectionId:e}),O()}var P=`verse-activity`,F=`verse-session-meta`;async function I(e,t){try{return await r(e,t)}catch(e){if(e instanceof i&&e.status===404)return null;throw e}}var L={key:P,fetch:e=>I(o,e)},R={key:F,fetch:e=>I(s,e)};async function z(e,t){let r={};typeof t.pinned==`boolean`&&(r.pinned=t.pinned),typeof t.archived==`boolean`&&(r.archived=t.archived);let i=await g(`${s}/${encodeURIComponent(e)}`,r);return n(F),i}async function B(t,n){let r=e();if(!r)return!1;let i={sessionId:t,turnCount:n};try{return await a(c,i,r),!0}catch{return!1}}export{p as C,R as S,T,z as _,v as a,E as b,j as c,_ as d,B as f,M as g,N as h,b as i,m as l,y as m,u as n,k as o,S as p,h as r,x as s,l as t,D as u,A as v,f as w,d as x,L as y};
2
- //# sourceMappingURL=verse-queries-2PxoBISm.js.map
1
+ import{D as e,P as t,at as n,l as r,s as i,u as a}from"./global-Di2PUgj4.js";import{a as o,g as s,o as c}from"./workbench-types-DzN-5trg.js";var l=`verse-bootstrap`,u=`verse-sessions`,d={key:l,fetch:e=>r(`/api/verse/bootstrap`,e)},f={key:u,fetch:e=>r(`/api/verse/sessions`,e)};function p(e,t=``){return`/api/verse/sessions/${encodeURIComponent(e)}${t}`}function m(e,t){return r(p(e),t)}var h=class extends Error{constructor(){super(`Unlock actions with the mutation token before chatting.`),this.name=`VerseMutationLockedError`}};async function g(n,r){let i=e();if(!i)throw new h;let o=await a(n,r,i);return t(),o}function _(){n(u),n(l)}async function v(e){let t=await g(`/api/verse/sessions`,e);return _(),t}async function y(e,t){let r={text:t},i=await g(p(e,`/turns`),r);return n(u),i}async function b(e){await g(p(e,`/cancel`),{}),n(u)}async function x(e){await g(p(e,`/delete`),{}),_()}async function S(e,t){let r=await g(p(e,`/rename`),{title:t});return n(u),r}var C=`verse-workspaces`,w=`verse-autonomy-scope`,T={key:C,fetch:e=>r(`/api/verse/workspaces`,e)},E={key:w,fetch:e=>r(`/api/verse/autonomy-scope`,e)};function D(e,t){return r(p(e,`/roots`),t)}function O(){n(C),n(w),n(l)}async function k(e){let t=await g(`/api/verse/workspaces`,e);return O(),t}async function A(e,t){let n=await g(`/api/verse/workspaces/${encodeURIComponent(e)}/update`,t);return O(),n}async function j(e){await g(`/api/verse/workspaces/${encodeURIComponent(e)}/delete`,{}),O()}async function M(e,t){await g(`/api/verse/workspaces/priority`,{path:e,priority:t}),O()}async function N(e){await g(`/api/verse/workspaces/focus`,{sectionId:e}),O()}var P=`verse-activity`,F=`verse-session-meta`;async function I(e,t){try{return await r(e,t)}catch(e){if(e instanceof i&&e.status===404)return null;throw e}}var L={key:P,fetch:e=>I(o,e)},R={key:F,fetch:e=>I(s,e)};async function z(e,t){let r={};typeof t.pinned==`boolean`&&(r.pinned=t.pinned),typeof t.archived==`boolean`&&(r.archived=t.archived);let i=await g(`${s}/${encodeURIComponent(e)}`,r);return n(F),i}async function B(t,n){let r=e();if(!r)return!1;let i={sessionId:t,turnCount:n};try{return await a(c,i,r),!0}catch{return!1}}export{p as C,R as S,T,z as _,v as a,E as b,j as c,_ as d,B as f,M as g,N as h,b as i,m as l,y as m,u as n,k as o,S as p,h as r,x as s,l as t,D as u,A as v,f as w,d as x,L as y};
2
+ //# sourceMappingURL=verse-queries-DvIJcn6Z.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"verse-queries-2PxoBISm.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/verse-queries.ts"],"sourcesContent":["/**\n * routes/verse/verse-queries.ts — every /api/verse/* call the Verse console\n * makes. Reads are QueryDefs consumed through useQuery (cache-backed, so a\n * sidebar refresh never blanks the list); writes are wrapped like\n * data/mutations.ts's helpers — they pull the held mutation token from\n * auth-store, touch the hold on success, and invalidate the cache keys they\n * obviously affect. Nothing here ever sees launcher commands or env: the\n * server strips those before any payload leaves it (docs/VERSE-CONTRACT-V1).\n */\nimport type {\n VerseAutonomyScopeView,\n VerseBootstrap,\n VerseCreateSessionRequest,\n VerseRootPriority,\n VerseSession,\n VerseSessionDetail,\n VerseSessionRootsResponse,\n VerseTurnRequest,\n VerseTurnResponse,\n VerseWorkspace,\n VerseWorkspaceCreateRequest,\n VerseWorkspacesResponse,\n VerseWorkspaceUpdateRequest,\n} from '../../data/api-types.js';\nimport type {\n VerseActivityResponse,\n VerseActivitySeenRequest,\n VerseSessionMeta,\n VerseSessionMetaResponse,\n VerseSessionMetaUpdate,\n} from '../../../core/verse/workbench-types.js';\nimport { VERSE_ACTIVITY_PATH, VERSE_ACTIVITY_SEEN_PATH, VERSE_SESSION_META_PATH } from '../../../core/verse/workbench-types.js';\nimport { getMutationToken, touchMutationHold } from '../../data/auth-store.js';\nimport { ApiError, apiGet, apiPost } from '../../data/client.js';\nimport { invalidate } from '../../data/cache.js';\nimport type { QueryDef } from '../../data/queries.js';\n\nexport const VERSE_BOOTSTRAP_KEY = 'verse-bootstrap';\nexport const VERSE_SESSIONS_KEY = 'verse-sessions';\n\nexport const verseBootstrapQuery: QueryDef<VerseBootstrap> = {\n key: VERSE_BOOTSTRAP_KEY,\n fetch: (signal) => apiGet<VerseBootstrap>('/api/verse/bootstrap', signal),\n};\n\nexport const verseSessionsQuery: QueryDef<VerseSession[]> = {\n key: VERSE_SESSIONS_KEY,\n fetch: (signal) => apiGet<VerseSession[]>('/api/verse/sessions', signal),\n};\n\nexport function verseSessionPath(sessionId: string, suffix = ''): string {\n return `/api/verse/sessions/${encodeURIComponent(sessionId)}${suffix}`;\n}\n\nexport function fetchVerseSessionDetail(sessionId: string, signal?: AbortSignal): Promise<VerseSessionDetail> {\n return apiGet<VerseSessionDetail>(verseSessionPath(sessionId), signal);\n}\n\nexport class VerseMutationLockedError extends Error {\n constructor() {\n super('Unlock actions with the mutation token before chatting.');\n this.name = 'VerseMutationLockedError';\n }\n}\n\nasync function post<T>(path: string, body: unknown): Promise<T> {\n const token = getMutationToken();\n if (!token) throw new VerseMutationLockedError();\n const result = await apiPost<T>(path, body, token);\n touchMutationHold();\n return result;\n}\n\n/** Sidebar + resources panel both read these; refresh them after any write. */\nexport function invalidateVerseLists(): void {\n invalidate(VERSE_SESSIONS_KEY);\n invalidate(VERSE_BOOTSTRAP_KEY);\n}\n\nexport async function createVerseSession(req: VerseCreateSessionRequest): Promise<VerseSession> {\n const session = await post<VerseSession>('/api/verse/sessions', req);\n invalidateVerseLists();\n return session;\n}\n\nexport async function sendVerseTurn(sessionId: string, text: string): Promise<VerseTurnResponse> {\n const body: VerseTurnRequest = { text };\n const response = await post<VerseTurnResponse>(verseSessionPath(sessionId, '/turns'), body);\n invalidate(VERSE_SESSIONS_KEY);\n return response;\n}\n\nexport async function cancelVerseTurn(sessionId: string): Promise<void> {\n await post<{ ok: true }>(verseSessionPath(sessionId, '/cancel'), {});\n invalidate(VERSE_SESSIONS_KEY);\n}\n\nexport async function deleteVerseSession(sessionId: string): Promise<void> {\n await post<{ ok: true }>(verseSessionPath(sessionId, '/delete'), {});\n invalidateVerseLists();\n}\n\nexport async function renameVerseSession(sessionId: string, title: string): Promise<VerseSession> {\n const session = await post<VerseSession>(verseSessionPath(sessionId, '/rename'), { title });\n invalidate(VERSE_SESSIONS_KEY);\n return session;\n}\n\n// ---------------------------------------------------------------------------\n// Workspaces (V2.2)\n// ---------------------------------------------------------------------------\n\nexport const VERSE_WORKSPACES_KEY = 'verse-workspaces';\nexport const VERSE_AUTONOMY_SCOPE_KEY = 'verse-autonomy-scope';\n\nexport const verseWorkspacesQuery: QueryDef<VerseWorkspacesResponse> = {\n key: VERSE_WORKSPACES_KEY,\n fetch: (signal) => apiGet<VerseWorkspacesResponse>('/api/verse/workspaces', signal),\n};\n\n/**\n * Enrolled repos, ordered by section focus and priority. Kept on its own key\n * from `verseScopeQuery` (which is the raw registry) so a re-rank refreshes\n * the ORDER without re-reading enrollment — and so it is obvious in the cache\n * that these are two different facts.\n */\nexport const verseAutonomyScopeQuery: QueryDef<VerseAutonomyScopeView> = {\n key: VERSE_AUTONOMY_SCOPE_KEY,\n fetch: (signal) => apiGet<VerseAutonomyScopeView>('/api/verse/autonomy-scope', signal),\n};\n\n/**\n * Per-root identity for one session: branch, dirty state, remote, whether the\n * engine can reach each root and whether the autonomous lane would.\n *\n * Deliberately NOT cached by session id alone at module scope — a branch goes\n * stale the moment a turn commits, so the panel refetches it per open.\n */\nexport function fetchVerseSessionRoots(sessionId: string, signal?: AbortSignal): Promise<VerseSessionRootsResponse> {\n return apiGet<VerseSessionRootsResponse>(verseSessionPath(sessionId, '/roots'), signal);\n}\n\nfunction invalidateWorkspaces(): void {\n invalidate(VERSE_WORKSPACES_KEY);\n invalidate(VERSE_AUTONOMY_SCOPE_KEY);\n invalidate(VERSE_BOOTSTRAP_KEY);\n}\n\nexport async function createVerseWorkspace(req: VerseWorkspaceCreateRequest): Promise<VerseWorkspace> {\n const workspace = await post<VerseWorkspace>('/api/verse/workspaces', req);\n invalidateWorkspaces();\n return workspace;\n}\n\nexport async function updateVerseWorkspace(id: string, patch: VerseWorkspaceUpdateRequest): Promise<VerseWorkspace> {\n const workspace = await post<VerseWorkspace>(`/api/verse/workspaces/${encodeURIComponent(id)}/update`, patch);\n invalidateWorkspaces();\n return workspace;\n}\n\nexport async function deleteVerseWorkspace(id: string): Promise<void> {\n await post<{ ok: true }>(`/api/verse/workspaces/${encodeURIComponent(id)}/delete`, {});\n invalidateWorkspaces();\n}\n\nexport async function setVerseRootPriority(path: string, priority: VerseRootPriority): Promise<void> {\n await post<unknown>('/api/verse/workspaces/priority', { path, priority });\n invalidateWorkspaces();\n}\n\nexport async function setVerseFocusSection(sectionId: string | null): Promise<void> {\n await post<unknown>('/api/verse/workspaces/focus', { sectionId });\n invalidateWorkspaces();\n}\n\n// ---------------------------------------------------------------------------\n// 3.10 — activity + per-chat meta (C1's routes; C2's sidebar reads them)\n// ---------------------------------------------------------------------------\n//\n// Both route families are mounted lazily (C0's mount table): on a build where\n// C1's module has not landed they answer a plain 404. That is \"this server\n// has no activity yet\", not an error the sidebar should paint red — so a 404\n// reads as `null` and every consumer falls back to what the session list\n// alone can say (running dot from `status`, no pins, no unread).\n\nexport const VERSE_ACTIVITY_KEY = 'verse-activity';\nexport const VERSE_SESSION_META_KEY = 'verse-session-meta';\n\nasync function getOrNull<T>(path: string, signal?: AbortSignal): Promise<T | null> {\n try {\n return await apiGet<T>(path, signal);\n } catch (err) {\n if (err instanceof ApiError && err.status === 404) return null;\n throw err;\n }\n}\n\n/**\n * The poll-shaped read (no `since`): running chats with their live line and\n * the Needs-you items. Completions are C1's concern (its cursor loop feeds\n * the rail and the native notifications); the sidebar needs only the present.\n */\nexport const verseActivityQuery: QueryDef<VerseActivityResponse | null> = {\n key: VERSE_ACTIVITY_KEY,\n fetch: (signal) => getOrNull<VerseActivityResponse>(VERSE_ACTIVITY_PATH, signal),\n};\n\nexport const verseSessionMetaQuery: QueryDef<VerseSessionMetaResponse | null> = {\n key: VERSE_SESSION_META_KEY,\n fetch: (signal) => getOrNull<VerseSessionMetaResponse>(VERSE_SESSION_META_PATH, signal),\n};\n\n/** Pin / archive one chat. Unknown keys are a 400 on the server, so only the two known ones are ever sent. */\nexport async function setVerseSessionMeta(sessionId: string, update: VerseSessionMetaUpdate): Promise<VerseSessionMeta> {\n const body: VerseSessionMetaUpdate = {};\n if (typeof update.pinned === 'boolean') body.pinned = update.pinned;\n if (typeof update.archived === 'boolean') body.archived = update.archived;\n const meta = await post<VerseSessionMeta>(`${VERSE_SESSION_META_PATH}/${encodeURIComponent(sessionId)}`, body);\n invalidate(VERSE_SESSION_META_KEY);\n return meta;\n}\n\n/**\n * \"The operator has read this chat up to `turnCount`.\" Best-effort and SILENT:\n * it runs only when a token is already held (opening a chat must never raise\n * the token dialog), and a failure is swallowed — the sidebar keeps its own\n * optimistic read state, so the unread dot clears either way.\n */\nexport async function markVerseSessionSeen(sessionId: string, turnCount: number): Promise<boolean> {\n const token = getMutationToken();\n if (!token) return false;\n const body: VerseActivitySeenRequest = { sessionId, turnCount };\n try {\n // apiPost, not post(): reading a chat is not operator ACTIVITY, so it\n // must not extend the mutation hold the way a real write does.\n await apiPost<unknown>(VERSE_ACTIVITY_SEEN_PATH, body, token);\n return true;\n } catch {\n return false;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"verse-queries-DvIJcn6Z.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/verse-queries.ts"],"sourcesContent":["/**\n * routes/verse/verse-queries.ts — every /api/verse/* call the Verse console\n * makes. Reads are QueryDefs consumed through useQuery (cache-backed, so a\n * sidebar refresh never blanks the list); writes are wrapped like\n * data/mutations.ts's helpers — they pull the held mutation token from\n * auth-store, touch the hold on success, and invalidate the cache keys they\n * obviously affect. Nothing here ever sees launcher commands or env: the\n * server strips those before any payload leaves it (docs/VERSE-CONTRACT-V1).\n */\nimport type {\n VerseAutonomyScopeView,\n VerseBootstrap,\n VerseCreateSessionRequest,\n VerseRootPriority,\n VerseSession,\n VerseSessionDetail,\n VerseSessionRootsResponse,\n VerseTurnRequest,\n VerseTurnResponse,\n VerseWorkspace,\n VerseWorkspaceCreateRequest,\n VerseWorkspacesResponse,\n VerseWorkspaceUpdateRequest,\n} from '../../data/api-types.js';\nimport type {\n VerseActivityResponse,\n VerseActivitySeenRequest,\n VerseSessionMeta,\n VerseSessionMetaResponse,\n VerseSessionMetaUpdate,\n} from '../../../core/verse/workbench-types.js';\nimport { VERSE_ACTIVITY_PATH, VERSE_ACTIVITY_SEEN_PATH, VERSE_SESSION_META_PATH } from '../../../core/verse/workbench-types.js';\nimport { getMutationToken, touchMutationHold } from '../../data/auth-store.js';\nimport { ApiError, apiGet, apiPost } from '../../data/client.js';\nimport { invalidate } from '../../data/cache.js';\nimport type { QueryDef } from '../../data/queries.js';\n\nexport const VERSE_BOOTSTRAP_KEY = 'verse-bootstrap';\nexport const VERSE_SESSIONS_KEY = 'verse-sessions';\n\nexport const verseBootstrapQuery: QueryDef<VerseBootstrap> = {\n key: VERSE_BOOTSTRAP_KEY,\n fetch: (signal) => apiGet<VerseBootstrap>('/api/verse/bootstrap', signal),\n};\n\nexport const verseSessionsQuery: QueryDef<VerseSession[]> = {\n key: VERSE_SESSIONS_KEY,\n fetch: (signal) => apiGet<VerseSession[]>('/api/verse/sessions', signal),\n};\n\nexport function verseSessionPath(sessionId: string, suffix = ''): string {\n return `/api/verse/sessions/${encodeURIComponent(sessionId)}${suffix}`;\n}\n\nexport function fetchVerseSessionDetail(sessionId: string, signal?: AbortSignal): Promise<VerseSessionDetail> {\n return apiGet<VerseSessionDetail>(verseSessionPath(sessionId), signal);\n}\n\nexport class VerseMutationLockedError extends Error {\n constructor() {\n super('Unlock actions with the mutation token before chatting.');\n this.name = 'VerseMutationLockedError';\n }\n}\n\nasync function post<T>(path: string, body: unknown): Promise<T> {\n const token = getMutationToken();\n if (!token) throw new VerseMutationLockedError();\n const result = await apiPost<T>(path, body, token);\n touchMutationHold();\n return result;\n}\n\n/** Sidebar + resources panel both read these; refresh them after any write. */\nexport function invalidateVerseLists(): void {\n invalidate(VERSE_SESSIONS_KEY);\n invalidate(VERSE_BOOTSTRAP_KEY);\n}\n\nexport async function createVerseSession(req: VerseCreateSessionRequest): Promise<VerseSession> {\n const session = await post<VerseSession>('/api/verse/sessions', req);\n invalidateVerseLists();\n return session;\n}\n\nexport async function sendVerseTurn(sessionId: string, text: string): Promise<VerseTurnResponse> {\n const body: VerseTurnRequest = { text };\n const response = await post<VerseTurnResponse>(verseSessionPath(sessionId, '/turns'), body);\n invalidate(VERSE_SESSIONS_KEY);\n return response;\n}\n\nexport async function cancelVerseTurn(sessionId: string): Promise<void> {\n await post<{ ok: true }>(verseSessionPath(sessionId, '/cancel'), {});\n invalidate(VERSE_SESSIONS_KEY);\n}\n\nexport async function deleteVerseSession(sessionId: string): Promise<void> {\n await post<{ ok: true }>(verseSessionPath(sessionId, '/delete'), {});\n invalidateVerseLists();\n}\n\nexport async function renameVerseSession(sessionId: string, title: string): Promise<VerseSession> {\n const session = await post<VerseSession>(verseSessionPath(sessionId, '/rename'), { title });\n invalidate(VERSE_SESSIONS_KEY);\n return session;\n}\n\n// ---------------------------------------------------------------------------\n// Workspaces (V2.2)\n// ---------------------------------------------------------------------------\n\nexport const VERSE_WORKSPACES_KEY = 'verse-workspaces';\nexport const VERSE_AUTONOMY_SCOPE_KEY = 'verse-autonomy-scope';\n\nexport const verseWorkspacesQuery: QueryDef<VerseWorkspacesResponse> = {\n key: VERSE_WORKSPACES_KEY,\n fetch: (signal) => apiGet<VerseWorkspacesResponse>('/api/verse/workspaces', signal),\n};\n\n/**\n * Enrolled repos, ordered by section focus and priority. Kept on its own key\n * from `verseScopeQuery` (which is the raw registry) so a re-rank refreshes\n * the ORDER without re-reading enrollment — and so it is obvious in the cache\n * that these are two different facts.\n */\nexport const verseAutonomyScopeQuery: QueryDef<VerseAutonomyScopeView> = {\n key: VERSE_AUTONOMY_SCOPE_KEY,\n fetch: (signal) => apiGet<VerseAutonomyScopeView>('/api/verse/autonomy-scope', signal),\n};\n\n/**\n * Per-root identity for one session: branch, dirty state, remote, whether the\n * engine can reach each root and whether the autonomous lane would.\n *\n * Deliberately NOT cached by session id alone at module scope — a branch goes\n * stale the moment a turn commits, so the panel refetches it per open.\n */\nexport function fetchVerseSessionRoots(sessionId: string, signal?: AbortSignal): Promise<VerseSessionRootsResponse> {\n return apiGet<VerseSessionRootsResponse>(verseSessionPath(sessionId, '/roots'), signal);\n}\n\nfunction invalidateWorkspaces(): void {\n invalidate(VERSE_WORKSPACES_KEY);\n invalidate(VERSE_AUTONOMY_SCOPE_KEY);\n invalidate(VERSE_BOOTSTRAP_KEY);\n}\n\nexport async function createVerseWorkspace(req: VerseWorkspaceCreateRequest): Promise<VerseWorkspace> {\n const workspace = await post<VerseWorkspace>('/api/verse/workspaces', req);\n invalidateWorkspaces();\n return workspace;\n}\n\nexport async function updateVerseWorkspace(id: string, patch: VerseWorkspaceUpdateRequest): Promise<VerseWorkspace> {\n const workspace = await post<VerseWorkspace>(`/api/verse/workspaces/${encodeURIComponent(id)}/update`, patch);\n invalidateWorkspaces();\n return workspace;\n}\n\nexport async function deleteVerseWorkspace(id: string): Promise<void> {\n await post<{ ok: true }>(`/api/verse/workspaces/${encodeURIComponent(id)}/delete`, {});\n invalidateWorkspaces();\n}\n\nexport async function setVerseRootPriority(path: string, priority: VerseRootPriority): Promise<void> {\n await post<unknown>('/api/verse/workspaces/priority', { path, priority });\n invalidateWorkspaces();\n}\n\nexport async function setVerseFocusSection(sectionId: string | null): Promise<void> {\n await post<unknown>('/api/verse/workspaces/focus', { sectionId });\n invalidateWorkspaces();\n}\n\n// ---------------------------------------------------------------------------\n// 3.10 — activity + per-chat meta (C1's routes; C2's sidebar reads them)\n// ---------------------------------------------------------------------------\n//\n// Both route families are mounted lazily (C0's mount table): on a build where\n// C1's module has not landed they answer a plain 404. That is \"this server\n// has no activity yet\", not an error the sidebar should paint red — so a 404\n// reads as `null` and every consumer falls back to what the session list\n// alone can say (running dot from `status`, no pins, no unread).\n\nexport const VERSE_ACTIVITY_KEY = 'verse-activity';\nexport const VERSE_SESSION_META_KEY = 'verse-session-meta';\n\nasync function getOrNull<T>(path: string, signal?: AbortSignal): Promise<T | null> {\n try {\n return await apiGet<T>(path, signal);\n } catch (err) {\n if (err instanceof ApiError && err.status === 404) return null;\n throw err;\n }\n}\n\n/**\n * The poll-shaped read (no `since`): running chats with their live line and\n * the Needs-you items. Completions are C1's concern (its cursor loop feeds\n * the rail and the native notifications); the sidebar needs only the present.\n */\nexport const verseActivityQuery: QueryDef<VerseActivityResponse | null> = {\n key: VERSE_ACTIVITY_KEY,\n fetch: (signal) => getOrNull<VerseActivityResponse>(VERSE_ACTIVITY_PATH, signal),\n};\n\nexport const verseSessionMetaQuery: QueryDef<VerseSessionMetaResponse | null> = {\n key: VERSE_SESSION_META_KEY,\n fetch: (signal) => getOrNull<VerseSessionMetaResponse>(VERSE_SESSION_META_PATH, signal),\n};\n\n/** Pin / archive one chat. Unknown keys are a 400 on the server, so only the two known ones are ever sent. */\nexport async function setVerseSessionMeta(sessionId: string, update: VerseSessionMetaUpdate): Promise<VerseSessionMeta> {\n const body: VerseSessionMetaUpdate = {};\n if (typeof update.pinned === 'boolean') body.pinned = update.pinned;\n if (typeof update.archived === 'boolean') body.archived = update.archived;\n const meta = await post<VerseSessionMeta>(`${VERSE_SESSION_META_PATH}/${encodeURIComponent(sessionId)}`, body);\n invalidate(VERSE_SESSION_META_KEY);\n return meta;\n}\n\n/**\n * \"The operator has read this chat up to `turnCount`.\" Best-effort and SILENT:\n * it runs only when a token is already held (opening a chat must never raise\n * the token dialog), and a failure is swallowed — the sidebar keeps its own\n * optimistic read state, so the unread dot clears either way.\n */\nexport async function markVerseSessionSeen(sessionId: string, turnCount: number): Promise<boolean> {\n const token = getMutationToken();\n if (!token) return false;\n const body: VerseActivitySeenRequest = { sessionId, turnCount };\n try {\n // apiPost, not post(): reading a chat is not operator ACTIVITY, so it\n // must not extend the mutation hold the way a real write does.\n await apiPost<unknown>(VERSE_ACTIVITY_SEEN_PATH, body, token);\n return true;\n } catch {\n return false;\n }\n}\n"],"mappings":"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"}
@@ -1,3 +1,3 @@
1
- import{tt as e}from"./global-DG1fmn4y.js";var t=[`minimal`,`low`,`medium`,`high`,`xhigh`,`max`],n=new Set([`thinking-delta`,`thinking-progress`,`progress`,`status`]);function r(e){return n.has(e.type)}var i=65536,a=12e3,o=[`This conversation is about to continue in a fresh session that has none of its context.`,`Write the handoff note that new session should start from. Do not edit files or run commands for this — only write the note.`,``,`Cover, concretely:`,`- The goal, and what "done" looks like.`,`- Decisions made so far, each with the reason it was made.`,`- Current state: what is finished, what is half-done, what is untested.`,`- Files changed and anything not yet committed.`,`- How to verify the work (exact commands).`,`- Open questions, risks, and approaches already tried that did not work.`,``,`Keep it under 600 words. Prefer file paths and commands over prose.`].join(`
1
+ import{tt as e}from"./global-Di2PUgj4.js";var t=[`minimal`,`low`,`medium`,`high`,`xhigh`,`max`],n=new Set([`thinking-delta`,`thinking-progress`,`progress`,`status`]);function r(e){return n.has(e.type)}var i=65536,a=12e3,o=[`This conversation is about to continue in a fresh session that has none of its context.`,`Write the handoff note that new session should start from. Do not edit files or run commands for this — only write the note.`,``,`Cover, concretely:`,`- The goal, and what "done" looks like.`,`- Decisions made so far, each with the reason it was made.`,`- Current state: what is finished, what is half-done, what is untested.`,`- Files changed and anything not yet committed.`,`- How to verify the work (exact commands).`,`- Open questions, risks, and approaches already tried that did not work.`,``,`Keep it under 600 words. Prefer file paths and commands over prose.`].join(`
2
2
  `),s=65536,c=139264,l=6144,u={turnId:null,startedAt:null,progress:null,thinking:null,notice:null,settledTurnId:null},d={session:null,events:[],lastSeq:0,loaded:!1,loadError:null,stream:`idle`,live:u},f=new Map,p=new Map,m=new Map,h=new Map,g=new Set,_=new Map,v=new Set;function y(e){if(e!==null){let t=_.get(e);if(t)for(let e of[...t])e()}else for(let e of[..._.values()])for(let t of[...e])t();for(let e of[...g])e()}function b(e){return g.add(e),()=>g.delete(e)}function ee(e,t){let n=_.get(e);return n||(n=new Set,_.set(e,n)),n.add(t),()=>{let n=_.get(e);n&&(n.delete(t),n.size===0&&_.delete(e))}}function x(e){return v.add(e),()=>v.delete(e)}function S(e){return{sessionId:e.sessionId,session:e.session,events:e.events,lastSeq:e.lastSeq,loaded:e.loaded,loadError:e.loadError,stream:e.stream}}function C(e){let t=f.get(e);return t||(t={sessionId:e,...d},f.set(e,t),p.set(e,S(t))),t}function w(e,t,n){f.set(e,t);let r=p.get(e);(!r||n||r.session!==t.session||r.loaded!==t.loaded||r.loadError!==t.loadError||r.stream!==t.stream)&&p.set(e,S(t))}function T(e,t,n=!1){w(e,{...C(e),...t},n),y(e)}var E={sessionId:``,...d},te=S(E);function ne(e){return e?C(e):E}function re(e){return e?(C(e),p.get(e)):te}function D(e){return e?C(e).live:u}var O={items:[],live:!1,usage:null,segments:[]};function k(e){if(!e)return O;let t=C(e),n=h.get(e);if(n&&n.events===t.events)return n.transcript;let r=n?.cache??ce(),i=le(t.events,{cache:r,thinkingStats:m.get(e)});return h.set(e,{events:t.events,transcript:i,cache:r}),i}function A(e,t,n){let r=C(e),i=ae(r.events,n),a=P(t,i),o=r.session&&se(r.session,a)?r.session:a,s=i!==r.events,c=s||o!==r.session?H(r.live,i,o):r.live;(s||o!==r.session||!r.loaded||r.loadError!==null||c!==r.live)&&(w(e,{...r,session:o,events:i,lastSeq:i.length?Math.max(r.lastSeq,i[i.length-1].seq):r.lastSeq,loaded:!0,loadError:null,live:c},s),y(e))}function j(e,t){T(e,{loadError:t,loaded:!0})}function M(e,t){C(e).stream!==t&&T(e,{stream:t})}function N(e,t,n){T(e,{session:P(t,C(e).events,n)})}function P(e,t,n){if(e.status!==`running`)return e;let r=-1,i=n??null;if(!n){for(let e of t)(e.type===`user-message`||e.type===`turn-started`)&&(r=e.seq,i=e.turnId);if(i===null)return e}let a=null,o=null;for(let e of t)e.seq<=r||(e.type===`error`&&e.turnId===i&&(o=e.message),(e.type===`turn-done`||e.type===`cancelled`)&&e.turnId===i&&(a=e));if(!a)return e;let s=a.type===`turn-done`&&!a.ok&&o!==null;return{...e,status:s?`error`:`idle`,lastError:s?o:null,updatedAt:a.at>e.updatedAt?a.at:e.updatedAt}}function F(e,t){let n=C(e);n.session&&n.session.status!==t&&T(e,{session:{...n.session,status:t}})}function I(e,t){let n=C(e),i=n.events,a=!1,o=n.lastSeq,s=n.session,c=n.live,l=0,u=!1,d=!1,f=!1,p=Date.now();for(let n of t){if(r(n)){let e=B(c,n,p);e!==c&&(c=e,f=!0);continue}if(!Number.isFinite(n.seq))continue;let t=i.length>0?i[i.length-1].seq:-1/0;if(n.seq>t)a||=(i=i.slice(),!0),i.push(n);else{let e=J(i,n.seq);if(e.found)continue;a||=(i=i.slice(),!0),i.splice(e.index,0,n)}l+=1,o=Math.max(o,n.seq),n.type!==`text-delta`&&(d=!0),(n.type===`turn-done`||n.type===`cancelled`||n.type===`error`)&&(u=!0),s&&=L(s,n);let m=V(c,n,p,e);m!==c&&(c=m)}return l===0&&!f?{applied:0,settled:!1,liveChanged:!1}:(w(e,{...n,events:i,lastSeq:o,session:s,live:c},d),y(e),{applied:l,settled:u,liveChanged:f})}function L(e,t){switch(t.type){case`turn-started`:return{...e,status:`running`,lastError:null,updatedAt:t.at};case`usage`:return{...e,usage:ie(e,t.usage),updatedAt:t.at};case`context`:return{...e,usage:G(e,t),updatedAt:t.at};case`compaction`:return{...e,compactionCount:(e.compactionCount??0)+1,updatedAt:t.at};case`turn-done`:return{...e,status:t.ok?`idle`:e.lastError?`error`:`idle`,turnCount:e.turnCount+1,nativeSessionId:t.nativeSessionId??e.nativeSessionId,updatedAt:t.at};case`error`:return{...e,status:`error`,lastError:t.message,updatedAt:t.at};case`cancelled`:return{...e,status:`idle`,updatedAt:t.at};default:return e}}function R(e,t){let n=Date.parse(e);return Number.isFinite(n)?n:t}function z(e,t,n){return e.turnId===t?e:{...u,turnId:t,startedAt:n,settledTurnId:e.settledTurnId}}function B(e,t,n){if(t.turnId!==null&&t.turnId===e.settledTurnId)return e;let r=t.turnId===null?e:z(e,t.turnId,n);switch(t.type){case`thinking-delta`:{if(t.text.length===0)return r;let e=r.thinking&&r.thinking.turnId===t.turnId?{...r.thinking,text:r.thinking.text+t.text}:{turnId:t.turnId,text:t.text,startedAt:n,estimatedTokens:null};return{...r,thinking:e,notice:null}}case`thinking-progress`:{let e=r.thinking&&r.thinking.turnId===t.turnId?{...r.thinking,estimatedTokens:t.estimatedTokens}:{turnId:t.turnId,text:``,startedAt:n,estimatedTokens:t.estimatedTokens};return{...r,thinking:e}}case`progress`:return{...r,progress:{phase:t.phase,tool:typeof t.tool==`string`&&t.tool.length>0?t.tool:null,elapsedMs:t.elapsedMs,outTokens:t.outTokens??null,tokPerSec:t.tokPerSec??null,receivedAt:n}};case`status`:return{...r,notice:{kind:t.kind,message:t.message,at:t.at,receivedAt:n}};default:return r}}function V(e,t,n,r){switch(t.type){case`turn-started`:return t.turnId===e.settledTurnId?e:e.turnId===t.turnId?{...e,startedAt:R(t.at,e.startedAt??n)}:{...u,turnId:t.turnId,startedAt:R(t.at,n),settledTurnId:e.settledTurnId};case`thinking`:{let i=e.thinking&&e.thinking.turnId===t.turnId?e.thinking:null;if(i){let e=m.get(r);e||(e=new Map,m.set(r,e)),e.set(t.seq,{durationMs:typeof t.durationMs==`number`?t.durationMs:Math.max(0,n-i.startedAt),estimatedTokens:i.estimatedTokens})}return i||e.notice?{...e,thinking:i?null:e.thinking,notice:null}:e}case`text-delta`:case`assistant-message`:case`tool-use`:case`tool-result`:return e.notice&&(t.turnId===e.turnId||e.turnId===null)?{...e,notice:null}:e;case`turn-done`:case`cancelled`:return{...u,settledTurnId:t.turnId};default:return e}}function H(e,t,n){let r=null,i=e.settledTurnId;for(let e=t.length-1;e>=0;--e){let n=t[e];if(n.type===`turn-done`||n.type===`cancelled`){i=n.turnId;break}if(n.type===`turn-started`){r=n;break}}return r?n&&n.status!==`running`?e.turnId===null?e:{...u,settledTurnId:e.settledTurnId}:e.turnId===r.turnId?e:{...u,turnId:r.turnId,startedAt:R(r.at,Date.now()),settledTurnId:e.settledTurnId}:e.turnId!==null&&e.turnId===i?{...u,settledTurnId:i}:e.settledTurnId===i?e:{...e,settledTurnId:i}}function ie(e,t){let n=e.usage,r={...n,inputTokens:n.inputTokens+t.inputTokens,outputTokens:n.outputTokens+t.outputTokens,cacheReadTokens:n.cacheReadTokens+t.cacheReadTokens,cacheCreationTokens:n.cacheCreationTokens+t.cacheCreationTokens,contextTokens:t.contextTokens},i=typeof t.contextWindow==`number`&&t.contextWindow>0?t.contextWindow:null,a=t.contextWindowSource!==void 0||e.engine!==`local`;return i!==null&&a&&(r.contextWindow=i),t.contextWindowSource!==void 0&&(r.contextWindowSource=t.contextWindowSource),t.autoCompactAt!==void 0&&(r.autoCompactAt=t.autoCompactAt),t.contextTokensExact===!1?r.contextTokensExact=!1:t.contextWindowSource!==void 0&&delete r.contextTokensExact,r}var U=new Set([`runtime`,`provider-catalog`,`cli-catalog`,`documented`,`fallback`]);function W(e){return typeof e==`string`&&U.has(e)?e:null}function G(t,n){let r=t.usage,i={...r,contextTokens:Math.max(0,Math.floor(n.contextTokens)),contextTokensExact:n.exact},a=typeof n.contextWindow==`number`&&n.contextWindow>0?n.contextWindow:null,o=W(n.contextWindowSource);return a===null||t.engine===`local`&&o===null?(n.autoCompactAt!==void 0&&n.autoCompactAt!==null&&(i.autoCompactAt=n.autoCompactAt),i):(i.contextWindow=a,i.contextWindowSource=o??`runtime`,n.autoCompactAt===void 0?a!==r.contextWindow&&(i.autoCompactAt=e({engine:t.engine,runtimeWindow:a,budget:r.contextWindow?{contextWindow:r.contextWindow,autoCompactAt:r.autoCompactAt??null}:null})):i.autoCompactAt=n.autoCompactAt,i)}function K(e){let t=null;for(let n of e)(n.type===`usage`||n.type===`turn-done`||n.type===`cancelled`||n.type===`context`&&n.turnId!==null)&&typeof n.at==`string`&&(t===null||n.at>t)&&(t=n.at);return t}function q(e){let t=f.delete(e);p.delete(e),h.delete(e),m.delete(e);for(let t of[...v])t({kind:`forget`,sessionId:e});t&&y(e)}function J(e,t){let n=0,r=e.length;for(;n<r;){let i=n+r>>>1,a=e[i].seq;if(a===t)return{found:!0,index:i};a<t?n=i+1:r=i}return{found:!1,index:n}}function Y(e){let t=!0;for(let n=0;n<e.length;n+=1){let r=e[n].seq;if(!Number.isFinite(r)||n>0&&r<=e[n-1].seq){t=!1;break}}if(t)return e.slice();let n=new Map;for(let t of e)Number.isFinite(t.seq)&&!n.has(t.seq)&&n.set(t.seq,t);return[...n.values()].sort((e,t)=>e.seq-t.seq)}function ae(e,t){if(t.length===0)return e;let n=Y(t);if(n.length===0)return e;if(e.length===0)return n;if(n[0].seq>e[e.length-1].seq)return e.concat(n);let r=[],i=0,a=0,o=0;for(;a<e.length||o<n.length;){let t=e[a],s=n[o];s===void 0||t!==void 0&&t.seq<s.seq?(r.push(t),a+=1):t===void 0||s.seq<t.seq?(r.push(s),i+=1,o+=1):(r.push(t),a+=1,o+=1)}return i===0?e:r}function oe(e,t){if(Object.is(e,t))return!0;if(!e||!t||typeof e!=`object`||typeof t!=`object`||Array.isArray(e)!==Array.isArray(t))return!1;let n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(let r of n)if(!Object.is(e[r],t[r]))return!1;return!0}function se(e,t){if(e===t)return!0;let n=Object.keys(e);return n.length===Object.keys(t).length&&n.every(n=>oe(e[n],t[n]))}function X(e,t){let n=Date.parse(e),r=Date.parse(t);return Number.isFinite(n)&&Number.isFinite(r)?Math.max(0,r-n):null}function ce(){return{segments:new Map}}function Z(e,t,n,r){let i=[],a=new Map,o=[],s=[],c=null,l=null,u=null,d=()=>{c&&=(i.push({kind:`assistant`,key:c.key,turnId:c.turnId,at:c.at,text:c.text,streaming:!1}),null)};for(let f=t;f<n;f+=1){let t=e[f];switch(t.type){case`user-message`:d(),i.push({kind:`user`,key:`u-${t.seq}`,turnId:t.turnId,at:t.at,text:t.text});break;case`turn-started`:l=!0;break;case`text-delta`:c&&c.turnId!==t.turnId&&d(),c||={turnId:t.turnId,at:t.at,text:``,key:`d-${t.seq}`},c.text+=t.text;break;case`assistant-message`:c=null,i.push({kind:`assistant`,key:`a-${t.seq}`,turnId:t.turnId,at:t.at,text:t.text,streaming:!1});break;case`thinking`:{d();let e=r?.get(t.seq);i.push({kind:`thinking`,key:`t-${t.seq}`,turnId:t.turnId,at:t.at,text:t.text,redacted:t.redacted===!0,durationMs:typeof t.durationMs==`number`&&Number.isFinite(t.durationMs)&&t.durationMs>=0?t.durationMs:e?.durationMs??null,estimatedTokens:e?.estimatedTokens??null,thinkingKind:t.kind??null});break}case`tool-use`:d(),a.set(t.toolUseId,i.length),s.push(t.toolUseId),i.push({kind:`tool`,key:`tu-${t.seq}`,turnId:t.turnId,at:t.at,toolUseId:t.toolUseId,name:t.name,input:t.input,result:null,durationMs:null});break;case`tool-result`:{let e=a.get(t.toolUseId),n=e===void 0?void 0:i[e];n&&n.kind===`tool`?i[e]={...n,result:{output:t.output,isError:t.isError},durationMs:X(n.at,t.at)}:(o.push(t.toolUseId),i.push({kind:`tool`,key:`tr-${t.seq}`,turnId:t.turnId,at:t.at,toolUseId:t.toolUseId,name:`tool`,input:null,result:{output:t.output,isError:t.isError},durationMs:null}));break}case`usage`:u=t.usage;break;case`compaction`:i.push({kind:`compaction`,key:`k-${t.seq}`,turnId:t.turnId,at:t.at,trigger:t.trigger,preTokens:t.preTokens,postTokens:t.postTokens,durationMs:t.durationMs});break;case`error`:d(),i.push({kind:`error`,key:`e-${t.seq}`,turnId:t.turnId,at:t.at,message:t.message,code:typeof t.code==`string`&&t.code?t.code:null});break;case`cancelled`:d(),l=!1,i.push({kind:`cancelled`,key:`c-${t.seq}`,turnId:t.turnId,at:t.at});break;case`turn-done`:d(),l=!1,i.push({kind:`turn-done`,key:`td-${t.seq}`,turnId:t.turnId,at:t.at,ok:t.ok,durationMs:t.durationMs});break;case`recovered`:i.push({kind:`recovered`,key:`r-${t.seq}`,turnId:t.turnId,at:t.at,how:t.how,message:t.message});break;case`history-truncated`:i.push({kind:`truncated`,key:`h-${t.seq}`,turnId:null,at:t.at,droppedBefore:t.droppedBefore})}}return{items:i,pending:c,liveEffect:l,usage:u,orphanResults:o,toolUseIds:s}}function Q(e,t,n){let r=t.pending;return r?{key:e,items:[...t.items,{kind:`assistant`,key:r.key,turnId:r.turnId,at:r.at,text:r.text,streaming:n}]}:{key:e,items:t.items}}function le(e,t={}){let{cache:n,thinkingStats:r}=t;if(e.length===0)return{items:[],live:!1,usage:null,segments:[]};let i=[0];for(let t=1;t<e.length;t+=1)e[t].type===`user-message`&&i.push(t);let a=[],o=new Set;for(let t=0;t<i.length;t+=1){let s=i[t],c=t+1<i.length?i[t+1]:e.length,l=e[s].seq,u=e[c-1].seq,d=c-s,f=`s-${l}`;o.add(f);let p=n?.segments.get(f);if(p&&p.firstSeq===l&&p.lastSeq===u&&p.count===d){a.push({key:f,build:p.build,cached:p});continue}let m=Z(e,s,c,r),h={firstSeq:l,lastSeq:u,count:d,build:m,finalized:null};n?.segments.set(f,h),a.push({key:f,build:m,cached:h})}if(n)for(let e of[...n.segments.keys()])o.has(e)||n.segments.delete(e);if(a.length>1){let t=new Set;for(let n of a){if(n.build.orphanResults.some(e=>t.has(e)))return $(e,r);for(let e of n.build.toolUseIds)t.add(e)}}let s=!1,c=null;for(let e of a)e.build.liveEffect!==null&&(s=e.build.liveEffect),e.build.usage!==null&&(c=e.build.usage);let l=[],u=[];for(let e=0;e<a.length;e+=1){let t=a[e],n=e===a.length-1&&s,r;t.cached?.finalized&&t.cached.finalized.streaming===n?r=t.cached.finalized.segment:(r=Q(t.key,t.build,n),t.cached&&(t.cached.finalized={streaming:n,segment:r})),l.push(r);for(let e of r.items)u.push(e)}return{items:u,live:s,usage:c,segments:l}}function $(e,t){let n=Z(e,0,e.length,t),r=n.liveEffect??!1,i=Q(`s-${e[0].seq}`,n,r);return{items:i.items,live:r,usage:n.usage,segments:[i]}}function ue(e){let t=[],n=[],r=()=>{if(n.length===0)return;let e=n.length;for(;e>0&&n[e-1].kind===`thinking`;)--e;let r=n.slice(0,e),i=n.slice(e);if(r.filter(e=>e.kind===`tool`).length>=2)t.push(de(r));else for(let e of r)t.push(e);for(let e of i)t.push(e);n=[]};for(let i of e){if((i.kind===`tool`||i.kind===`thinking`)&&(n.length===0||n[0].turnId===i.turnId)){n.push(i);continue}r(),i.kind===`tool`||i.kind===`thinking`?n.push(i):t.push(i)}return r(),t}function de(e){let t=new Map,n=0,r=!1;for(let i of e)i.kind===`tool`&&(t.set(i.name,(t.get(i.name)??0)+1),i.result===null?r=!0:i.result.isError&&(n+=1));let i=[...t.values()].reduce((e,t)=>e+t,0),a=[...t.entries()].map(([e,t])=>t>1?`${e} ×${t}`:e).join(`, `),o=X(e[0].at,e[e.length-1].at);return{kind:`toolGroup`,key:`g-${e[0].key}`,turnId:e[0].turnId,at:e[0].at,items:e,toolCount:i,summary:a,errorCount:n,pending:r,spanMs:o}}function fe(e){return e==null||!Number.isFinite(e)?`—`:Math.round(e)<1e3?String(Math.round(e)):Math.round(e/1e3)<1e3?`${Math.round(e/1e3)}k`:`${(e/1e6).toFixed(1).replace(/\.0$/,``)}M`}export{c as C,l as S,x as _,re as a,o as b,ue as c,j as d,N as f,b as g,ee as h,D as i,K as l,M as m,q as n,ne as o,F as p,fe as r,k as s,I as t,A as u,t as v,s as w,i as x,a as y};
3
- //# sourceMappingURL=verse-store-DHTuZpYa.js.map
3
+ //# sourceMappingURL=verse-store-DjBWj04q.js.map