@ashlr/hub 3.10.0 → 3.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +156 -0
- package/README.md +343 -82
- package/dist/authority-surface.json +109 -29
- package/dist/build-identity.json +2 -2
- package/dist/cli/cloud.d.ts +39 -0
- package/dist/cli/cloud.js +448 -0
- package/dist/cli/cloud.js.map +1 -0
- package/dist/cli/completions.js +4 -0
- package/dist/cli/completions.js.map +1 -1
- package/dist/cli/help.js +2 -0
- package/dist/cli/help.js.map +1 -1
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +10 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/core/cloud/backlog.d.ts +17 -0
- package/dist/core/cloud/backlog.js +177 -0
- package/dist/core/cloud/backlog.js.map +1 -0
- package/dist/core/cloud/budget.d.ts +19 -0
- package/dist/core/cloud/budget.js +99 -0
- package/dist/core/cloud/budget.js.map +1 -0
- package/dist/core/cloud/checkout.d.ts +41 -0
- package/dist/core/cloud/checkout.js +168 -0
- package/dist/core/cloud/checkout.js.map +1 -0
- package/dist/core/cloud/cloud-api.d.ts +86 -0
- package/dist/core/cloud/cloud-api.js +599 -0
- package/dist/core/cloud/cloud-api.js.map +1 -0
- package/dist/core/cloud/delivery-contract.d.ts +25 -0
- package/dist/core/cloud/delivery-contract.js +138 -0
- package/dist/core/cloud/delivery-contract.js.map +1 -0
- package/dist/core/cloud/improvement-backlog.d.ts +11 -0
- package/dist/core/cloud/improvement-backlog.js +26 -0
- package/dist/core/cloud/improvement-backlog.js.map +1 -0
- package/dist/core/cloud/launcher.d.ts +68 -0
- package/dist/core/cloud/launcher.js +312 -0
- package/dist/core/cloud/launcher.js.map +1 -0
- package/dist/core/cloud/service.d.ts +51 -0
- package/dist/core/cloud/service.js +215 -0
- package/dist/core/cloud/service.js.map +1 -0
- package/dist/core/cloud/store.d.ts +41 -0
- package/dist/core/cloud/store.js +278 -0
- package/dist/core/cloud/store.js.map +1 -0
- package/dist/core/cloud/tracker.d.ts +30 -0
- package/dist/core/cloud/tracker.js +152 -0
- package/dist/core/cloud/tracker.js.map +1 -0
- package/dist/core/cloud/types.d.ts +233 -0
- package/dist/core/cloud/types.js +73 -0
- package/dist/core/cloud/types.js.map +1 -0
- package/dist/core/daemon/capacity-publisher.d.ts +19 -0
- package/dist/core/daemon/capacity-publisher.js +49 -2
- package/dist/core/daemon/capacity-publisher.js.map +1 -1
- package/dist/core/daemon/overnight-status.d.ts +13 -0
- package/dist/core/daemon/overnight-status.js +93 -8
- package/dist/core/daemon/overnight-status.js.map +1 -1
- package/dist/core/fleet/dispatch-router.js +26 -9
- package/dist/core/fleet/dispatch-router.js.map +1 -1
- package/dist/core/fleet/fleet-runtime-journal.js +12 -5
- package/dist/core/fleet/fleet-runtime-journal.js.map +1 -1
- package/dist/core/fleet/fleet-types.d.ts +13 -0
- package/dist/core/routing/budget-store.js +11 -5
- package/dist/core/routing/budget-store.js.map +1 -1
- package/dist/core/routing/capacity-history-api.d.ts +30 -0
- package/dist/core/routing/capacity-history-api.js +147 -0
- package/dist/core/routing/capacity-history-api.js.map +1 -0
- package/dist/core/routing/capacity-history-types.d.ts +63 -0
- package/dist/core/routing/capacity-history-types.js +18 -0
- package/dist/core/routing/capacity-history-types.js.map +1 -0
- package/dist/core/routing/capacity-history.d.ts +130 -0
- package/dist/core/routing/capacity-history.js +654 -0
- package/dist/core/routing/capacity-history.js.map +1 -0
- package/dist/core/routing/headroom.d.ts +5 -1
- package/dist/core/routing/headroom.js +82 -41
- package/dist/core/routing/headroom.js.map +1 -1
- package/dist/core/routing/router.d.ts +8 -1
- package/dist/core/routing/router.js +49 -16
- package/dist/core/routing/router.js.map +1 -1
- package/dist/core/routing/seat-reasons.d.ts +35 -0
- package/dist/core/routing/seat-reasons.js +48 -0
- package/dist/core/routing/seat-reasons.js.map +1 -0
- package/dist/core/routing/types.d.ts +37 -0
- package/dist/core/routing/types.js.map +1 -1
- package/dist/core/verse/activity-api.d.ts +3 -1
- package/dist/core/verse/activity-api.js +16 -1
- package/dist/core/verse/activity-api.js.map +1 -1
- package/dist/core/verse/activity.d.ts +7 -0
- package/dist/core/verse/activity.js +23 -0
- package/dist/core/verse/activity.js.map +1 -1
- package/dist/core/verse/fleet-history-types.d.ts +12 -4
- package/dist/core/verse/fleet-history-types.js +4 -2
- package/dist/core/verse/fleet-history-types.js.map +1 -1
- package/dist/core/verse/fleet-live-api.d.ts +14 -1
- package/dist/core/verse/fleet-live-api.js +31 -11
- package/dist/core/verse/fleet-live-api.js.map +1 -1
- package/dist/core/verse/preferences.d.ts +3 -1
- package/dist/core/verse/preferences.js +5 -2
- package/dist/core/verse/preferences.js.map +1 -1
- package/dist/core/verse/types.d.ts +5 -1
- package/dist/core/verse/types.js.map +1 -1
- package/dist/core/verse/verse-api.d.ts +1 -1
- package/dist/core/verse/verse-api.js +4 -1
- package/dist/core/verse/verse-api.js.map +1 -1
- package/dist/core/vision/leader-cloud.d.ts +63 -0
- package/dist/core/vision/leader-cloud.js +134 -0
- package/dist/core/vision/leader-cloud.js.map +1 -0
- package/dist/core/vision/leader.d.ts +6 -0
- package/dist/core/vision/leader.js +12 -1
- package/dist/core/vision/leader.js.map +1 -1
- package/dist/core/web/public/next/assets/{ActionMenu-DhbNne-M.js → ActionMenu-CQvNJvHY.js} +2 -2
- package/dist/core/web/public/next/assets/{ActionMenu-DhbNne-M.js.map → ActionMenu-CQvNJvHY.js.map} +1 -1
- package/dist/core/web/public/next/assets/Advanced-Bywv_iYR.css +1 -0
- package/dist/core/web/public/next/assets/Advanced-DEM93sKI.js +2 -0
- package/dist/core/web/public/next/assets/Advanced-DEM93sKI.js.map +1 -0
- package/dist/core/web/public/next/assets/{App-DyBg1v_q.js → App-CimXmK0L.js} +5 -5
- package/dist/core/web/public/next/assets/{App-DyBg1v_q.js.map → App-CimXmK0L.js.map} +1 -1
- package/dist/core/web/public/next/assets/AppsSection-D6U-dSj6.js +2 -0
- package/dist/core/web/public/next/assets/AppsSection-D6U-dSj6.js.map +1 -0
- package/dist/core/web/public/next/assets/AreaTrend-LD9lCPkT.js +2 -0
- package/dist/core/web/public/next/assets/AreaTrend-LD9lCPkT.js.map +1 -0
- package/dist/core/web/public/next/assets/AutonomySection-3V9pUyxm.js +2 -0
- package/dist/core/web/public/next/assets/{AutonomySection-CoMngwNB.js.map → AutonomySection-3V9pUyxm.js.map} +1 -1
- package/dist/core/web/public/next/assets/BranchBar-BZNQ50YE.css +1 -0
- package/dist/core/web/public/next/assets/BranchBar-U8UdpfEB.js +2 -0
- package/dist/core/web/public/next/assets/BranchBar-U8UdpfEB.js.map +1 -0
- package/dist/core/web/public/next/assets/BudgetControl-DOTlMSmW.js +2 -0
- package/dist/core/web/public/next/assets/BudgetControl-DOTlMSmW.js.map +1 -0
- package/dist/core/web/public/next/assets/BurnDown-x4PWH9JF.js +2 -0
- package/dist/core/web/public/next/assets/BurnDown-x4PWH9JF.js.map +1 -0
- package/dist/core/web/public/next/assets/{Button-0-nNbv1h.js → Button-DYv_KKxr.js} +2 -2
- package/dist/core/web/public/next/assets/{Button-0-nNbv1h.js.map → Button-DYv_KKxr.js.map} +1 -1
- package/dist/core/web/public/next/assets/CapacityStrip-C667yQe8.js +2 -0
- package/dist/core/web/public/next/assets/CapacityStrip-C667yQe8.js.map +1 -0
- package/dist/core/web/public/next/assets/CapacityStrip-Cc28CyWk.css +1 -0
- package/dist/core/web/public/next/assets/ChatSection-CCcIPpOq.js +3 -0
- package/dist/core/web/public/next/assets/{ChatSection-B9cdRKUh.js.map → ChatSection-CCcIPpOq.js.map} +1 -1
- package/dist/core/web/public/next/assets/CloudBudgetForm-DJeJvBEu.js +2 -0
- package/dist/core/web/public/next/assets/CloudBudgetForm-DJeJvBEu.js.map +1 -0
- package/dist/core/web/public/next/assets/{CommandPalette-GpeCSrPy.js → CommandPalette-FiD4N8XD.js} +2 -2
- package/dist/core/web/public/next/assets/{CommandPalette-GpeCSrPy.js.map → CommandPalette-FiD4N8XD.js.map} +1 -1
- package/dist/core/web/public/next/assets/CommandSection-DN8KwH-X.js +2 -0
- package/dist/core/web/public/next/assets/CommandSection-DN8KwH-X.js.map +1 -0
- package/dist/core/web/public/next/assets/Composer-ByzxOJK6.css +1 -0
- package/dist/core/web/public/next/assets/Composer.module-C8U73KdQ.js +2 -0
- package/dist/core/web/public/next/assets/{Composer.module-DJMdrqNt.js.map → Composer.module-C8U73KdQ.js.map} +1 -1
- package/dist/core/web/public/next/assets/DiffPane-BAvvbBsf.css +1 -0
- package/dist/core/web/public/next/assets/DiffPane-DLJ3gGGK.js +2 -0
- package/dist/core/web/public/next/assets/DiffPane-DLJ3gGGK.js.map +1 -0
- package/dist/core/web/public/next/assets/{DiffViewer-tOGWk0CA.js → DiffViewer-B7NWPjIO.js} +2 -2
- package/dist/core/web/public/next/assets/{DiffViewer-tOGWk0CA.js.map → DiffViewer-B7NWPjIO.js.map} +1 -1
- package/dist/core/web/public/next/assets/DockHost-B4RaYOET.css +1 -0
- package/dist/core/web/public/next/assets/DockHost-DvR-hPhZ.js +2 -0
- package/dist/core/web/public/next/assets/DockHost-DvR-hPhZ.js.map +1 -0
- package/dist/core/web/public/next/assets/{EmptyState-DdJ4CxtO.js → EmptyState-DhNgDDrF.js} +2 -2
- package/dist/core/web/public/next/assets/{EmptyState-DdJ4CxtO.js.map → EmptyState-DhNgDDrF.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Epistemic-BLjM5y_y.js → Epistemic-uARPnx9x.js} +2 -2
- package/dist/core/web/public/next/assets/{Epistemic-BLjM5y_y.js.map → Epistemic-uARPnx9x.js.map} +1 -1
- package/dist/core/web/public/next/assets/FleetSection-CFiWeOEs.css +1 -0
- package/dist/core/web/public/next/assets/FleetSection-D_zRBCub.js +3 -0
- package/dist/core/web/public/next/assets/FleetSection-D_zRBCub.js.map +1 -0
- package/dist/core/web/public/next/assets/Funnel-CL8uHONq.js +2 -0
- package/dist/core/web/public/next/assets/Funnel-CL8uHONq.js.map +1 -0
- package/dist/core/web/public/next/assets/GearTray-C7k4l_BW.js +2 -0
- package/dist/core/web/public/next/assets/GearTray-C7k4l_BW.js.map +1 -0
- package/dist/core/web/public/next/assets/GrowthSection-DwdNSGj8.js +2 -0
- package/dist/core/web/public/next/assets/GrowthSection-DwdNSGj8.js.map +1 -0
- package/dist/core/web/public/next/assets/HandoffDialog-FPVOqOMN.js +2 -0
- package/dist/core/web/public/next/assets/HandoffDialog-FPVOqOMN.js.map +1 -0
- package/dist/core/web/public/next/assets/{Input-CTu0CycC.js → Input-B9-VLcHS.js} +2 -2
- package/dist/core/web/public/next/assets/{Input-CTu0CycC.js.map → Input-B9-VLcHS.js.map} +1 -1
- package/dist/core/web/public/next/assets/{LeaderCard-BuSDeATv.js → LeaderCard-4R0BhDzT.js} +2 -2
- package/dist/core/web/public/next/assets/{LeaderCard-BuSDeATv.js.map → LeaderCard-4R0BhDzT.js.map} +1 -1
- package/dist/core/web/public/next/assets/{MatrixHeatmap-9dKgJ_pT.css → MatrixHeatmap-Bmnvo1l1.css} +1 -1
- package/dist/core/web/public/next/assets/MatrixHeatmap-DiuushcS.js +2 -0
- package/dist/core/web/public/next/assets/MatrixHeatmap-DiuushcS.js.map +1 -0
- package/dist/core/web/public/next/assets/McpSection-CJ__OJKl.js +2 -0
- package/dist/core/web/public/next/assets/{McpSection-1UncWBpW.js.map → McpSection-CJ__OJKl.js.map} +1 -1
- package/dist/core/web/public/next/assets/MessageMarkdown-Cgh5f1-Q.css +1 -0
- package/dist/core/web/public/next/assets/MessageMarkdown-qWKyJvAQ.js +3 -0
- package/dist/core/web/public/next/assets/{MessageMarkdown-C4pl9LI5.js.map → MessageMarkdown-qWKyJvAQ.js.map} +1 -1
- package/dist/core/web/public/next/assets/{MessageMarkdownRenderer-CZsF77ZM.js → MessageMarkdownRenderer-x05TrsrW.js} +2 -2
- package/dist/core/web/public/next/assets/{MessageMarkdownRenderer-CZsF77ZM.js.map → MessageMarkdownRenderer-x05TrsrW.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Meter-C18ciKz4.js → Meter-D-hncpkO.js} +2 -2
- package/dist/core/web/public/next/assets/{Meter-C18ciKz4.js.map → Meter-D-hncpkO.js.map} +1 -1
- package/dist/core/web/public/next/assets/MindSection-BjXHkQPS.js +2 -0
- package/dist/core/web/public/next/assets/MindSection-BjXHkQPS.js.map +1 -0
- package/dist/core/web/public/next/assets/MutationTokenDialog-SkRxqV_I.js +2 -0
- package/dist/core/web/public/next/assets/MutationTokenDialog-SkRxqV_I.js.map +1 -0
- package/dist/core/web/public/next/assets/NeedsYouDrawer-BpvidnM2.css +1 -0
- package/dist/core/web/public/next/assets/NeedsYouDrawer-rSd1ZHAR.js +2 -0
- package/dist/core/web/public/next/assets/NeedsYouDrawer-rSd1ZHAR.js.map +1 -0
- package/dist/core/web/public/next/assets/NeedsYouList-CG-nB1tr.js +2 -0
- package/dist/core/web/public/next/assets/NeedsYouList-CG-nB1tr.js.map +1 -0
- package/dist/core/web/public/next/assets/NeedsYouList-CruOt4JT.css +1 -0
- package/dist/core/web/public/next/assets/NewChatDialog-BeDQ1eW3.js +3 -0
- package/dist/core/web/public/next/assets/{NewChatDialog-B_BsS9pr.js.map → NewChatDialog-BeDQ1eW3.js.map} +1 -1
- package/dist/core/web/public/next/assets/OnboardingFlow-CkTZtt-m.js +2 -0
- package/dist/core/web/public/next/assets/{OnboardingFlow-CtCPpgoX.js.map → OnboardingFlow-CkTZtt-m.js.map} +1 -1
- package/dist/core/web/public/next/assets/PreviewPane-DoMsJSG3.css +1 -0
- package/dist/core/web/public/next/assets/PreviewPane-kzbbSK4u.js +2 -0
- package/dist/core/web/public/next/assets/PreviewPane-kzbbSK4u.js.map +1 -0
- package/dist/core/web/public/next/assets/RailStatus-D-t2gPae.js +2 -0
- package/dist/core/web/public/next/assets/RailStatus-D-t2gPae.js.map +1 -0
- package/dist/core/web/public/next/assets/{RefreshIndicator-CnhEovMZ.js → RefreshIndicator-BLnr9IOM.js} +2 -2
- package/dist/core/web/public/next/assets/{RefreshIndicator-CnhEovMZ.js.map → RefreshIndicator-BLnr9IOM.js.map} +1 -1
- package/dist/core/web/public/next/assets/{ResourcePoolConsoleApp-28gLwmwV.js → ResourcePoolConsoleApp-BeG0gBif.js} +4 -4
- package/dist/core/web/public/next/assets/{ResourcePoolConsoleApp-28gLwmwV.js.map → ResourcePoolConsoleApp-BeG0gBif.js.map} +1 -1
- package/dist/core/web/public/next/assets/ResourcesChrome-B3Z3O98t.css +1 -0
- package/dist/core/web/public/next/assets/ResourcesChrome-BzV6bkIa.js +3 -0
- package/dist/core/web/public/next/assets/ResourcesChrome-BzV6bkIa.js.map +1 -0
- package/dist/core/web/public/next/assets/ResourcesDrawer-CSKIO_wZ.css +1 -0
- package/dist/core/web/public/next/assets/ResourcesDrawer-o4ILHdep.js +2 -0
- package/dist/core/web/public/next/assets/ResourcesDrawer-o4ILHdep.js.map +1 -0
- package/dist/core/web/public/next/assets/{RouteErrorBoundary-AyUPCIb3.js → RouteErrorBoundary-C5SxA2Dg.js} +2 -2
- package/dist/core/web/public/next/assets/{RouteErrorBoundary-AyUPCIb3.js.map → RouteErrorBoundary-C5SxA2Dg.js.map} +1 -1
- package/dist/core/web/public/next/assets/RunInCloudAction-C3LBp7C4.js +2 -0
- package/dist/core/web/public/next/assets/RunInCloudAction-C3LBp7C4.js.map +1 -0
- package/dist/core/web/public/next/assets/SeatSelector-DpvvbjNm.js +3 -0
- package/dist/core/web/public/next/assets/{SeatSelector-DaUO-zoK.js.map → SeatSelector-DpvvbjNm.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Segmented-B_8c_83S.js → Segmented-BL40udoO.js} +2 -2
- package/dist/core/web/public/next/assets/{Segmented-B_8c_83S.js.map → Segmented-BL40udoO.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Select-Bl5g5Dt_.js → Select-FWLnAw_j.js} +2 -2
- package/dist/core/web/public/next/assets/{Select-Bl5g5Dt_.js.map → Select-FWLnAw_j.js.map} +1 -1
- package/dist/core/web/public/next/assets/{SessionInsightChip-w0I21q0c.js → SessionInsightChip-CWye87Ju.js} +2 -2
- package/dist/core/web/public/next/assets/{SessionInsightChip-w0I21q0c.js.map → SessionInsightChip-CWye87Ju.js.map} +1 -1
- package/dist/core/web/public/next/assets/SessionSearch-YvCHFUuN.js +2 -0
- package/dist/core/web/public/next/assets/{SessionSearch-B5aQ0BCM.js.map → SessionSearch-YvCHFUuN.js.map} +1 -1
- package/dist/core/web/public/next/assets/SettingsSection-Dr18upeE.js +2 -0
- package/dist/core/web/public/next/assets/SettingsSection-Dr18upeE.js.map +1 -0
- package/dist/core/web/public/next/assets/{Sheet-CVjk-cLI.js → Sheet-DZKcQXQg.js} +2 -2
- package/dist/core/web/public/next/assets/{Sheet-CVjk-cLI.js.map → Sheet-DZKcQXQg.js.map} +1 -1
- package/dist/core/web/public/next/assets/{ShortcutsOverlay-BiBjnBcc.js → ShortcutsOverlay-BpDimdPq.js} +2 -2
- package/dist/core/web/public/next/assets/{ShortcutsOverlay-BiBjnBcc.js.map → ShortcutsOverlay-BpDimdPq.js.map} +1 -1
- package/dist/core/web/public/next/assets/Sidebar-BRc1vGDF.css +1 -0
- package/dist/core/web/public/next/assets/Sidebar-BoBzBEFX.js +3 -0
- package/dist/core/web/public/next/assets/Sidebar-BoBzBEFX.js.map +1 -0
- package/dist/core/web/public/next/assets/{Slider-BS9MU5ZV.js → Slider-DUMo9HDD.js} +2 -2
- package/dist/core/web/public/next/assets/{Slider-BS9MU5ZV.js.map → Slider-DUMo9HDD.js.map} +1 -1
- package/dist/core/web/public/next/assets/{StatusBadge-DAf-ArKE.js → StatusBadge-BwnBNFQr.js} +2 -2
- package/dist/core/web/public/next/assets/{StatusBadge-DAf-ArKE.js.map → StatusBadge-BwnBNFQr.js.map} +1 -1
- package/dist/core/web/public/next/assets/StepBand-PDXMIlRk.js +2 -0
- package/dist/core/web/public/next/assets/StepBand-PDXMIlRk.js.map +1 -0
- package/dist/core/web/public/next/assets/{Surface-CiYOdNKQ.js → Surface-B3TZVoER.js} +2 -2
- package/dist/core/web/public/next/assets/{Surface-CiYOdNKQ.js.map → Surface-B3TZVoER.js.map} +1 -1
- package/dist/core/web/public/next/assets/Swimlane-DR4OgON_.js +2 -0
- package/dist/core/web/public/next/assets/Swimlane-DR4OgON_.js.map +1 -0
- package/dist/core/web/public/next/assets/{Switch-BzRXtNPt.js → Switch-CcR5Llk5.js} +2 -2
- package/dist/core/web/public/next/assets/{Switch-BzRXtNPt.js.map → Switch-CcR5Llk5.js.map} +1 -1
- package/dist/core/web/public/next/assets/{Tag-DEEbDz7T.js → Tag-_-K1h7Hk.js} +2 -2
- package/dist/core/web/public/next/assets/{Tag-DEEbDz7T.js.map → Tag-_-K1h7Hk.js.map} +1 -1
- package/dist/core/web/public/next/assets/TerminalPane-BwfMbnJz.css +1 -0
- package/dist/core/web/public/next/assets/TerminalPane-_1aH4ndN.js +7 -0
- package/dist/core/web/public/next/assets/TerminalPane-_1aH4ndN.js.map +1 -0
- package/dist/core/web/public/next/assets/UniverseConsoleApp-BUsq-inZ.js +2 -0
- package/dist/core/web/public/next/assets/{UniverseConsoleApp-DKqAf-eD.js.map → UniverseConsoleApp-BUsq-inZ.js.map} +1 -1
- package/dist/core/web/public/next/assets/{UniverseView-D6081LQL.js → UniverseView-Dogy_dsB.js} +2 -2
- package/dist/core/web/public/next/assets/{UniverseView-D6081LQL.js.map → UniverseView-Dogy_dsB.js.map} +1 -1
- package/dist/core/web/public/next/assets/UsageSection-DiX_dTyo.js +2 -0
- package/dist/core/web/public/next/assets/UsageSection-DiX_dTyo.js.map +1 -0
- package/dist/core/web/public/next/assets/UsageSection-DsB-Jqyl.css +1 -0
- package/dist/core/web/public/next/assets/VerseConsoleApp-Cxqr-3qc.css +1 -0
- package/dist/core/web/public/next/assets/VerseConsoleApp-WVeyJnW7.js +3 -0
- package/dist/core/web/public/next/assets/VerseConsoleApp-WVeyJnW7.js.map +1 -0
- package/dist/core/web/public/next/assets/Workspace-BYW9dm90.css +1 -0
- package/dist/core/web/public/next/assets/Workspace-BbxZHwQd.js +10 -0
- package/dist/core/web/public/next/assets/Workspace-BbxZHwQd.js.map +1 -0
- package/dist/core/web/public/next/assets/actions-Ddfg2iLl.css +1 -0
- package/dist/core/web/public/next/assets/actions-s2lfm_5k.js +2 -0
- package/dist/core/web/public/next/assets/actions-s2lfm_5k.js.map +1 -0
- package/dist/core/web/public/next/assets/apps-model-CDFvmsQV.js +2 -0
- package/dist/core/web/public/next/assets/apps-model-CDFvmsQV.js.map +1 -0
- package/dist/core/web/public/next/assets/{budget-queries-Dacv1VYP.js → budget-queries-wUshcovN.js} +2 -2
- package/dist/core/web/public/next/assets/{budget-queries-Dacv1VYP.js.map → budget-queries-wUshcovN.js.map} +1 -1
- package/dist/core/web/public/next/assets/calendar-day-BxBYHfX1.js +2 -0
- package/dist/core/web/public/next/assets/calendar-day-BxBYHfX1.js.map +1 -0
- package/dist/core/web/public/next/assets/capacity-strip-model-Bj_9ztzs.js +2 -0
- package/dist/core/web/public/next/assets/capacity-strip-model-Bj_9ztzs.js.map +1 -0
- package/dist/core/web/public/next/assets/charts-CMSgAUKn.js +2 -0
- package/dist/core/web/public/next/assets/charts-CMSgAUKn.js.map +1 -0
- package/dist/core/web/public/next/assets/cloud-C1KPNRHC.css +1 -0
- package/dist/core/web/public/next/assets/cloud-queries-CnV1yaNG.js +2 -0
- package/dist/core/web/public/next/assets/cloud-queries-CnV1yaNG.js.map +1 -0
- package/dist/core/web/public/next/assets/cloud.module-CiwatLj3.js +2 -0
- package/dist/core/web/public/next/assets/cloud.module-CiwatLj3.js.map +1 -0
- package/dist/core/web/public/next/assets/colors-BZ3a9wFf.js +2 -0
- package/dist/core/web/public/next/assets/colors-BZ3a9wFf.js.map +1 -0
- package/dist/core/web/public/next/assets/{command-bus-CpYuam1F.js → command-bus-DqimKCUY.js} +2 -2
- package/dist/core/web/public/next/assets/{command-bus-CpYuam1F.js.map → command-bus-DqimKCUY.js.map} +1 -1
- package/dist/core/web/public/next/assets/command-catalog-BdtDH93o.js +2 -0
- package/dist/core/web/public/next/assets/command-catalog-BdtDH93o.js.map +1 -0
- package/dist/core/web/public/next/assets/{composer-keys-CYz4U4Bg.js → composer-keys-DBRymxQn.js} +2 -2
- package/dist/core/web/public/next/assets/{composer-keys-CYz4U4Bg.js.map → composer-keys-DBRymxQn.js.map} +1 -1
- package/dist/core/web/public/next/assets/context-model-Dwd49-dp.js +2 -0
- package/dist/core/web/public/next/assets/context-model-Dwd49-dp.js.map +1 -0
- package/dist/core/web/public/next/assets/context-model-MT17V86_.js +2 -0
- package/dist/core/web/public/next/assets/context-model-MT17V86_.js.map +1 -0
- package/dist/core/web/public/next/assets/context-queries-xVKIeynP.js +2 -0
- package/dist/core/web/public/next/assets/context-queries-xVKIeynP.js.map +1 -0
- package/dist/core/web/public/next/assets/context.module-BijAfoJw.js +2 -0
- package/dist/core/web/public/next/assets/context.module-BijAfoJw.js.map +1 -0
- package/dist/core/web/public/next/assets/{control-queries-BGjarMm9.js → control-queries-DOZR-D8G.js} +2 -2
- package/dist/core/web/public/next/assets/{control-queries-BGjarMm9.js.map → control-queries-DOZR-D8G.js.map} +1 -1
- package/dist/core/web/public/next/assets/dark-since-DOMvtB_G.js +2 -0
- package/dist/core/web/public/next/assets/dark-since-DOMvtB_G.js.map +1 -0
- package/dist/core/web/public/next/assets/dock-icons-8EtARwUm.js +2 -0
- package/dist/core/web/public/next/assets/dock-icons-8EtARwUm.js.map +1 -0
- package/dist/core/web/public/next/assets/dock-panes-UKS-mXhr.js +2 -0
- package/dist/core/web/public/next/assets/{dock-panes-BNTLvX7G.js.map → dock-panes-UKS-mXhr.js.map} +1 -1
- package/dist/core/web/public/next/assets/{dock-store-_E5h6TEq.js → dock-store-BA1cHOYA.js} +2 -2
- package/dist/core/web/public/next/assets/{dock-store-_E5h6TEq.js.map → dock-store-BA1cHOYA.js.map} +1 -1
- package/dist/core/web/public/next/assets/fleet-model-CNe8Wh-s.js +2 -0
- package/dist/core/web/public/next/assets/fleet-model-CNe8Wh-s.js.map +1 -0
- package/dist/core/web/public/next/assets/fleet-queries-BSdRlUwJ.js +2 -0
- package/dist/core/web/public/next/assets/fleet-queries-BSdRlUwJ.js.map +1 -0
- package/dist/core/web/public/next/assets/format-B8DAVcn2.js +2 -0
- package/dist/core/web/public/next/assets/format-B8DAVcn2.js.map +1 -0
- package/dist/core/web/public/next/assets/format-DKrNjdwD.js +2 -0
- package/dist/core/web/public/next/assets/format-DKrNjdwD.js.map +1 -0
- package/dist/core/web/public/next/assets/{git-model-5v5xGobf.js → git-model-CivuBY_D.js} +2 -2
- package/dist/core/web/public/next/assets/{git-model-5v5xGobf.js.map → git-model-CivuBY_D.js.map} +1 -1
- package/dist/core/web/public/next/assets/global-Di2PUgj4.js +2 -0
- package/dist/core/web/public/next/assets/global-Di2PUgj4.js.map +1 -0
- package/dist/core/web/public/next/assets/{guarded-action-vOPc8v75.js → guarded-action-CvOHcqyH.js} +2 -2
- package/dist/core/web/public/next/assets/{guarded-action-vOPc8v75.js.map → guarded-action-CvOHcqyH.js.map} +1 -1
- package/dist/core/web/public/next/assets/{icons-DWb24OA6.js → icons-B_yuAgdN.js} +2 -2
- package/dist/core/web/public/next/assets/{icons-DWb24OA6.js.map → icons-B_yuAgdN.js.map} +1 -1
- package/dist/core/web/public/next/assets/{index-afDA8cwW.js → index-oAAq8XJa.js} +3 -3
- package/dist/core/web/public/next/assets/{index-afDA8cwW.js.map → index-oAAq8XJa.js.map} +1 -1
- package/dist/core/web/public/next/assets/live-model-DCw_IFRI.js +2 -0
- package/dist/core/web/public/next/assets/live-model-DCw_IFRI.js.map +1 -0
- package/dist/core/web/public/next/assets/local-model-DFyjKX0b.js +2 -0
- package/dist/core/web/public/next/assets/local-model-DFyjKX0b.js.map +1 -0
- package/dist/core/web/public/next/assets/mind-B9PzLcl0.css +1 -0
- package/dist/core/web/public/next/assets/mind.module-vnuJcwvD.js +2 -0
- package/dist/core/web/public/next/assets/mind.module-vnuJcwvD.js.map +1 -0
- package/dist/core/web/public/next/assets/mutations-Dpsql5t7.js +2 -0
- package/dist/core/web/public/next/assets/{mutations-C6E10SPX.js.map → mutations-Dpsql5t7.js.map} +1 -1
- package/dist/core/web/public/next/assets/{overnight-queries-CCGfiS-g.js → overnight-queries-X-44Gsw5.js} +2 -2
- package/dist/core/web/public/next/assets/{overnight-queries-CCGfiS-g.js.map → overnight-queries-X-44Gsw5.js.map} +1 -1
- package/dist/core/web/public/next/assets/pane-chrome-8JmEhHVD.css +1 -0
- package/dist/core/web/public/next/assets/pane-chrome.module-D7o-fVd0.js +2 -0
- package/dist/core/web/public/next/assets/pane-chrome.module-D7o-fVd0.js.map +1 -0
- package/dist/core/web/public/next/assets/primitives-BDIcUvob.js +1 -0
- package/dist/core/web/public/next/assets/{queries-BuYIEHst.js → queries-BA4rNGD-.js} +2 -2
- package/dist/core/web/public/next/assets/{queries-BuYIEHst.js.map → queries-BA4rNGD-.js.map} +1 -1
- package/dist/core/web/public/next/assets/{reasoning-pref-BVzGczV7.js → reasoning-pref-B9-DJUXP.js} +2 -2
- package/dist/core/web/public/next/assets/{reasoning-pref-BVzGczV7.js.map → reasoning-pref-B9-DJUXP.js.map} +1 -1
- package/dist/core/web/public/next/assets/seat-subscription-CH6fW4fJ.js +2 -0
- package/dist/core/web/public/next/assets/seat-subscription-CH6fW4fJ.js.map +1 -0
- package/dist/core/web/public/next/assets/{section-visibility-CSrsTcwK.js → section-visibility-qFqc_d4Z.js} +2 -2
- package/dist/core/web/public/next/assets/{section-visibility-CSrsTcwK.js.map → section-visibility-qFqc_d4Z.js.map} +1 -1
- package/dist/core/web/public/next/assets/{sidebar-model-C8fyqSQY.js → sidebar-model-M1GaQU5l.js} +2 -2
- package/dist/core/web/public/next/assets/{sidebar-model-C8fyqSQY.js.map → sidebar-model-M1GaQU5l.js.map} +1 -1
- package/dist/core/web/public/next/assets/slots-Ds9ZIqUL.js +3 -0
- package/dist/core/web/public/next/assets/{slots-W8gkmdfE.js.map → slots-Ds9ZIqUL.js.map} +1 -1
- package/dist/core/web/public/next/assets/surface-data-J52iIGMD.js +2 -0
- package/dist/core/web/public/next/assets/surface-data-J52iIGMD.js.map +1 -0
- package/dist/core/web/public/next/assets/surface-prefetch-CgZ-LEJK.js +2 -0
- package/dist/core/web/public/next/assets/surface-prefetch-CgZ-LEJK.js.map +1 -0
- package/dist/core/web/public/next/assets/tasks-model-ent8f0jZ.js +2 -0
- package/dist/core/web/public/next/assets/{tasks-model-CnYQzgxk.js.map → tasks-model-ent8f0jZ.js.map} +1 -1
- package/dist/core/web/public/next/assets/{terminal-icons-CxUYaWX9.js → terminal-icons-DJTK7QpR.js} +2 -2
- package/dist/core/web/public/next/assets/{terminal-icons-CxUYaWX9.js.map → terminal-icons-DJTK7QpR.js.map} +1 -1
- package/dist/core/web/public/next/assets/{tool-semantics-CTRuLF5j.js → tool-semantics-GX8ScuSH.js} +2 -2
- package/dist/core/web/public/next/assets/{tool-semantics-CTRuLF5j.js.map → tool-semantics-GX8ScuSH.js.map} +1 -1
- package/dist/core/web/public/next/assets/{turn-files-BvB5LLNw.js → turn-files-BPHQzYuH.js} +2 -2
- package/dist/core/web/public/next/assets/{turn-files-BvB5LLNw.js.map → turn-files-BPHQzYuH.js.map} +1 -1
- package/dist/core/web/public/next/assets/types-D5XOdyw8.js +2 -0
- package/dist/core/web/public/next/assets/types-D5XOdyw8.js.map +1 -0
- package/dist/core/web/public/next/assets/{usage-queries-CQOpeE1H.js → usage-queries-Bn8ccqyN.js} +2 -2
- package/dist/core/web/public/next/assets/{usage-queries-CQOpeE1H.js.map → usage-queries-Bn8ccqyN.js.map} +1 -1
- package/dist/core/web/public/next/assets/use-guarded-action-C2HlSzkz.js +2 -0
- package/dist/core/web/public/next/assets/use-guarded-action-C2HlSzkz.js.map +1 -0
- package/dist/core/web/public/next/assets/{use-ticker-hryPXnyp.js → use-ticker-BNc1H4ZC.js} +2 -2
- package/dist/core/web/public/next/assets/{use-ticker-hryPXnyp.js.map → use-ticker-BNc1H4ZC.js.map} +1 -1
- package/dist/core/web/public/next/assets/use-token-gate-B3IJL6bf.js +2 -0
- package/dist/core/web/public/next/assets/use-token-gate-B3IJL6bf.js.map +1 -0
- package/dist/core/web/public/next/assets/{useActivity-Cg_9-7nt.js → useActivity-Bk3XgXjL.js} +2 -2
- package/dist/core/web/public/next/assets/{useActivity-Cg_9-7nt.js.map → useActivity-Bk3XgXjL.js.map} +1 -1
- package/dist/core/web/public/next/assets/useChartWidth-BAtVgn2n.css +1 -0
- package/dist/core/web/public/next/assets/useChartWidth-lZ9PrQn0.js +2 -0
- package/dist/core/web/public/next/assets/useChartWidth-lZ9PrQn0.js.map +1 -0
- package/dist/core/web/public/next/assets/{useSeatsRefresh-4Ov9eT1F.js → useSeatsRefresh-CG4jczeL.js} +2 -2
- package/dist/core/web/public/next/assets/{useSeatsRefresh-4Ov9eT1F.js.map → useSeatsRefresh-CG4jczeL.js.map} +1 -1
- package/dist/core/web/public/next/assets/verse-model-D7NZQFAR.js +2 -0
- package/dist/core/web/public/next/assets/verse-model-D7NZQFAR.js.map +1 -0
- package/dist/core/web/public/next/assets/{verse-queries-BjQoOTwv.js → verse-queries-DvIJcn6Z.js} +2 -2
- package/dist/core/web/public/next/assets/{verse-queries-BjQoOTwv.js.map → verse-queries-DvIJcn6Z.js.map} +1 -1
- package/dist/core/web/public/next/assets/verse-store-DjBWj04q.js +3 -0
- package/dist/core/web/public/next/assets/verse-store-DjBWj04q.js.map +1 -0
- package/dist/core/web/public/next/assets/verse-ui-store-zafyzXKD.js +3 -0
- package/dist/core/web/public/next/assets/{verse-ui-store-KTTKfv-T.js.map → verse-ui-store-zafyzXKD.js.map} +1 -1
- package/dist/core/web/public/next/assets/{viewport-ZB86jdES.js → viewport-BEqGUoTA.js} +2 -2
- package/dist/core/web/public/next/assets/{viewport-ZB86jdES.js.map → viewport-BEqGUoTA.js.map} +1 -1
- package/dist/core/web/public/next/assets/warmup-BR6pxAKs.js +3 -0
- package/dist/core/web/public/next/assets/warmup-BR6pxAKs.js.map +1 -0
- package/dist/core/web/public/next/assets/{workspace-model-4hq_Mv3N.js → workspace-model-D_tWD5Wt.js} +2 -2
- package/dist/core/web/public/next/assets/{workspace-model-4hq_Mv3N.js.map → workspace-model-D_tWD5Wt.js.map} +1 -1
- package/dist/core/web/public/next/index.html +1 -1
- package/dist/release-dependency-inventory.json +1 -1
- package/package.json +1 -1
- package/dist/core/web/public/next/assets/Advanced-CHjxJt2z.css +0 -1
- package/dist/core/web/public/next/assets/Advanced-DM0DYibH.js +0 -2
- package/dist/core/web/public/next/assets/Advanced-DM0DYibH.js.map +0 -1
- package/dist/core/web/public/next/assets/AppsSection-CXxbfPJQ.js +0 -2
- package/dist/core/web/public/next/assets/AppsSection-CXxbfPJQ.js.map +0 -1
- package/dist/core/web/public/next/assets/AreaTrend-gUVXkfhf.js +0 -2
- package/dist/core/web/public/next/assets/AreaTrend-gUVXkfhf.js.map +0 -1
- package/dist/core/web/public/next/assets/AutonomySection-CoMngwNB.js +0 -2
- package/dist/core/web/public/next/assets/BranchBar-C-NovaXr.js +0 -2
- package/dist/core/web/public/next/assets/BranchBar-C-NovaXr.js.map +0 -1
- package/dist/core/web/public/next/assets/BranchBar-C9BpPVLr.css +0 -1
- package/dist/core/web/public/next/assets/BudgetControl-P5lMxHvQ.js +0 -2
- package/dist/core/web/public/next/assets/BudgetControl-P5lMxHvQ.js.map +0 -1
- package/dist/core/web/public/next/assets/BurnDown-4P1LDoCL.js +0 -2
- package/dist/core/web/public/next/assets/BurnDown-4P1LDoCL.js.map +0 -1
- package/dist/core/web/public/next/assets/CapacityStrip-D6Yyg4a1.js +0 -2
- package/dist/core/web/public/next/assets/CapacityStrip-D6Yyg4a1.js.map +0 -1
- package/dist/core/web/public/next/assets/CapacityStrip-wgFP9MUA.css +0 -1
- package/dist/core/web/public/next/assets/ChatSection-B9cdRKUh.js +0 -3
- package/dist/core/web/public/next/assets/CommandSection-BC0uXim_.js +0 -2
- package/dist/core/web/public/next/assets/CommandSection-BC0uXim_.js.map +0 -1
- package/dist/core/web/public/next/assets/Composer-CkcwbQhG.css +0 -1
- package/dist/core/web/public/next/assets/Composer.module-DJMdrqNt.js +0 -2
- package/dist/core/web/public/next/assets/DiffPane-5uLKa0au.js +0 -2
- package/dist/core/web/public/next/assets/DiffPane-5uLKa0au.js.map +0 -1
- package/dist/core/web/public/next/assets/DiffPane-Csboxnn0.css +0 -1
- package/dist/core/web/public/next/assets/DockHost-BGnTgdIb.css +0 -1
- package/dist/core/web/public/next/assets/DockHost-CBV_6Ehi.js +0 -2
- package/dist/core/web/public/next/assets/DockHost-CBV_6Ehi.js.map +0 -1
- package/dist/core/web/public/next/assets/FleetSection-DuJcQCGg.js +0 -3
- package/dist/core/web/public/next/assets/FleetSection-DuJcQCGg.js.map +0 -1
- package/dist/core/web/public/next/assets/FleetSection-w9AjqfTR.css +0 -1
- package/dist/core/web/public/next/assets/Funnel-qX3Hlbce.js +0 -2
- package/dist/core/web/public/next/assets/Funnel-qX3Hlbce.js.map +0 -1
- package/dist/core/web/public/next/assets/GearTray-kVGP1coG.js +0 -2
- package/dist/core/web/public/next/assets/GearTray-kVGP1coG.js.map +0 -1
- package/dist/core/web/public/next/assets/GrowthSection-CYxJ9MH5.js +0 -2
- package/dist/core/web/public/next/assets/GrowthSection-CYxJ9MH5.js.map +0 -1
- package/dist/core/web/public/next/assets/HandoffDialog-DHZo3Ev0.js +0 -2
- package/dist/core/web/public/next/assets/HandoffDialog-DHZo3Ev0.js.map +0 -1
- package/dist/core/web/public/next/assets/MatrixHeatmap-B_JWCjZx.js +0 -2
- package/dist/core/web/public/next/assets/MatrixHeatmap-B_JWCjZx.js.map +0 -1
- package/dist/core/web/public/next/assets/McpSection-1UncWBpW.js +0 -2
- package/dist/core/web/public/next/assets/MessageMarkdown-C4pl9LI5.js +0 -3
- package/dist/core/web/public/next/assets/MessageMarkdown-Czcl3L_Q.css +0 -1
- package/dist/core/web/public/next/assets/MindSection-C3fCw_fD.js +0 -2
- package/dist/core/web/public/next/assets/MindSection-C3fCw_fD.js.map +0 -1
- package/dist/core/web/public/next/assets/MutationTokenDialog-Dn0tzCrh.js +0 -2
- package/dist/core/web/public/next/assets/MutationTokenDialog-Dn0tzCrh.js.map +0 -1
- package/dist/core/web/public/next/assets/NeedsYouDrawer-CuNYJCJ0.js +0 -2
- package/dist/core/web/public/next/assets/NeedsYouDrawer-CuNYJCJ0.js.map +0 -1
- package/dist/core/web/public/next/assets/NeedsYouDrawer-SkhvvdLb.css +0 -1
- package/dist/core/web/public/next/assets/NewChatDialog-B_BsS9pr.js +0 -3
- package/dist/core/web/public/next/assets/OnboardingFlow-CtCPpgoX.js +0 -2
- package/dist/core/web/public/next/assets/PreviewPane-Cx6RRwzM.js +0 -2
- package/dist/core/web/public/next/assets/PreviewPane-Cx6RRwzM.js.map +0 -1
- package/dist/core/web/public/next/assets/PreviewPane-WQJFjSXe.css +0 -1
- package/dist/core/web/public/next/assets/RailStatus-BWs6xevj.js +0 -2
- package/dist/core/web/public/next/assets/RailStatus-BWs6xevj.js.map +0 -1
- package/dist/core/web/public/next/assets/SeatSelector-DaUO-zoK.js +0 -3
- package/dist/core/web/public/next/assets/SessionSearch-B5aQ0BCM.js +0 -2
- package/dist/core/web/public/next/assets/SettingsSection-CuESA30a.js +0 -2
- package/dist/core/web/public/next/assets/SettingsSection-CuESA30a.js.map +0 -1
- package/dist/core/web/public/next/assets/Sidebar-DfD8MNZt.css +0 -1
- package/dist/core/web/public/next/assets/Sidebar-q11dtYZf.js +0 -3
- package/dist/core/web/public/next/assets/Sidebar-q11dtYZf.js.map +0 -1
- package/dist/core/web/public/next/assets/StepBand-B1W7rU70.js +0 -2
- package/dist/core/web/public/next/assets/StepBand-B1W7rU70.js.map +0 -1
- package/dist/core/web/public/next/assets/Swimlane-BR40WVcj.js +0 -2
- package/dist/core/web/public/next/assets/Swimlane-BR40WVcj.js.map +0 -1
- package/dist/core/web/public/next/assets/TerminalPane-CPKUTD9K.js +0 -7
- package/dist/core/web/public/next/assets/TerminalPane-CPKUTD9K.js.map +0 -1
- package/dist/core/web/public/next/assets/TerminalPane-CmE2QL-Q.css +0 -1
- package/dist/core/web/public/next/assets/UniverseConsoleApp-DKqAf-eD.js +0 -2
- package/dist/core/web/public/next/assets/UsageSection-B6fR3cru.js +0 -2
- package/dist/core/web/public/next/assets/UsageSection-B6fR3cru.js.map +0 -1
- package/dist/core/web/public/next/assets/UsageSection-DwgNOYvi.css +0 -1
- package/dist/core/web/public/next/assets/VerseConsoleApp-C0V221WL.css +0 -1
- package/dist/core/web/public/next/assets/VerseConsoleApp-bjARLPwN.js +0 -3
- package/dist/core/web/public/next/assets/VerseConsoleApp-bjARLPwN.js.map +0 -1
- package/dist/core/web/public/next/assets/Workspace-DQXMVDf7.css +0 -1
- package/dist/core/web/public/next/assets/Workspace-DtJb5tiM.js +0 -10
- package/dist/core/web/public/next/assets/Workspace-DtJb5tiM.js.map +0 -1
- package/dist/core/web/public/next/assets/actions-Bszsdpms.js +0 -2
- package/dist/core/web/public/next/assets/actions-Bszsdpms.js.map +0 -1
- package/dist/core/web/public/next/assets/actions-Dug8YIf0.css +0 -1
- package/dist/core/web/public/next/assets/capacity-strip-model-BR539Ci8.js +0 -2
- package/dist/core/web/public/next/assets/capacity-strip-model-BR539Ci8.js.map +0 -1
- package/dist/core/web/public/next/assets/charts-D4NaLaXA.js +0 -2
- package/dist/core/web/public/next/assets/charts-D4NaLaXA.js.map +0 -1
- package/dist/core/web/public/next/assets/colors-B-vHsX1S.js +0 -2
- package/dist/core/web/public/next/assets/colors-B-vHsX1S.js.map +0 -1
- package/dist/core/web/public/next/assets/command-catalog-s3W6Z96D.js +0 -2
- package/dist/core/web/public/next/assets/command-catalog-s3W6Z96D.js.map +0 -1
- package/dist/core/web/public/next/assets/context-model-Bto3LZn2.js +0 -2
- package/dist/core/web/public/next/assets/context-model-Bto3LZn2.js.map +0 -1
- package/dist/core/web/public/next/assets/context-queries-DVdSLrYy.js +0 -2
- package/dist/core/web/public/next/assets/context-queries-DVdSLrYy.js.map +0 -1
- package/dist/core/web/public/next/assets/context.module-B_k02HNU.js +0 -2
- package/dist/core/web/public/next/assets/context.module-B_k02HNU.js.map +0 -1
- package/dist/core/web/public/next/assets/dock-icons-oG8d7mNZ.js +0 -2
- package/dist/core/web/public/next/assets/dock-icons-oG8d7mNZ.js.map +0 -1
- package/dist/core/web/public/next/assets/dock-panes-BNTLvX7G.js +0 -2
- package/dist/core/web/public/next/assets/fleet-model-ClBbQ0Uj.js +0 -2
- package/dist/core/web/public/next/assets/fleet-model-ClBbQ0Uj.js.map +0 -1
- package/dist/core/web/public/next/assets/format-BNYWGJat.js +0 -2
- package/dist/core/web/public/next/assets/format-BNYWGJat.js.map +0 -1
- package/dist/core/web/public/next/assets/global-DVgMguLr.js +0 -2
- package/dist/core/web/public/next/assets/global-DVgMguLr.js.map +0 -1
- package/dist/core/web/public/next/assets/live-model-Dm6ITHvX.js +0 -2
- package/dist/core/web/public/next/assets/live-model-Dm6ITHvX.js.map +0 -1
- package/dist/core/web/public/next/assets/mind-B-lYfSUJ.css +0 -1
- package/dist/core/web/public/next/assets/mind.module-BzhAlg3e.js +0 -2
- package/dist/core/web/public/next/assets/mind.module-BzhAlg3e.js.map +0 -1
- package/dist/core/web/public/next/assets/mutations-C6E10SPX.js +0 -2
- package/dist/core/web/public/next/assets/primitives-DQvYikjm.js +0 -1
- package/dist/core/web/public/next/assets/seat-subscription-CrWOV4Qc.js +0 -2
- package/dist/core/web/public/next/assets/seat-subscription-CrWOV4Qc.js.map +0 -1
- package/dist/core/web/public/next/assets/slots-W8gkmdfE.js +0 -3
- package/dist/core/web/public/next/assets/surface-data-ZtCegYMQ.js +0 -2
- package/dist/core/web/public/next/assets/surface-data-ZtCegYMQ.js.map +0 -1
- package/dist/core/web/public/next/assets/tasks-model-CnYQzgxk.js +0 -2
- package/dist/core/web/public/next/assets/types-Dypu22dp.js +0 -3
- package/dist/core/web/public/next/assets/types-Dypu22dp.js.map +0 -1
- package/dist/core/web/public/next/assets/use-guarded-action-CO_aAsed.js +0 -2
- package/dist/core/web/public/next/assets/use-guarded-action-CO_aAsed.js.map +0 -1
- package/dist/core/web/public/next/assets/use-token-gate-DYA2-ALC.js +0 -2
- package/dist/core/web/public/next/assets/use-token-gate-DYA2-ALC.js.map +0 -1
- package/dist/core/web/public/next/assets/useChartWidth-B8E5mJgM.css +0 -1
- package/dist/core/web/public/next/assets/useChartWidth-MEXvDxDL.js +0 -2
- package/dist/core/web/public/next/assets/useChartWidth-MEXvDxDL.js.map +0 -1
- package/dist/core/web/public/next/assets/verse-model-E98kXngO.js +0 -2
- package/dist/core/web/public/next/assets/verse-model-E98kXngO.js.map +0 -1
- package/dist/core/web/public/next/assets/verse-store-BgKx_YGs.js +0 -2
- package/dist/core/web/public/next/assets/verse-store-BgKx_YGs.js.map +0 -1
- package/dist/core/web/public/next/assets/verse-ui-store-KTTKfv-T.js +0 -3
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useChartWidth-MEXvDxDL.js","names":[],"sources":["../../../../../../src/web-ui/components/charts/chart-tokens.css","../../../../../../src/web-ui/components/charts/format.ts","../../../../../../src/web-ui/components/charts/TableView.module.css","../../../../../../src/web-ui/components/charts/TableView.tsx","../../../../../../src/web-ui/components/charts/plot.module.css","../../../../../../src/web-ui/components/charts/ChartParts.tsx","../../../../../../src/web-ui/components/charts/ChartFrame.module.css","../../../../../../src/web-ui/components/charts/ChartFrame.tsx","../../../../../../src/web-ui/components/charts/chart-math.ts","../../../../../../src/web-ui/components/charts/useChartWidth.ts"],"sourcesContent":["/**\n * components/charts/chart-tokens.css — chart-only aliases over the design\n * tokens (owner: unit C0, with colors.ts; the chart components are C7's).\n * Every value below is `var(--existing-token)`, never a hex: the raw values\n * and their light/dark variants live in design/tokens.css, so theming is\n * inherited and can never drift out of sync with the rest of the app.\n *\n * V3.10 COLOUR ROLES (SPEC-310C §6), one meaning per hue:\n *\n * QUANTITY — `--chart-seq-1..7`, the fixed azure ramp at 214°\n * (tokens.css --data-seq-*). Every magnitude — heat cells, a single\n * nominal series, gauge fills, the positive diverging pole — is azure.\n * It is NEVER the accent: the accent is interaction-only and the\n * operator can drag it to any hue, which used to re-colour every chart\n * (tokens-310.test.ts fails if a data token here points at --accent-*).\n *\n * CATEGORICAL — `--chart-series-1..6` (tokens.css --data-cat-*). Six\n * identity inks chosen to avoid every engine, status and quantity hue,\n * with the validator scores recorded in tokens.css. Order is identity,\n * never rank: a series keeps its slot even when others are filtered out.\n * A seventh series goes to `--chart-neutral` (\"Other\") — colors.ts never\n * cycles, because a repeated colour would say two series are one.\n *\n * UNKNOWN — gray, drawn as a 45° HATCH with an outline, never a solid\n * fill on a data ramp (a solid gray would read as \"zero\" or \"neutral\").\n * `--chart-unknown-hatch` for CSS fills; colors.ts UNKNOWN_HATCH for SVG.\n *\n * QUEUED / PARKED — a neutral OUTLINE with no fill (Fleet Gantt, Swimlane).\n *\n * ENGINES — identity only, and only in charts that show nothing else\n * (runs by engine, usage bars); passed explicitly via colors.ts\n * engineColor(), never picked by index.\n *\n * STATUS — unchanged; always travels with a text label.\n *\n * Mandatory secondary encoding (direct or legend labels, and the TableView\n * twin every chart has) stays in place whatever the palette scores — colour\n * is never the only carrier of meaning.\n */\n:root {\n /* Categorical identity (fixed order; see tokens.css for the derivation). */\n --chart-series-1: var(--data-cat-1); /* steel */\n --chart-series-2: var(--data-cat-2); /* olive */\n --chart-series-3: var(--data-cat-3); /* wine */\n --chart-series-4: var(--data-cat-4); /* purple */\n --chart-series-5: var(--data-cat-5); /* green */\n --chart-series-6: var(--data-cat-6); /* pink */\n\n /* Overflow \"Other\" bucket — never part of the identity rotation above. */\n --chart-neutral: var(--status-neutral-solid);\n\n /* Quantity: the fixed azure ramp, low → high. */\n --chart-seq-1: var(--data-seq-1);\n --chart-seq-2: var(--data-seq-2);\n --chart-seq-3: var(--data-seq-3);\n --chart-seq-4: var(--data-seq-4);\n --chart-seq-5: var(--data-seq-5);\n --chart-seq-6: var(--data-seq-6);\n --chart-seq-7: var(--data-seq-7);\n\n /* The single hue for magnitude and for one nominal series (one series\n needs no legend box — it takes this colour and a direct label). */\n --chart-sequential: var(--chart-seq-5);\n --chart-sequential-soft: var(--chart-seq-3);\n\n /* Diverging pair around a neutral midpoint: azure reads \"up / better\",\n danger reads \"down / worse\" (ForestPlot effect sizes, deltas). */\n --chart-diverging-pos: var(--chart-seq-5);\n --chart-diverging-neg: var(--status-danger-solid);\n --chart-diverging-mid: var(--border-strong);\n\n /* Unknown: gray, hatched at 45°, outlined. */\n --chart-unknown: var(--status-unknown-solid);\n --chart-unknown-hatch: repeating-linear-gradient(135deg, var(--chart-unknown) 0 1px, transparent 1px 5px);\n\n /* Queued / parked: an outline, no fill. */\n --chart-queued-outline: var(--status-neutral-solid);\n\n /* Chart chrome — hairline grid/axis, one step off the surface. */\n --chart-grid: var(--border-subtle);\n --chart-axis: var(--border-strong);\n --chart-surface: var(--bg-surface);\n --chart-tooltip-bg: var(--bg-surface-raised);\n --chart-tooltip-border: var(--border-default);\n\n /* Heat (CalendarHeatmap, MatrixHeatmap): four steps of the quantity ramp.\n Step 0 is a TRUE ZERO; \"no data\" is the unknown hatch or an outlined\n empty cell, never a colour on this ramp. */\n --chart-heat-0: var(--chart-grid);\n --chart-heat-1: var(--chart-seq-2);\n --chart-heat-2: var(--chart-seq-3);\n --chart-heat-3: var(--chart-seq-5);\n --chart-heat-4: var(--chart-seq-7);\n\n /* Gauge/meter track: the lightest step of the fill's own ramp. */\n --chart-track: var(--chart-seq-1);\n}\n","/**\n * components/charts/format.ts — number formatting shared by every chart and\n * stat tile. Proportional figures everywhere EXCEPT columns that must align\n * vertically (table cells, axis ticks) — see marks-and-anatomy.md \"Proportional\n * figures for big numbers; tabular only in columns.\" Callers apply\n * `font-variant-numeric: tabular-nums` via CSS where that applies; these\n * functions only produce the string.\n */\n\n/** Auto-compact a count: 1,284 / 12.9K / 4.2M. */\nexport function formatCompact(n: number): string {\n if (!Number.isFinite(n)) return '—';\n const abs = Math.abs(n);\n if (abs >= 1_000_000) return `${(n / 1_000_000).toFixed(abs >= 10_000_000 ? 0 : 1)}M`;\n if (abs >= 10_000) return `${Math.round(n / 1000)}K`;\n if (abs >= 1_000) return n.toLocaleString('en-US');\n return Number.isInteger(n) ? String(n) : n.toFixed(1);\n}\n\n/** Auto-compact USD: $4.20 / $1.2K / $4.2M. */\nexport function formatUsd(n: number): string {\n if (!Number.isFinite(n)) return '—';\n const abs = Math.abs(n);\n const sign = n < 0 ? '-' : '';\n if (abs >= 1_000_000) return `${sign}$${(abs / 1_000_000).toFixed(1)}M`;\n if (abs >= 1_000) return `${sign}$${(abs / 1_000).toFixed(1)}K`;\n return `${sign}$${abs.toFixed(2)}`;\n}\n\n/** Fraction (0..1) as a percentage. */\nexport function formatPercent(fraction: number, digits = 0): string {\n if (!Number.isFinite(fraction)) return '—';\n return `${(fraction * 100).toFixed(digits)}%`;\n}\n\n/** Signed delta for a stat tile: \"+12\" / \"-3\" / \"0\". */\nexport function formatSignedCompact(n: number): string {\n if (!Number.isFinite(n)) return '—';\n const s = formatCompact(Math.abs(n));\n if (n > 0) return `+${s}`;\n if (n < 0) return `-${s}`;\n return s;\n}\n\n/** YYYY-MM-DD -> short label, e.g. \"Aug 14\". Local-independent (UTC parse). */\nexport function formatDayLabel(day: string): string {\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(day)) return day;\n const d = new Date(`${day}T00:00:00Z`);\n // Date normalizes impossible dates; compare the padded UTC date to reject rollover.\n if (Number.isNaN(d.getTime()) || d.toISOString().slice(0, 10) !== day) return day;\n return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric', timeZone: 'UTC' });\n}\n\n/** Epoch ms -> short label for axis ticks. */\nexport function formatTimeLabel(ms: number): string {\n const d = new Date(ms);\n if (Number.isNaN(d.getTime())) return '';\n return d.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });\n}\n",".table {\n width: 100%;\n border-collapse: collapse;\n font-size: var(--text-xs-size);\n}\n\n.table th,\n.table td {\n text-align: left;\n padding: var(--space-1) var(--space-2);\n border-bottom: 1px solid var(--border-subtle);\n}\n\n.table th {\n color: var(--text-tertiary);\n font-weight: var(--font-weight-medium);\n text-transform: uppercase;\n letter-spacing: 0.04em;\n font-size: var(--text-xs-size);\n}\n\n.numeric {\n text-align: right;\n font-variant-numeric: tabular-nums;\n}\n\n.empty {\n color: var(--text-tertiary);\n text-align: center;\n}\n","/**\n * components/charts/TableView.tsx — the WCAG-clean accessibility twin every\n * chart should ship (dataviz skill: \"no table view / color-only encoding on\n * a continuous scale\" is an anti-pattern). Every value a chart's tooltip or\n * direct label shows must also be reachable here without hovering anything.\n */\nimport type { ReactNode } from 'react';\nimport styles from './TableView.module.css';\n\nexport interface TableColumn<T> {\n key: string;\n label: string;\n numeric?: boolean;\n render: (row: T) => ReactNode;\n}\n\nexport function TableView<T>({\n caption,\n columns,\n rows,\n rowKey,\n emptyMessage = 'No rows.',\n}: {\n caption: string;\n columns: TableColumn<T>[];\n rows: T[];\n rowKey: (row: T, index: number) => string;\n /** Shown as a single full-width row when `rows` is empty (V3.10). */\n emptyMessage?: string;\n}) {\n return (\n <table className={styles.table}>\n <caption className=\"visually-hidden\">{caption}</caption>\n <thead>\n <tr>\n {columns.map((c) => (\n <th key={c.key} scope=\"col\" className={c.numeric ? styles.numeric : undefined}>\n {c.label}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {rows.length === 0 ? (\n <tr>\n <td colSpan={Math.max(1, columns.length)} className={styles.empty}>\n {emptyMessage}\n </td>\n </tr>\n ) : null}\n {rows.map((row, i) => (\n <tr key={rowKey(row, i)}>\n {columns.map((c) => (\n <td key={c.key} className={c.numeric ? styles.numeric : undefined}>\n {c.render(row)}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n );\n}\n","/* Shared plot chrome for the V3.10 charts: recessive hairline grid/axes,\n text in text tokens (never the series colour), one tooltip style. */\n.plotWrap {\n position: relative;\n width: 100%;\n min-width: 0;\n}\n\n.svg {\n display: block;\n overflow: visible;\n max-width: 100%;\n}\n\n.grid {\n stroke: var(--chart-grid);\n stroke-width: 1;\n shape-rendering: crispEdges;\n}\n\n.axis {\n stroke: var(--chart-axis);\n stroke-width: 1;\n shape-rendering: crispEdges;\n}\n\n.tick {\n font-family: var(--font-ui);\n font-size: var(--text-xs-size);\n fill: var(--text-tertiary);\n font-variant-numeric: tabular-nums;\n}\n\n.label {\n font-family: var(--font-ui);\n font-size: var(--text-xs-size);\n fill: var(--text-secondary);\n}\n\n.labelStrong {\n font-family: var(--font-ui);\n font-size: var(--text-xs-size);\n font-weight: var(--font-weight-medium);\n fill: var(--text-primary);\n}\n\n.line {\n fill: none;\n stroke-width: 2;\n stroke-linecap: round;\n stroke-linejoin: round;\n}\n\n.wash {\n stroke: none;\n opacity: 0.1;\n}\n\n.reference {\n fill: none;\n stroke: var(--text-tertiary);\n stroke-width: 1;\n stroke-dasharray: 4 3;\n}\n\n.projection {\n fill: none;\n stroke-width: 2;\n stroke-dasharray: 5 4;\n stroke-linecap: round;\n}\n\n.marker {\n stroke: var(--chart-surface);\n stroke-width: 2;\n}\n\n.crosshair {\n stroke: var(--chart-axis);\n stroke-width: 1;\n pointer-events: none;\n}\n\n.hit {\n fill: transparent;\n cursor: default;\n}\n\n.hit:focus {\n outline: none;\n}\n\n.hit:focus-visible {\n stroke: var(--border-focus);\n stroke-width: 2;\n}\n\n.focusable:focus {\n outline: none;\n}\n\n.focusable:focus-visible {\n outline: 2px solid var(--border-focus);\n outline-offset: 2px;\n border-radius: var(--radius-sm);\n}\n\n.track {\n fill: var(--chart-track);\n}\n\n.noData {\n fill: none;\n stroke: var(--chart-grid);\n stroke-width: 1;\n stroke-dasharray: 2 2;\n}\n\n.tooltip {\n position: absolute;\n z-index: var(--z-dropdown);\n pointer-events: none;\n transform: translate(-50%, calc(-100% - 8px));\n padding: var(--space-2);\n border: 1px solid var(--chart-tooltip-border);\n border-radius: var(--radius-sm);\n background: var(--chart-tooltip-bg);\n box-shadow: var(--shadow-md);\n color: var(--text-primary);\n font-size: var(--text-xs-size);\n white-space: nowrap;\n}\n\n.tooltipTitle {\n color: var(--text-tertiary);\n margin-bottom: var(--space-1);\n}\n\n.tooltipRow {\n display: flex;\n align-items: center;\n gap: var(--space-2);\n}\n\n.tooltipKey {\n width: 8px;\n height: 8px;\n border-radius: 2px;\n flex: none;\n}\n\n.tooltipValue {\n margin-left: auto;\n padding-left: var(--space-3);\n font-weight: var(--font-weight-semibold);\n font-variant-numeric: tabular-nums;\n}\n\n.tooltipMuted {\n color: var(--text-tertiary);\n font-style: italic;\n}\n\n.legend {\n display: flex;\n flex-wrap: wrap;\n gap: var(--space-1) var(--space-3);\n margin: var(--space-2) 0 0;\n padding: 0;\n list-style: none;\n font-size: var(--text-xs-size);\n color: var(--text-secondary);\n}\n\n.legendItem {\n display: inline-flex;\n align-items: center;\n gap: var(--space-1);\n}\n\n.swatch {\n width: 10px;\n height: 10px;\n border-radius: 2px;\n flex: none;\n}\n\n.swatchLine {\n width: 12px;\n height: 2px;\n flex: none;\n}\n\n.swatchEmpty {\n width: 10px;\n height: 10px;\n border-radius: 2px;\n flex: none;\n border: 1px dashed var(--chart-axis);\n}\n\n.note {\n margin: var(--space-2) 0 0;\n font-size: var(--text-xs-size);\n color: var(--text-tertiary);\n}\n\n.srOnly {\n position: absolute;\n width: 1px;\n height: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border: 0;\n}\n\n@media (prefers-reduced-motion: no-preference) {\n .animated {\n transition: opacity 120ms ease;\n }\n}\n\n/* V3.10 — engine monogram beside a lane label (EngineTick). */\n.monogram {\n font-family: var(--font-display);\n font-size: var(--text-2xs-size);\n font-weight: var(--font-weight-semibold);\n fill: var(--text-secondary);\n}\n\n/* V3.10 — an unknown mark: hatch fill (set inline via url(#id)) + outline. */\n.unknownMark {\n stroke: var(--chart-unknown);\n stroke-width: 1;\n}\n\n/* A swatch in a legend that stands for \"unknown / not measured\". */\n.swatchHatch {\n width: 10px;\n height: 10px;\n border-radius: 2px;\n flex: none;\n border: 1px solid var(--chart-unknown);\n background: var(--chart-unknown-hatch);\n}\n\n/* Text laid over the plot (reference labels): a surface-coloured halo keeps it\n legible where it crosses a line, in both themes. */\n.halo {\n paint-order: stroke;\n stroke: var(--chart-surface);\n stroke-width: 3px;\n stroke-linejoin: round;\n}\n","/**\n * components/charts/ChartParts.tsx — small shared pieces of the V3.10 charts:\n * the legend list, the tooltip, the unknown hatch and the engine tick.\n * Identity is never colour alone: every swatch sits beside its text label,\n * and text always wears text tokens.\n */\nimport type { ReactNode } from 'react';\nimport { UNKNOWN_HATCH, engineColor, type ChartEngine } from './colors.js';\nimport plot from './plot.module.css';\n\nexport interface ChartLegendItem {\n label: string;\n color?: string;\n /** `hatch` = the unknown texture (not measured), never a colour. */\n kind?: 'swatch' | 'line' | 'empty' | 'hatch';\n}\n\n/** Renders nothing for fewer than `min` items (a lone series is named by the title). */\nexport function ChartLegend({ items, min = 2 }: { items: ChartLegendItem[]; min?: number }): ReactNode {\n if (items.length < min) return null;\n return (\n <ul className={plot.legend}>\n {items.map((item) => (\n <li key={item.label} className={plot.legendItem}>\n <span\n aria-hidden=\"true\"\n className={\n item.kind === 'line' ? plot.swatchLine : item.kind === 'empty' ? plot.swatchEmpty : item.kind === 'hatch' ? plot.swatchHatch : plot.swatch\n }\n style={item.kind === 'empty' || item.kind === 'hatch' ? undefined : { background: item.color }}\n />\n {item.label}\n </li>\n ))}\n </ul>\n );\n}\n\nexport interface TooltipRow {\n key: string;\n label: string;\n value: string | null;\n color?: string;\n}\n\n/**\n * Positioned in the plot's own pixel space (the plot wrapper is\n * position:relative). `left` is clamped by the caller so it never overflows.\n */\nexport function ChartTooltip({ left, top, title, rows }: { left: number; top: number; title: string; rows: TooltipRow[] }) {\n return (\n <div className={plot.tooltip} style={{ left, top }} role=\"presentation\">\n <div className={plot.tooltipTitle}>{title}</div>\n {rows.map((row) => (\n <div key={row.key} className={plot.tooltipRow}>\n {row.color ? <span className={plot.tooltipKey} style={{ background: row.color }} aria-hidden=\"true\" /> : null}\n <span>{row.label}</span>\n {row.value === null ? (\n <span className={`${plot.tooltipValue} ${plot.tooltipMuted}`}>no data</span>\n ) : (\n <span className={plot.tooltipValue}>{row.value}</span>\n )}\n </div>\n ))}\n </div>\n );\n}\n\n/** Keep a centred tooltip inside [margin, width - margin]. */\nexport function clampTooltipLeft(x: number, width: number, margin = 70): number {\n return Math.min(Math.max(x, Math.min(margin, width / 2)), Math.max(width - margin, width / 2));\n}\n\n// ---------------------------------------------------------------------------\n// Unknown hatch (V3.10) — one <pattern> per chart instance\n// ---------------------------------------------------------------------------\n\n/**\n * The 45° unknown hatch as an SVG <pattern>. Render it inside the chart's own\n * <svg><defs> with an id from `hatchPatternId(useId())` (colors.ts) — ids are\n * document-global, so a shared literal id would let one chart's unmount blank\n * another's hatch — then fill unknown marks with `url(#id)` and outline them\n * with CHART_UNKNOWN. Texture, not hue, is what separates \"not measured\" from\n * a low value, so it survives colour-blindness and greyscale print.\n */\nexport function HatchPattern({ id }: { id: string }) {\n const { size, angle, strokeWidth, stroke } = UNKNOWN_HATCH;\n return (\n <pattern id={id} width={size} height={size} patternUnits=\"userSpaceOnUse\" patternTransform={`rotate(${angle})`}>\n <line x1={0} y1={0} x2={0} y2={size} stroke={stroke} strokeWidth={strokeWidth} />\n </pattern>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Engine identity (V3.10) — a 2px tick plus a one-letter monogram\n// ---------------------------------------------------------------------------\n\nconst ENGINE_LETTER: Readonly<Record<ChartEngine, string>> = { claude: 'C', codex: 'X', grok: 'G', local: 'L' };\n\n/** The monogram letter for an engine (mirrors workbench-types ENGINE_MONOGRAM; charts stay core-free). */\nexport function engineLetter(engine: ChartEngine): string {\n return ENGINE_LETTER[engine];\n}\n\n/**\n * SVG engine mark for a lane label: the 2px identity tick and the monogram.\n * Never a vendor logo (SPEC-310C §6). The engine's NAME still travels in the\n * lane's spoken summary and the table — the letter is a glance aid only.\n */\nexport function EngineTick({ engine, x, y, height }: { engine: ChartEngine; x: number; y: number; height: number }) {\n return (\n <g data-engine={engine} aria-hidden=\"true\">\n <rect x={x} y={y} width={2} height={height} rx={1} fill={engineColor(engine)} />\n <text className={plot.monogram} x={x + 6} y={y + height / 2} dy=\"0.34em\">\n {ENGINE_LETTER[engine]}\n </text>\n </g>\n );\n}\n\n/** A quiet ⋯ glyph (three dots), currentColor, 16px. */\nexport function MoreGlyph() {\n return (\n <svg width={16} height={16} viewBox=\"0 0 16 16\" aria-hidden=\"true\" focusable=\"false\">\n <circle cx={3.5} cy={8} r={1.4} fill=\"currentColor\" />\n <circle cx={8} cy={8} r={1.4} fill=\"currentColor\" />\n <circle cx={12.5} cy={8} r={1.4} fill=\"currentColor\" />\n </svg>\n );\n}\n",".frame {\n margin: 0;\n min-width: 0;\n border: 1px solid var(--border-subtle);\n border-radius: var(--radius-lg);\n background: var(--bg-surface);\n /* V3.10: 16px (12px compact density) — the card-pad token follows density. */\n padding: var(--card-pad, var(--space-4));\n}\n\n.header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: var(--space-3);\n flex-wrap: wrap;\n margin-bottom: var(--space-3);\n}\n\n.actions {\n display: inline-flex;\n align-items: center;\n gap: var(--space-2);\n flex: none;\n margin-left: auto;\n}\n\n.menuWrap {\n position: relative;\n display: inline-flex;\n}\n\n/* The ⋯ button: quiet until hovered or focused, but always a real control. */\n.more {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: calc(var(--control-h-xs, 20px) + 4px);\n height: calc(var(--control-h-xs, 20px) + 4px);\n padding: 0;\n border: 1px solid transparent;\n border-radius: var(--radius-sm);\n background: transparent;\n color: var(--text-tertiary);\n cursor: pointer;\n transition: background-color var(--duration-fast) var(--ease-standard), color var(--duration-fast) var(--ease-standard);\n}\n\n.more:hover,\n.more[aria-expanded='true'] {\n background: var(--bg-hover);\n color: var(--text-primary);\n}\n\n.more:focus-visible {\n outline: 2px solid var(--border-focus);\n outline-offset: 1px;\n}\n\n.menu {\n position: absolute;\n top: calc(100% + var(--space-1));\n right: 0;\n z-index: var(--z-dropdown);\n display: flex;\n flex-direction: column;\n min-width: 176px;\n padding: var(--space-1);\n border: 1px solid var(--border-default);\n border-radius: var(--radius-md);\n background: var(--bg-surface-raised);\n box-shadow: var(--shadow-menu);\n}\n\n.menuItem {\n display: flex;\n align-items: center;\n gap: var(--space-2);\n padding: var(--space-1) var(--space-2);\n border: 0;\n border-radius: var(--radius-sm);\n background: transparent;\n color: var(--text-primary);\n font: inherit;\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n text-align: left;\n cursor: pointer;\n}\n\n.menuItem:hover,\n.menuItem:focus-visible {\n background: var(--bg-hover);\n outline: none;\n}\n\n.check {\n width: 1em;\n color: var(--text-secondary);\n}\n\n.hint {\n margin-left: auto;\n padding: 0 var(--space-1);\n border: 1px solid var(--border-subtle);\n border-radius: var(--radius-xs, 3px);\n color: var(--text-tertiary);\n font-family: var(--font-mono);\n font-size: var(--text-2xs-size);\n}\n\n.heading {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.title {\n font-size: var(--text-sm-size);\n font-weight: var(--font-weight-semibold);\n color: var(--text-primary);\n}\n\n.description {\n font-size: var(--text-xs-size);\n color: var(--text-tertiary);\n}\n\n.plot {\n position: relative;\n width: 100%;\n min-width: 0;\n}\n\n.table {\n max-height: 360px;\n overflow: auto;\n}\n\n.caveat {\n margin: 0 0 var(--space-3);\n padding: var(--space-2) var(--space-3);\n border-radius: var(--radius-md);\n background: var(--status-unknown-bg);\n color: var(--status-unknown-fg);\n font-size: var(--text-xs-size);\n line-height: var(--text-sm-line);\n}\n\n.state {\n margin: 0;\n padding: var(--space-6) var(--space-3);\n text-align: center;\n color: var(--text-tertiary);\n font-size: var(--text-sm-size);\n}\n\n.dark {\n display: flex;\n flex-direction: column;\n gap: var(--space-1);\n align-items: center;\n}\n\n.darkTitle {\n margin: 0;\n color: var(--text-secondary);\n font-weight: var(--font-weight-semibold);\n}\n\n.darkBody {\n margin: 0;\n font-size: var(--text-xs-size);\n max-width: 44ch;\n}\n\n.unknown {\n color: var(--status-unknown-fg);\n}\n","/**\n * components/charts/ChartFrame.tsx — the shell every V3.10 chart renders in:\n * title + description, an honest caveat, the Table twin (the WCAG-clean view,\n * reachable without hovering anything), and the designed non-ready states. A\n * chart never draws empty axes: it says what the emptiness means.\n *\n * loading — the previous render is held when there is one (no skeleton\n * flash on refetch); otherwise a quiet placeholder.\n * empty — \"No runs in this window.\" A genuine, known zero.\n * dark — \"Fleet dark since Sep 1\": nothing has happened since a date.\n * unknown — the source could not be read. Never drawn as zeros.\n *\n * V3.10 (SPEC-310C §6 \"Table toggle: moves into ⋯\"): the Chart | Table\n * segmented control used to sit beside every title — noise on a KPI-sized\n * card, and it wrapped against long titles (\"Memo hit rate\"). It is now a\n * quiet ⋯ menu button (still a real, labelled button: the table stays one\n * Tab + Enter away) plus the `T` key anywhere inside the card, which is the\n * `chart.table` command in routes/verse/shell/command-catalog.ts. The key is\n * matched here directly rather than through the catalog so this shared kit\n * (also used by the legacy console) never imports a route module; the chart\n * tests assert the two stay the same key.\n */\nimport { useCallback, useEffect, useId, useRef, useState, type KeyboardEvent, type ReactNode } from 'react';\nimport { MoreGlyph } from './ChartParts.js';\nimport { formatDayLabel } from './format.js';\nimport './chart-tokens.css';\nimport styles from './ChartFrame.module.css';\n\nexport type ChartStatus =\n | { kind: 'ready' }\n | { kind: 'loading' }\n | { kind: 'empty'; message?: string }\n | { kind: 'dark'; since: string; subject?: string; detail?: string }\n | { kind: 'unknown'; reason?: string };\n\nexport type ChartView = 'chart' | 'table';\n\n/** The key that flips a focused chart card between plot and table (catalog `chart.table`). */\nexport const CHART_TABLE_KEY = 't';\n\nexport interface ChartFrameProps {\n title: string;\n description?: string;\n caveat?: string;\n status?: ChartStatus;\n /** Start on the table (e.g. a screen-reader-first surface, or a matrix at 375 px). */\n defaultView?: ChartView;\n /** Hide the view menu (only for a chart that already IS its numbers). */\n hideToggle?: boolean;\n /** Extra header controls (a facet picker), rendered before the ⋯ menu. */\n actions?: ReactNode;\n /** The plot. */\n children: ReactNode;\n table: ReactNode;\n /** Rendered under the plot in chart view (legends, notes). */\n footer?: ReactNode;\n}\n\n/** \"Sep 1\" from an ISO timestamp or YYYY-MM-DD (UTC day, like the axis labels). */\nexport function sinceLabel(since: string): string {\n return formatDayLabel(since.slice(0, 10));\n}\n\nfunction StatusMessage({ status }: { status: Exclude<ChartStatus, { kind: 'ready' }> }): ReactNode {\n switch (status.kind) {\n case 'loading':\n return <p className={styles.state} aria-busy=\"true\">Loading…</p>;\n case 'empty':\n return <p className={styles.state}>{status.message ?? 'Nothing happened in this window.'}</p>;\n case 'dark':\n return (\n <div className={`${styles.state} ${styles.dark}`}>\n <p className={styles.darkTitle}>\n {status.subject ?? 'Fleet'} dark since {sinceLabel(status.since)}\n </p>\n <p className={styles.darkBody}>{status.detail ?? 'No runs or proposals have been recorded since then.'}</p>\n </div>\n );\n case 'unknown':\n return (\n <p className={`${styles.state} ${styles.unknown}`} role=\"note\">\n Unknown — {status.reason ?? 'the data source could not be read.'} Nothing is shown rather than a guess.\n </p>\n );\n }\n}\n\n/** True when a key press is typing into a field — never steal it for the T shortcut. */\nfunction isEditableTarget(target: EventTarget | null): boolean {\n if (!(target instanceof HTMLElement)) return false;\n const tag = target.tagName;\n return tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT' || target.isContentEditable;\n}\n\nconst VIEW_ITEMS: ReadonlyArray<{ view: ChartView; label: string; hint: string | null }> = [\n { view: 'chart', label: 'Show as chart', hint: null },\n { view: 'table', label: 'Show as table', hint: 'T' },\n];\n\n/**\n * The ⋯ menu: a menu button (WAI-ARIA menu-button pattern) with two\n * menuitemradio entries. Arrow keys move, Enter / Space pick, Escape and Tab\n * close; focus returns to the button on every close so the keyboard user is\n * never dropped at the top of the document.\n */\nfunction ViewMenu({ title, view, onPick }: { title: string; view: ChartView; onPick: (view: ChartView) => void }) {\n const [open, setOpen] = useState(false);\n const [active, setActive] = useState(0);\n const buttonRef = useRef<HTMLButtonElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n const menuId = useId();\n\n const close = useCallback((refocus: boolean) => {\n setOpen(false);\n if (refocus) buttonRef.current?.focus();\n }, []);\n\n useEffect(() => {\n if (!open) return undefined;\n const onDown = (e: PointerEvent): void => {\n const t = e.target as Node | null;\n if (t && (menuRef.current?.contains(t) || buttonRef.current?.contains(t))) return;\n setOpen(false);\n };\n document.addEventListener('pointerdown', onDown);\n return () => document.removeEventListener('pointerdown', onDown);\n }, [open]);\n\n useEffect(() => {\n if (!open) return;\n menuRef.current?.querySelectorAll<HTMLElement>('[role=\"menuitemradio\"]')[active]?.focus();\n }, [open, active]);\n\n function openAt(index: number): void {\n setActive(index);\n setOpen(true);\n }\n\n function onButtonKey(e: KeyboardEvent<HTMLButtonElement>): void {\n if (e.key === 'ArrowDown' || e.key === 'ArrowUp') {\n e.preventDefault();\n openAt(e.key === 'ArrowUp' ? VIEW_ITEMS.length - 1 : 0);\n }\n }\n\n function onMenuKey(e: KeyboardEvent<HTMLDivElement>): void {\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n setActive((a) => (a + 1) % VIEW_ITEMS.length);\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n setActive((a) => (a - 1 + VIEW_ITEMS.length) % VIEW_ITEMS.length);\n } else if (e.key === 'Home') {\n e.preventDefault();\n setActive(0);\n } else if (e.key === 'End') {\n e.preventDefault();\n setActive(VIEW_ITEMS.length - 1);\n } else if (e.key === 'Escape') {\n e.preventDefault();\n e.stopPropagation();\n close(true);\n } else if (e.key === 'Tab') {\n close(false);\n }\n }\n\n return (\n <span className={styles.menuWrap}>\n <button\n ref={buttonRef}\n type=\"button\"\n className={styles.more}\n aria-label={`${title}: view options`}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-controls={open ? menuId : undefined}\n title=\"View options (T toggles the table)\"\n onClick={() => (open ? close(false) : openAt(Math.max(0, VIEW_ITEMS.findIndex((i) => i.view === view))))}\n onKeyDown={onButtonKey}\n >\n <MoreGlyph />\n </button>\n {open ? (\n <div ref={menuRef} id={menuId} role=\"menu\" aria-label={`${title} view`} className={styles.menu} onKeyDown={onMenuKey}>\n {VIEW_ITEMS.map((item, i) => (\n <button\n key={item.view}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={view === item.view}\n tabIndex={i === active ? 0 : -1}\n className={styles.menuItem}\n onClick={() => {\n onPick(item.view);\n close(true);\n }}\n >\n <span className={styles.check} aria-hidden=\"true\">{view === item.view ? '✓' : ''}</span>\n <span>{item.label}</span>\n {item.hint ? <kbd className={styles.hint}>{item.hint}</kbd> : null}\n </button>\n ))}\n </div>\n ) : null}\n </span>\n );\n}\n\nexport function ChartFrame({\n title,\n description,\n caveat,\n status = { kind: 'ready' },\n defaultView = 'chart',\n hideToggle = false,\n actions,\n children,\n table,\n footer,\n}: ChartFrameProps) {\n const [view, setView] = useState<ChartView>(defaultView);\n const titleId = useId();\n const ready = status.kind === 'ready';\n const canToggle = ready && !hideToggle;\n\n function onKeyDown(e: KeyboardEvent<HTMLElement>): void {\n if (!canToggle || e.defaultPrevented) return;\n if (e.metaKey || e.ctrlKey || e.altKey || e.shiftKey) return;\n if (e.key.toLowerCase() !== CHART_TABLE_KEY || isEditableTarget(e.target)) return;\n e.preventDefault();\n setView((v) => (v === 'chart' ? 'table' : 'chart'));\n }\n\n return (\n <figure className={styles.frame} aria-labelledby={titleId} data-chart-card=\"\" data-view={view} onKeyDown={onKeyDown}>\n <figcaption className={styles.header}>\n <span className={styles.heading}>\n <span id={titleId} className={styles.title}>{title}</span>\n {description ? <span className={styles.description}>{description}</span> : null}\n </span>\n {actions || canToggle ? (\n <span className={styles.actions}>\n {actions}\n {canToggle ? <ViewMenu title={title} view={view} onPick={setView} /> : null}\n </span>\n ) : null}\n </figcaption>\n {caveat ? (\n <p className={styles.caveat} role=\"note\">\n {caveat}\n </p>\n ) : null}\n {!ready ? (\n <StatusMessage status={status} />\n ) : view === 'table' ? (\n <div className={styles.table}>{table}</div>\n ) : (\n <>\n <div className={styles.plot}>{children}</div>\n {footer}\n </>\n )}\n </figure>\n );\n}\n","/**\n * components/charts/chart-math.ts — the pure geometry and statistics behind\n * the V3.10 chart kit (AreaTrend, BarStack, Swimlane, Funnel, CalendarHeatmap,\n * BurnDown, Gauge). No React, no DOM: every function here is unit tested\n * directly, so a chart component is only layout glue around numbers that are\n * already proven.\n *\n * Honesty rule shared with types.ts: `null` is UNKNOWN and is never coerced to\n * 0 by anything in this file. Functions that need a number skip nulls and say\n * so in their return value.\n */\n\n// ---------------------------------------------------------------------------\n// Scales and ticks\n// ---------------------------------------------------------------------------\n\n/**\n * \"Nice\" axis ticks: a step of 1, 2, 2.5 or 5 × 10^n chosen so there are\n * about `count` intervals, starting at or below `min` and ending at or above\n * `max`. Clean numbers (0 / 250 / 500), never 0 / 233.3 / 466.7.\n */\nexport function niceTicks(min: number, max: number, count = 4): number[] {\n if (!Number.isFinite(min) || !Number.isFinite(max)) return [0];\n if (max < min) [min, max] = [max, min];\n if (max === min) {\n if (max === 0) return [0, 1];\n const pad = Math.abs(max) * 0.5;\n return niceTicks(Math.min(0, min - pad), max + pad, count);\n }\n const rawStep = (max - min) / Math.max(1, count);\n const magnitude = 10 ** Math.floor(Math.log10(rawStep));\n const residual = rawStep / magnitude;\n const nice = residual <= 1 ? 1 : residual <= 2 ? 2 : residual <= 2.5 ? 2.5 : residual <= 5 ? 5 : 10;\n const step = nice * magnitude;\n const start = Math.floor(min / step) * step;\n const end = Math.ceil(max / step) * step;\n const ticks: number[] = [];\n // Round away float drift (0.1 + 0.2) so labels stay clean.\n const decimals = Math.max(0, -Math.floor(Math.log10(step)) + 1);\n for (let v = start; v <= end + step / 2; v += step) ticks.push(Number(v.toFixed(decimals)));\n return ticks;\n}\n\n/** Linear map from [d0, d1] to [r0, r1]; a zero-width domain maps to the range midpoint. */\nexport function linearScale(d0: number, d1: number, r0: number, r1: number): (v: number) => number {\n const span = d1 - d0;\n if (span === 0) return () => (r0 + r1) / 2;\n return (v: number) => r0 + ((v - d0) / span) * (r1 - r0);\n}\n\n/** Evenly thinned indexes so at most `max` labels are drawn, always keeping the last one. */\nexport function thinIndexes(length: number, max: number): number[] {\n if (length <= 0) return [];\n if (max <= 1) return [length - 1];\n if (length <= max) return Array.from({ length }, (_, i) => i);\n const step = Math.ceil((length - 1) / (max - 1));\n const out: number[] = [];\n for (let i = length - 1; i >= 0; i -= step) out.push(i);\n return out.reverse();\n}\n\n/** Clamp to [lo, hi]. */\nexport function clamp(v: number, lo: number, hi: number): number {\n return Math.min(hi, Math.max(lo, v));\n}\n\n// ---------------------------------------------------------------------------\n// Runs (null-aware line segments)\n// ---------------------------------------------------------------------------\n\nexport interface XY {\n x: number;\n y: number;\n}\n\n/** Split a series at nulls so a gap renders as a break, never as a dip to zero. */\nexport function splitRuns(points: ReadonlyArray<{ x: number; y: number | null }>): XY[][] {\n const runs: XY[][] = [];\n let current: XY[] = [];\n for (const p of points) {\n if (p.y === null || !Number.isFinite(p.y)) {\n if (current.length) runs.push(current);\n current = [];\n continue;\n }\n current.push({ x: p.x, y: p.y });\n }\n if (current.length) runs.push(current);\n return runs;\n}\n\nexport function linePath(run: ReadonlyArray<XY>): string {\n return run.map((p, i) => `${i === 0 ? 'M' : 'L'}${round(p.x)},${round(p.y)}`).join(' ');\n}\n\n/** Closed area under (or between) a run and a baseline run of equal length. */\nexport function areaPath(top: ReadonlyArray<XY>, bottom: ReadonlyArray<XY>): string {\n if (top.length === 0) return '';\n const back = [...bottom].reverse();\n return `${linePath(top)} ${back.map((p) => `L${round(p.x)},${round(p.y)}`).join(' ')} Z`;\n}\n\nexport function round(v: number): number {\n return Math.round(v * 10) / 10;\n}\n\n// ---------------------------------------------------------------------------\n// Stacking\n// ---------------------------------------------------------------------------\n\nexport interface StackSegment {\n /** Segment index in the caller's segment list. */\n index: number;\n value: number;\n y0: number;\n y1: number;\n}\n\nexport interface StackedColumn {\n segments: StackSegment[];\n /** Sum of known values. */\n total: number;\n /** True when at least one segment value is null (the total is a lower bound). */\n incomplete: boolean;\n /** True when every segment value is null (nothing is known). */\n unknown: boolean;\n}\n\n/** Stack one column's values bottom-up. Nulls are skipped and flagged, zeros take no height. */\nexport function stackColumn(values: ReadonlyArray<number | null>): StackedColumn {\n let acc = 0;\n let incomplete = false;\n let known = 0;\n const segments: StackSegment[] = [];\n values.forEach((value, index) => {\n if (value === null || !Number.isFinite(value)) {\n incomplete = true;\n return;\n }\n known++;\n const v = Math.max(0, value);\n if (v > 0) segments.push({ index, value: v, y0: acc, y1: acc + v });\n acc += v;\n });\n return { segments, total: acc, incomplete, unknown: known === 0 && values.length > 0 };\n}\n\n// ---------------------------------------------------------------------------\n// Rounded-end bars (4 px data end, square at the baseline)\n// ---------------------------------------------------------------------------\n\n/**\n * Path for a vertical bar whose TOP corners are rounded by `r` (the data end)\n * and whose bottom sits square on the baseline. `r` shrinks for short bars so\n * the corners never cross.\n */\nexport function roundedTopBar(x: number, y: number, w: number, h: number, r = 4): string {\n if (h <= 0 || w <= 0) return '';\n const rr = Math.max(0, Math.min(r, w / 2, h));\n return [\n `M${round(x)},${round(y + h)}`,\n `L${round(x)},${round(y + rr)}`,\n `Q${round(x)},${round(y)} ${round(x + rr)},${round(y)}`,\n `L${round(x + w - rr)},${round(y)}`,\n `Q${round(x + w)},${round(y)} ${round(x + w)},${round(y + rr)}`,\n `L${round(x + w)},${round(y + h)}`,\n 'Z',\n ].join(' ');\n}\n\n/** Horizontal twin: RIGHT corners rounded (the data end), left square on the baseline. */\nexport function roundedRightBar(x: number, y: number, w: number, h: number, r = 4): string {\n if (h <= 0 || w <= 0) return '';\n const rr = Math.max(0, Math.min(r, h / 2, w));\n return [\n `M${round(x)},${round(y)}`,\n `L${round(x + w - rr)},${round(y)}`,\n `Q${round(x + w)},${round(y)} ${round(x + w)},${round(y + rr)}`,\n `L${round(x + w)},${round(y + h - rr)}`,\n `Q${round(x + w)},${round(y + h)} ${round(x + w - rr)},${round(y + h)}`,\n `L${round(x)},${round(y + h)}`,\n 'Z',\n ].join(' ');\n}\n\n// ---------------------------------------------------------------------------\n// Funnel\n// ---------------------------------------------------------------------------\n\nexport interface FunnelStep {\n value: number | null;\n /** Share of the FIRST stage (0..1), null when either side is unknown or the first is 0. */\n ofFirst: number | null;\n /** Share of the PREVIOUS stage (0..1), null for the first stage or when unknown. */\n ofPrevious: number | null;\n}\n\nexport function funnelSteps(values: ReadonlyArray<number | null>): FunnelStep[] {\n const first = values[0] ?? null;\n return values.map((value, i) => {\n const previous = i > 0 ? values[i - 1] ?? null : null;\n return {\n value,\n ofFirst: value !== null && first !== null && first > 0 ? value / first : null,\n ofPrevious: i > 0 && value !== null && previous !== null && previous > 0 ? value / previous : null,\n };\n });\n}\n\n// ---------------------------------------------------------------------------\n// Calendar heatmap\n// ---------------------------------------------------------------------------\n\nexport interface CalendarCell {\n day: string;\n value: number | null;\n /** Column (week index from the first rendered week). */\n week: number;\n /** Row, 0 = weekStart. */\n weekday: number;\n /** True for days before the first datum / after the last (padding cells). */\n outside: boolean;\n}\n\nexport interface CalendarGrid {\n cells: CalendarCell[];\n weeks: number;\n /** Week index where each month first appears, for the month labels. */\n months: { week: number; label: string }[];\n}\n\nconst MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\n\nfunction utcDayMs(day: string): number | null {\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(day)) return null;\n const ms = Date.parse(`${day}T00:00:00Z`);\n return Number.isFinite(ms) && new Date(ms).toISOString().slice(0, 10) === day ? ms : null;\n}\n\n/**\n * Lay out consecutive days on a weeks × weekdays grid. Input days may be\n * sparse or unordered; missing days in the span become `value: null`\n * (unknown), never 0. `weekStart` 1 = Monday (ISO), 0 = Sunday.\n */\nexport function calendarGrid(\n days: ReadonlyArray<{ day: string; value: number | null }>,\n weekStart: 0 | 1 = 1,\n): CalendarGrid {\n const byDay = new Map<string, number | null>();\n let minMs = Infinity;\n let maxMs = -Infinity;\n for (const d of days) {\n const ms = utcDayMs(d.day);\n if (ms === null) continue;\n byDay.set(d.day, d.value);\n minMs = Math.min(minMs, ms);\n maxMs = Math.max(maxMs, ms);\n }\n if (!Number.isFinite(minMs)) return { cells: [], weeks: 0, months: [] };\n const DAY = 86_400_000;\n const firstWeekday = (new Date(minMs).getUTCDay() - weekStart + 7) % 7;\n const gridStart = minMs - firstWeekday * DAY;\n const lastWeekday = (new Date(maxMs).getUTCDay() - weekStart + 7) % 7;\n const gridEnd = maxMs + (6 - lastWeekday) * DAY;\n const cells: CalendarCell[] = [];\n const months: { week: number; label: string }[] = [];\n let lastMonth = -1;\n for (let ms = gridStart, i = 0; ms <= gridEnd; ms += DAY, i++) {\n const day = new Date(ms).toISOString().slice(0, 10);\n const week = Math.floor(i / 7);\n const weekday = i % 7;\n const outside = ms < minMs || ms > maxMs;\n cells.push({ day, value: outside ? null : byDay.has(day) ? byDay.get(day)! : null, week, weekday, outside });\n const month = new Date(ms).getUTCMonth();\n // First rendered week of each month; the component drops a label that\n // would collide with the previous one.\n if (!outside && month !== lastMonth) {\n months.push({ week, label: MONTHS[month]! });\n lastMonth = month;\n }\n }\n return { cells, weeks: Math.floor((gridEnd - gridStart) / DAY / 7) + 1, months };\n}\n\n/**\n * Bucket a value into 0..steps for a sequential ramp: 0 is reserved for a\n * true zero, 1..steps split (0, max] evenly. null → null (unknown).\n */\nexport function heatBucket(value: number | null, max: number, steps = 4): number | null {\n if (value === null || !Number.isFinite(value)) return null;\n if (value <= 0 || max <= 0) return 0;\n return clamp(Math.ceil((value / max) * steps), 1, steps);\n}\n\n// ---------------------------------------------------------------------------\n// Burn-down projection\n// ---------------------------------------------------------------------------\n\nexport interface BurnPoint {\n t: number;\n remaining: number | null;\n}\n\nexport interface BurnProjection {\n /** Units per millisecond (negative while burning). Null with fewer than two known points. */\n slopePerMs: number | null;\n /** When the projection crosses 0, if it does before `resetAt`. */\n exhaustAt: number | null;\n /** When it crosses `reserve`, if a reserve is set and it does before `resetAt`. */\n reserveAt: number | null;\n /** Projected remaining at reset (clamped at 0), or null when there is no slope. */\n remainingAtReset: number | null;\n /** The last known point the projection starts from. */\n from: { t: number; remaining: number } | null;\n}\n\n/**\n * Least-squares slope over the most recent `window` known points, projected\n * forward from the last known point. A flat or rising series never\n * \"exhausts\". Pure: the caller supplies `resetAt`.\n */\nexport function projectBurnDown(\n points: ReadonlyArray<BurnPoint>,\n resetAt: number,\n opts: { window?: number; reserve?: number | null } = {},\n): BurnProjection {\n const known = points\n .filter((p): p is { t: number; remaining: number } => p.remaining !== null && Number.isFinite(p.remaining) && Number.isFinite(p.t))\n .sort((a, b) => a.t - b.t);\n const from = known.length ? known[known.length - 1]! : null;\n const recent = known.slice(-(opts.window ?? 6));\n if (!from || recent.length < 2) {\n return { slopePerMs: null, exhaustAt: null, reserveAt: null, remainingAtReset: null, from };\n }\n const n = recent.length;\n const meanT = recent.reduce((s, p) => s + p.t, 0) / n;\n const meanR = recent.reduce((s, p) => s + p.remaining, 0) / n;\n let num = 0;\n let den = 0;\n for (const p of recent) {\n num += (p.t - meanT) * (p.remaining - meanR);\n den += (p.t - meanT) ** 2;\n }\n const slope = den === 0 ? 0 : num / den;\n const crossing = (level: number): number | null => {\n if (slope >= 0 || from.remaining <= level) return from.remaining <= level ? from.t : null;\n const at = from.t + (level - from.remaining) / slope;\n return at <= resetAt ? at : null;\n };\n const reserve = opts.reserve ?? null;\n return {\n slopePerMs: slope,\n exhaustAt: crossing(0),\n reserveAt: reserve === null ? null : crossing(reserve),\n remainingAtReset: Math.max(0, from.remaining + slope * Math.max(0, resetAt - from.t)),\n from,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Gauge arcs\n// ---------------------------------------------------------------------------\n\n/** Point on a circle; angle in radians, 0 = +x axis, measured counter-clockwise (SVG y flipped). */\nexport function polar(cx: number, cy: number, r: number, angle: number): XY {\n return { x: cx + r * Math.cos(angle), y: cy - r * Math.sin(angle) };\n}\n\n/**\n * SVG arc for a 180° gauge from fraction `f0` to `f1` (0 = left end, 1 =\n * right end, sweeping over the top). Fractions are clamped to [0, 1].\n */\nexport function gaugeArc(cx: number, cy: number, r: number, f0: number, f1: number): string {\n const a = clamp(f0, 0, 1);\n const b = clamp(f1, 0, 1);\n if (b <= a) return '';\n const start = polar(cx, cy, r, Math.PI * (1 - a));\n const end = polar(cx, cy, r, Math.PI * (1 - b));\n // A 180° gauge never needs the large-arc flag (the span is at most π).\n return `M${round(start.x)},${round(start.y)} A${r},${r} 0 0 1 ${round(end.x)},${round(end.y)}`;\n}\n\nexport type GaugeSeverity = 'ok' | 'warn' | 'danger' | 'unknown';\n\nexport function gaugeSeverity(value: number | null, warn: number, danger: number): GaugeSeverity {\n if (value === null || !Number.isFinite(value)) return 'unknown';\n if (value >= danger) return 'danger';\n if (value >= warn) return 'warn';\n return 'ok';\n}\n","/**\n * components/charts/useChartWidth.ts — the measured pixel width of a chart's\n * container, so the V3.10 charts draw at their REAL size (text stays 12 px at\n * 375 px wide) instead of scaling a fixed viewBox down until labels are\n * unreadable. Falls back to `fallback` until measured (jsdom, SSR, first paint).\n */\nimport { useLayoutEffect, useState, type RefObject } from 'react';\n\n/** Narrowest width any chart lays itself out for (a 375 px phone minus padding). */\nexport const MIN_CHART_WIDTH = 280;\n\nexport function useChartWidth(ref: RefObject<HTMLElement | null>, fixed: number | undefined, fallback = 640): number {\n const [measured, setMeasured] = useState<number | null>(null);\n // WHY track the node: a chart whose frame starts in a non-ready state\n // (loading / empty / dark) mounts its plot — and so this ref — LATER than\n // the hook. An effect keyed only on the ref object never re-ran, so every\n // chart that first rendered \"Loading…\" stayed at the 640 px fallback and\n // was scaled down by CSS (V3.10 fix, found in the 1440 harness).\n const [node, setNode] = useState<HTMLElement | null>(null);\n // Runs after every render on purpose (ref.current is not a dependency React\n // can see); the equality guard makes it settle in one pass, never a loop.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useLayoutEffect(() => {\n if (ref.current !== node) setNode(ref.current);\n });\n useLayoutEffect(() => {\n if (fixed !== undefined) return undefined;\n const el = node;\n if (!el) return undefined;\n const read = (): void => {\n const w = Math.floor(el.getBoundingClientRect().width);\n // 0 means \"not laid out yet\" (hidden tab, jsdom) — keep the fallback.\n if (w > 0) setMeasured((prev) => (prev === w ? prev : w));\n };\n read();\n if (typeof ResizeObserver === 'undefined') return undefined;\n // rAF-coalesced: a drag-resize fires many entries per frame.\n let frame = 0;\n const observer = new ResizeObserver(() => {\n cancelAnimationFrame(frame);\n frame = requestAnimationFrame(read);\n });\n observer.observe(el);\n return () => {\n cancelAnimationFrame(frame);\n observer.disconnect();\n };\n }, [node, fixed]);\n return Math.max(MIN_CHART_WIDTH, fixed ?? measured ?? fallback);\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{o as e}from"./index-afDA8cwW.js";import{K as t,W as n,q as r,tt as i}from"./global-DVgMguLr.js";var a=e({CODEX_EXPANSIVE_METERING_NOTE:()=>_,ENGINE_LABEL:()=>s,ENGINE_ORDER:()=>o,SEAT_CAPACITY_WORD:()=>b,WINDOW_SOURCE_TEXT:()=>h,firstRunnableModel:()=>v,formatDuration:()=>D,formatElapsed:()=>E,formatRelative:()=>O,groupSeats:()=>w,groupSessions:()=>T,isAbsolutePath:()=>M,modelLabel:()=>d,modelOptionFor:()=>f,prettyJson:()=>j,projectName:()=>c,seatById:()=>l,seatCapacity:()=>C,seatLabel:()=>u,seatPillLabel:()=>N,seatUnavailableReason:()=>y,seatWindowLabel:()=>S,sessionContextBudget:()=>m,summarizeToolInput:()=>k,truncate:()=>A,windowSourceText:()=>g}),o=[`claude`,`codex`,`grok`,`local`],s={claude:`Claude`,codex:`Codex`,grok:`Grok`,local:`Local`};function c(e,t=[]){let n=t.find(t=>t.path===e);return n?n.name:e.split(/[\\/]/).filter(Boolean).at(-1)??e}function l(e,t){return e.find(e=>e.id===t)}function u(e,t){return l(e,t.seatId)?.label??s[t.engine]}function d(e,t){return l(e,t.seatId)?.models.find(e=>e.id===t.model)?.label??t.model}function f(e,n){let r=l(e,n.seatId);if(!r)return null;let i=r.models.find(e=>e.id===n.model);if(i)return i;let a=t(n.model);return r.models.find(e=>t(e.id)===a)??null}function p(e){return typeof e==`number`&&Number.isFinite(e)&&e>0?e:null}function m(e,t){let a=t.usage,o=t.contextMode??`standard`,s=f(e,t),c={contextTokens:typeof a.contextTokens==`number`&&Number.isFinite(a.contextTokens)?Math.max(0,a.contextTokens):0,exact:a.contextTokensExact!==!1,mode:o,option:s},u=n(s,o),d=p(a.contextWindow);if(d!==null&&(t.engine===`local`||a.contextWindowSource===`runtime`)){let e=p(a.autoCompactAt??null)??i({engine:t.engine,runtimeWindow:d,budget:t.engine===`local`?null:u,autocompactWindow:t.engine===`claude`?r(s,o):null,maxOutputTokens:s?.maxOutputTokens??null}),n=t.engine===`local`?a.contextWindowSource??null:`runtime`;return{...c,contextWindow:d,autoCompactAt:e,source:n}}if(u)return{...c,contextWindow:u.contextWindow,autoCompactAt:u.autoCompactAt,source:s?.windowSource??`fallback`};if(d!==null)return{...c,contextWindow:d,autoCompactAt:p(a.autoCompactAt??null),source:a.contextWindowSource??null};let m=p(l(e,t.seatId)?.contextWindow??null);return{...c,contextWindow:m,autoCompactAt:null,source:m===null?null:`fallback`}}var h={runtime:`reported by the CLI on the last turn`,"provider-catalog":`from this seat's own model catalog`,"cli-catalog":`from the pinned CLI's built-in model table`,documented:`from the provider's published model table`,fallback:`a default estimate — the CLI has not reported the real window yet`};function g(e,t){return t===`local`?`${e===`runtime`?`measured from the local model server`:e===`fallback`?`a default estimate — the model server did not report one`:h[e]}; Verse passes this window to Claude Code for this chat`:h[e]}var _=`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.`;function v(e){return e.models.find(e=>!e.unavailableReason)??null}function y(e){return e.health.state===`unavailable`?e.health.summary??`seat unavailable`:null}var b={ready:`usable`,tight:`tight`,blocked:`blocked`,unread:`no reading`},x=85;function S(e){let t={five_hour:`5-hour window`,seven_day:`weekly window`,codex:`weekly window`};if(t[e])return t[e];let n=/^seven_day_(.+)$/.exec(e);return n?`weekly ${n[1].replace(/_/g,` `)} window`:`${e.replace(/_/g,` `)} window`}function C(e){let t=y(e);if(t!==null)return{cls:`blocked`,usedPercent:null,text:t};let n=e.health.windows.filter(e=>typeof e.usedPercent==`number`&&Number.isFinite(e.usedPercent));if(n.length===0)return{cls:`unread`,usedPercent:null,text:`no capacity reading`};let r=n.reduce((e,t)=>t.usedPercent>e.usedPercent?t:e),i=Math.max(0,Math.min(100,r.usedPercent)),a=S(r.id);return i>=100?{cls:`blocked`,usedPercent:null,text:`${a} limit reached`}:{cls:i>=x?`tight`:`ready`,usedPercent:i,text:`${Math.round(i)}% of ${a} used`}}function w(e){return o.map(t=>({engine:t,seats:e.filter(e=>e.engine===t)})).filter(e=>e.seats.length>0)}function T(e,t,n=``){let r=n.trim().toLowerCase(),i=r?e.filter(e=>e.title.toLowerCase().includes(r)||e.projectPath.toLowerCase().includes(r)||e.model.toLowerCase().includes(r)||e.seatId.toLowerCase().includes(r)):[...e],a=new Map;for(let e of i){let t=a.get(e.projectPath)??[];t.push(e),a.set(e.projectPath,t)}let o=[];for(let[e,n]of a)n.sort((e,t)=>t.updatedAt.localeCompare(e.updatedAt)),o.push({projectPath:e,name:c(e,t),enrolled:t.find(t=>t.path===e)?.enrolled??!1,sessions:n});return o.sort((e,t)=>t.sessions[0].updatedAt.localeCompare(e.sessions[0].updatedAt)),o}function E(e){if(!Number.isFinite(e)||e<0)return`0s`;let t=Math.floor(e/1e3);if(t<60)return`${t}s`;let n=Math.floor(t/60);return n<60?`${n}m ${t%60}s`:`${Math.floor(n/60)}h ${n%60}m`}function D(e){return!Number.isFinite(e)||e<0?`—`:e<1e3?`${Math.round(e)}ms`:e<6e4?`${(e/1e3).toFixed(1)}s`:E(e)}function O(e,t=Date.now()){let n=Date.parse(e);if(!Number.isFinite(n))return``;let r=Math.round((t-n)/1e3);if(r<0||r<60)return`now`;let i=Math.floor(r/60);if(i<60)return`${i}m`;let a=Math.floor(i/60);if(a<24)return`${a}h`;let o=Math.floor(a/24);return o<7?`${o}d`:new Date(n).toLocaleDateString([],{month:`short`,day:`numeric`})}function k(e){if(e==null)return``;if(typeof e==`string`)return A(e,96);if(typeof e!=`object`)return A(String(e),96);let t=e;for(let e of[`command`,`cmd`,`file_path`,`path`,`pattern`,`query`,`url`,`description`,`prompt`,`text`]){let n=t[e];if(typeof n==`string`&&n.trim())return A(n.trim().replace(/\s+/g,` `),96)}let n=Object.keys(t);if(n.length===0)return``;let r=t[n[0]],i=typeof r==`string`?r:JSON.stringify(r);return A(`${n[0]}: ${i??``}`.replace(/\s+/g,` `),96)}function A(e,t){return e.length>t?`${e.slice(0,t-1)}…`:e}function j(e){if(typeof e==`string`)return e;try{return JSON.stringify(e,null,2)??``}catch{return String(e)}}function M(e){return/^(?:\/|~(?:\/|$)|[a-zA-Z]:[\\/]|\\\\)/.test(e)&&![...e].some(e=>e.charCodeAt(0)<32||e.charCodeAt(0)>=127&&e.charCodeAt(0)<=159)}function N(e,t){let n=u(e,t),r=d(e,t);return!r||n.toLowerCase().includes(r.toLowerCase())?n:`${n} · ${r}`}export{g as C,a as S,N as _,v as a,m as b,O as c,M as d,f,C as g,l as h,h as i,w as l,c as m,s as n,D as o,j as p,b as r,E as s,_ as t,T as u,y as v,k as x,S as y};
|
|
2
|
-
//# sourceMappingURL=verse-model-E98kXngO.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"verse-model-E98kXngO.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';\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 const rounded = Math.round(pct);\n return {\n cls: pct >= TIGHT_PERCENT ? 'tight' : 'ready',\n usedPercent: pct,\n text: `${rounded}% 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 +0,0 @@
|
|
|
1
|
-
import{tt as e}from"./global-DVgMguLr.js";import{c as t}from"./types-Dypu22dp.js";var n={turnId:null,startedAt:null,progress:null,thinking:null,notice:null,settledTurnId:null},r={session:null,events:[],lastSeq:0,loaded:!1,loadError:null,stream:`idle`,live:n},i=new Map,a=new Map,o=new Map,s=new Map,c=new Set,l=new Map,u=new Set;function d(e){if(e!==null){let t=l.get(e);if(t)for(let e of[...t])e()}else for(let e of[...l.values()])for(let t of[...e])t();for(let e of[...c])e()}function f(e){return c.add(e),()=>c.delete(e)}function p(e,t){let n=l.get(e);return n||(n=new Set,l.set(e,n)),n.add(t),()=>{let n=l.get(e);n&&(n.delete(t),n.size===0&&l.delete(e))}}function m(e){return u.add(e),()=>u.delete(e)}function h(e){return{sessionId:e.sessionId,session:e.session,events:e.events,lastSeq:e.lastSeq,loaded:e.loaded,loadError:e.loadError,stream:e.stream}}function g(e){let t=i.get(e);return t||(t={sessionId:e,...r},i.set(e,t),a.set(e,h(t))),t}function _(e,t,n){i.set(e,t);let r=a.get(e);(!r||n||r.session!==t.session||r.loaded!==t.loaded||r.loadError!==t.loadError||r.stream!==t.stream)&&a.set(e,h(t))}function v(e,t,n=!1){_(e,{...g(e),...t},n),d(e)}var y={sessionId:``,...r},b=h(y);function x(e){return e?g(e):y}function S(e){return e?(g(e),a.get(e)):b}function C(e){return e?g(e).live:n}var w={items:[],live:!1,usage:null,segments:[]};function T(e){if(!e)return w;let t=g(e),n=s.get(e);if(n&&n.events===t.events)return n.transcript;let r=n?.cache??X(),i=$(t.events,{cache:r,thinkingStats:o.get(e)});return s.set(e,{events:t.events,transcript:i,cache:r}),i}function E(e,t,n){let r=g(e),i=K(r.events,n),a=A(t,i),o=r.session&&J(r.session,a)?r.session:a,s=i!==r.events,c=s||o!==r.session?R(r.live,i,o):r.live;(s||o!==r.session||!r.loaded||r.loadError!==null||c!==r.live)&&(_(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),d(e))}function D(e,t){v(e,{loadError:t,loaded:!0})}function O(e,t){g(e).stream!==t&&v(e,{stream:t})}function k(e,t,n){v(e,{session:A(t,g(e).events,n)})}function A(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 j(e,t){let n=g(e);n.session&&n.session.status!==t&&v(e,{session:{...n.session,status:t}})}function M(e,n){let r=g(e),i=r.events,a=!1,o=r.lastSeq,s=r.session,c=r.live,l=0,u=!1,f=!1,p=!1,m=Date.now();for(let r of n){if(t(r)){let e=I(c,r,m);e!==c&&(c=e,p=!0);continue}if(!Number.isFinite(r.seq))continue;let n=i.length>0?i[i.length-1].seq:-1/0;if(r.seq>n)a||=(i=i.slice(),!0),i.push(r);else{let e=W(i,r.seq);if(e.found)continue;a||=(i=i.slice(),!0),i.splice(e.index,0,r)}l+=1,o=Math.max(o,r.seq),r.type!==`text-delta`&&(f=!0),(r.type===`turn-done`||r.type===`cancelled`||r.type===`error`)&&(u=!0),s&&=N(s,r);let d=L(c,r,m,e);d!==c&&(c=d)}return l===0&&!p?{applied:0,settled:!1,liveChanged:!1}:(_(e,{...r,events:i,lastSeq:o,session:s,live:c},f),d(e),{applied:l,settled:u,liveChanged:p})}function N(e,t){switch(t.type){case`turn-started`:return{...e,status:`running`,lastError:null,updatedAt:t.at};case`usage`:return{...e,usage:z(e,t.usage),updatedAt:t.at};case`context`:return{...e,usage:ee(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 P(e,t){let n=Date.parse(e);return Number.isFinite(n)?n:t}function F(e,t,r){return e.turnId===t?e:{...n,turnId:t,startedAt:r,settledTurnId:e.settledTurnId}}function I(e,t,n){if(t.turnId!==null&&t.turnId===e.settledTurnId)return e;let r=t.turnId===null?e:F(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 L(e,t,r,i){switch(t.type){case`turn-started`:return t.turnId===e.settledTurnId?e:e.turnId===t.turnId?{...e,startedAt:P(t.at,e.startedAt??r)}:{...n,turnId:t.turnId,startedAt:P(t.at,r),settledTurnId:e.settledTurnId};case`thinking`:{let n=e.thinking&&e.thinking.turnId===t.turnId?e.thinking:null;if(n){let e=o.get(i);e||(e=new Map,o.set(i,e)),e.set(t.seq,{durationMs:typeof t.durationMs==`number`?t.durationMs:Math.max(0,r-n.startedAt),estimatedTokens:n.estimatedTokens})}return n||e.notice?{...e,thinking:n?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{...n,settledTurnId:t.turnId};default:return e}}function R(e,t,r){let i=null,a=e.settledTurnId;for(let e=t.length-1;e>=0;--e){let n=t[e];if(n.type===`turn-done`||n.type===`cancelled`){a=n.turnId;break}if(n.type===`turn-started`){i=n;break}}return i?r&&r.status!==`running`?e.turnId===null?e:{...n,settledTurnId:e.settledTurnId}:e.turnId===i.turnId?e:{...n,turnId:i.turnId,startedAt:P(i.at,Date.now()),settledTurnId:e.settledTurnId}:e.turnId!==null&&e.turnId===a?{...n,settledTurnId:a}:e.settledTurnId===a?e:{...e,settledTurnId:a}}function z(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 B=new Set([`runtime`,`provider-catalog`,`cli-catalog`,`documented`,`fallback`]);function V(e){return typeof e==`string`&&B.has(e)?e:null}function ee(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=V(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 H(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 U(e){let t=i.delete(e);a.delete(e),s.delete(e),o.delete(e);for(let t of[...u])t({kind:`forget`,sessionId:e});t&&d(e)}function W(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 G(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 K(e,t){if(t.length===0)return e;let n=G(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 q(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 J(e,t){if(e===t)return!0;let n=Object.keys(e);return n.length===Object.keys(t).length&&n.every(n=>q(e[n],t[n]))}function Y(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 X(){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:Y(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 $(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 te(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 te(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 ne(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(re(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 re(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=Y(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 ie(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{m as _,S as a,ne as c,D as d,k as f,f as g,p as h,C as i,H as l,O as m,U as n,x as o,j as p,ie as r,T as s,M as t,E as u};
|
|
2
|
-
//# sourceMappingURL=verse-store-BgKx_YGs.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"verse-store-BgKx_YGs.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/verse-store.ts"],"sourcesContent":["/**\n * routes/verse/verse-store.ts — per-session transcript state for the Verse\n * console. Framework-free (useSyncExternalStore glue lives in\n * useVerseSession.ts, the live stream in session-stream.ts), same split as\n * data/cache.ts + data/hooks.ts.\n *\n * One entry per session id holds the ordered, seq-deduplicated event log,\n * the latest session record we know of, the stream connection state, and —\n * V3.10 — the LIVE state of a running turn (reasoning streaming in, what the\n * turn is doing, retry/watchdog notices), which is fed by transient events\n * that are never persisted and never enter the event log.\n * Snapshots are replaced wholesale on every change (Object.is semantics —\n * see DESIGN.md §3 for the bug that rule prevents).\n *\n * V3.10 DATA PATH. The previous store merged every event with a Map + spread\n * + sort and told every subscriber about it: replaying 5k events took 2.45 s\n * and 10k took 17 s, and every streamed token re-rendered the whole Chat\n * section. Now:\n *\n * - `applyVerseEvents` applies a BATCH: an event past the newest seq is a\n * plain append (one array copy per batch, not per event), an older one\n * is binary-searched (duplicate → dropped, gap → inserted in place);\n * - subscribers are per session (`subscribeVerseSession`) and read one of\n * three snapshots that change independently:\n * · the HEAD (`getVerseSessionHead`) — session record, stream state\n * and the event log as of the last STRUCTURAL event. A text-delta\n * alone does not republish it, so the sidebar, header and resources\n * panel do not re-render per token;\n * · the TRANSCRIPT (`getVerseTranscript`) — derived lazily, per turn\n * segment, with unchanged turns returned as the same objects so the\n * renderer can skip them;\n * · the LIVE state (`getVerseLive`) — transient signals only.\n * - the stream (session-stream.ts) calls `applyVerseEvents` once per\n * animation frame, so a burst of frames costs one render.\n *\n * `buildTranscript()` derives what the transcript renders from the raw\n * events: streamed `text-delta`s accumulate into a provisional assistant\n * bubble until the matching `assistant-message` arrives and replaces it;\n * `tool-use` and `tool-result` pair up by toolUseId into one card.\n */\nimport type { VerseEvent, VerseSession, VerseUsage } from '../../data/api-types.js';\nimport {\n isTransientVerseEvent,\n type VerseProgressPhase,\n type VerseRecoveryHow,\n type VerseStatusKind,\n type VerseThinkingKind,\n type VerseTransientEvent,\n type VerseWindowSource,\n} from '../../../core/verse/types.js';\nimport { reconcileAutoCompactAt } from '../../../core/verse/context-math.js';\n\nexport type VerseStreamState = 'idle' | 'connecting' | 'open' | 'reconnecting' | 'closed';\n\n// ---------------------------------------------------------------------------\n// Live (transient) state\n// ---------------------------------------------------------------------------\n\n/** The reasoning block currently streaming in (`thinking-delta` / `thinking-progress`). */\nexport interface VerseLiveThinking {\n turnId: string;\n /** Streamed text so far; empty when the CLI reports only a token estimate. */\n text: string;\n /** Client clock (ms) when this block's first signal arrived. */\n startedAt: number;\n /** Latest `thinking-progress` estimate; null when the CLI sent none (unknown, never 0). */\n estimatedTokens: number | null;\n}\n\nexport interface VerseLiveProgress {\n phase: VerseProgressPhase;\n tool: string | null;\n /** Server-measured turn wall time when the frame was sent. */\n elapsedMs: number;\n outTokens: number | null;\n tokPerSec: number | null;\n /** Client clock (ms) the frame arrived, so elapsed can keep counting between frames. */\n receivedAt: number;\n}\n\nexport interface VerseLiveNotice {\n kind: VerseStatusKind;\n message: string;\n at: string;\n receivedAt: number;\n}\n\nexport interface VerseLiveState {\n /** The running turn these signals belong to; null when none is running. */\n turnId: string | null;\n /** Client clock (ms) the running turn started, from its `turn-started` stamp when parseable. */\n startedAt: number | null;\n progress: VerseLiveProgress | null;\n thinking: VerseLiveThinking | null;\n /** The latest plumbing notice (API retry, preflight, no-output watchdog); cleared when output resumes. */\n notice: VerseLiveNotice | null;\n /** Last turn that settled, so a late transient frame for it cannot resurrect the live line. */\n settledTurnId: string | null;\n}\n\n/** What this tab measured about a reasoning block while it streamed — keyed by the persisted `thinking` event's seq. */\nexport interface VerseThinkingStat {\n durationMs: number | null;\n estimatedTokens: number | null;\n}\n\nconst EMPTY_LIVE: VerseLiveState = {\n turnId: null,\n startedAt: null,\n progress: null,\n thinking: null,\n notice: null,\n settledTurnId: null,\n};\n\n// ---------------------------------------------------------------------------\n// Entries, heads and subscriptions\n// ---------------------------------------------------------------------------\n\nexport interface VerseSessionState {\n sessionId: string;\n session: VerseSession | null;\n events: VerseEvent[];\n /** Highest PERSISTED seq held — the resume cursor. Transient frames never move it. */\n lastSeq: number;\n loaded: boolean;\n loadError: string | null;\n stream: VerseStreamState;\n /** V3.10 transient signals of the running turn. */\n live: VerseLiveState;\n}\n\n/**\n * Everything about a session EXCEPT its live signals, republished only on\n * structural change. `events` is the log as of the last non-`text-delta`\n * event: streamed tokens reach the transcript through its own subscription,\n * so a consumer of the head (session record, meters, activity stats) never\n * re-renders per token. Code that needs every delta reads\n * `getVerseSessionState` or `getVerseTranscript` instead.\n */\nexport type VerseSessionHead = Omit<VerseSessionState, 'live'>;\n\nconst EMPTY: Omit<VerseSessionState, 'sessionId'> = {\n session: null,\n events: [],\n lastSeq: 0,\n loaded: false,\n loadError: null,\n stream: 'idle',\n live: EMPTY_LIVE,\n};\n\nconst sessions = new Map<string, VerseSessionState>();\nconst heads = new Map<string, VerseSessionHead>();\nconst thinkingStats = new Map<string, Map<number, VerseThinkingStat>>();\nconst transcriptMemo = new Map<string, { events: readonly VerseEvent[]; transcript: Transcript; cache: TranscriptCache }>();\nconst listeners = new Set<() => void>();\nconst sessionListeners = new Map<string, Set<() => void>>();\n\nexport type VerseStoreLifecycle = { kind: 'reset' } | { kind: 'forget'; sessionId: string };\nconst lifecycleListeners = new Set<(event: VerseStoreLifecycle) => void>();\n\nfunction notify(sessionId: string | null): void {\n if (sessionId !== null) {\n const scoped = sessionListeners.get(sessionId);\n if (scoped) for (const l of [...scoped]) l();\n } else {\n for (const set of [...sessionListeners.values()]) for (const l of [...set]) l();\n }\n for (const l of [...listeners]) l();\n}\n\n/** Every change to every session. Prefer `subscribeVerseSession` in components. */\nexport function subscribeVerseStore(listener: () => void): () => void {\n listeners.add(listener);\n return () => listeners.delete(listener);\n}\n\n/** Changes to ONE session only — what a component showing that session subscribes to. */\nexport function subscribeVerseSession(sessionId: string, listener: () => void): () => void {\n let set = sessionListeners.get(sessionId);\n if (!set) {\n set = new Set();\n sessionListeners.set(sessionId, set);\n }\n set.add(listener);\n return () => {\n const current = sessionListeners.get(sessionId);\n if (!current) return;\n current.delete(listener);\n if (current.size === 0) sessionListeners.delete(sessionId);\n };\n}\n\n/**\n * Reset / forget notifications, so the live-stream registry can close the\n * connection of a chat that was deleted or of a store that was cleared on\n * logout (and so tests never inherit a previous test's stream).\n */\nexport function subscribeVerseStoreLifecycle(listener: (event: VerseStoreLifecycle) => void): () => void {\n lifecycleListeners.add(listener);\n return () => lifecycleListeners.delete(listener);\n}\n\nfunction headOf(state: VerseSessionState): VerseSessionHead {\n return {\n sessionId: state.sessionId,\n session: state.session,\n events: state.events,\n lastSeq: state.lastSeq,\n loaded: state.loaded,\n loadError: state.loadError,\n stream: state.stream,\n };\n}\n\nfunction entryFor(sessionId: string): VerseSessionState {\n let e = sessions.get(sessionId);\n if (!e) {\n e = { sessionId, ...EMPTY };\n sessions.set(sessionId, e);\n heads.set(sessionId, headOf(e));\n }\n return e;\n}\n\n/**\n * Store `next` and republish the head when anything it carries changed.\n * `structural` = the event log gained something other than a text-delta.\n */\nfunction commit(sessionId: string, next: VerseSessionState, structural: boolean): void {\n sessions.set(sessionId, next);\n const head = heads.get(sessionId);\n if (\n !head || structural || head.session !== next.session || head.loaded !== next.loaded ||\n head.loadError !== next.loadError || head.stream !== next.stream\n ) {\n heads.set(sessionId, headOf(next));\n }\n}\n\nfunction patch(sessionId: string, delta: Partial<VerseSessionState>, structural = false): void {\n const current = entryFor(sessionId);\n commit(sessionId, { ...current, ...delta }, structural);\n notify(sessionId);\n}\n\nconst NONE: VerseSessionState = { sessionId: '', ...EMPTY };\nconst NONE_HEAD: VerseSessionHead = headOf(NONE);\n\n/** Stable reference until the entry changes, so useSyncExternalStore is happy. */\nexport function getVerseSessionState(sessionId: string | null): VerseSessionState {\n if (!sessionId) return NONE;\n return entryFor(sessionId);\n}\n\n/** The head snapshot (see VerseSessionHead) — stable across text-deltas. */\nexport function getVerseSessionHead(sessionId: string | null): VerseSessionHead {\n if (!sessionId) return NONE_HEAD;\n entryFor(sessionId);\n return heads.get(sessionId)!;\n}\n\n/** Live signals of the running turn; the same object until one of them changes. */\nexport function getVerseLive(sessionId: string | null): VerseLiveState {\n if (!sessionId) return EMPTY_LIVE;\n return entryFor(sessionId).live;\n}\n\nconst EMPTY_TRANSCRIPT: Transcript = { items: [], live: false, usage: null, segments: [] };\n\n/**\n * The derived transcript, rebuilt only when the event log changed and then\n * only for the turn segments that changed (see buildTranscript's cache).\n */\nexport function getVerseTranscript(sessionId: string | null): Transcript {\n if (!sessionId) return EMPTY_TRANSCRIPT;\n const entry = entryFor(sessionId);\n const memo = transcriptMemo.get(sessionId);\n if (memo && memo.events === entry.events) return memo.transcript;\n const cache = memo?.cache ?? createTranscriptCache();\n const transcript = buildTranscript(entry.events, { cache, thinkingStats: thinkingStats.get(sessionId) });\n transcriptMemo.set(sessionId, { events: entry.events, transcript, cache });\n return transcript;\n}\n\n/** Merge a fetched detail (session + full event log) into the entry. Events\n * already known (same seq) are kept once; the union stays sorted by seq. The\n * detail fetch can race a live stream, so a `turn-done` that streamed in\n * meanwhile wins over the older `running` snapshot. A refetch that brings\n * nothing new changes nothing — no re-render. */\nexport function seedVerseSession(sessionId: string, session: VerseSession, events: readonly VerseEvent[]): void {\n const current = entryFor(sessionId);\n const merged = mergeEvents(current.events, events);\n const settled = settledStatus(session, merged);\n const nextSession = current.session && sameSession(current.session, settled) ? current.session : settled;\n const eventsChanged = merged !== current.events;\n const live = eventsChanged || nextSession !== current.session ? liveFromLog(current.live, merged, nextSession) : current.live;\n if (!eventsChanged && nextSession === current.session && current.loaded && current.loadError === null && live === current.live) return;\n commit(sessionId, {\n ...current,\n session: nextSession,\n events: merged,\n lastSeq: merged.length ? Math.max(current.lastSeq, merged[merged.length - 1]!.seq) : current.lastSeq,\n loaded: true,\n loadError: null,\n live,\n }, eventsChanged);\n notify(sessionId);\n}\n\nexport function setVerseLoadError(sessionId: string, message: string): void {\n patch(sessionId, { loadError: message, loaded: true });\n}\n\nexport function setVerseStreamState(sessionId: string, stream: VerseStreamState): void {\n if (entryFor(sessionId).stream === stream) return;\n patch(sessionId, { stream });\n}\n\n/**\n * Replace the session record (after a turn POST / rename / list refresh).\n * `turnId` is the turn the snapshot claims is running (POST …/turns returns\n * it): when the log already holds that turn's `turn-done`/`cancelled` — a\n * spawn failure settles in the same tick as the 202 — the snapshot is stale\n * and must not drag the composer back to running.\n */\nexport function setVerseSession(sessionId: string, session: VerseSession, turnId?: string): void {\n const current = entryFor(sessionId);\n patch(sessionId, { session: settledStatus(session, current.events, turnId) });\n}\n\n/**\n * Reconcile a `running` snapshot against the event log. Without a `turnId`\n * the running turn is the last `user-message`/`turn-started` in the log; a\n * later `turn-done`/`cancelled` means the server already settled it. With a\n * `turnId`, only that turn's terminal event counts (its `user-message` may\n * not have streamed in yet, so a previous turn's `turn-done` proves nothing).\n * Status follows the same rules applyVerseEvent uses: cancelled → idle,\n * `turn-done ok:false` → error only when an `error` event was logged for it.\n */\nexport function settledStatus(session: VerseSession, events: readonly VerseEvent[], turnId?: string): VerseSession {\n if (session.status !== 'running') return session;\n let anchorSeq = -1;\n let anchorTurn: string | null = turnId ?? null;\n if (!turnId) {\n for (const e of events) {\n if (e.type === 'user-message' || e.type === 'turn-started') {\n anchorSeq = e.seq;\n anchorTurn = e.turnId;\n }\n }\n if (anchorTurn === null) return session;\n }\n let terminal: Extract<VerseEvent, { type: 'turn-done' | 'cancelled' }> | null = null;\n let lastError: string | null = null;\n for (const e of events) {\n if (e.seq <= anchorSeq) continue;\n if (e.type === 'error' && e.turnId === anchorTurn) lastError = e.message;\n if ((e.type === 'turn-done' || e.type === 'cancelled') && e.turnId === anchorTurn) terminal = e;\n }\n if (!terminal) return session;\n const failed = terminal.type === 'turn-done' && !terminal.ok && lastError !== null;\n return {\n ...session,\n status: failed ? 'error' : 'idle',\n lastError: failed ? lastError : null,\n updatedAt: terminal.at > session.updatedAt ? terminal.at : session.updatedAt,\n };\n}\n\n/** Optimistic status flip (e.g. right after POST …/turns returns 202). */\nexport function setVerseSessionStatus(sessionId: string, status: VerseSession['status']): void {\n const current = entryFor(sessionId);\n if (!current.session || current.session.status === status) return;\n patch(sessionId, { session: { ...current.session, status } });\n}\n\nexport interface VerseApplyResult {\n /** Persisted events newly added to the log (duplicates excluded). */\n applied: number;\n /** A newly added event settled a turn (`turn-done` / `cancelled` / `error`) — the lists may be stale. */\n settled: boolean;\n /** A transient frame changed the live state. */\n liveChanged: boolean;\n}\n\n/**\n * Apply a BATCH of live events in arrival order, then notify once.\n *\n * Persisted events: duplicates (a stream that replays from the start, or a\n * resume that overlaps the detail fetch) are dropped by seq; an event past\n * the newest seq is appended; an older unseen one is inserted in place.\n * Session-level side effects: `usage` and `context` update the live context\n * meter, `compaction` counts a native compaction, `turn-started` flips\n * status to running, `turn-done`/`cancelled`/`error` settle it, and a codex\n * `turn-done.nativeSessionId` is captured.\n *\n * Transient events (VERSE_TRANSIENT_EVENT_TYPES) never enter the log and\n * never move `lastSeq`: they carry the last PERSISTED seq, so deduping them\n * by seq would drop every one of them. They only update `live`.\n */\nexport function applyVerseEvents(sessionId: string, incoming: readonly VerseEvent[]): VerseApplyResult {\n const current = entryFor(sessionId);\n let events: VerseEvent[] = current.events;\n let copied = false;\n let lastSeq = current.lastSeq;\n let session = current.session;\n let live = current.live;\n let applied = 0;\n let settled = false;\n let structural = false;\n let liveChanged = false;\n const now = Date.now();\n\n for (const event of incoming) {\n if (isTransientVerseEvent(event)) {\n const next = applyTransient(live, event, now);\n if (next !== live) {\n live = next;\n liveChanged = true;\n }\n continue;\n }\n if (!Number.isFinite(event.seq)) continue;\n const tail = events.length > 0 ? events[events.length - 1]!.seq : -Infinity;\n if (event.seq > tail) {\n if (!copied) {\n events = events.slice();\n copied = true;\n }\n events.push(event);\n } else {\n const at = seqIndex(events, event.seq);\n if (at.found) continue;\n if (!copied) {\n events = events.slice();\n copied = true;\n }\n events.splice(at.index, 0, event);\n }\n applied += 1;\n lastSeq = Math.max(lastSeq, event.seq);\n if (event.type !== 'text-delta') structural = true;\n if (event.type === 'turn-done' || event.type === 'cancelled' || event.type === 'error') settled = true;\n if (session) session = sessionAfter(session, event);\n const nextLive = livePersisted(live, event, now, sessionId);\n if (nextLive !== live) live = nextLive;\n }\n\n if (applied === 0 && !liveChanged) return { applied: 0, settled: false, liveChanged: false };\n commit(sessionId, { ...current, events, lastSeq, session, live }, structural);\n notify(sessionId);\n return { applied, settled, liveChanged };\n}\n\n/**\n * Apply one live event (the single-event form of applyVerseEvents). Returns\n * true when the log gained the event, or — for a transient frame — when the\n * live state changed.\n */\nexport function applyVerseEvent(sessionId: string, event: VerseEvent): boolean {\n const result = applyVerseEvents(sessionId, [event]);\n return result.applied > 0 || result.liveChanged;\n}\n\n/** A persisted event's effect on the session record (the old applyVerseEvent switch). */\nfunction sessionAfter(session: VerseSession, event: VerseEvent): VerseSession {\n switch (event.type) {\n case 'turn-started':\n return { ...session, status: 'running', lastError: null, updatedAt: event.at };\n case 'usage':\n return { ...session, usage: applyUsageFrame(session, event.usage), updatedAt: event.at };\n case 'context':\n return { ...session, usage: applyContextReading(session, event), updatedAt: event.at };\n case 'compaction':\n // Counted exactly as the server counts it (session-engine), so a reload\n // shows the same number the live stream did. Occupancy is NOT touched\n // here: the next `usage`/`context` reading is the measurement.\n return { ...session, compactionCount: (session.compactionCount ?? 0) + 1, updatedAt: event.at };\n case 'turn-done':\n return {\n ...session,\n status: event.ok ? 'idle' : session.lastError ? 'error' : 'idle',\n turnCount: session.turnCount + 1,\n nativeSessionId: event.nativeSessionId ?? session.nativeSessionId,\n updatedAt: event.at,\n };\n case 'error':\n return { ...session, status: 'error', lastError: event.message, updatedAt: event.at };\n case 'cancelled':\n return { ...session, status: 'idle', updatedAt: event.at };\n default:\n return session;\n }\n}\n\nfunction stampMs(at: string, fallback: number): number {\n const parsed = Date.parse(at);\n return Number.isFinite(parsed) ? parsed : fallback;\n}\n\n/** Enter (or stay in) the live context of `turnId`. */\nfunction liveForTurn(live: VerseLiveState, turnId: string, startedAt: number): VerseLiveState {\n if (live.turnId === turnId) return live;\n return { ...EMPTY_LIVE, turnId, startedAt, settledTurnId: live.settledTurnId };\n}\n\nfunction applyTransient(live: VerseLiveState, event: VerseTransientEvent, now: number): VerseLiveState {\n // A frame for a turn that already settled (late delivery after turn-done)\n // must not bring the live line back.\n if (event.turnId !== null && event.turnId === live.settledTurnId) return live;\n const base = event.turnId !== null ? liveForTurn(live, event.turnId, now) : live;\n switch (event.type) {\n case 'thinking-delta': {\n if (event.text.length === 0) return base;\n const block = base.thinking && base.thinking.turnId === event.turnId\n ? { ...base.thinking, text: base.thinking.text + event.text }\n : { turnId: event.turnId, text: event.text, startedAt: now, estimatedTokens: null };\n return { ...base, thinking: block, notice: null };\n }\n case 'thinking-progress': {\n const block = base.thinking && base.thinking.turnId === event.turnId\n ? { ...base.thinking, estimatedTokens: event.estimatedTokens }\n : { turnId: event.turnId, text: '', startedAt: now, estimatedTokens: event.estimatedTokens };\n return { ...base, thinking: block };\n }\n case 'progress':\n return {\n ...base,\n progress: {\n phase: event.phase,\n tool: typeof event.tool === 'string' && event.tool.length > 0 ? event.tool : null,\n elapsedMs: event.elapsedMs,\n outTokens: event.outTokens ?? null,\n tokPerSec: event.tokPerSec ?? null,\n receivedAt: now,\n },\n };\n case 'status':\n return { ...base, notice: { kind: event.kind, message: event.message, at: event.at, receivedAt: now } };\n default:\n return base;\n }\n}\n\n/** A persisted event's effect on the live state. */\nfunction livePersisted(live: VerseLiveState, event: VerseEvent, now: number, sessionId: string): VerseLiveState {\n switch (event.type) {\n case 'turn-started':\n if (event.turnId === live.settledTurnId) return live;\n return live.turnId === event.turnId\n ? { ...live, startedAt: stampMs(event.at, live.startedAt ?? now) }\n : { ...EMPTY_LIVE, turnId: event.turnId, startedAt: stampMs(event.at, now), settledTurnId: live.settledTurnId };\n case 'thinking': {\n // The persisted block supersedes the streamed one. What this tab\n // measured while it streamed (duration, the CLI's token estimate) is\n // kept beside the log, by seq, so the finished block can still say\n // \"Thought 12s · ~1.8k tok\" — the event itself is immutable.\n const streamed = live.thinking && live.thinking.turnId === event.turnId ? live.thinking : null;\n if (streamed) {\n let stats = thinkingStats.get(sessionId);\n if (!stats) {\n stats = new Map();\n thinkingStats.set(sessionId, stats);\n }\n stats.set(event.seq, {\n durationMs: typeof event.durationMs === 'number' ? event.durationMs : Math.max(0, now - streamed.startedAt),\n estimatedTokens: streamed.estimatedTokens,\n });\n }\n return streamed || live.notice ? { ...live, thinking: streamed ? null : live.thinking, notice: null } : live;\n }\n case 'text-delta':\n case 'assistant-message':\n case 'tool-use':\n case 'tool-result':\n // Output resumed: a retry went through, the watchdog's silence ended.\n return live.notice && (event.turnId === live.turnId || live.turnId === null) ? { ...live, notice: null } : live;\n case 'turn-done':\n case 'cancelled':\n return { ...EMPTY_LIVE, settledTurnId: event.turnId };\n default:\n return live;\n }\n}\n\n/**\n * Live state implied by a freshly merged log: a chat opened (or reloaded)\n * mid-turn still shows its live line, timed from the turn's own stamp; a\n * log whose last turn is settled shows none.\n */\nfunction liveFromLog(live: VerseLiveState, events: readonly VerseEvent[], session: VerseSession | null): VerseLiveState {\n let openTurn: Extract<VerseEvent, { type: 'turn-started' }> | null = null;\n let settledTurnId: string | null = live.settledTurnId;\n for (let i = events.length - 1; i >= 0; i -= 1) {\n const e = events[i]!;\n if (e.type === 'turn-done' || e.type === 'cancelled') {\n settledTurnId = e.turnId;\n break;\n }\n if (e.type === 'turn-started') {\n openTurn = e;\n break;\n }\n }\n if (!openTurn) {\n if (live.turnId !== null && live.turnId === settledTurnId) return { ...EMPTY_LIVE, settledTurnId };\n // No turn-started in the log yet (the POST just went out): keep whatever\n // the stream already told us; nothing in the log contradicts it.\n return live.settledTurnId === settledTurnId ? live : { ...live, settledTurnId };\n }\n if (session && session.status !== 'running') return live.turnId === null ? live : { ...EMPTY_LIVE, settledTurnId: live.settledTurnId };\n if (live.turnId === openTurn.turnId) return live;\n return { ...EMPTY_LIVE, turnId: openTurn.turnId, startedAt: stampMs(openTurn.at, Date.now()), settledTurnId: live.settledTurnId };\n}\n\n/**\n * Fold one `usage` frame into the session record. The frame carries THIS\n * turn's counts; the record keeps the session totals (server: session-engine\n * applyUsage). Occupancy and the window are live values, not sums.\n *\n * V3.9 fields are adopted only when the frame carries them (spread-when-\n * present), so a pre-3.9 server's frames leave the record's shape unchanged.\n * The one exception is a local seat: Verse SETS that window\n * (`CLAUDE_CODE_MAX_CONTEXT_TOKENS`), so a window a frame reports without\n * provenance is not allowed to replace it — the server ignores runtime\n * windows on local for the same reason.\n */\nexport function applyUsageFrame(session: VerseSession, frame: VerseUsage): VerseUsage {\n const prev = session.usage;\n const next: VerseUsage = {\n ...prev,\n inputTokens: prev.inputTokens + frame.inputTokens,\n outputTokens: prev.outputTokens + frame.outputTokens,\n cacheReadTokens: prev.cacheReadTokens + frame.cacheReadTokens,\n cacheCreationTokens: prev.cacheCreationTokens + frame.cacheCreationTokens,\n contextTokens: frame.contextTokens,\n };\n const frameWindow = typeof frame.contextWindow === 'number' && frame.contextWindow > 0 ? frame.contextWindow : null;\n const trusted = frame.contextWindowSource !== undefined || session.engine !== 'local';\n if (frameWindow !== null && trusted) next.contextWindow = frameWindow;\n if (frame.contextWindowSource !== undefined) next.contextWindowSource = frame.contextWindowSource;\n if (frame.autoCompactAt !== undefined) next.autoCompactAt = frame.autoCompactAt;\n // The server marks an EXACT reading by OMITTING the key (it only writes\n // `false`), so a resolved frame without it must clear an earlier \"≤\" — a\n // frame from a pre-3.9 server (no V3.9 fields at all) leaves it alone.\n if (frame.contextTokensExact === false) next.contextTokensExact = false;\n else if (frame.contextWindowSource !== undefined) delete next.contextTokensExact;\n return next;\n}\n\n/** The provenance values a frame may carry; anything else is ignored, never stored. */\nconst WINDOW_SOURCES: ReadonlySet<string> = new Set<VerseWindowSource>(['runtime', 'provider-catalog', 'cli-catalog', 'documented', 'fallback']);\n\nfunction frameWindowSource(value: unknown): VerseWindowSource | null {\n return typeof value === 'string' && WINDOW_SOURCES.has(value) ? (value as VerseWindowSource) : null;\n}\n\n/**\n * Apply a `context` reading: it REPLACES occupancy (never summed). When it\n * names a window, the window's provenance is the one the EVENT states\n * (`contextWindowSource`, V3.9): the engine also emits a `context` event\n * after a MODE SWITCH, carrying the new mode's CATALOG budget, and stamping\n * that 'runtime' made the tooltip say \"reported by the CLI on the last turn\"\n * for a number no CLI reported — and pinned it ahead of later catalog\n * corrections (sessionContextBudget precedence 1). Only an event from a\n * server that predates the field (no source at all) is taken as a runtime\n * reading, which is what every such event was.\n *\n * The engine fills `autoCompactAt` for the window in force; a frame without\n * it (an older server) is reconciled from the previous budget rather than\n * left pointing at a compaction point that belonged to a different window.\n */\nexport function applyContextReading(\n session: VerseSession,\n event: Extract<VerseEvent, { type: 'context' }>,\n): VerseUsage {\n const prev = session.usage;\n const next: VerseUsage = {\n ...prev,\n contextTokens: Math.max(0, Math.floor(event.contextTokens)),\n contextTokensExact: event.exact,\n };\n const window = typeof event.contextWindow === 'number' && event.contextWindow > 0 ? event.contextWindow : null;\n const stated = frameWindowSource(event.contextWindowSource);\n // Local windows are SET by Verse (CLAUDE_CODE_MAX_CONTEXT_TOKENS), not\n // measured: a window without provenance is not allowed to move one (see\n // applyUsageFrame). A V3.9 event that states its source is the engine's\n // own record of the window it just launched with, so it is adopted.\n if (window === null || (session.engine === 'local' && stated === null)) {\n if (event.autoCompactAt !== undefined && event.autoCompactAt !== null) next.autoCompactAt = event.autoCompactAt;\n return next;\n }\n next.contextWindow = window;\n next.contextWindowSource = stated ?? 'runtime';\n if (event.autoCompactAt !== undefined) {\n next.autoCompactAt = event.autoCompactAt;\n } else if (window !== prev.contextWindow) {\n next.autoCompactAt = reconcileAutoCompactAt({\n engine: session.engine,\n runtimeWindow: window,\n budget: prev.contextWindow ? { contextWindow: prev.contextWindow, autoCompactAt: prev.autoCompactAt ?? null } : null,\n });\n }\n return next;\n}\n\n/**\n * When this chat last talked to its provider — the newest `usage`,\n * `turn-done`, `cancelled` or TURN-attributed `context` event — or null when\n * the log holds none (no turn yet, or the log is not loaded).\n *\n * WHY NOT `session.updatedAt`: the idle-cache advice (\"the prompt cache has\n * likely expired\") asks how long the PROVIDER has gone without a request,\n * and `updatedAt` moves on things that never reach a provider: a rename, a\n * context-mode switch (whose `context` event has `turnId: null`), a reload's\n * record save. Measured from `updatedAt`, one rename silenced the warning\n * for another hour while the cache stayed cold.\n */\nexport function lastTurnActivityAt(events: readonly VerseEvent[]): string | null {\n let latest: string | null = null;\n for (const e of events) {\n const turnActivity = e.type === 'usage' || e.type === 'turn-done' || e.type === 'cancelled' ||\n (e.type === 'context' && e.turnId !== null);\n if (turnActivity && typeof e.at === 'string' && (latest === null || e.at > latest)) latest = e.at;\n }\n return latest;\n}\n\nexport function forgetVerseSession(sessionId: string): void {\n const existed = sessions.delete(sessionId);\n heads.delete(sessionId);\n transcriptMemo.delete(sessionId);\n thinkingStats.delete(sessionId);\n for (const l of [...lifecycleListeners]) l({ kind: 'forget', sessionId });\n if (existed) notify(sessionId);\n}\n\n/** Test/logout hygiene. */\nexport function resetVerseStore(): void {\n sessions.clear();\n heads.clear();\n transcriptMemo.clear();\n thinkingStats.clear();\n for (const l of [...lifecycleListeners]) l({ kind: 'reset' });\n notify(null);\n}\n\n/** Position of `seq` in a seq-sorted log (binary search). */\nfunction seqIndex(events: readonly VerseEvent[], seq: number): { found: boolean; index: number } {\n let lo = 0;\n let hi = events.length;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n const s = events[mid]!.seq;\n if (s === seq) return { found: true, index: mid };\n if (s < seq) lo = mid + 1;\n else hi = mid;\n }\n return { found: false, index: lo };\n}\n\n/** Sorted by seq, one event per seq (first occurrence wins), non-finite seqs dropped. */\nfunction normalizeEvents(events: readonly VerseEvent[]): VerseEvent[] {\n let ascending = true;\n for (let i = 0; i < events.length; i += 1) {\n const seq = events[i]!.seq;\n if (!Number.isFinite(seq) || (i > 0 && seq <= events[i - 1]!.seq)) {\n ascending = false;\n break;\n }\n }\n if (ascending) return events.slice();\n const bySeq = new Map<number, VerseEvent>();\n for (const e of events) if (Number.isFinite(e.seq) && !bySeq.has(e.seq)) bySeq.set(e.seq, e);\n return [...bySeq.values()].sort((a, b) => a.seq - b.seq);\n}\n\n/**\n * Union of two logs by seq, existing events winning. Returns `existing`\n * itself when `incoming` adds nothing, so a refetch that brought no news is\n * not a change. Linear in the two lengths (both are seq-sorted).\n */\nfunction mergeEvents(existing: VerseEvent[], incomingRaw: readonly VerseEvent[]): VerseEvent[] {\n if (incomingRaw.length === 0) return existing;\n const incoming = normalizeEvents(incomingRaw);\n if (incoming.length === 0) return existing;\n if (existing.length === 0) return incoming;\n if (incoming[0]!.seq > existing[existing.length - 1]!.seq) return existing.concat(incoming);\n const out: VerseEvent[] = [];\n let added = 0;\n let i = 0;\n let j = 0;\n while (i < existing.length || j < incoming.length) {\n const a = existing[i];\n const b = incoming[j];\n if (b === undefined || (a !== undefined && a.seq < b.seq)) {\n out.push(a!);\n i += 1;\n } else if (a === undefined || b.seq < a.seq) {\n out.push(b);\n added += 1;\n j += 1;\n } else {\n out.push(a);\n i += 1;\n j += 1;\n }\n }\n return added === 0 ? existing : out;\n}\n\nfunction shallowEqualValue(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true;\n if (!a || !b || typeof a !== 'object' || typeof b !== 'object' || Array.isArray(a) !== Array.isArray(b)) return false;\n const ka = Object.keys(a as object);\n const kb = Object.keys(b as object);\n if (ka.length !== kb.length) return false;\n for (const k of ka) {\n if (!Object.is((a as Record<string, unknown>)[k], (b as Record<string, unknown>)[k])) return false;\n }\n return true;\n}\n\n/** Same record, one level deep — a refetched but unchanged session must not re-render its chat. */\nfunction sameSession(a: VerseSession, b: VerseSession): boolean {\n if (a === b) return true;\n const ka = Object.keys(a) as Array<keyof VerseSession>;\n if (ka.length !== Object.keys(b).length) return false;\n return ka.every((k) => shallowEqualValue(a[k], b[k]));\n}\n\n// ---------------------------------------------------------------------------\n// Transcript derivation\n// ---------------------------------------------------------------------------\n\nexport type TranscriptItem =\n | { kind: 'user'; key: string; turnId: string; at: string; text: string }\n | { kind: 'assistant'; key: string; turnId: string; at: string; text: string; streaming: boolean }\n | {\n kind: 'thinking';\n key: string;\n turnId: string;\n at: string;\n text: string;\n /** V3.10: the CLI sent a signature-only / redacted block — the model thought, the text is withheld. */\n redacted: boolean;\n /** Streaming wall time: the event's own figure, else what this tab measured; null = unknown. */\n durationMs: number | null;\n /** The CLI's reasoning-token estimate this tab saw while it streamed; null = unknown. */\n estimatedTokens: number | null;\n thinkingKind: VerseThinkingKind | null;\n }\n | {\n kind: 'tool';\n key: string;\n turnId: string;\n at: string;\n toolUseId: string;\n name: string;\n input: unknown;\n result: { output: string; isError: boolean } | null;\n /** tool-use → tool-result wall time; null while pending or unstamped. */\n durationMs: number | null;\n }\n | { kind: 'error'; key: string; turnId: string | null; at: string; message: string; code: string | null }\n | {\n /** V3.9: the CLI compacted its own context. Counts are null when the CLI does not report them (codex). */\n kind: 'compaction';\n key: string;\n turnId: string | null;\n at: string;\n trigger: 'auto' | 'manual';\n preTokens: number | null;\n postTokens: number | null;\n durationMs: number | null;\n }\n | { kind: 'cancelled'; key: string; turnId: string; at: string }\n | { kind: 'turn-done'; key: string; turnId: string; at: string; ok: boolean; durationMs: number }\n /** V3.10: the engine restored a lost native conversation. */\n | { kind: 'recovered'; key: string; turnId: string | null; at: string; how: VerseRecoveryHow; message: string }\n /** V3.10: the log hit its cap and dropped everything before `droppedBefore` (at a turn boundary). */\n | { kind: 'truncated'; key: string; turnId: null; at: string; droppedBefore: number };\n\n/**\n * One turn's worth of items — the log cut at each `user-message`. Unchanged\n * segments come back as the SAME object from a cached build, which is what\n * lets the renderer skip every finished turn while one is streaming.\n */\nexport interface TranscriptSegment {\n key: string;\n items: TranscriptItem[];\n}\n\nexport interface Transcript {\n items: TranscriptItem[];\n /** True while a turn is open (started and not yet done/cancelled). */\n live: boolean;\n /** Most recent usage frame seen in the log, if any. */\n usage: VerseUsage | null;\n /** `items`, cut into turn segments. Absent on a hand-built transcript (treated as one segment). */\n segments?: TranscriptSegment[];\n}\n\n/** Wall time between two ISO stamps; null when either is unparseable. */\nfunction spanMs(from: string, to: string): number | null {\n const a = Date.parse(from);\n const b = Date.parse(to);\n return Number.isFinite(a) && Number.isFinite(b) ? Math.max(0, b - a) : null;\n}\n\ninterface PendingText {\n turnId: string;\n at: string;\n text: string;\n key: string;\n}\n\ninterface SegmentBuild {\n /** Items without the trailing streamed text, which depends on whether the WHOLE log is live. */\n items: TranscriptItem[];\n pending: PendingText | null;\n /** The last live-flag change in this segment: true (started), false (ended) or null (none). */\n liveEffect: boolean | null;\n usage: VerseUsage | null;\n /** tool-results in this segment whose tool-use is not in it. */\n orphanResults: string[];\n toolUseIds: string[];\n}\n\ninterface CachedSegment {\n firstSeq: number;\n lastSeq: number;\n count: number;\n build: SegmentBuild;\n /** The finished segment per trailing-streaming flag it was finalized with. */\n finalized: { streaming: boolean; segment: TranscriptSegment } | null;\n}\n\nexport interface TranscriptCache {\n segments: Map<string, CachedSegment>;\n}\n\nexport function createTranscriptCache(): TranscriptCache {\n return { segments: new Map() };\n}\n\nexport interface BuildTranscriptOptions {\n /** Reuse segments from a previous build of the same session's log. */\n cache?: TranscriptCache;\n /** Measured figures for reasoning blocks this tab watched stream, by the persisted event's seq. */\n thinkingStats?: ReadonlyMap<number, VerseThinkingStat>;\n}\n\n/**\n * The original single-pass derivation over `events[from, to)`. A whole log\n * run through it in one range is exactly the pre-3.10 buildTranscript; cut\n * at `user-message` boundaries (where it flushes anyway) the pieces\n * concatenate to the same items.\n */\nfunction buildSegment(\n events: readonly VerseEvent[],\n from: number,\n to: number,\n stats: ReadonlyMap<number, VerseThinkingStat> | undefined,\n): SegmentBuild {\n const items: TranscriptItem[] = [];\n const toolIndex = new Map<string, number>();\n const orphanResults: string[] = [];\n const toolUseIds: string[] = [];\n let pending: PendingText | null = null;\n let liveEffect: boolean | null = null;\n let usage: VerseUsage | null = null;\n\n const flushPending = () => {\n if (!pending) return;\n items.push({ kind: 'assistant', key: pending.key, turnId: pending.turnId, at: pending.at, text: pending.text, streaming: false });\n pending = null;\n };\n\n for (let i = from; i < to; i += 1) {\n const e = events[i]!;\n switch (e.type) {\n case 'user-message':\n flushPending();\n items.push({ kind: 'user', key: `u-${e.seq}`, turnId: e.turnId, at: e.at, text: e.text });\n break;\n case 'turn-started':\n liveEffect = true;\n break;\n case 'text-delta':\n if (pending && pending.turnId !== e.turnId) flushPending();\n if (!pending) pending = { turnId: e.turnId, at: e.at, text: '', key: `d-${e.seq}` };\n pending.text += e.text;\n break;\n case 'assistant-message':\n // The complete message supersedes whatever deltas streamed before it.\n pending = null;\n items.push({ kind: 'assistant', key: `a-${e.seq}`, turnId: e.turnId, at: e.at, text: e.text, streaming: false });\n break;\n case 'thinking': {\n flushPending();\n const measured = stats?.get(e.seq);\n items.push({\n kind: 'thinking',\n key: `t-${e.seq}`,\n turnId: e.turnId,\n at: e.at,\n text: e.text,\n redacted: e.redacted === true,\n durationMs: typeof e.durationMs === 'number' && Number.isFinite(e.durationMs) && e.durationMs >= 0\n ? e.durationMs\n : measured?.durationMs ?? null,\n estimatedTokens: measured?.estimatedTokens ?? null,\n thinkingKind: e.kind ?? null,\n });\n break;\n }\n case 'tool-use':\n flushPending();\n toolIndex.set(e.toolUseId, items.length);\n toolUseIds.push(e.toolUseId);\n items.push({\n kind: 'tool',\n key: `tu-${e.seq}`,\n turnId: e.turnId,\n at: e.at,\n toolUseId: e.toolUseId,\n name: e.name,\n input: e.input,\n result: null,\n durationMs: null,\n });\n break;\n case 'tool-result': {\n const idx = toolIndex.get(e.toolUseId);\n const existing = idx === undefined ? undefined : items[idx];\n if (existing && existing.kind === 'tool') {\n items[idx!] = { ...existing, result: { output: e.output, isError: e.isError }, durationMs: spanMs(existing.at, e.at) };\n } else {\n orphanResults.push(e.toolUseId);\n items.push({\n kind: 'tool',\n key: `tr-${e.seq}`,\n turnId: e.turnId,\n at: e.at,\n toolUseId: e.toolUseId,\n name: 'tool',\n input: null,\n result: { output: e.output, isError: e.isError },\n durationMs: null,\n });\n }\n break;\n }\n case 'usage':\n usage = e.usage;\n break;\n case 'compaction':\n // Deliberately NO flushPending: CLIs compact between model calls, and\n // flushing a streamed bubble here would leave it in the list when the\n // complete `assistant-message` arrives — the same reply twice.\n items.push({\n kind: 'compaction',\n key: `k-${e.seq}`,\n turnId: e.turnId,\n at: e.at,\n trigger: e.trigger,\n preTokens: e.preTokens,\n postTokens: e.postTokens,\n durationMs: e.durationMs,\n });\n break;\n case 'error':\n flushPending();\n items.push({ kind: 'error', key: `e-${e.seq}`, turnId: e.turnId, at: e.at, message: e.message, code: typeof e.code === 'string' && e.code ? e.code : null });\n break;\n case 'cancelled':\n flushPending();\n liveEffect = false;\n items.push({ kind: 'cancelled', key: `c-${e.seq}`, turnId: e.turnId, at: e.at });\n break;\n case 'turn-done':\n flushPending();\n liveEffect = false;\n items.push({ kind: 'turn-done', key: `td-${e.seq}`, turnId: e.turnId, at: e.at, ok: e.ok, durationMs: e.durationMs });\n break;\n case 'recovered':\n // Like compaction, no flush: recovery happens before the new native\n // session produces anything, never in the middle of a reply.\n items.push({ kind: 'recovered', key: `r-${e.seq}`, turnId: e.turnId, at: e.at, how: e.how, message: e.message });\n break;\n case 'history-truncated':\n items.push({ kind: 'truncated', key: `h-${e.seq}`, turnId: null, at: e.at, droppedBefore: e.droppedBefore });\n break;\n default:\n break;\n }\n }\n return { items, pending, liveEffect, usage, orphanResults, toolUseIds };\n}\n\nfunction finalizeSegment(key: string, build: SegmentBuild, streaming: boolean): TranscriptSegment {\n const p = build.pending;\n if (!p) return { key, items: build.items };\n return {\n key,\n items: [...build.items, { kind: 'assistant', key: p.key, turnId: p.turnId, at: p.at, text: p.text, streaming }],\n };\n}\n\n// `VerseEvent[]` (not readonly) is the published signature: callers type\n// their fixture arrays as `Parameters<typeof buildTranscript>[0]` and push.\nexport function buildTranscript(events: VerseEvent[], options: BuildTranscriptOptions = {}): Transcript {\n const { cache, thinkingStats: stats } = options;\n if (events.length === 0) return { items: [], live: false, usage: null, segments: [] };\n\n // Cut at every user-message: a new ask always opens a new turn, and the\n // derivation flushes its streamed text there, so nothing spans the cut.\n const starts: number[] = [0];\n for (let i = 1; i < events.length; i += 1) if (events[i]!.type === 'user-message') starts.push(i);\n\n const builds: Array<{ key: string; build: SegmentBuild; cached: CachedSegment | null }> = [];\n const seenKeys = new Set<string>();\n for (let s = 0; s < starts.length; s += 1) {\n const from = starts[s]!;\n const to = s + 1 < starts.length ? starts[s + 1]! : events.length;\n const firstSeq = events[from]!.seq;\n const lastSeq = events[to - 1]!.seq;\n const count = to - from;\n const key = `s-${firstSeq}`;\n seenKeys.add(key);\n const hit = cache?.segments.get(key);\n if (hit && hit.firstSeq === firstSeq && hit.lastSeq === lastSeq && hit.count === count) {\n builds.push({ key, build: hit.build, cached: hit });\n continue;\n }\n const build = buildSegment(events, from, to, stats);\n const entry: CachedSegment = { firstSeq, lastSeq, count, build, finalized: null };\n cache?.segments.set(key, entry);\n builds.push({ key, build, cached: entry });\n }\n if (cache) for (const key of [...cache.segments.keys()]) if (!seenKeys.has(key)) cache.segments.delete(key);\n\n // A tool-result whose tool-use sits in an EARLIER segment would have\n // updated that earlier card in the single-pass derivation. It never\n // happens in a real log (a result follows its call inside one turn); if it\n // does, derive the whole log in one pass rather than render it differently.\n if (builds.length > 1) {\n const earlier = new Set<string>();\n for (const b of builds) {\n if (b.build.orphanResults.some((id) => earlier.has(id))) return singlePass(events, stats);\n for (const id of b.build.toolUseIds) earlier.add(id);\n }\n }\n\n let live = false;\n let usage: VerseUsage | null = null;\n for (const b of builds) {\n if (b.build.liveEffect !== null) live = b.build.liveEffect;\n if (b.build.usage !== null) usage = b.build.usage;\n }\n\n const segments: TranscriptSegment[] = [];\n const items: TranscriptItem[] = [];\n for (let s = 0; s < builds.length; s += 1) {\n const b = builds[s]!;\n // Deltas still arriving for an open turn render as a streaming bubble;\n // every earlier segment's trailing text was flushed by the next ask.\n const streaming = s === builds.length - 1 ? live : false;\n let segment: TranscriptSegment;\n if (b.cached?.finalized && b.cached.finalized.streaming === streaming) {\n segment = b.cached.finalized.segment;\n } else {\n segment = finalizeSegment(b.key, b.build, streaming);\n if (b.cached) b.cached.finalized = { streaming, segment };\n }\n segments.push(segment);\n for (const item of segment.items) items.push(item);\n }\n return { items, live, usage, segments };\n}\n\nfunction singlePass(events: readonly VerseEvent[], stats: ReadonlyMap<number, VerseThinkingStat> | undefined): Transcript {\n const build = buildSegment(events, 0, events.length, stats);\n const live = build.liveEffect ?? false;\n const segment = finalizeSegment(`s-${events[0]!.seq}`, build, live);\n return { items: segment.items, live, usage: build.usage, segments: [segment] };\n}\n\n// ---------------------------------------------------------------------------\n// Render-time grouping\n// ---------------------------------------------------------------------------\n\nexport type ToolGroupMember = Extract<TranscriptItem, { kind: 'tool' | 'thinking' }>;\n\nexport interface ToolGroupItem {\n kind: 'toolGroup';\n key: string;\n turnId: string;\n at: string;\n items: ToolGroupMember[];\n /** Tool calls only (thinking blocks are not counted). */\n toolCount: number;\n /** \"Read ×6, Edit ×4\" — names in first-seen order. */\n summary: string;\n errorCount: number;\n /** A member is still waiting for its result. */\n pending: boolean;\n /** Wall time between the first and last member, when both have parseable timestamps. */\n spanMs: number | null;\n}\n\nexport type TranscriptRenderItem = TranscriptItem | ToolGroupItem;\n\n/**\n * Fold runs of consecutive tool calls from the same turn that hold two or\n * more calls into one `toolGroup`, so an agentic turn reads as \"N tool calls\"\n * with a single disclosure instead of a wall of cards. A single call (with\n * whatever reasoning surrounds it) stays as it is.\n * Pure over buildTranscript()'s output (the index-based tool-result pairing\n * there is untouched).\n *\n * Reasoning INTERLEAVED between tool calls folds with them (it explains the\n * next call). Reasoning that ENDS a run — the model's last thought before it\n * answers or before the next ask — is lifted out and rendered on its own, so\n * the part worth reading is never two disclosures deep. A run of reasoning\n * alone never folds.\n */\nexport function groupTranscriptItems(items: readonly TranscriptItem[]): TranscriptRenderItem[] {\n const out: TranscriptRenderItem[] = [];\n let run: ToolGroupMember[] = [];\n\n const flush = () => {\n if (run.length === 0) return;\n let end = run.length;\n while (end > 0 && run[end - 1]!.kind === 'thinking') end -= 1;\n const folded = run.slice(0, end);\n const trailing = run.slice(end);\n // Only a run with two or more CALLS is worth a disclosure: \"1 tool\" hiding\n // a single call plus the reasoning before it is a click for nothing.\n if (folded.filter((m) => m.kind === 'tool').length >= 2) out.push(makeToolGroup(folded));\n else for (const member of folded) out.push(member);\n for (const thought of trailing) out.push(thought);\n run = [];\n };\n\n for (const item of items) {\n if ((item.kind === 'tool' || item.kind === 'thinking') && (run.length === 0 || run[0]!.turnId === item.turnId)) {\n run.push(item);\n continue;\n }\n flush();\n if (item.kind === 'tool' || item.kind === 'thinking') run.push(item);\n else out.push(item);\n }\n flush();\n return out;\n}\n\nfunction makeToolGroup(members: ToolGroupMember[]): ToolGroupItem {\n const counts = new Map<string, number>();\n let errorCount = 0;\n let pending = false;\n for (const m of members) {\n if (m.kind !== 'tool') continue;\n counts.set(m.name, (counts.get(m.name) ?? 0) + 1);\n if (m.result === null) pending = true;\n else if (m.result.isError) errorCount += 1;\n }\n const toolCount = [...counts.values()].reduce((a, b) => a + b, 0);\n const summary = [...counts.entries()].map(([name, n]) => (n > 1 ? `${name} ×${n}` : name)).join(', ');\n const span = spanMs(members[0]!.at, members[members.length - 1]!.at);\n return {\n kind: 'toolGroup',\n key: `g-${members[0]!.key}`,\n turnId: members[0]!.turnId,\n at: members[0]!.at,\n items: members,\n toolCount,\n summary,\n errorCount,\n pending,\n spanMs: span,\n };\n}\n\n/**\n * \"123k\" / \"1.2M\" — compact token counts for the meter and usage rows.\n *\n * The unit is chosen AFTER rounding: choosing it first printed 999,500–\n * 999,999 as \"1000k\" (and 999.5–999.9 as \"1000\"), a band a 1M Claude chat in\n * Expansive can actually reach.\n */\nexport function formatTokens(n: number | null | undefined): string {\n if (n === null || n === undefined || !Number.isFinite(n)) return '—';\n if (Math.round(n) < 1000) return String(Math.round(n));\n if (Math.round(n / 1000) < 1000) return `${Math.round(n / 1000)}k`;\n return `${(n / 1_000_000).toFixed(1).replace(/\\.0$/, '')}M`;\n}\n"],"mappings":"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"}
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/AppsSection-CXxbfPJQ.js","assets/index-afDA8cwW.js","assets/global-DVgMguLr.js","assets/global-_tOCFt9y.css","assets/MutationTokenDialog-Dn0tzCrh.js","assets/MutationTokenDialog-Cum_DqQZ.css","assets/workbench-types-DzN-5trg.js","assets/dock-store-_E5h6TEq.js","assets/viewport-ZB86jdES.js","assets/verse-queries-BjQoOTwv.js","assets/section-visibility-CSrsTcwK.js","assets/icons-DWb24OA6.js","assets/VerseConsoleApp-bjARLPwN.js","assets/RouteErrorBoundary-AyUPCIb3.js","assets/RouteErrorBoundary-6RMd_aZg.css","assets/command-catalog-s3W6Z96D.js","assets/guarded-action-vOPc8v75.js","assets/composer-keys-CYz4U4Bg.js","assets/command-bus-CpYuam1F.js","assets/useActivity-Cg_9-7nt.js","assets/VerseConsoleApp-C0V221WL.css","assets/capacity-strip-model-BR539Ci8.js","assets/verse-model-E98kXngO.js","assets/seat-subscription-CrWOV4Qc.js","assets/CapacityStrip-D6Yyg4a1.js","assets/Tag-DEEbDz7T.js","assets/Tag-D0rAEciH.css","assets/budget-queries-Dacv1VYP.js","assets/useSeatsRefresh-4Ov9eT1F.js","assets/CapacityStrip-wgFP9MUA.css","assets/Button-0-nNbv1h.js","assets/Button-DrnKsvnQ.css","assets/use-token-gate-DYA2-ALC.js","assets/slots-W8gkmdfE.js","assets/EmptyState-DdJ4CxtO.js","assets/EmptyState-B3YUPGaa.css","assets/Switch-BzRXtNPt.js","assets/Switch-CU044EaE.css","assets/BudgetControl-P5lMxHvQ.js","assets/Segmented-B_8c_83S.js","assets/Segmented-BnjHbKzH.css","assets/Slider-BS9MU5ZV.js","assets/Slider-AgAdMFpo.css","assets/BudgetControl-CmG1JOWK.css","assets/Select-Bl5g5Dt_.js","assets/Select-DSu5ghId.css","assets/Input-CTu0CycC.js","assets/Input-BQ3PR065.css","assets/Sheet-CVjk-cLI.js","assets/Sheet-ChxlNivX.css","assets/AppsSection-D88QlDpG.css","assets/AutonomySection-CoMngwNB.js","assets/Advanced-DM0DYibH.js","assets/Epistemic-BLjM5y_y.js","assets/Epistemic-OaGnEJkn.css","assets/StatusBadge-DAf-ArKE.js","assets/StatusBadge-BVi0IBb9.css","assets/RefreshIndicator-CnhEovMZ.js","assets/RefreshIndicator-CVv22U_j.css","assets/workspace-model-4hq_Mv3N.js","assets/Meter-C18ciKz4.js","assets/Meter-CYt9KpM0.css","assets/control-queries-BGjarMm9.js","assets/mutations-C6E10SPX.js","assets/format-BNYWGJat.js","assets/use-ticker-hryPXnyp.js","assets/fleet-model-ClBbQ0Uj.js","assets/overnight-queries-CCGfiS-g.js","assets/use-guarded-action-CO_aAsed.js","assets/Advanced-CHjxJt2z.css","assets/ChatSection-B9cdRKUh.js","assets/verse-store-BgKx_YGs.js","assets/types-Dypu22dp.js","assets/ChatSection-C9obUsLL.css","assets/CommandSection-BC0uXim_.js","assets/Swimlane-BR40WVcj.js","assets/useChartWidth-MEXvDxDL.js","assets/colors-B-vHsX1S.js","assets/useChartWidth-B8E5mJgM.css","assets/Swimlane-o6_Zsrnr.css","assets/BurnDown-4P1LDoCL.js","assets/BurnDown-BuLMsJMx.css","assets/AreaTrend-gUVXkfhf.js","assets/surface-data-ZtCegYMQ.js","assets/actions-Bszsdpms.js","assets/actions-Dug8YIf0.css","assets/Surface-CiYOdNKQ.js","assets/Surface-DMca0gAe.css","assets/LeaderCard-BuSDeATv.js","assets/live-model-Dm6ITHvX.js","assets/FleetSection-DuJcQCGg.js","assets/Funnel-qX3Hlbce.js","assets/FleetSection-w9AjqfTR.css","assets/GrowthSection-CYxJ9MH5.js","assets/queries-BuYIEHst.js","assets/StepBand-B1W7rU70.js","assets/StepBand-Dz_9Kryb.css","assets/McpSection-1UncWBpW.js","assets/MindSection-C3fCw_fD.js","assets/MatrixHeatmap-B_JWCjZx.js","assets/MatrixHeatmap-9dKgJ_pT.css","assets/mind.module-BzhAlg3e.js","assets/mind-B-lYfSUJ.css","assets/SettingsSection-CuESA30a.js","assets/reasoning-pref-BVzGczV7.js","assets/primitives-DQvYikjm.js","assets/ShortcutsOverlay-BiBjnBcc.js","assets/ShortcutsOverlay-QSjxmW0a.css","assets/SettingsSection-B8yD34ZM.css","assets/UsageSection-B6fR3cru.js","assets/charts-D4NaLaXA.js","assets/charts-uSX6xVYN.css","assets/context-model-Bto3LZn2.js","assets/usage-queries-CQOpeE1H.js","assets/UsageSection-DwgNOYvi.css"])))=>i.map(i=>d[i]);
|
|
2
|
-
import{t as e}from"./index-afDA8cwW.js";import{r as t,x as n}from"./workbench-types-DzN-5trg.js";import{f as r,i,v as a,y as o}from"./dock-store-_E5h6TEq.js";Object.freeze({entries:Object.freeze([]),index:-1});function s(e,t){return!!e&&e.section===t.section&&(e.section!==`chat`||e.sessionId===t.sessionId)}function c(e,t){let n={section:t.section,sessionId:t.section===`chat`?t.sessionId:null},r=e.entries[e.index];if(s(r,n))return e;if(r&&r.section===`chat`&&r.sessionId===null&&n.section===`chat`){let t=[...e.entries.slice(0,e.index),n];return{entries:t,index:t.length-1}}let i=[...e.entries.slice(0,e.index+1),n].slice(-50);return{entries:i,index:i.length-1}}function l(e,t){let n=e.index+t,r=e.entries[n];return r?{history:{entries:e.entries,index:n},entry:r}:null}var u=1500;function d(e,t,n,r,i=u){let a=!t||r-t.at>i,o=a?e:t.order;if(o.length<2)return null;let s=((a?0:t.position)+n+o.length)%o.length;return{sessionId:o[s],cycle:{order:o,position:s,at:r}}}function f(e,t,n=10){return[t,...e.filter(e=>e!==t)].slice(0,n)}var p=Object.fromEntries(Object.entries(Object.assign({"../sections/AppsSection.tsx":()=>e(()=>import(`./AppsSection-CXxbfPJQ.js`),__vite__mapDeps([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50])),"../sections/AutonomySection.tsx":()=>e(()=>import(`./AutonomySection-CoMngwNB.js`),__vite__mapDeps([51,1,52,2,3,4,5,53,54,55,56,13,14,57,58,9,6,12,15,16,8,17,18,10,19,11,20,39,40,59,22,60,61,44,45,62,63,64,65,66,67,68,69])),"../sections/ChatSection.tsx":()=>e(()=>import(`./ChatSection-B9cdRKUh.js`).then(e=>e.t),__vite__mapDeps([70,1,2,3,4,5,13,14,15,7,8,9,6,18,10,12,16,17,19,11,20,71,72,30,31,73])),"../sections/CommandSection.tsx":()=>e(()=>import(`./CommandSection-BC0uXim_.js`),__vite__mapDeps([74,1,2,3,57,58,75,76,77,78,79,80,81,82,15,8,9,6,10,19,11,12,13,4,5,14,16,17,18,20,39,40,25,26,27,30,31,38,21,22,23,32,41,42,36,37,43,64,65,83,62,63,48,49,84,68,85,86,87,88,89])),"../sections/FleetSection.tsx":()=>e(()=>import(`./FleetSection-DuJcQCGg.js`),__vite__mapDeps([90,1,2,3,57,58,75,76,77,78,79,91,8,10,11,12,13,4,5,14,15,6,16,9,17,18,19,20,25,26,27,30,31,64,65,67,62,63,83,84,68,85,86,87,89,92])),"../sections/GrowthSection.tsx":()=>e(()=>import(`./GrowthSection-CYxJ9MH5.js`),__vite__mapDeps([93,1,2,3,94,57,58,76,77,78,82,91,95,96,10,65,83,19,6,62,63,86,8,87])),"../sections/McpSection.tsx":()=>e(()=>import(`./McpSection-1UncWBpW.js`),__vite__mapDeps([97,1,0,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50])),"../sections/MindSection.tsx":()=>e(()=>import(`./MindSection-C3fCw_fD.js`),__vite__mapDeps([98,1,2,3,57,58,82,76,77,78,99,100,8,10,12,13,4,5,14,15,6,16,9,17,18,19,11,20,64,83,62,63,101,102,84,30,31,68,85,86,87,88,65])),"../sections/SettingsSection.tsx":()=>e(()=>import(`./SettingsSection-CuESA30a.js`),__vite__mapDeps([103,1,2,3,4,5,55,56,13,14,15,11,12,6,16,8,9,17,18,10,19,20,39,40,72,25,26,30,31,104,32,60,61,41,42,36,37,44,45,46,47,105,53,54,57,58,34,35,48,49,106,107,108])),"../sections/UsageSection.tsx":()=>e(()=>import(`./UsageSection-B6fR3cru.js`),__vite__mapDeps([109,1,2,3,53,54,55,56,94,76,77,78,110,75,79,80,81,82,91,95,96,99,100,111,9,6,71,72,22,112,24,10,21,23,25,26,27,28,29,64,66,113,114]))})).map(([e,t])=>[e.replace(/^\.\.\//,`./`),t]));function m(e,t=p){return t[`./sections/${e}.tsx`]}var h=[{id:`command`,label:`Command`,module:`CommandSection`,placement:`rail`,blurb:`What the fleet did, what needs you, and the autonomy switch — the morning read.`},{id:`fleet`,label:`Fleet`,module:`FleetSection`,fallbackModules:[`AutonomySection`],placement:`rail`,blurb:`Every lane live: what is building, what the gates refused, and why each seat was chosen.`},{id:`growth`,label:`Growth`,module:`GrowthSection`,placement:`rail`,blurb:`Is the fleet getting better? Merges, cost per merge and the experiments behind them.`},{id:`mind`,label:`Mind`,module:`MindSection`,placement:`rail`,blurb:`The Leader's memos, what came of each move, and what the reasoning shows.`},{id:`chat`,label:`Chat`,module:`ChatSection`,placement:`rail`,blurb:`Talk to a seat. Chats are grouped by project and resume where they stopped.`},{id:`settings`,label:`Settings`,module:`SettingsSection`,placement:`tray`,blurb:`Theme, chat, desktop and keyboard — and this tour again.`},{id:`apps`,label:`Apps & Accounts`,module:`AppsSection`,placement:`tray`,blurb:`Seats, terminal agents, local models and MCP servers in one list.`},{id:`usage`,label:`Usage`,module:`UsageSection`,placement:`tray`,blurb:`Which account you can actually use right now, and what it costs.`}],g=h.filter(e=>e.placement===`rail`);h.filter(e=>e.placement===`tray`);var _=new Set(h.map(e=>e.id));function v(e){return h.find(t=>t.id===e)}function y(e,t=e=>m(e)!==void 0){let n=v(e);for(let e of[n.module,...n.fallbackModules??[]])if(t(e))return e;return null}var b=[`all`,...t],x={min:240,max:360,def:264},S={min:260,max:480,def:320},C={section:`chat`,railExpanded:!1,sidebarWidth:x.def,sidebarCollapsed:!1,resourcesOpen:!0,resourcesWidth:S.def,recentActions:[],recentChats:[],mounted:[`chat`],overlay:null,needsYouSplit:`all`,needsYouFocus:null,history:{entries:[{section:`chat`,sessionId:null}],index:0},activeSessionId:null,command:null,announceChatMoved:!1};function w(e,t){let n=Number(e);return!Number.isFinite(n)||n<=0?t.def:Math.max(t.min,Math.min(t.max,Math.round(n)))}function ee(e){let t=new Date(e),n=e=>String(e).padStart(2,`0`);return`${t.getFullYear()}-${n(t.getMonth()+1)}-${n(t.getDate())}`}function te(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function T(e,t,n){if(!Array.isArray(e))return[];let r=[];for(let i of e)if(typeof i==`string`&&n.test(i)&&!r.includes(i)&&r.push(i),r.length>=t)break;return r}function E(e){try{let t=localStorage.getItem(e);if(!t)return null;let n=JSON.parse(t);return te(n)?n:null}catch{return null}}var D=null,O=!1;function k(e={}){let t=e.now??Date.now(),r=e.landed??(e=>m(e)!==void 0),i=E(a),s=i?null:E(o),c=i??s??{},l=C.section,u=null,d=n(c.section);d&&_.has(d.section)&&(l=d.section,d.openNeedsYou&&!i&&(u=`needs-you`)),D=i&&typeof i.lastLaunchDay==`string`?i.lastLaunchDay:null,O=i?i.chatMovedAnnounced===!0:!1;let f=ee(t);return D!==f&&y(`command`,r)!==null&&(l=`command`),D=f,{...C,section:l,railExpanded:c.railExpanded===!0,sidebarWidth:w(c.sidebarWidth,x),sidebarCollapsed:c.sidebarCollapsed===!0,resourcesOpen:c.resourcesOpen!==!1,resourcesWidth:w(c.resourcesWidth,S),recentActions:T(c.recentActions,5,/^[a-z][a-z0-9.-]{0,63}$/),recentChats:T(c.recentChats,10,/^[\w.-]{1,200}$/),mounted:[l],overlay:u,history:{entries:[{section:l,sessionId:null}],index:0},announceChatMoved:s!==null&&!O}}var A=C,j=0,M=null,N=new Set;function P(e){let t={version:3,section:e.section,railExpanded:e.railExpanded,sidebarWidth:e.sidebarWidth,sidebarCollapsed:e.sidebarCollapsed,resourcesOpen:e.resourcesOpen,resourcesWidth:e.resourcesWidth,recentActions:[...e.recentActions],recentChats:[...e.recentChats],lastLaunchDay:D,chatMovedAnnounced:O,dock:i()};try{localStorage.setItem(a,JSON.stringify(t))}catch{}}var ne=[`section`,`railExpanded`,`sidebarWidth`,`sidebarCollapsed`,`resourcesOpen`,`resourcesWidth`,`recentActions`,`recentChats`];function F(e){let t={...A,...e};if(Object.keys(e).every(e=>Object.is(A[e],t[e])))return;let n=ne.some(e=>!Object.is(A[e],t[e]));A=t,n&&P(t);for(let e of[...N])e()}function I(){A=k(),P(A)}I();var L=``;r(()=>{let e=``;try{e=JSON.stringify(i())}catch{e=``}e!==L&&(L=e,P(A))});function R(e){return N.add(e),()=>N.delete(e)}function re(){return A}function ie(e,t){let n=t===`chat`||e.includes(`chat`),r=e.filter(e=>e!==`chat`&&e!==t),i=(t===`chat`?r:[t,...r]).slice(0,3),a=t===`chat`?[`chat`,...i]:i;return n&&!a.includes(`chat`)&&a.push(`chat`),a}function z(e,t){if(!_.has(e))return;let n=t.history?c(A.history,{section:e,sessionId:e===`chat`?A.activeSessionId:null}):A.history;F({section:e,mounted:ie(A.mounted,e),history:n})}var B=`ashlr:verse-anchor`;function V(e,t=null){if(z(e,{history:!0}),!t||typeof window>`u`)return;let n={section:e,anchor:t};window.dispatchEvent(new CustomEvent(B,{detail:n}))}function H(e){let t=l(A.history,e);if(!t)return!1;F({history:t.history}),z(t.entry.section,{history:!1});let n=t.entry.sessionId;return t.entry.section===`chat`&&n&&n!==A.activeSessionId&&(K(`open-session`,{sessionId:n},!1),F({activeSessionId:n,recentChats:f(A.recentChats,n)})),!0}function U(e){e!==A.activeSessionId&&F({activeSessionId:e,recentChats:e?f(A.recentChats,e):A.recentChats,history:e&&A.section===`chat`?c(A.history,{section:`chat`,sessionId:e}):A.history})}function W(e,t=Date.now()){let n=d(A.activeSessionId?f(A.recentChats,A.activeSessionId):[...A.recentChats],M,e,t);return n?(M=n.cycle,J(n.sessionId),n.sessionId):null}var G=`ashlr.verse.selected.v1`;function K(e,t,n){j+=1;let r={name:e,nonce:j,...t};n&&A.section!==`chat`&&z(`chat`,{history:!0}),F({command:r})}function q(e,t={}){K(e,t,!0)}function J(e){if(/^[\w.-]{1,200}$/.test(e)){if(!A.mounted.includes(`chat`))try{localStorage.setItem(G,e)}catch{}K(`open-session`,{sessionId:e},!0),U(e)}}function ae(){F({command:null})}function oe(e){F({overlay:e})}function se(){F({overlay:null,needsYouFocus:null})}function ce(e){F({overlay:A.overlay===e?null:e,needsYouFocus:null})}function le(e={}){F({overlay:`needs-you`,needsYouSplit:e.split??A.needsYouSplit,needsYouFocus:e.focusId??null})}function ue(e){b.includes(e)&&F({needsYouSplit:e})}function de(){F({railExpanded:!A.railExpanded})}function fe(e){F({sidebarCollapsed:e})}function Y(e){/^[a-z][a-z0-9.-]{0,63}$/.test(e)&&F({recentActions:[e,...A.recentActions.filter(t=>t!==e)].slice(0,5)})}function pe(){O=!0,A.announceChatMoved&&F({announceChatMoved:!1}),P(A)}var X=`ashlr.verse.seats.v1`,me=50,Z=null;function Q(){if(Z)return Z;let e={};try{let t=localStorage.getItem(X),n=t?JSON.parse(t):null;if(n&&typeof n==`object`&&!Array.isArray(n))for(let[t,r]of Object.entries(n)){if(!r||typeof r!=`object`||Array.isArray(r))continue;let{seatId:n,model:i}=r;typeof n==`string`&&n.length!==0&&typeof i==`string`&&i.length!==0&&(e[t]={seatId:n,model:i})}}catch{}return Z=e,e}function he(e){let t=Q();if(e){let n=t[e];if(n)return n}let n=Object.keys(t),r=n[n.length-1];return r?t[r]??null:null}function ge(e,t){if(!e||!t.seatId||!t.model)return;let n=Q();delete n[e],n[e]={seatId:t.seatId,model:t.model};let r=Object.keys(n);for(let e of r.slice(0,Math.max(0,r.length-me)))delete n[e];try{localStorage.setItem(X,JSON.stringify(n))}catch{}}var $=new Map,_e=50;function ve(e,t){if(!e||!t)return;let n=$.get(e)??new Set;n.add(t),$.delete(e),$.set(e,n);for(let e of[...$.keys()].slice(0,Math.max(0,$.size-_e)))$.delete(e)}function ye(e,t){return $.get(e)?.has(t)??!1}export{m as A,V as C,ce as D,R as E,de as O,ue as S,H as T,Y as _,pe as a,v as b,W as c,ye as d,y as f,J as g,oe as h,h as i,p as k,ve as l,le as m,g as n,ae as o,he as p,B as r,se as s,b as t,re as u,ge as v,fe as w,U as x,q as y};
|
|
3
|
-
//# sourceMappingURL=verse-ui-store-KTTKfv-T.js.map
|