@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":"BranchBar-C-NovaXr.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/git/BranchBar.module.css","../../../../../../src/web-ui/routes/verse/git/ActionMenu.tsx","../../../../../../src/web-ui/routes/verse/git/GitDialogs.module.css","../../../../../../src/web-ui/routes/verse/git/GitDialogs.tsx","../../../../../../src/web-ui/routes/verse/git/PrChip.module.css","../../../../../../src/web-ui/routes/verse/git/PrChip.tsx","../../../../../../src/web-ui/routes/verse/git/useGitStatuses.ts","../../../../../../src/web-ui/routes/verse/git/BranchBar.tsx"],"sourcesContent":["/*\n * Branch bar (SPEC-310C §2): one quiet line above the composer. Identity in\n * secondary text, the ± counts as a button in the diff's own add/remove\n * colours (with the +/− glyph carrying the meaning), the PR chip, and one\n * primary split button pinned right. At compact width the row wraps: the\n * identity takes the first line, counts + chip + button the second.\n */\n.bar {\n display: flex;\n flex-direction: column;\n gap: var(--space-1);\n min-width: 0;\n}\n\n.rows {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: var(--space-1);\n}\n\n.row {\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: var(--space-2);\n min-width: 0;\n min-height: var(--control-h-sm);\n padding: var(--space-1) var(--space-1) var(--space-1) var(--space-3);\n border: 1px solid var(--border-subtle);\n border-radius: var(--radius-md);\n background: var(--bg-surface);\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line);\n}\n\n.ident {\n display: inline-flex;\n align-items: center;\n gap: var(--space-2);\n min-width: 0;\n flex: 0 1 auto;\n overflow: hidden;\n}\n.glyph { flex: none; color: var(--text-tertiary); }\n.repo {\n flex: none;\n color: var(--text-primary);\n font-weight: var(--font-weight-semibold);\n max-width: 18ch;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.branch {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n font-family: var(--font-mono);\n font-size: var(--text-xs-size);\n color: var(--text-secondary);\n}\n.drift {\n flex: none;\n font-size: var(--text-xs-size);\n color: var(--status-warning-fg);\n}\n\n.stat {\n flex: none;\n display: inline-flex;\n align-items: center;\n gap: var(--space-2);\n min-height: var(--control-h-xs);\n padding: 0 var(--space-2);\n border: 1px solid transparent;\n border-radius: var(--radius-sm);\n background: transparent;\n font-family: var(--font-mono);\n font-size: var(--text-xs-size);\n font-variant-numeric: tabular-nums;\n cursor: pointer;\n transition: background var(--duration-fast) var(--ease-standard), border-color var(--duration-fast) var(--ease-standard);\n}\n.stat:hover { background: var(--bg-hover); border-color: var(--border-default); }\n.stat:focus-visible { outline: none; box-shadow: var(--shadow-focus-ring); }\n.add { color: var(--status-success-fg); }\n.del { color: var(--status-danger-fg); }\n\n.checking,\n.conflicts {\n flex: none;\n font-size: var(--text-xs-size);\n color: var(--text-tertiary);\n}\n.conflicts { color: var(--status-danger-fg); font-weight: var(--font-weight-medium); }\n\n.spacer { flex: 1 1 0; min-width: 0; }\n\n/* ---- split button ------------------------------------------------------ */\n\n.split {\n position: relative;\n flex: none;\n display: inline-flex;\n align-items: stretch;\n margin-left: auto;\n}\n\n.primary,\n.menuButton {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n gap: var(--space-2);\n min-height: var(--control-h-sm);\n border: 1px solid var(--accent-600);\n background: var(--accent-600);\n color: var(--text-on-accent);\n font: inherit;\n font-size: var(--text-sm-size);\n font-weight: var(--font-weight-semibold);\n cursor: pointer;\n transition: background var(--duration-fast) var(--ease-standard), border-color var(--duration-fast) var(--ease-standard);\n}\n.primary {\n padding: 0 var(--space-3);\n border-radius: var(--radius-sm) 0 0 var(--radius-sm);\n}\n.menuButton {\n width: var(--control-h-sm);\n padding: 0;\n border-left-color: color-mix(in srgb, var(--text-on-accent) 35%, var(--accent-600));\n border-radius: 0 var(--radius-sm) var(--radius-sm) 0;\n}\n.primary:hover,\n.menuButton:hover { background: var(--accent-700); border-color: var(--accent-700); }\n.primary:focus-visible,\n.menuButton:focus-visible { outline: none; box-shadow: var(--shadow-focus-ring); z-index: 1; }\n.primary:disabled,\n.menuButton:disabled { cursor: default; opacity: 0.6; }\n\n/* View PR (and a lone ▾) is a quiet action: the work is done, nothing to push. */\n.primary[data-tone='subtle'],\n.primary[data-tone='subtle'] + .visuallyHidden + .menuButton,\n.menuButton[data-alone='true'] {\n background: var(--bg-surface-raised);\n border-color: var(--border-default);\n color: var(--text-primary);\n}\n.primary[data-tone='subtle']:hover,\n.primary[data-tone='subtle'] + .visuallyHidden + .menuButton:hover,\n.menuButton[data-alone='true']:hover { background: var(--bg-hover); border-color: var(--border-strong); }\n.menuButton[data-alone='true'] { border-radius: var(--radius-sm); }\n\n.spinner {\n width: 12px;\n height: 12px;\n border: 2px solid color-mix(in srgb, currentColor 35%, transparent);\n border-top-color: currentColor;\n border-radius: var(--radius-full);\n animation: branch-spin 0.8s linear infinite;\n}\n@keyframes branch-spin { to { transform: rotate(360deg); } }\n@media (prefers-reduced-motion: reduce) {\n :root:not([data-motion='full']) .spinner { animation-duration: 2.4s; }\n}\n\n.menu {\n position: absolute;\n right: 0;\n bottom: calc(100% + var(--space-1));\n z-index: var(--z-dropdown);\n min-width: 15rem;\n max-width: min(20rem, calc(100vw - var(--space-8)));\n padding: var(--space-1);\n display: flex;\n flex-direction: column;\n background: var(--bg-surface-raised);\n border: 1px solid var(--border-default);\n border-radius: var(--radius-md);\n box-shadow: var(--shadow-menu);\n animation: menu-in var(--duration-fast) var(--ease-decelerate);\n}\n.menu:focus { outline: none; }\n@keyframes menu-in {\n from { opacity: 0; transform: translateY(2px); }\n}\n@media (prefers-reduced-motion: reduce) {\n :root:not([data-motion='full']) .menu { animation: none; }\n}\n\n.menuItem {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: 2px;\n width: 100%;\n padding: var(--space-2) var(--space-3);\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-sm-size);\n line-height: var(--text-sm-line);\n text-align: left;\n cursor: pointer;\n}\n.menuItem:hover:not([aria-disabled='true']),\n.menuItem:focus-visible { background: var(--bg-hover); outline: none; }\n.menuItem[aria-disabled='true'] { cursor: default; color: var(--text-tertiary); }\n.menuLabel { font-weight: var(--font-weight-medium); }\n.menuReason {\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n color: var(--text-tertiary);\n}\n\n/* ---- footer lines ------------------------------------------------------ */\n\n.more {\n align-self: flex-start;\n min-height: var(--control-h-xs);\n padding: 0 var(--space-2);\n border: 0;\n background: transparent;\n color: var(--text-link);\n font: inherit;\n font-size: var(--text-xs-size);\n cursor: pointer;\n border-radius: var(--radius-sm);\n}\n.more:hover { text-decoration: underline; }\n.more:focus-visible { outline: none; box-shadow: var(--shadow-focus-ring); }\n\n.notice {\n margin: 0;\n padding: 0 var(--space-3);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n color: var(--text-secondary);\n}\n.notice:empty { display: none; }\n.notice[data-tone='error'] { color: var(--status-danger-fg); }\n\n.visuallyHidden {\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/* ---- compact (< 480) ---------------------------------------------------- */\n\n.bar[data-compact='true'] .row { padding-left: var(--space-2); }\n.bar[data-compact='true'] .ident { flex: 1 1 100%; }\n.bar[data-compact='true'] .repo { max-width: 14ch; }\n","/**\n * routes/verse/git/ActionMenu.tsx — the branch bar's split button: one\n * primary action beside a ▾ menu of the rest (unit C5; SPEC-310C §2).\n *\n * WAI-ARIA menu-button pattern, keyboard first:\n * ▾ / Enter / Space / ↓ open the menu on the first enabled item, ↑ on the\n * last; ↑ ↓ Home End move; Enter or Space runs; Escape closes and returns\n * focus to ▾; Tab closes and lets focus move on; a click outside closes.\n *\n * A disabled item stays in the menu with its reason as visible text under\n * the label (never colour alone, never only a tooltip) and is skipped by the\n * arrow keys — so the operator can always see why Push is not offered.\n */\nimport { useCallback, useEffect, useId, useRef, useState, type KeyboardEvent as ReactKeyboardEvent, type ReactNode } from 'react';\nimport { IconChevronDown } from '../../../components/primitives/icons.js';\nimport styles from './BranchBar.module.css';\n\nexport interface ActionMenuItem<Id extends string> {\n id: Id;\n label: string;\n disabledReason: string | null;\n}\n\nexport interface ActionMenuProps<Id extends string> {\n /** The primary button; null renders the menu button alone. */\n primary: { label: string; disclosure: string; onClick: () => void; busy?: boolean; tone?: 'primary' | 'subtle' } | null;\n items: ReadonlyArray<ActionMenuItem<Id>>;\n onSelect: (id: Id) => void;\n /** Names the menu button for screen readers (\"More git actions for ashlr-hub\"). */\n menuLabel: string;\n disabled?: boolean;\n children?: ReactNode;\n}\n\nexport function ActionMenu<Id extends string>({ primary, items, onSelect, menuLabel, disabled = false }: ActionMenuProps<Id>) {\n const [open, setOpen] = useState(false);\n const [active, setActive] = useState(-1);\n const menuId = useId();\n const disclosureId = useId();\n const buttonRef = useRef<HTMLButtonElement>(null);\n const menuRef = useRef<HTMLDivElement>(null);\n const itemRefs = useRef<Array<HTMLButtonElement | null>>([]);\n\n const enabled = items.map((it, i) => (it.disabledReason === null ? i : -1)).filter((i) => i >= 0);\n\n const close = useCallback((refocus: boolean) => {\n setOpen(false);\n setActive(-1);\n if (refocus) buttonRef.current?.focus();\n }, []);\n\n const openAt = (which: 'first' | 'last') => {\n setOpen(true);\n setActive(enabled.length === 0 ? -1 : which === 'first' ? enabled[0]! : enabled[enabled.length - 1]!);\n };\n\n useEffect(() => {\n if (!open) return;\n if (active >= 0) itemRefs.current[active]?.focus();\n else menuRef.current?.focus();\n }, [open, active]);\n\n useEffect(() => {\n if (!open) return;\n const onDown = (e: MouseEvent) => {\n const t = e.target as Node;\n if (menuRef.current?.contains(t) || buttonRef.current?.contains(t)) return;\n close(false);\n };\n document.addEventListener('mousedown', onDown);\n return () => document.removeEventListener('mousedown', onDown);\n }, [open, close]);\n\n const move = (delta: 1 | -1) => {\n if (enabled.length === 0) return;\n const at = enabled.indexOf(active);\n const next = at === -1 ? (delta === 1 ? 0 : enabled.length - 1) : (at + delta + enabled.length) % enabled.length;\n setActive(enabled[next]!);\n };\n\n const onButtonKey = (e: ReactKeyboardEvent<HTMLButtonElement>) => {\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n openAt('first');\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n openAt('last');\n }\n };\n\n const onMenuKey = (e: ReactKeyboardEvent<HTMLDivElement>) => {\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n move(1);\n break;\n case 'ArrowUp':\n e.preventDefault();\n move(-1);\n break;\n case 'Home':\n e.preventDefault();\n if (enabled.length) setActive(enabled[0]!);\n break;\n case 'End':\n e.preventDefault();\n if (enabled.length) setActive(enabled[enabled.length - 1]!);\n break;\n case 'Escape':\n e.preventDefault();\n e.stopPropagation();\n close(true);\n break;\n case 'Tab':\n close(false);\n break;\n default:\n break;\n }\n };\n\n const run = (item: ActionMenuItem<Id>) => {\n if (item.disabledReason !== null) return;\n close(true);\n onSelect(item.id);\n };\n\n return (\n <div className={styles.split} data-open={open ? 'true' : 'false'}>\n {primary ? (\n <button\n type=\"button\"\n className={styles.primary}\n data-tone={primary.tone ?? 'primary'}\n onClick={primary.onClick}\n disabled={disabled || primary.busy}\n aria-busy={primary.busy || undefined}\n aria-describedby={disclosureId}\n title={primary.disclosure}\n >\n {primary.busy ? <span className={styles.spinner} aria-hidden=\"true\" /> : null}\n {primary.label}\n </button>\n ) : null}\n <span id={disclosureId} className={styles.visuallyHidden}>{primary?.disclosure ?? ''}</span>\n <button\n ref={buttonRef}\n type=\"button\"\n className={styles.menuButton}\n data-alone={primary ? 'false' : 'true'}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-controls={open ? menuId : undefined}\n aria-label={menuLabel}\n disabled={disabled}\n onClick={() => (open ? close(false) : openAt('first'))}\n onKeyDown={onButtonKey}\n >\n <IconChevronDown width={14} height={14} aria-hidden=\"true\" />\n </button>\n {open ? (\n <div ref={menuRef} id={menuId} role=\"menu\" aria-label={menuLabel} className={styles.menu} tabIndex={-1} onKeyDown={onMenuKey}>\n {items.map((item, i) => (\n <button\n key={item.id}\n ref={(el) => { itemRefs.current[i] = el; }}\n type=\"button\"\n role=\"menuitem\"\n className={styles.menuItem}\n tabIndex={i === active ? 0 : -1}\n aria-disabled={item.disabledReason !== null || undefined}\n onClick={() => run(item)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n run(item);\n }\n }}\n >\n <span className={styles.menuLabel}>{item.label}</span>\n {item.disabledReason ? <span className={styles.menuReason}>{item.disabledReason}</span> : null}\n </button>\n ))}\n </div>\n ) : null}\n </div>\n );\n}\n","/*\n * Git dialogs: a list of facts (what the click does), the fields, then the\n * actions. Facts read like a receipt — short lines, refs in mono.\n */\n.form {\n display: flex;\n flex-direction: column;\n gap: var(--space-2);\n}\n\n.facts {\n list-style: none;\n margin: 0 0 var(--space-2);\n padding: var(--space-3);\n display: flex;\n flex-direction: column;\n gap: var(--space-2);\n border: 1px solid var(--border-subtle);\n border-radius: var(--radius-md);\n background: var(--bg-surface);\n}\n\n.fact {\n display: flex;\n gap: var(--space-2);\n align-items: baseline;\n color: var(--text-secondary);\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line);\n}\n.fact strong { color: var(--text-primary); font-weight: var(--font-weight-semibold); }\n.fact[data-tone='warning'] { color: var(--text-primary); }\n\n.factWord {\n flex: none;\n font-family: var(--font-display);\n font-size: var(--text-2xs-size);\n line-height: var(--text-2xs-line);\n letter-spacing: var(--tracking-label);\n text-transform: uppercase;\n color: var(--status-warning-fg);\n font-weight: var(--font-weight-semibold);\n}\n\n.ref {\n font-family: var(--font-mono);\n font-size: var(--text-xs-size);\n color: var(--text-primary);\n padding: 0 var(--space-1);\n border-radius: var(--radius-xs);\n background: var(--bg-code);\n overflow-wrap: anywhere;\n}\n\n.label {\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line);\n font-weight: var(--font-weight-semibold);\n color: var(--text-primary);\n margin-top: var(--space-1);\n}\n.optional {\n font-weight: var(--font-weight-regular);\n color: var(--text-tertiary);\n margin-left: var(--space-1);\n}\n\n.input,\n.textarea {\n width: 100%;\n box-sizing: border-box;\n border: 1px solid var(--border-default);\n border-radius: var(--radius-sm);\n background: var(--bg-input);\n color: var(--text-primary);\n font: inherit;\n font-size: var(--text-base-size);\n line-height: var(--text-base-line);\n padding: var(--space-2) var(--space-3);\n}\n.input { min-height: var(--control-h-sm); }\n.textarea { resize: vertical; min-height: calc(var(--text-base-line) * 3 + var(--space-4)); }\n.input:focus-visible,\n.textarea:focus-visible { outline: none; border-color: var(--border-focus); box-shadow: var(--shadow-focus-ring); }\n.mono { font-family: var(--font-mono); font-size: var(--text-sm-size); }\n\n.row {\n display: flex;\n align-items: flex-end;\n gap: var(--space-3);\n flex-wrap: wrap;\n}\n.field {\n display: flex;\n flex-direction: column;\n gap: var(--space-2);\n flex: 1 1 12rem;\n min-width: 0;\n}\n.check {\n display: inline-flex;\n align-items: center;\n gap: var(--space-2);\n min-height: var(--control-h-sm);\n font-size: var(--text-sm-size);\n color: var(--text-primary);\n cursor: pointer;\n}\n.check input { accent-color: var(--accent-600); width: 16px; height: 16px; }\n\n.hint {\n margin: 0;\n color: var(--text-tertiary);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n}\n.hint kbd {\n font-family: var(--font-mono);\n font-size: var(--text-2xs-size);\n padding: 0 var(--space-1);\n border: 1px solid var(--border-subtle);\n border-radius: var(--radius-xs);\n margin-right: 2px;\n}\n\n.error {\n margin: 0;\n padding: var(--space-2) var(--space-3);\n border-left: 2px solid var(--status-danger-solid);\n background: var(--status-danger-bg);\n color: var(--status-danger-fg);\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line);\n border-radius: var(--radius-xs);\n}\n\n.actions {\n display: flex;\n justify-content: flex-end;\n gap: var(--space-2);\n margin-top: var(--space-3);\n}\n","/**\n * routes/verse/git/GitDialogs.tsx — Commit, Create PR and Merge, each a\n * short dialog that says exactly what the click will do BEFORE it happens\n * (unit C5; the before-click disclosure pattern of github-proposal.ts,\n * SPEC-310C research r5/panes.md §3).\n *\n * Push has no dialog: it never forces, it only publishes commits the operator\n * already made, and the button's own description says where they go.\n *\n * Keys: ⌘/Ctrl+Enter submits from any field; Escape closes (Dialog). The\n * submit button stays disabled while a request runs, so a double press is one\n * action — the server would refuse the second with a 409 anyway.\n */\nimport { useEffect, useId, useRef, useState, type FormEvent, type KeyboardEvent as ReactKeyboardEvent, type ReactNode } from 'react';\nimport { Button } from '../../../components/primitives/Button.js';\nimport { Dialog } from '../../../components/primitives/Dialog.js';\nimport { defaultPrTitle, diffstatText, formatCount, mergeDrift, mergeHeadFact, type GitStatusView, type PinnedMerge } from './git-model.js';\nimport styles from './GitDialogs.module.css';\n\ninterface BaseProps {\n open: boolean;\n status: GitStatusView;\n onClose: () => void;\n /** The server's refusal, shown in the dialog so the operator can fix and retry. */\n error: string | null;\n busy: boolean;\n}\n\n/** ⌘Enter / Ctrl+Enter from any field in the form submits it. */\nfunction submitOnModEnter(e: ReactKeyboardEvent<HTMLFormElement>): void {\n if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {\n e.preventDefault();\n e.currentTarget.requestSubmit();\n }\n}\n\nfunction Facts({ children }: { children: ReactNode }) {\n return <ul className={styles.facts}>{children}</ul>;\n}\n\nfunction Fact({ tone = 'neutral', children }: { tone?: 'neutral' | 'warning'; children: ReactNode }) {\n return (\n <li className={styles.fact} data-tone={tone}>\n {tone === 'warning' ? <span className={styles.factWord}>Note</span> : null}\n <span>{children}</span>\n </li>\n );\n}\n\nfunction ErrorLine({ error }: { error: string | null }) {\n if (!error) return null;\n return (\n <p role=\"alert\" className={styles.error}>\n {error}\n </p>\n );\n}\n\nfunction Branch({ name }: { name: string | null }) {\n return <code className={styles.ref}>{name ?? 'HEAD'}</code>;\n}\n\n// ---------------------------------------------------------------------------\n// Commit\n// ---------------------------------------------------------------------------\n\nexport interface CommitDialogProps extends BaseProps {\n onSubmit: (message: string) => void;\n}\n\nexport function CommitDialog({ open, status, onClose, onSubmit, error, busy }: CommitDialogProps) {\n const titleId = useId();\n const messageId = useId();\n const [message, setMessage] = useState('');\n const ref = useRef<HTMLTextAreaElement>(null);\n useEffect(() => {\n if (open) setMessage('');\n }, [open]);\n\n const submit = (e: FormEvent) => {\n e.preventDefault();\n if (message.trim() && !busy) onSubmit(message.trim());\n };\n\n return (\n <Dialog open={open} onClose={onClose} titleId={titleId} title=\"Commit changes\" initialFocusRef={ref}>\n <form className={styles.form} onSubmit={submit} onKeyDown={submitOnModEnter}>\n <Facts>\n <Fact>\n {formatCount(status.dirty)} changed {status.dirty === 1 ? 'file' : 'files'} in <strong>{status.name}</strong> on <Branch name={status.branch} />, untracked files included.\n </Fact>\n </Facts>\n <label className={styles.label} htmlFor={messageId}>\n Message\n </label>\n <textarea\n id={messageId}\n ref={ref}\n className={styles.textarea}\n rows={4}\n value={message}\n onChange={(e) => setMessage(e.target.value)}\n placeholder=\"What changed, and why\"\n maxLength={10_000}\n required\n />\n <p className={styles.hint}>\n Git hooks in this repository run as usual. <kbd>⌘</kbd>\n <kbd>Enter</kbd> commits.\n </p>\n <ErrorLine error={error} />\n <div className={styles.actions}>\n <Button variant=\"ghost\" onClick={onClose}>\n Cancel\n </Button>\n <Button type=\"submit\" variant=\"primary\" busy={busy} disabled={!message.trim()}>\n Commit\n </Button>\n </div>\n </form>\n </Dialog>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Create PR\n// ---------------------------------------------------------------------------\n\nexport interface CreatePrDialogProps extends BaseProps {\n /** Opened from \"Create draft PR…\". */\n draft: boolean;\n onSubmit: (req: { title: string; body: string; base: string; draft: boolean }) => void;\n}\n\nexport function CreatePrDialog({ open, status, onClose, onSubmit, error, busy, draft: initialDraft }: CreatePrDialogProps) {\n const titleId = useId();\n const fieldTitle = useId();\n const fieldBody = useId();\n const fieldBase = useId();\n const [title, setTitle] = useState('');\n const [body, setBody] = useState('');\n const [base, setBase] = useState('');\n const [draft, setDraft] = useState(initialDraft);\n const ref = useRef<HTMLInputElement>(null);\n\n useEffect(() => {\n if (!open) return;\n setTitle(defaultPrTitle(status));\n setBody('');\n setBase(status.base ?? '');\n setDraft(initialDraft);\n // Seeded once per open: a background status refresh must not wipe what the operator typed.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open]);\n\n const needsPush = status.upstream === null || status.ahead > 0;\n const submit = (e: FormEvent) => {\n e.preventDefault();\n if (title.trim() && base.trim() && !busy) onSubmit({ title: title.trim(), body, base: base.trim(), draft });\n };\n\n return (\n <Dialog open={open} onClose={onClose} titleId={titleId} title={draft ? 'Create draft pull request' : 'Create pull request'} initialFocusRef={ref}>\n <form className={styles.form} onSubmit={submit} onKeyDown={submitOnModEnter}>\n <Facts>\n {needsPush ? (\n <Fact>\n Pushes <Branch name={status.branch} /> to {status.upstream ?? 'origin'} first\n {status.upstream && status.ahead > 0 ? ` (${formatCount(status.ahead)} ${status.ahead === 1 ? 'commit' : 'commits'})` : ''}.\n </Fact>\n ) : null}\n <Fact>\n Then opens a PR from <Branch name={status.branch} /> into <Branch name={base.trim() || null} />:{' '}\n {formatCount(status.diffstat.files)} {status.diffstat.files === 1 ? 'file' : 'files'}, {diffstatText(status.diffstat.additions, status.diffstat.deletions)}.\n </Fact>\n {status.dirty > 0 ? (\n <Fact tone=\"warning\">\n {formatCount(status.dirty)} uncommitted {status.dirty === 1 ? 'change is' : 'changes are'} not in the PR. Commit first to include {status.dirty === 1 ? 'it' : 'them'}.\n </Fact>\n ) : null}\n </Facts>\n <label className={styles.label} htmlFor={fieldTitle}>\n Title\n </label>\n <input id={fieldTitle} ref={ref} className={styles.input} value={title} onChange={(e) => setTitle(e.target.value)} maxLength={256} required />\n <label className={styles.label} htmlFor={fieldBody}>\n Description <span className={styles.optional}>optional</span>\n </label>\n <textarea id={fieldBody} className={styles.textarea} rows={4} value={body} onChange={(e) => setBody(e.target.value)} maxLength={60_000} />\n <div className={styles.row}>\n <div className={styles.field}>\n <label className={styles.label} htmlFor={fieldBase}>\n Base branch\n </label>\n <input\n id={fieldBase}\n className={`${styles.input} ${styles.mono}`}\n value={base}\n onChange={(e) => setBase(e.target.value)}\n spellCheck={false}\n autoCapitalize=\"off\"\n autoCorrect=\"off\"\n required\n />\n </div>\n <label className={styles.check}>\n <input type=\"checkbox\" checked={draft} onChange={(e) => setDraft(e.target.checked)} />\n Draft\n </label>\n </div>\n <ErrorLine error={error} />\n <div className={styles.actions}>\n <Button variant=\"ghost\" onClick={onClose}>\n Cancel\n </Button>\n <Button type=\"submit\" variant=\"primary\" busy={busy} disabled={!title.trim() || !base.trim()}>\n {draft ? 'Create draft PR' : 'Create PR'}\n </Button>\n </div>\n </form>\n </Dialog>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Merge\n// ---------------------------------------------------------------------------\n\nexport interface MergeDialogProps extends Omit<BaseProps, 'status'> {\n /** The PR as it was when the dialog opened — what the operator is confirming (git-model.ts `pinMerge`). */\n pin: PinnedMerge;\n /** The latest polled status for the same root; only used to notice drift, never to change what is shown or sent. */\n live: GitStatusView | null;\n onSubmit: () => void;\n}\n\nexport function MergeDialog({ open, pin, live, onClose, onSubmit, error, busy }: MergeDialogProps) {\n const titleId = useId();\n const confirmRef = useRef<HTMLButtonElement>(null);\n const head = mergeHeadFact(pin);\n // Merge stays disabled when the pin itself is not verified (the facts line\n // then says what is missing) or when the live PR moved away from it.\n const drift = mergeDrift(pin, live);\n const blocked = drift ?? (head.verified ? null : 'This head has not passed every check GitHub needs to merge it.');\n return (\n <Dialog\n open={open}\n onClose={onClose}\n titleId={titleId}\n title={`Merge #${pin.number}?`}\n description={pin.title}\n initialFocusRef={confirmRef}\n >\n <form\n className={styles.form}\n onSubmit={(e) => {\n e.preventDefault();\n if (!busy && blocked === null) onSubmit();\n }}\n onKeyDown={submitOnModEnter}\n >\n <Facts>\n <Fact>\n Squash-merges <Branch name={pin.headRef || null} /> into <Branch name={pin.baseRef || null} /> on GitHub.\n </Fact>\n <Fact tone={head.verified ? 'neutral' : 'warning'}>\n Head <code className={styles.ref}>{head.sha}</code>, {head.detail}\n </Fact>\n <Fact>Only this head merges: GitHub re-checks it first, so if a commit landed after it, nothing merges. Admin overrides are never used.</Fact>\n {blocked !== null ? <Fact tone=\"warning\">{blocked}</Fact> : null}\n </Facts>\n <ErrorLine error={error} />\n <div className={styles.actions}>\n <Button variant=\"ghost\" onClick={onClose}>\n Cancel\n </Button>\n <Button ref={confirmRef} type=\"submit\" variant=\"primary\" busy={busy} disabled={blocked !== null}>\n Merge #{pin.number}\n </Button>\n </div>\n </form>\n </Dialog>\n );\n}\n","/*\n * PR chip: one line, icon + number + state word (+ checks). The tone tints\n * the text and hairline only; the word carries the meaning (DESIGN §13.2).\n */\n.chip {\n display: inline-flex;\n align-items: center;\n gap: var(--space-1);\n min-width: 0;\n max-width: 100%;\n min-height: var(--control-h-xs);\n padding: 0 var(--space-2);\n border: 1px solid var(--border-subtle);\n border-radius: var(--radius-full);\n background: var(--bg-surface);\n color: var(--text-secondary);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n text-decoration: none;\n white-space: nowrap;\n transition: border-color var(--duration-fast) var(--ease-standard), background var(--duration-fast) var(--ease-standard);\n}\n.chip:hover { background: var(--bg-hover); border-color: var(--border-default); }\n.chip:focus-visible { outline: none; box-shadow: var(--shadow-focus-ring); }\n\n.glyph { flex: none; }\n\n.chip[data-tone='success'] .glyph,\n.chip[data-tone='merged'] .glyph,\n.chip[data-tone='success'] .state,\n.chip[data-tone='merged'] .state { color: var(--status-success-fg); }\n.chip[data-tone='danger'] .glyph,\n.chip[data-tone='danger'] .checks { color: var(--status-danger-fg); }\n.chip[data-tone='running'] .checks { color: var(--status-running-fg); }\n.chip[data-tone='warning'] .glyph { color: var(--status-warning-fg); }\n\n.number {\n font-family: var(--font-mono);\n color: var(--text-primary);\n font-variant-numeric: tabular-nums;\n}\n\n.title {\n min-width: 0;\n max-width: 22ch;\n overflow: hidden;\n text-overflow: ellipsis;\n color: var(--text-secondary);\n}\n\n.state { font-weight: var(--font-weight-medium); color: var(--text-primary); }\n.state::before,\n.checks::before {\n content: '·';\n margin-right: var(--space-1);\n color: var(--text-tertiary);\n font-weight: var(--font-weight-regular);\n}\n.checks { color: var(--text-secondary); overflow: hidden; text-overflow: ellipsis; }\n\n.pulse {\n flex: none;\n width: 8px;\n height: 8px;\n margin: 0 2px;\n border-radius: var(--radius-full);\n background: var(--status-running-solid);\n animation: pr-pulse var(--duration-pulse) var(--ease-standard) infinite;\n}\n\n@keyframes pr-pulse {\n 50% { opacity: 0.35; }\n}\n","/**\n * routes/verse/git/PrChip.tsx — a pull request as one chip: an icon WITH a\n * word (`#463 · Merged ✓`, `#481 · Open · 2 of 9 checks failing`) — never a\n * colour alone (DESIGN §13.2 status rule; SPEC-310C §2 \"PR chips\").\n *\n * It is a link to the PR on GitHub (a new window; the desktop shell hands it\n * to the browser). The title is shown at wide widths and folded into the\n * accessible name at narrow ones.\n */\nimport type { VerseGitPr } from '../../../data/api-types.js';\nimport { prChip, type GitCheckCounts, type PrTone } from './git-model.js';\nimport styles from './PrChip.module.css';\n\nexport interface PrChipProps {\n pr: VerseGitPr;\n counts?: GitCheckCounts | null;\n /** Show the PR title (wide layouts). */\n showTitle?: boolean;\n}\n\nexport function PrChip({ pr, counts = null, showTitle = true }: PrChipProps) {\n const model = prChip(pr, counts);\n return (\n <a\n className={styles.chip}\n data-tone={model.tone}\n href={pr.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n aria-label={`${model.label}. Opens on GitHub.`}\n title={pr.title}\n >\n <PrGlyph tone={model.tone} state={pr.state} />\n <span className={styles.number}>{model.number}</span>\n {showTitle && pr.title ? <span className={styles.title}>{pr.title}</span> : null}\n <span className={styles.state}>\n {model.state}\n {pr.state === 'merged' ? ' ✓' : ''}\n </span>\n {model.checks ? <span className={styles.checks}>{model.checks}</span> : null}\n </a>\n );\n}\n\n/** Small state glyph, drawn in currentColor so it follows the tone token. */\nfunction PrGlyph({ tone, state }: { tone: PrTone; state: VerseGitPr['state'] }) {\n const common = { width: 12, height: 12, viewBox: '0 0 16 16', 'aria-hidden': true as const, className: styles.glyph };\n if (state === 'merged') {\n return (\n <svg {...common} fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.6\" strokeLinecap=\"round\">\n <circle cx=\"4\" cy=\"3.5\" r=\"1.8\" />\n <circle cx=\"4\" cy=\"12.5\" r=\"1.8\" />\n <circle cx=\"12\" cy=\"8\" r=\"1.8\" />\n <path d=\"M4 5.3v5.4M5.2 4.6c1.4 2.2 3.2 3.4 5 3.4\" />\n </svg>\n );\n }\n if (state === 'closed') {\n return (\n <svg {...common} fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.6\" strokeLinecap=\"round\">\n <circle cx=\"4\" cy=\"3.5\" r=\"1.8\" />\n <circle cx=\"4\" cy=\"12.5\" r=\"1.8\" />\n <path d=\"M4 5.3v5.4M10 3l4 4M14 3l-4 4\" />\n </svg>\n );\n }\n if (tone === 'running') return <span className={styles.pulse} aria-hidden=\"true\" />;\n if (tone === 'danger') {\n return (\n <svg {...common} fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\">\n <circle cx=\"8\" cy=\"8\" r=\"6\" />\n <path d=\"M5.8 5.8l4.4 4.4M10.2 5.8l-4.4 4.4\" />\n </svg>\n );\n }\n if (tone === 'success') {\n return (\n <svg {...common} fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.8\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <circle cx=\"8\" cy=\"8\" r=\"6\" />\n <path d=\"M5.2 8.2l2 2 3.6-4\" />\n </svg>\n );\n }\n // Open or draft with nothing to report: the pull-request glyph (dashed for a draft).\n return (\n <svg {...common} fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.6\" strokeLinecap=\"round\" strokeDasharray={state === 'draft' ? '2 2' : undefined}>\n <circle cx=\"4\" cy=\"3.5\" r=\"1.8\" />\n <circle cx=\"4\" cy=\"12.5\" r=\"1.8\" />\n <circle cx=\"12\" cy=\"12.5\" r=\"1.8\" />\n <path d=\"M4 5.3v5.4M12 10.7V6.5c0-1.4-.8-2.2-2.2-2.2H7.5\" />\n </svg>\n );\n}\n","/**\n * routes/verse/git/useGitStatuses.ts — one git status per chat root, kept\n * fresh while the chat is on screen (unit C5).\n *\n * Freshness without waste:\n * - one read per root on mount and whenever the root list changes;\n * - a poll every GIT_POLL_MS through `usePollWhileVisible`, so a hidden\n * surface or a minimised window costs nothing and a returning one\n * re-reads on sight (the server caches 5 s, so a poll is cheap);\n * - ONE extra read GIT_PR_RECHECK_MS after a status that says GitHub has\n * not answered yet (`prLookup: 'pending'`), so \"Checking GitHub…\" turns\n * into the real button in about two seconds instead of one poll later;\n * - `replace` after an action — the POST already answered with the fresh\n * status, so there is no second round trip.\n *\n * A root that is not a repository (or not one Verse knows) is dropped for the\n * life of the root list: it can never have a bar, and re-asking every poll\n * would be noise in the server log.\n */\nimport { useCallback, useEffect, useMemo, useRef, useState } from 'react';\nimport { usePollWhileVisible, useSectionVisible } from '../shell/section-visibility.js';\nimport type { GitStatusView } from './git-model.js';\nimport { fetchGitStatus, isRootUnavailable } from './git-queries.js';\n\nexport const GIT_POLL_MS = 10_000;\nexport const GIT_PR_RECHECK_MS = 2_500;\n\nexport interface GitStatusesState {\n /** Statuses in the chat's root order, for roots that are repositories. */\n statuses: GitStatusView[];\n /** True until every root has answered once. */\n loading: boolean;\n /** A read failure other than \"not a repository\" (the newest one), or null. */\n error: string | null;\n refresh: () => void;\n /** Swap in the status a git action answered with, keyed by the root that was asked. */\n replace: (root: string, status: GitStatusView) => void;\n}\n\nexport interface GitStatusesOptions {\n /** Test seam. */\n fetchStatus?: (root: string, signal?: AbortSignal) => Promise<GitStatusView>;\n enabled?: boolean;\n}\n\nexport function useGitStatuses(roots: readonly string[], options: GitStatusesOptions = {}): GitStatusesState {\n const fetchStatus = options.fetchStatus ?? fetchGitStatus;\n const enabled = options.enabled ?? true;\n const visible = useSectionVisible();\n const key = roots.join('\\0');\n // Stable across renders that pass an equal-but-new array.\n const stableRoots = useMemo(() => (key === '' ? [] : key.split('\\0')), [key]);\n\n const [byRoot, setByRoot] = useState<Record<string, GitStatusView>>({});\n const [answered, setAnswered] = useState<ReadonlySet<string>>(new Set());\n const [error, setError] = useState<string | null>(null);\n const unavailable = useRef(new Set<string>());\n const inFlight = useRef<AbortController | null>(null);\n const recheck = useRef<ReturnType<typeof setTimeout> | null>(null);\n const alive = useRef(true);\n\n const readAll = useCallback(() => {\n inFlight.current?.abort();\n const controller = new AbortController();\n inFlight.current = controller;\n const targets = stableRoots.filter((r) => !unavailable.current.has(r));\n if (targets.length === 0) {\n setAnswered(new Set(stableRoots));\n return;\n }\n void Promise.all(\n targets.map(async (root) => {\n try {\n const status = await fetchStatus(root, controller.signal);\n return { root, status, err: null as unknown };\n } catch (err) {\n return { root, status: null, err };\n }\n }),\n ).then((results) => {\n if (!alive.current || controller.signal.aborted) return;\n // Decided from the results, not inside the state updater: React may run\n // an updater later (or twice), so nothing read after it may be set in it.\n let failure: string | null = null;\n let pending = false;\n const fresh: Record<string, GitStatusView> = {};\n const dropped: string[] = [];\n for (const r of results) {\n if (r.status) {\n fresh[r.root] = r.status;\n if (r.status.prLookup === 'pending') pending = true;\n } else if (isRootUnavailable(r.err)) {\n unavailable.current.add(r.root);\n dropped.push(r.root);\n } else {\n // The console, not the page, gets the details (DESIGN §13.8).\n console.warn('[verse] git status failed', r.err);\n failure = 'Could not read git status.';\n }\n }\n setByRoot((prev) => {\n const next = { ...prev, ...fresh };\n for (const root of dropped) delete next[root];\n return next;\n });\n setAnswered(new Set(stableRoots));\n setError(failure);\n if (pending && recheck.current === null) {\n recheck.current = setTimeout(() => {\n recheck.current = null;\n // The newest readAll: the root list may have changed meanwhile.\n if (alive.current) latestRead.current();\n }, GIT_PR_RECHECK_MS);\n }\n });\n }, [stableRoots, fetchStatus]);\n const latestRead = useRef(readAll);\n latestRead.current = readAll;\n\n // A new root list starts clean: rows for roots the chat no longer has go.\n useEffect(() => {\n unavailable.current = new Set();\n setByRoot({});\n setAnswered(new Set());\n setError(null);\n }, [key]);\n\n // First read on mount and on a new root list. Coming back into view is the\n // poll's job (refreshOnShow), so visibility is read, not depended on.\n const visibleRef = useRef(visible);\n visibleRef.current = visible;\n useEffect(() => {\n if (!enabled || !visibleRef.current) return;\n readAll();\n }, [readAll, enabled]);\n\n usePollWhileVisible(readAll, GIT_POLL_MS, { enabled });\n\n useEffect(() => {\n alive.current = true;\n return () => {\n alive.current = false;\n inFlight.current?.abort();\n if (recheck.current !== null) clearTimeout(recheck.current);\n };\n }, []);\n\n const replace = useCallback((root: string, status: GitStatusView) => {\n setByRoot((prev) => ({ ...prev, [root]: { ...status, root } }));\n }, []);\n\n const statuses = useMemo(\n () => stableRoots.map((r) => byRoot[r]).filter((s): s is GitStatusView => s !== undefined),\n [stableRoots, byRoot],\n );\n const loading = stableRoots.some((r) => !answered.has(r));\n\n return { statuses, loading, error, refresh: readAll, replace };\n}\n","/**\n * routes/verse/git/BranchBar.tsx — the row above the composer that turns a\n * chat's edits into a merged PR (unit C5; SPEC-310C §2 item 4):\n *\n * ashlr-hub v310-foundation +35,079 −1,074 #463 · Open · 9/9 checks passed [Merge ▾]\n *\n * Mounted by C2 through the `branch-bar` slot (shell/slots.tsx) with exactly\n * BranchBarProps. One row per REPOSITORY with something to do (two chat roots\n * inside one repo share a row), the first shown and the rest behind\n * \"Show N more\". Renders nothing at all when no root has changes — the space\n * above the composer is the chat's, not an empty toolbar's.\n *\n * The primary button is the server's `suggested` action (git-ops.ts\n * `suggestGitAction`: commit → push → create PR → merge → view), so the bar\n * never has to re-derive the ladder and can never offer Merge on a PR whose\n * checks the server has not seen pass. The ▾ menu holds the rest, each item\n * disabled WITH its reason rather than hidden.\n *\n * Every write goes through the mutation-token gate (the unlock dialog opens\n * with a sentence saying what the click will do) and answers with the fresh\n * status, which replaces the row — no refetch. Outcomes are announced in a\n * polite live region; failures in an alert, in the server's own words.\n */\nimport { useCallback, useEffect, useId, useRef, useState } from 'react';\nimport { MutationTokenDialog } from '../../../components/auth/MutationTokenDialog.js';\nimport { useTokenGate } from '../context/use-token-gate.js';\nimport { useCommandHandler } from '../shell/command-bus.js';\nimport type { BranchBarProps, DiffPaneRequest } from '../shell/slots.js';\nimport { useViewport } from '../shell/viewport.js';\nimport { ActionMenu } from './ActionMenu.js';\nimport { CommitDialog, CreatePrDialog, MergeDialog } from './GitDialogs.js';\nimport {\n dedupeByRepo,\n describeGitError,\n diffstatLabel,\n formatCount,\n hasBranchActivity,\n menuItems,\n mergeDrift,\n pinMerge,\n primaryAction,\n type GitStatusView,\n type PinnedMerge,\n type MenuActionId,\n} from './git-model.js';\nimport { commitGit, mergeGitPr, openGitPr, pushGit } from './git-queries.js';\nimport { PrChip } from './PrChip.js';\nimport { useGitStatuses, type GitStatusesOptions } from './useGitStatuses.js';\nimport styles from './BranchBar.module.css';\n\n/** How long \"Pushed feat/x to origin.\" stays before the line clears. */\nconst NOTICE_MS = 6_000;\n\n/** The palette commands this bar serves (command-catalog.ts `git.*`). */\ntype PaletteGitCommand = 'create-pr' | 'merge';\n\ntype DialogState =\n | { kind: 'commit'; root: string }\n | { kind: 'pr'; root: string; draft: boolean }\n // `pin` is the PR as shown when the dialog opened (git-model.ts pinMerge):\n // the dialog asserts and submits THAT head, never whatever the 10 s poll\n // brought in while it was open.\n | { kind: 'merge'; root: string; pin: PinnedMerge }\n | null;\n\nexport interface BranchBarTestProps {\n /** Test seam for the status reads. */\n statusOptions?: GitStatusesOptions;\n}\n\nexport function BranchBar({ roots, onOpenDiff, statusOptions }: BranchBarProps & BranchBarTestProps) {\n const { statuses, loading, replace } = useGitStatuses(roots, statusOptions);\n const { compact } = useViewport();\n const gate = useTokenGate();\n const [expanded, setExpanded] = useState(false);\n const [dialog, setDialog] = useState<DialogState>(null);\n const [busyRoot, setBusyRoot] = useState<string | null>(null);\n const [dialogError, setDialogError] = useState<string | null>(null);\n const [notice, setNotice] = useState<{ text: string; tone: 'ok' | 'error' } | null>(null);\n // A palette command that arrived before the first status read answered.\n const [pendingCommand, setPendingCommand] = useState<PaletteGitCommand | null>(null);\n const listId = useId();\n\n // A confirmation fades after a few seconds; an error stays until the next action.\n useEffect(() => {\n if (notice?.tone !== 'ok') return;\n const id = setTimeout(() => setNotice(null), NOTICE_MS);\n return () => clearTimeout(id);\n }, [notice]);\n\n const rows = dedupeByRepo(statuses).filter(hasBranchActivity);\n const statusFor = (root: string) => statuses.find((s) => s.root === root) ?? null;\n\n /**\n * Run one git write: token gate → request → swap in the answered status.\n * From a dialog, a refusal stays IN the dialog (the operator fixes and\n * retries); from a one-click action it goes to the bar's alert line.\n */\n const act = useCallback(\n async (root: string, reason: string, request: () => Promise<{ status: GitStatusView }>, done: (s: GitStatusView) => string, inDialog: boolean) => {\n setBusyRoot(root);\n setDialogError(null);\n setNotice(null);\n try {\n const result = await gate.run(reason, request);\n if (result === null) return; // unlock dismissed: nothing happened\n replace(root, result.status);\n setDialog(null);\n setNotice({ text: done(result.status), tone: 'ok' });\n } catch (err) {\n console.warn('[verse] git action failed', err);\n const text = describeGitError(err);\n if (inDialog) setDialogError(text);\n else setNotice({ text, tone: 'error' });\n } finally {\n setBusyRoot(null);\n }\n },\n [gate, replace],\n );\n\n const push = (s: GitStatusView) =>\n act(s.root, `Push ${s.branch ?? 'this branch'} to ${s.upstream ?? 'origin'}.`, () => pushGit(s.root), (next) => `Pushed ${next.branch ?? 'the branch'} to ${next.upstream ?? 'origin'}.`, false);\n\n const openDiff = (request: DiffPaneRequest) => onOpenDiff(request);\n\n const openMerge = (s: GitStatusView) => {\n const pin = pinMerge(s);\n if (!pin) return;\n setDialogError(null);\n setDialog({ kind: 'merge', root: s.root, pin });\n };\n\n const onPrimary = (s: GitStatusView) => {\n switch (s.suggested) {\n case 'commit':\n setDialogError(null);\n setDialog({ kind: 'commit', root: s.root });\n break;\n case 'push':\n void push(s);\n break;\n case 'create-pr':\n setDialogError(null);\n setDialog({ kind: 'pr', root: s.root, draft: false });\n break;\n case 'merge':\n openMerge(s);\n break;\n case 'view-pr':\n if (s.pr) window.open(s.pr.url, '_blank', 'noopener,noreferrer');\n break;\n default:\n break;\n }\n };\n\n const onMenu = (s: GitStatusView, id: MenuActionId) => {\n switch (id) {\n case 'draft-pr':\n setDialogError(null);\n setDialog({ kind: 'pr', root: s.root, draft: true });\n break;\n case 'commit':\n setDialogError(null);\n setDialog({ kind: 'commit', root: s.root });\n break;\n case 'push':\n void push(s);\n break;\n case 'open-github':\n if (s.pr) window.open(s.pr.url, '_blank', 'noopener,noreferrer');\n break;\n case 'copy-branch':\n if (s.branch) {\n void navigator.clipboard?.writeText(s.branch).then(\n () => setNotice({ text: `Copied ${s.branch}.`, tone: 'ok' }),\n () => setNotice({ text: 'Could not copy the branch name.', tone: 'error' }),\n );\n }\n break;\n case 'review':\n openDiff({ root: s.root, scope: s.dirty > 0 && s.diffstat.files === 0 ? 'working' : 'branch' });\n break;\n }\n };\n\n /**\n * ⌘K \"Create pull request…\" / \"Merge pull request…\" (command-catalog.ts\n * `git.create-pr` / `git.merge-pr`). The palette only OPENS the same dialog\n * the row's button would — the disclosure, the token gate and the server's\n * own checks all still stand between the operator and the write. It never\n * declines: a declined command from the palette vanishes without a word,\n * so when no row can take the action the bar says why instead.\n */\n const servePaletteCommand = (command: PaletteGitCommand) => {\n setDialogError(null);\n if (command === 'create-pr') {\n // The server's suggestion first; otherwise any row whose \"Create draft\n // PR…\" item is enabled — the same preconditions the ▾ menu applies, so\n // the palette offers nothing the bar itself would refuse.\n const target =\n rows.find((s) => s.suggested === 'create-pr') ??\n rows.find((s) => menuItems(s).find((item) => item.id === 'draft-pr')?.disabledReason === null);\n if (target) {\n setNotice(null);\n setDialog({ kind: 'pr', root: target.root, draft: false });\n return;\n }\n const reason = rows.length > 0 ? menuItems(rows[0]!).find((item) => item.id === 'draft-pr')?.disabledReason : null;\n setNotice({ text: reason ? `Can't open a pull request: ${reason}.` : 'No branch in this chat has changes to open a pull request from.', tone: 'error' });\n return;\n }\n // Merge only where the server suggests it: that is the one place its\n // checks are known to have passed (see the header).\n const target = rows.find((s) => s.suggested === 'merge' && s.pr !== null);\n if (target) {\n setNotice(null);\n openMerge(target);\n return;\n }\n const open = rows.find((s) => s.pr !== null && (s.pr.state === 'open' || s.pr.state === 'draft'));\n setNotice({\n text: open?.pr ? `#${open.pr.number} isn't ready to merge yet — its checks haven't passed or it isn't mergeable.` : 'No pull request in this chat is ready to merge.',\n tone: 'error',\n });\n };\n\n // A command parked while the operator was on another surface is delivered\n // the moment this bar mounts — before its first status read answers. Hold\n // it until the read lands rather than answering \"nothing to merge\" from an\n // empty list.\n const onPaletteCommand = (command: PaletteGitCommand) => {\n if (loading) setPendingCommand(command);\n else servePaletteCommand(command);\n };\n useCommandHandler('git.create-pr', () => onPaletteCommand('create-pr'));\n useCommandHandler('git.merge-pr', () => onPaletteCommand('merge'));\n const serveRef = useRef(servePaletteCommand);\n serveRef.current = servePaletteCommand;\n useEffect(() => {\n if (pendingCommand === null || loading) return;\n setPendingCommand(null);\n serveRef.current(pendingCommand);\n }, [pendingCommand, loading]);\n\n if (rows.length === 0 && !notice) return null;\n\n const shown = expanded ? rows : rows.slice(0, 1);\n const hiddenCount = rows.length - shown.length;\n const dialogStatus = dialog ? statusFor(dialog.root) : null;\n\n return (\n <section className={styles.bar} aria-label=\"Branches\" data-compact={compact ? 'true' : 'false'}>\n <ul id={listId} className={styles.rows}>\n {shown.map((s) => (\n <BranchRow\n key={s.gitRoot ?? s.root}\n status={s}\n compact={compact}\n busy={busyRoot === s.root}\n onPrimary={() => onPrimary(s)}\n onMenu={(id) => onMenu(s, id)}\n onOpenDiff={() => openDiff({ root: s.root, scope: 'branch' })}\n />\n ))}\n </ul>\n {rows.length > 1 ? (\n <button type=\"button\" className={styles.more} aria-expanded={expanded} aria-controls={listId} onClick={() => setExpanded((v) => !v)}>\n {expanded ? 'Show fewer' : `Show ${hiddenCount} more`}\n </button>\n ) : null}\n <p className={styles.notice} role={notice?.tone === 'error' ? 'alert' : 'status'} aria-live={notice?.tone === 'error' ? 'assertive' : 'polite'} data-tone={notice?.tone ?? 'ok'}>\n {notice?.text ?? ''}\n </p>\n\n {dialogStatus && dialog?.kind === 'commit' ? (\n <CommitDialog\n open\n status={dialogStatus}\n busy={busyRoot === dialog.root}\n error={dialogError}\n onClose={() => setDialog(null)}\n onSubmit={(message) =>\n void act(dialog.root, `Commit ${dialogStatus.dirty} changed files on ${dialogStatus.branch ?? 'this branch'}.`, () => commitGit({ root: dialog.root, message }), (next) => `Committed on ${next.branch ?? 'the branch'}.`, true)\n }\n />\n ) : null}\n {dialogStatus && dialog?.kind === 'pr' ? (\n <CreatePrDialog\n open\n draft={dialog.draft}\n status={dialogStatus}\n busy={busyRoot === dialog.root}\n error={dialogError}\n onClose={() => setDialog(null)}\n onSubmit={(req) =>\n void act(\n dialog.root,\n `Push ${dialogStatus.branch ?? 'this branch'} and open a pull request into ${req.base}.`,\n async () => {\n const res = await openGitPr({ root: dialog.root, title: req.title, base: req.base, ...(req.body.trim() ? { body: req.body } : {}), ...(req.draft ? { draft: true } : {}) });\n return { status: { ...res.status, pr: res.pr ?? res.status.pr } };\n },\n (next) => (next.pr ? `Opened #${next.pr.number}.` : 'Opened the pull request.'),\n true,\n )\n }\n />\n ) : null}\n {dialog?.kind === 'merge' ? (\n // Rendered from the pin even if the live PR vanished from the poll:\n // the dialog then says so and keeps Merge disabled, rather than\n // closing under the operator's cursor.\n <MergeDialog\n open\n pin={dialog.pin}\n live={dialogStatus}\n busy={busyRoot === dialog.root}\n error={dialogError}\n onClose={() => setDialog(null)}\n onSubmit={() => {\n const { pin } = dialog;\n // Belt and braces: the dialog disables Merge on drift, and this\n // re-check covers a poll that lands between render and click.\n if (pin.headSha === null || mergeDrift(pin, statusFor(dialog.root)) !== null) return;\n void act(\n dialog.root,\n `Squash-merge #${pin.number} (head ${pin.headSha.slice(0, 7)}) into ${pin.baseRef}.`,\n async () => {\n const res = await mergeGitPr({ root: dialog.root, number: pin.number, headSha: pin.headSha! });\n return { status: { ...res.status, pr: res.pr ?? res.status.pr } };\n },\n () => `Merged #${pin.number} into ${pin.baseRef}.`,\n true,\n );\n }}\n />\n ) : null}\n <MutationTokenDialog {...gate.dialog} tokenLabel=\"Mutation token\" tokenHelp=\"the mutation token ashlr verse printed\" />\n </section>\n );\n}\n\ninterface BranchRowProps {\n status: GitStatusView;\n compact: boolean;\n busy: boolean;\n onPrimary: () => void;\n onMenu: (id: MenuActionId) => void;\n onOpenDiff: () => void;\n}\n\nfunction BranchRow({ status: s, compact, busy, onPrimary, onMenu, onOpenDiff }: BranchRowProps) {\n const primary = primaryAction(s);\n const items = menuItems(s);\n const hasStat = s.diffstat.files > 0;\n const checking = s.pr === null && s.prLookup === 'pending' && s.branch !== null && s.suggested === 'none';\n return (\n <li className={styles.row} aria-label={`${s.name}, ${s.branch ? `branch ${s.branch}` : 'detached HEAD'}`}>\n <span className={styles.ident}>\n <BranchGlyph />\n <span className={styles.repo}>{s.name}</span>\n <span className={styles.branch} title={s.branch ?? undefined}>\n {s.branch ?? 'detached HEAD'}\n </span>\n {s.behind > 0 ? <span className={styles.drift}>{s.behind} behind</span> : null}\n </span>\n {hasStat ? (\n <button\n type=\"button\"\n className={styles.stat}\n onClick={onOpenDiff}\n aria-label={`${diffstatLabel(s.diffstat.files, s.diffstat.additions, s.diffstat.deletions)}. Open the branch diff.`}\n title=\"Open the branch diff\"\n >\n <span className={styles.add}>+{formatCount(s.diffstat.additions)}</span>\n <span className={styles.del}>{'\\u2212'}{formatCount(s.diffstat.deletions)}</span>\n </button>\n ) : null}\n {s.pr ? <PrChip pr={s.pr} counts={s.prCheckCounts ?? null} showTitle={!compact} /> : null}\n {checking ? <span className={styles.checking}>Checking GitHub…</span> : null}\n {(s.conflicts ?? 0) > 0 ? <span className={styles.conflicts}>{s.conflicts} conflicted</span> : null}\n <span className={styles.spacer} />\n <ActionMenu\n primary={primary ? { label: primary.label, disclosure: primary.disclosure, onClick: onPrimary, busy, tone: primary.action === 'view-pr' ? 'subtle' : 'primary' } : null}\n items={items}\n onSelect={onMenu}\n menuLabel={`More git actions for ${s.name}`}\n disabled={busy}\n />\n </li>\n );\n}\n\nfunction BranchGlyph() {\n return (\n <svg className={styles.glyph} width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" aria-hidden=\"true\">\n <circle cx=\"4.5\" cy=\"3.5\" r=\"1.7\" />\n <circle cx=\"4.5\" cy=\"12.5\" r=\"1.7\" />\n <circle cx=\"11.5\" cy=\"5\" r=\"1.7\" />\n <path d=\"M4.5 5.2v5.6M11.5 6.7c0 3-3.5 2.7-6.3 4.6\" />\n </svg>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
._bar_14lez_8{gap:var(--space-1);flex-direction:column;min-width:0;display:flex}._rows_14lez_15{gap:var(--space-1);flex-direction:column;margin:0;padding:0;list-style:none;display:flex}._row_14lez_15{align-items:center;gap:var(--space-2);min-width:0;min-height:var(--control-h-sm);padding:var(--space-1) var(--space-1) var(--space-1) var(--space-3);border:1px solid var(--border-subtle);border-radius:var(--radius-md);background:var(--bg-surface);font-size:var(--text-sm-size);line-height:var(--text-sm-line);flex-wrap:wrap;display:flex}._ident_14lez_39{align-items:center;gap:var(--space-2);flex:0 auto;min-width:0;display:inline-flex;overflow:hidden}._glyph_14lez_47{color:var(--text-tertiary);flex:none}._repo_14lez_48{color:var(--text-primary);font-weight:var(--font-weight-semibold);text-overflow:ellipsis;white-space:nowrap;flex:none;max-width:18ch;overflow:hidden}._branch_14lez_57{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-family:var(--font-mono);font-size:var(--text-xs-size);color:var(--text-secondary);overflow:hidden}._drift_14lez_66{font-size:var(--text-xs-size);color:var(--status-warning-fg);flex:none}._stat_14lez_72{align-items:center;gap:var(--space-2);min-height:var(--control-h-xs);padding:0 var(--space-2);border-radius:var(--radius-sm);font-family:var(--font-mono);font-size:var(--text-xs-size);font-variant-numeric:tabular-nums;cursor:pointer;transition:background var(--duration-fast) var(--ease-standard), border-color var(--duration-fast) var(--ease-standard);background:0 0;border:1px solid #0000;flex:none;display:inline-flex}._stat_14lez_72:hover{background:var(--bg-hover);border-color:var(--border-default)}._stat_14lez_72:focus-visible{box-shadow:var(--shadow-focus-ring);outline:none}._add_14lez_90{color:var(--status-success-fg)}._del_14lez_91{color:var(--status-danger-fg)}._checking_14lez_93,._conflicts_14lez_94{font-size:var(--text-xs-size);color:var(--text-tertiary);flex:none}._conflicts_14lez_94{color:var(--status-danger-fg);font-weight:var(--font-weight-medium)}._spacer_14lez_101{flex:1 1 0;min-width:0}._split_14lez_105{flex:none;align-items:stretch;margin-left:auto;display:inline-flex;position:relative}._primary_14lez_113,._menuButton_14lez_114{justify-content:center;align-items:center;gap:var(--space-2);min-height:var(--control-h-sm);border:1px solid var(--accent-600);background:var(--accent-600);color:var(--text-on-accent);font:inherit;font-size:var(--text-sm-size);font-weight:var(--font-weight-semibold);cursor:pointer;transition:background var(--duration-fast) var(--ease-standard), border-color var(--duration-fast) var(--ease-standard);display:inline-flex}._primary_14lez_113{padding:0 var(--space-3);border-radius:var(--radius-sm) 0 0 var(--radius-sm)}._menuButton_14lez_114{width:var(--control-h-sm);border-left-color:color-mix(in srgb, var(--text-on-accent) 35%, var(--accent-600));border-radius:0 var(--radius-sm) var(--radius-sm) 0;padding:0}._primary_14lez_113:hover,._menuButton_14lez_114:hover{background:var(--accent-700);border-color:var(--accent-700)}._primary_14lez_113:focus-visible,._menuButton_14lez_114:focus-visible{box-shadow:var(--shadow-focus-ring);z-index:1;outline:none}._primary_14lez_113:disabled,._menuButton_14lez_114:disabled{cursor:default;opacity:.6}._primary_14lez_113[data-tone=subtle],._primary_14lez_113[data-tone=subtle]+._visuallyHidden_14lez_148+._menuButton_14lez_114,._menuButton_14lez_114[data-alone=true]{background:var(--bg-surface-raised);border-color:var(--border-default);color:var(--text-primary)}._primary_14lez_113[data-tone=subtle]:hover,._primary_14lez_113[data-tone=subtle]+._visuallyHidden_14lez_148+._menuButton_14lez_114:hover,._menuButton_14lez_114[data-alone=true]:hover{background:var(--bg-hover);border-color:var(--border-strong)}._menuButton_14lez_114[data-alone=true]{border-radius:var(--radius-sm)}._spinner_14lez_159{border:2px solid color-mix(in srgb, currentColor 35%, transparent);border-radius:var(--radius-full);border-top-color:currentColor;width:12px;height:12px;animation:.8s linear infinite _branch-spin_14lez_1}@keyframes _branch-spin_14lez_1{to{transform:rotate(360deg)}}@media (prefers-reduced-motion:reduce){:root:not([data-motion=full]) ._spinner_14lez_159{animation-duration:2.4s}}._menu_14lez_114{right:0;bottom:calc(100% + var(--space-1));z-index:var(--z-dropdown);min-width:15rem;max-width:min(20rem, calc(100vw - var(--space-8)));padding:var(--space-1);background:var(--bg-surface-raised);border:1px solid var(--border-default);border-radius:var(--radius-md);box-shadow:var(--shadow-menu);animation:_menu-in_14lez_1 var(--duration-fast) var(--ease-decelerate);flex-direction:column;display:flex;position:absolute}._menu_14lez_114:focus{outline:none}@keyframes _menu-in_14lez_1{0%{opacity:0;transform:translateY(2px)}}@media (prefers-reduced-motion:reduce){:root:not([data-motion=full]) ._menu_14lez_114{animation:none}}._menuItem_14lez_196{width:100%;padding:var(--space-2) var(--space-3);border-radius:var(--radius-sm);color:var(--text-primary);font:inherit;font-size:var(--text-sm-size);line-height:var(--text-sm-line);text-align:left;cursor:pointer;background:0 0;border:0;flex-direction:column;align-items:flex-start;gap:2px;display:flex}._menuItem_14lez_196:hover:not([aria-disabled=true]),._menuItem_14lez_196:focus-visible{background:var(--bg-hover);outline:none}._menuItem_14lez_196[aria-disabled=true]{cursor:default;color:var(--text-tertiary)}._menuLabel_14lez_216{font-weight:var(--font-weight-medium)}._menuReason_14lez_217{font-size:var(--text-xs-size);line-height:var(--text-xs-line);color:var(--text-tertiary)}._more_14lez_225{min-height:var(--control-h-xs);padding:0 var(--space-2);color:var(--text-link);font:inherit;font-size:var(--text-xs-size);cursor:pointer;border-radius:var(--radius-sm);background:0 0;border:0;align-self:flex-start}._more_14lez_225:hover{text-decoration:underline}._more_14lez_225:focus-visible{box-shadow:var(--shadow-focus-ring);outline:none}._notice_14lez_240{padding:0 var(--space-3);font-size:var(--text-xs-size);line-height:var(--text-xs-line);color:var(--text-secondary);margin:0}._notice_14lez_240:empty{display:none}._notice_14lez_240[data-tone=error]{color:var(--status-danger-fg)}._visuallyHidden_14lez_148{clip:rect(0 0 0 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}._bar_14lez_8[data-compact=true] ._row_14lez_15{padding-left:var(--space-2)}._bar_14lez_8[data-compact=true] ._ident_14lez_39{flex:100%}._bar_14lez_8[data-compact=true] ._repo_14lez_48{max-width:14ch}._form_1pzii_5{gap:var(--space-2);flex-direction:column;display:flex}._facts_1pzii_11{margin:0 0 var(--space-2);padding:var(--space-3);gap:var(--space-2);border:1px solid var(--border-subtle);border-radius:var(--radius-md);background:var(--bg-surface);flex-direction:column;list-style:none;display:flex}._fact_1pzii_11{gap:var(--space-2);color:var(--text-secondary);font-size:var(--text-sm-size);line-height:var(--text-sm-line);align-items:baseline;display:flex}._fact_1pzii_11 strong{color:var(--text-primary);font-weight:var(--font-weight-semibold)}._fact_1pzii_11[data-tone=warning]{color:var(--text-primary)}._factWord_1pzii_34{font-family:var(--font-display);font-size:var(--text-2xs-size);line-height:var(--text-2xs-line);letter-spacing:var(--tracking-label);text-transform:uppercase;color:var(--status-warning-fg);font-weight:var(--font-weight-semibold);flex:none}._ref_1pzii_45{font-family:var(--font-mono);font-size:var(--text-xs-size);color:var(--text-primary);padding:0 var(--space-1);border-radius:var(--radius-xs);background:var(--bg-code);overflow-wrap:anywhere}._label_1pzii_55{font-size:var(--text-sm-size);line-height:var(--text-sm-line);font-weight:var(--font-weight-semibold);color:var(--text-primary);margin-top:var(--space-1)}._optional_1pzii_62{font-weight:var(--font-weight-regular);color:var(--text-tertiary);margin-left:var(--space-1)}._input_1pzii_68,._textarea_1pzii_69{box-sizing:border-box;border:1px solid var(--border-default);border-radius:var(--radius-sm);background:var(--bg-input);width:100%;color:var(--text-primary);font:inherit;font-size:var(--text-base-size);line-height:var(--text-base-line);padding:var(--space-2) var(--space-3)}._input_1pzii_68{min-height:var(--control-h-sm)}._textarea_1pzii_69{resize:vertical;min-height:calc(var(--text-base-line) * 3 + var(--space-4))}._input_1pzii_68:focus-visible,._textarea_1pzii_69:focus-visible{border-color:var(--border-focus);box-shadow:var(--shadow-focus-ring);outline:none}._mono_1pzii_85{font-family:var(--font-mono);font-size:var(--text-sm-size)}._row_1pzii_87{align-items:flex-end;gap:var(--space-3);flex-wrap:wrap;display:flex}._field_1pzii_93{gap:var(--space-2);flex-direction:column;flex:12rem;min-width:0;display:flex}._check_1pzii_100{align-items:center;gap:var(--space-2);min-height:var(--control-h-sm);font-size:var(--text-sm-size);color:var(--text-primary);cursor:pointer;display:inline-flex}._check_1pzii_100 input{accent-color:var(--accent-600);width:16px;height:16px}._hint_1pzii_111{color:var(--text-tertiary);font-size:var(--text-xs-size);line-height:var(--text-xs-line);margin:0}._hint_1pzii_111 kbd{font-family:var(--font-mono);font-size:var(--text-2xs-size);padding:0 var(--space-1);border:1px solid var(--border-subtle);border-radius:var(--radius-xs);margin-right:2px}._error_1pzii_126{padding:var(--space-2) var(--space-3);border-left:2px solid var(--status-danger-solid);background:var(--status-danger-bg);color:var(--status-danger-fg);font-size:var(--text-sm-size);line-height:var(--text-sm-line);border-radius:var(--radius-xs);margin:0}._actions_1pzii_137{justify-content:flex-end;gap:var(--space-2);margin-top:var(--space-3);display:flex}._chip_j74d0_5{align-items:center;gap:var(--space-1);min-width:0;max-width:100%;min-height:var(--control-h-xs);padding:0 var(--space-2);border:1px solid var(--border-subtle);border-radius:var(--radius-full);background:var(--bg-surface);color:var(--text-secondary);font-size:var(--text-xs-size);line-height:var(--text-xs-line);white-space:nowrap;transition:border-color var(--duration-fast) var(--ease-standard), background var(--duration-fast) var(--ease-standard);text-decoration:none;display:inline-flex}._chip_j74d0_5:hover{background:var(--bg-hover);border-color:var(--border-default)}._chip_j74d0_5:focus-visible{box-shadow:var(--shadow-focus-ring);outline:none}._glyph_j74d0_26{flex:none}._chip_j74d0_5[data-tone=success] ._glyph_j74d0_26,._chip_j74d0_5[data-tone=merged] ._glyph_j74d0_26,._chip_j74d0_5[data-tone=success] ._state_j74d0_30,._chip_j74d0_5[data-tone=merged] ._state_j74d0_30{color:var(--status-success-fg)}._chip_j74d0_5[data-tone=danger] ._glyph_j74d0_26,._chip_j74d0_5[data-tone=danger] ._checks_j74d0_33{color:var(--status-danger-fg)}._chip_j74d0_5[data-tone=running] ._checks_j74d0_33{color:var(--status-running-fg)}._chip_j74d0_5[data-tone=warning] ._glyph_j74d0_26{color:var(--status-warning-fg)}._number_j74d0_37{font-family:var(--font-mono);color:var(--text-primary);font-variant-numeric:tabular-nums}._title_j74d0_43{text-overflow:ellipsis;min-width:0;max-width:22ch;color:var(--text-secondary);overflow:hidden}._state_j74d0_30{font-weight:var(--font-weight-medium);color:var(--text-primary)}._state_j74d0_30:before,._checks_j74d0_33:before{content:"·";margin-right:var(--space-1);color:var(--text-tertiary);font-weight:var(--font-weight-regular)}._checks_j74d0_33{color:var(--text-secondary);text-overflow:ellipsis;overflow:hidden}._pulse_j74d0_61{border-radius:var(--radius-full);background:var(--status-running-solid);width:8px;height:8px;animation:_pr-pulse_j74d0_1 var(--duration-pulse) var(--ease-standard) infinite;flex:none;margin:0 2px}@keyframes _pr-pulse_j74d0_1{50%{opacity:.35}}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{a as e,n as t,o as n,s as r}from"./index-afDA8cwW.js";import{h as i,m as a}from"./global-DVgMguLr.js";import{t as o}from"./MutationTokenDialog-Dn0tzCrh.js";import{t as s}from"./Segmented-B_8c_83S.js";import{a as c,d as l,f as u,g as d,h as f,m as p,p as m}from"./capacity-strip-model-BR539Ci8.js";import{t as h}from"./Tag-DEEbDz7T.js";import{n as g,r as _,t as v}from"./budget-queries-Dacv1VYP.js";import{n as y,t as b}from"./use-token-gate-DYA2-ALC.js";import{t as x}from"./Slider-BS9MU5ZV.js";import{t as S}from"./Switch-BzRXtNPt.js";var C=r(e(),1),w={panel:`_panel_18a87_5`,header:`_header_18a87_14`,title:`_title_18a87_20`,summary:`_summary_18a87_26`,age:`_age_18a87_32`,mode:`_mode_18a87_38`,modeText:`_modeText_18a87_44`,preview:`_preview_18a87_51`,previewLead:`_previewLead_18a87_62`,previewWhy:`_previewWhy_18a87_63`,error:`_error_18a87_69`,loading:`_loading_18a87_74`,empty:`_empty_18a87_75`,seats:`_seats_18a87_81`,seat:`_seat_18a87_81`,seatHead:`_seatHead_18a87_98`,marker:`_marker_18a87_105`,seatName:`_seatName_18a87_111`,status:`_status_18a87_119`,free:`_free_18a87_131`,toggle:`_toggle_18a87_135`,bars:`_bars_18a87_137`,bar:`_bar_18a87_137`,barLabel:`_barLabel_18a87_149`,bindingMark:`_bindingMark_18a87_157`,barValue:`_barValue_18a87_161`,unknown:`_unknown_18a87_166`,track:`_track_18a87_172`,used:`_used_18a87_179`,room:`_room_18a87_180`,reserveBand:`_reserveBand_18a87_181`,ceiling:`_ceiling_18a87_203`,trackUnknown:`_trackUnknown_18a87_211`,controls:`_controls_18a87_218`,freeLine:`_freeLine_18a87_224`,why:`_why_18a87_225`,more:`_more_18a87_230`,footnote:`_footnote_18a87_240`},T=n({BUDGET_COMMIT_DELAY_MS:()=>450,BUDGET_POLL_MS:()=>D,BudgetControl:()=>M,BudgetControlView:()=>j}),E=t(),D=6e4;function O({bar:e}){let t=e.usedPercent,n=p(e.ceilingPercent);if(t===null)return(0,E.jsxs)(`div`,{className:w.bar,"data-binding":e.binding||void 0,children:[(0,E.jsx)(`span`,{className:w.barLabel,children:e.label}),(0,E.jsx)(`div`,{className:w.trackUnknown,role:`img`,"aria-label":e.description}),(0,E.jsx)(`span`,{className:`${w.barValue} ${w.unknown}`,children:`no reading`})]});let r=p(t),i=r>=n;return(0,E.jsxs)(`div`,{className:w.bar,"data-binding":e.binding||void 0,children:[(0,E.jsxs)(`span`,{className:w.barLabel,children:[e.label,e.binding?(0,E.jsx)(`span`,{className:w.bindingMark,title:`This window limits autonomy right now`,children:`binding`}):null]}),(0,E.jsxs)(`div`,{className:w.track,role:`img`,"aria-label":e.description,children:[n<100?(0,E.jsx)(`div`,{className:w.reserveBand,style:{left:`${n}%`,width:`${100-n}%`}}):null,i?null:(0,E.jsx)(`div`,{className:w.room,style:{left:`${r}%`,width:`${n-r}%`}}),(0,E.jsx)(`div`,{className:w.used,"data-over":i||void 0,style:{width:`${r}%`}}),n<100?(0,E.jsx)(`div`,{className:w.ceiling,style:{left:`${n}%`}}):null]}),(0,E.jsxs)(`span`,{className:w.barValue,children:[r,`% used`,n<100?` · stops at ${n}%`:``]})]})}function k(e,t){let[n,r]=(0,C.useState)(e),i=(0,C.useRef)(!1),a=(0,C.useRef)(null),o=(0,C.useRef)(t);return o.current=t,(0,C.useEffect)(()=>{i.current||r(e)},[e]),(0,C.useEffect)(()=>()=>{a.current&&clearTimeout(a.current)},[]),[n,(0,C.useCallback)(e=>{r(e),i.current=!0,a.current&&clearTimeout(a.current),a.current=setTimeout(()=>{i.current=!1,a.current=null,o.current(e)},450)},[])]}function A({row:e,saving:t,readOnly:n,onSeat:r}){let i=(0,C.useId)(),a=e.policy.reservePercent,o=e.policy.maxSessionWindowPercent??100,[s,c]=k(a,t=>{t!==a&&r(e.seatId,{reservePercent:t})}),[l,d]=k(o,t=>{t!==o&&r(e.seatId,{maxSessionWindowPercent:t>=100?null:t})}),f=n||t;return(0,E.jsxs)(`li`,{className:w.seat,"aria-labelledby":i,"data-status":e.status,"aria-busy":t||void 0,children:[(0,E.jsxs)(`div`,{className:w.seatHead,children:[(0,E.jsx)(h,{engine:e.engine,className:w.marker}),(0,E.jsx)(`span`,{id:i,className:w.seatName,children:e.label}),(0,E.jsx)(`span`,{className:w.status,"data-status":e.status,children:u[e.status]}),e.free?(0,E.jsx)(`span`,{className:w.free,children:`free`}):null,(0,E.jsx)(S,{className:w.toggle,checked:e.policy.enabled,disabled:f,"aria-label":`Autonomy on ${e.label}`,label:`Autonomy`,onChange:t=>r(e.seatId,{enabled:t})})]}),e.bars.length>0?(0,E.jsx)(`div`,{className:w.bars,children:e.bars.map(e=>(0,E.jsx)(O,{bar:e},e.kind))}):e.free?(0,E.jsx)(`p`,{className:w.freeLine,children:`No usage window — local models cost nothing and are never held back for you.`}):null,!e.free&&e.policy.enabled?(0,E.jsxs)(`div`,{className:w.controls,children:[(0,E.jsx)(x,{label:`Kept for you`,min:0,max:100,step:5,value:s,disabled:f,valueLabel:`${s}%`,valueText:`${s} percent of the ${e.engine===`grok`?`billing period`:`weekly window`} kept for you`,onChange:e=>c(p(Number(e.currentTarget.value)))}),e.hasSessionCeiling?(0,E.jsx)(x,{label:`5-hour ceiling`,min:10,max:100,step:5,value:l,disabled:f,valueLabel:l>=100?`none`:`${l}%`,valueText:l>=100?`no 5-hour ceiling`:`autonomy stops at ${l} percent of the 5-hour window`,onChange:e=>d(p(Number(e.currentTarget.value),10,100))}):null]}):null,(0,E.jsx)(`p`,{className:w.why,children:e.why}),e.more.length>0?(0,E.jsxs)(`details`,{className:w.more,children:[(0,E.jsx)(`summary`,{children:e.more.length===1?`1 more note`:`${e.more.length} more notes`}),(0,E.jsx)(`ul`,{children:e.more.map(e=>(0,E.jsx)(`li`,{children:e},e))})]}):null]})}function j({view:e,preview:t,nowMs:n,pending:r,error:i,readOnly:a=!1,maxMode:o=null,onMode:u,onSeat:p}){let h=(0,C.useId)(),g=[...c(e).values()],_=m(g),v=l.find(t=>t.value===e.mode)??null,y=v??l[1],b=typeof e.readingMaxAgeMs==`number`&&Number.isFinite(e.readingMaxAgeMs)?e.readingMaxAgeMs:null,x=o?l.find(e=>e.value===o)?.label??o:null,S=f(e.mode,o),T=t?.seatId?g.find(e=>e.seatId===t.seatId):null;return(0,E.jsxs)(`section`,{className:w.panel,"aria-labelledby":h,children:[(0,E.jsxs)(`header`,{className:w.header,children:[(0,E.jsx)(`h2`,{id:h,className:w.title,children:`Budget`}),(0,E.jsx)(`p`,{className:w.summary,children:_.sentence}),(0,E.jsxs)(`span`,{className:w.age,children:[`Readings `,d(e.sampledAt,n)]})]}),(0,E.jsxs)(`div`,{className:w.mode,children:[(0,E.jsx)(s,{"aria-label":`Budget mode`,options:l.map(e=>({value:e.value,label:e.label,...f(e.value,o)?{ariaLabel:`${e.label} — above your grant`}:{},disabled:a||r!==null||f(e.value,o)})),value:e.mode,onChange:t=>{t!==e.mode&&!f(t,o)&&u(t)}}),(0,E.jsx)(`p`,{className:w.modeText,children:v?y.description:`The server did not say which mode is on.`}),x?(0,E.jsx)(`p`,{className:w.modeText,"data-ceiling":``,children:S?`Your grant allows up to ${x}, so autonomy spends as ${x} until this moves down.`:`Your grant allows up to ${x}; modes above it are off. Re-approve the grant to raise it.`}):null]}),t?(0,E.jsxs)(`p`,{className:w.preview,"aria-live":`polite`,children:[(0,E.jsx)(`span`,{className:w.previewLead,children:`Next medium task →`}),` `,(0,E.jsx)(`strong`,{children:T?.label??t.seatId??`nowhere right now`}),(0,E.jsx)(`span`,{className:w.previewWhy,children:t.why})]}):null,i?(0,E.jsx)(`p`,{className:w.error,role:`alert`,children:i}):null,g.length===0?(0,E.jsx)(`p`,{className:w.empty,children:`No seats yet — connect an account or start Ollama, and they appear here.`}):(0,E.jsx)(`ul`,{className:w.seats,children:g.map(e=>(0,E.jsx)(A,{row:e,saving:r===e.seatId||r===`mode`,readOnly:a,onSeat:p},e.seatId))}),(0,E.jsxs)(`p`,{className:w.footnote,children:[`Reserves apply to autonomous work only — your own chats can always use a seat. Unknown usage is never treated as headroom: a seat with no reading, or one `,b===null?`whose reading is stale`:`older than ${Math.round(b/6e4)} minutes`,`, is held back.`]})]})}function M({maxMode:e=null}={}){let t=a(g,{freshMs:0}),n=a(v,{freshMs:0}),r=i(g),s=i(v),c=y(),[l,u]=(0,C.useState)(null),[d,f]=(0,C.useState)(null),[p,m]=(0,C.useState)(null),[h,x]=(0,C.useState)(()=>Date.now());(0,C.useEffect)(()=>{let e=()=>{(typeof document>`u`||document.visibilityState!==`hidden`)&&(r(),s(),x(Date.now()))},t=window.setInterval(e,D);return document.addEventListener(`visibilitychange`,e),()=>{window.clearInterval(t),document.removeEventListener(`visibilitychange`,e)}},[r,s]);let S=t.data,T=l&&(!S||!(Date.parse(l.sampledAt)<Date.parse(S.sampledAt)))?l:S,O=(0,C.useCallback)(async(e,t,n)=>{f(e),m(null);try{let e=await c.run(t,()=>_(n));e&&u(e)}catch(e){m(b(e))}finally{f(null),x(Date.now())}},[c]);return T?(0,E.jsxs)(E.Fragment,{children:[(0,E.jsx)(j,{view:T,preview:n.data??null,nowMs:h,pending:d,error:p,maxMode:e,onMode:e=>void O(`mode`,`Switch the budget to ${e}`,{mode:e}),onSeat:(e,t)=>void O(e,`Change the budget for ${e}`,{seatId:e,policy:t})}),(0,E.jsx)(o,{open:c.dialog.open,reason:c.dialog.reason,tokenLabel:`Mutation token`,tokenHelp:`the mutation token ashlr verse printed`,onClose:c.dialog.onClose,onUnlocked:c.dialog.onUnlocked})]}):(0,E.jsx)(`section`,{className:w.panel,"aria-label":`Budget`,children:t.status===`error`?(0,E.jsxs)(`p`,{className:w.error,role:`alert`,children:[`Budget unavailable: `,t.error?.message??`the request failed.`]}):(0,E.jsx)(`p`,{className:w.loading,children:`Reading seat usage…`})})}export{T as n,M as t};
|
|
2
|
-
//# sourceMappingURL=BudgetControl-P5lMxHvQ.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BudgetControl-P5lMxHvQ.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/budget/BudgetControl.module.css","../../../../../../src/web-ui/routes/verse/budget/BudgetControl.tsx"],"sourcesContent":["/* Budget panel. Hairlines and whitespace, no nested boxes (DESIGN-V2 §6).\n Every state is a WORD first; colour reinforces it. Status tokens are\n defined for both themes in tokens.css, so nothing here needs a dark rule. */\n\n.panel {\n display: flex;\n flex-direction: column;\n gap: var(--space-4);\n min-width: 0;\n color: var(--text-primary);\n font-family: var(--font-ui);\n}\n\n.header {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: var(--space-2) var(--space-3);\n}\n.title {\n margin: 0;\n font-family: var(--font-display);\n font-size: var(--text-lg-size);\n font-weight: var(--font-weight-semibold);\n}\n.summary {\n margin: 0;\n flex: 1 1 16rem;\n font-size: var(--text-sm-size);\n color: var(--text-secondary);\n}\n.age {\n font-size: var(--text-2xs-size);\n color: var(--text-tertiary);\n font-variant-numeric: tabular-nums;\n}\n\n.mode {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-2) var(--space-3);\n}\n.modeText {\n margin: 0;\n flex: 1 1 14rem;\n font-size: var(--text-sm-size);\n color: var(--text-secondary);\n}\n\n.preview {\n margin: 0;\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: var(--space-1) var(--space-2);\n padding: var(--space-2) 0;\n border-top: 1px solid var(--border-subtle);\n border-bottom: 1px solid var(--border-subtle);\n font-size: var(--text-sm-size);\n}\n.previewLead { color: var(--text-secondary); }\n.previewWhy {\n flex-basis: 100%;\n font-size: var(--text-xs-size);\n color: var(--text-tertiary);\n}\n\n.error {\n margin: 0;\n font-size: var(--text-sm-size);\n color: var(--status-danger-fg);\n}\n.loading,\n.empty {\n margin: 0;\n font-size: var(--text-sm-size);\n color: var(--text-secondary);\n}\n\n.seats {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n}\n.seat {\n display: flex;\n flex-direction: column;\n gap: var(--space-2);\n padding: var(--space-3) 0;\n border-bottom: 1px solid var(--border-subtle);\n min-width: 0;\n}\n.seat[aria-busy='true'] { opacity: 0.7; }\n\n.seatHead {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--space-2);\n min-width: 0;\n}\n.marker {\n width: 3px;\n height: 16px;\n border-radius: 2px;\n flex: none;\n}\n.seatName {\n font-weight: var(--font-weight-medium);\n font-size: var(--text-base-size);\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n.status {\n font-family: var(--font-display);\n font-size: var(--text-2xs-size);\n font-weight: var(--font-weight-medium);\n letter-spacing: var(--tracking-label, 0.06em);\n text-transform: uppercase;\n color: var(--status-unknown-fg);\n}\n.status[data-status='eligible'] { color: var(--status-success-fg); }\n.status[data-status='held'] { color: var(--status-warning-fg); }\n.status[data-status='off'] { color: var(--status-neutral-fg); }\n.status[data-status='unknown'] { color: var(--status-unknown-fg); }\n.free {\n font-size: var(--text-2xs-size);\n color: var(--text-tertiary);\n}\n.toggle { margin-left: auto; }\n\n.bars {\n display: flex;\n flex-direction: column;\n gap: var(--space-1);\n}\n.bar {\n display: grid;\n grid-template-columns: 6.5rem minmax(0, 1fr) auto;\n align-items: center;\n gap: var(--space-2);\n font-size: var(--text-xs-size);\n}\n.barLabel {\n display: inline-flex;\n align-items: baseline;\n gap: var(--space-1);\n color: var(--text-secondary);\n white-space: nowrap;\n}\n.bar[data-binding] .barLabel { color: var(--text-primary); }\n.bindingMark {\n font-size: var(--text-2xs-size);\n color: var(--text-tertiary);\n}\n.barValue {\n font-variant-numeric: tabular-nums;\n color: var(--text-secondary);\n white-space: nowrap;\n}\n.unknown {\n font-style: italic;\n color: var(--status-unknown-fg);\n}\n\n/* The track: used (solid) · autonomy room (tint) · kept for you (hatched). */\n.track {\n position: relative;\n height: 8px;\n border-radius: var(--radius-full);\n background: var(--meter-track);\n overflow: hidden;\n}\n.used,\n.room,\n.reserveBand {\n position: absolute;\n top: 0;\n bottom: 0;\n}\n.used {\n left: 0;\n /* Quantity, not interaction: the fixed azure ramp, never the operator-chosen accent (DESIGN §13.2). */\n background: var(--data-seq-5);\n border-radius: var(--radius-full) 0 0 var(--radius-full);\n}\n.used[data-over] { background: var(--status-warning-solid); }\n.room {\n background: color-mix(in srgb, var(--data-seq-5) 28%, transparent);\n}\n.reserveBand {\n background: repeating-linear-gradient(\n 135deg,\n color-mix(in srgb, var(--text-tertiary) 30%, transparent) 0 3px,\n transparent 3px 6px\n );\n}\n.ceiling {\n position: absolute;\n top: -2px;\n bottom: -2px;\n width: 2px;\n margin-left: -1px;\n background: var(--text-primary);\n}\n.trackUnknown {\n height: 8px;\n border-radius: var(--radius-full);\n border: 1px dashed var(--border-strong);\n background: transparent;\n}\n\n.controls {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));\n gap: var(--space-2) var(--space-4);\n}\n\n.freeLine,\n.why {\n margin: 0;\n font-size: var(--text-xs-size);\n color: var(--text-secondary);\n}\n.more {\n font-size: var(--text-xs-size);\n color: var(--text-tertiary);\n}\n.more summary { cursor: pointer; }\n.more ul {\n margin: var(--space-1) 0 0;\n padding-left: var(--space-4);\n}\n\n.footnote {\n margin: 0;\n font-size: var(--text-2xs-size);\n color: var(--text-tertiary);\n}\n\n@media (max-width: 480px) {\n .bar {\n grid-template-columns: minmax(0, 1fr) auto;\n }\n .bar .track,\n .bar .trackUnknown {\n grid-column: 1 / -1;\n grid-row: 2;\n }\n .toggle { margin-left: 0; }\n}\n","/**\n * routes/verse/budget/BudgetControl.tsx — budget modes, per-seat reserves and\n * live headroom, in one panel.\n *\n * ┌ Budget ─────────────────────────── 3 of 7 seats can take autonomous work\n * │ [ Reserve | Balanced | All-in ] Autonomy stops at each seat's reserve…\n * │ Next medium task → Grok · why\n * │ ● Claude Code Eligible Autonomy [on]\n * │ Weekly ███████▒▒▒▒▒▒▒▒░░░░░░░░░ 20% used · stops at 60%\n * │ 5-hour ███▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░ 15% used · stops at 70%\n * │ Kept for you ──●──── 40% 5-hour ceiling ─────●── 70%\n * │ 40% of the weekly window is left for autonomy (40% kept for you).\n *\n * Each bar reads left to right: what is USED (solid), what autonomy may\n * still use (tinted), and the band KEPT FOR MASON (hatched) past the ceiling\n * tick. An unread window is a dashed track and the words \"no reading\" —\n * never an empty bar (which would claim headroom) or a full one.\n *\n * `BudgetControlView` is pure (props in, callbacks out) and is what the tests\n * render; `BudgetControl` wires it to the API, the mutation-token gate and a\n * 60 s refresh while the document is visible.\n *\n * Mount point: a Track B surface (Command home / Autonomy) owns placement —\n * this file only exports the panel.\n */\nimport { useCallback, useEffect, useId, useRef, useState } from 'react';\nimport type { BudgetView } from '../../../../core/routing/policy.js';\nimport type { BudgetMode, SeatDecision } from '../../../../core/routing/types.js';\nimport { MutationTokenDialog } from '../../../components/auth/MutationTokenDialog.js';\nimport { Segmented } from '../../../components/primitives/Segmented.js';\nimport { Slider } from '../../../components/primitives/Slider.js';\nimport { Switch } from '../../../components/primitives/Switch.js';\nimport { EngineMarker } from '../../../components/primitives/Tag.js';\nimport { useQuery, useRefetch } from '../../../data/hooks.js';\nimport { describeContextError, useTokenGate } from '../context/use-token-gate.js';\nimport { readBudgetRows } from '../usage/capacity-strip-model.js';\nimport {\n BUDGET_MODE_OPTIONS,\n budgetSummary,\n clampPercent,\n modeAboveCeiling,\n readingAge,\n STATUS_WORDS,\n type BudgetBar,\n type BudgetSeatRow,\n} from './budget-model.js';\nimport { budgetPreviewQuery, budgetQuery, updateBudget, type BudgetSeatPatchWire } from './budget-queries.js';\nimport styles from './BudgetControl.module.css';\n\n/** Headroom moves with the collector (30 s cycle); a minute is plenty for a settings panel. */\nexport const BUDGET_POLL_MS = 60_000;\n/** Slider changes are committed this long after the last movement. */\nexport const BUDGET_COMMIT_DELAY_MS = 450;\n\n// ---------------------------------------------------------------------------\n// Headroom bar\n// ---------------------------------------------------------------------------\n\nfunction HeadroomBar({ bar }: { bar: BudgetBar }) {\n const used = bar.usedPercent;\n const ceiling = clampPercent(bar.ceilingPercent);\n if (used === null) {\n return (\n <div className={styles.bar} data-binding={bar.binding || undefined}>\n <span className={styles.barLabel}>{bar.label}</span>\n <div className={styles.trackUnknown} role=\"img\" aria-label={bar.description} />\n <span className={`${styles.barValue} ${styles.unknown}`}>no reading</span>\n </div>\n );\n }\n const usedPct = clampPercent(used);\n const over = usedPct >= ceiling;\n return (\n <div className={styles.bar} data-binding={bar.binding || undefined}>\n <span className={styles.barLabel}>\n {bar.label}\n {bar.binding ? <span className={styles.bindingMark} title=\"This window limits autonomy right now\">binding</span> : null}\n </span>\n <div className={styles.track} role=\"img\" aria-label={bar.description}>\n {ceiling < 100 ? (\n <div className={styles.reserveBand} style={{ left: `${ceiling}%`, width: `${100 - ceiling}%` }} />\n ) : null}\n {!over ? (\n <div className={styles.room} style={{ left: `${usedPct}%`, width: `${ceiling - usedPct}%` }} />\n ) : null}\n <div className={styles.used} data-over={over || undefined} style={{ width: `${usedPct}%` }} />\n {ceiling < 100 ? <div className={styles.ceiling} style={{ left: `${ceiling}%` }} /> : null}\n </div>\n <span className={styles.barValue}>\n {usedPct}% used{ceiling < 100 ? ` · stops at ${ceiling}%` : ''}\n </span>\n </div>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Draft slider — commits after the hand leaves it\n// ---------------------------------------------------------------------------\n\nfunction useCommittedDraft(serverValue: number, commit: (value: number) => void): [number, (v: number) => void] {\n const [draft, setDraft] = useState(serverValue);\n const dirty = useRef(false);\n const timer = useRef<ReturnType<typeof setTimeout> | null>(null);\n const commitRef = useRef(commit);\n commitRef.current = commit;\n\n // A new server value wins unless the operator is mid-drag.\n useEffect(() => {\n if (!dirty.current) setDraft(serverValue);\n }, [serverValue]);\n\n useEffect(() => () => {\n if (timer.current) clearTimeout(timer.current);\n }, []);\n\n const change = useCallback((value: number) => {\n setDraft(value);\n dirty.current = true;\n if (timer.current) clearTimeout(timer.current);\n timer.current = setTimeout(() => {\n dirty.current = false;\n timer.current = null;\n commitRef.current(value);\n }, BUDGET_COMMIT_DELAY_MS);\n }, []);\n\n return [draft, change];\n}\n\n// ---------------------------------------------------------------------------\n// One seat\n// ---------------------------------------------------------------------------\n\ninterface SeatRowProps {\n row: BudgetSeatRow;\n saving: boolean;\n readOnly: boolean;\n onSeat: (seatId: string, patch: BudgetSeatPatchWire) => void;\n}\n\nfunction SeatRow({ row, saving, readOnly, onSeat }: SeatRowProps) {\n const headingId = useId();\n const reserveServer = row.policy.reservePercent;\n const sessionServer = row.policy.maxSessionWindowPercent ?? 100;\n const [reserve, setReserve] = useCommittedDraft(reserveServer, (v) => {\n if (v !== reserveServer) onSeat(row.seatId, { reservePercent: v });\n });\n const [session, setSession] = useCommittedDraft(sessionServer, (v) => {\n if (v !== sessionServer) onSeat(row.seatId, { maxSessionWindowPercent: v >= 100 ? null : v });\n });\n const disabled = readOnly || saving;\n\n return (\n <li className={styles.seat} aria-labelledby={headingId} data-status={row.status} aria-busy={saving || undefined}>\n <div className={styles.seatHead}>\n <EngineMarker engine={row.engine} className={styles.marker} />\n <span id={headingId} className={styles.seatName}>{row.label}</span>\n <span className={styles.status} data-status={row.status}>{STATUS_WORDS[row.status]}</span>\n {row.free ? <span className={styles.free}>free</span> : null}\n <Switch\n className={styles.toggle}\n checked={row.policy.enabled}\n disabled={disabled}\n aria-label={`Autonomy on ${row.label}`}\n label=\"Autonomy\"\n onChange={(next) => onSeat(row.seatId, { enabled: next })}\n />\n </div>\n\n {row.bars.length > 0 ? (\n <div className={styles.bars}>\n {row.bars.map((bar) => <HeadroomBar key={bar.kind} bar={bar} />)}\n </div>\n ) : row.free ? (\n <p className={styles.freeLine}>No usage window — local models cost nothing and are never held back for you.</p>\n ) : null}\n\n {!row.free && row.policy.enabled ? (\n <div className={styles.controls}>\n <Slider\n label=\"Kept for you\"\n min={0}\n max={100}\n step={5}\n value={reserve}\n disabled={disabled}\n valueLabel={`${reserve}%`}\n valueText={`${reserve} percent of the ${row.engine === 'grok' ? 'billing period' : 'weekly window'} kept for you`}\n onChange={(e) => setReserve(clampPercent(Number(e.currentTarget.value)))}\n />\n {row.hasSessionCeiling ? (\n <Slider\n label=\"5-hour ceiling\"\n min={10}\n max={100}\n step={5}\n value={session}\n disabled={disabled}\n valueLabel={session >= 100 ? 'none' : `${session}%`}\n valueText={session >= 100 ? 'no 5-hour ceiling' : `autonomy stops at ${session} percent of the 5-hour window`}\n onChange={(e) => setSession(clampPercent(Number(e.currentTarget.value), 10, 100))}\n />\n ) : null}\n </div>\n ) : null}\n\n <p className={styles.why}>{row.why}</p>\n {row.more.length > 0 ? (\n <details className={styles.more}>\n <summary>{row.more.length === 1 ? '1 more note' : `${row.more.length} more notes`}</summary>\n <ul>\n {row.more.map((reason) => <li key={reason}>{reason}</li>)}\n </ul>\n </details>\n ) : null}\n </li>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Pure view\n// ---------------------------------------------------------------------------\n\nexport interface BudgetControlViewProps {\n view: BudgetView;\n preview: SeatDecision | null;\n nowMs: number;\n /** `'mode'` or a seat id while its change is in flight. */\n pending: string | null;\n error: string | null;\n readOnly?: boolean;\n /**\n * The standing grant's ceiling (`spend.maxMode`). Modes above it are shown\n * DISABLED with the reason — never hidden — because autonomy could not\n * spend them anyway. Moving toward Reserve is always allowed. Null/absent\n * = no grant ceiling applies (every mode selectable).\n */\n maxMode?: BudgetMode | null;\n onMode: (mode: BudgetMode) => void;\n onSeat: (seatId: string, patch: BudgetSeatPatchWire) => void;\n}\n\nexport function BudgetControlView({ view, preview, nowMs, pending, error, readOnly = false, maxMode = null, onMode, onSeat }: BudgetControlViewProps) {\n const titleId = useId();\n // The wire view is read defensively (the capacity strip's own guard): this\n // panel is opened from Apps, the composer's seat chip and the autonomy bar,\n // and a budget answer of `{}` or a garbled seat entry used to throw inside\n // buildBudgetRows and take the whole sheet down. A seat whose policy is\n // malformed is dropped, not shown as \"off\" — see readBudgetRows.\n const rows = [...readBudgetRows(view).values()];\n const summary = budgetSummary(rows);\n const knownMode = BUDGET_MODE_OPTIONS.find((o) => o.value === view.mode) ?? null;\n const mode = knownMode ?? BUDGET_MODE_OPTIONS[1]!;\n const maxAgeMs = typeof view.readingMaxAgeMs === 'number' && Number.isFinite(view.readingMaxAgeMs) ? view.readingMaxAgeMs : null;\n const ceilingLabel = maxMode ? BUDGET_MODE_OPTIONS.find((o) => o.value === maxMode)?.label ?? maxMode : null;\n const aboveNow = modeAboveCeiling(view.mode, maxMode);\n const chosen = preview?.seatId ? rows.find((r) => r.seatId === preview.seatId) : null;\n\n return (\n <section className={styles.panel} aria-labelledby={titleId}>\n <header className={styles.header}>\n <h2 id={titleId} className={styles.title}>Budget</h2>\n <p className={styles.summary}>{summary.sentence}</p>\n <span className={styles.age}>Readings {readingAge(view.sampledAt, nowMs)}</span>\n </header>\n\n <div className={styles.mode}>\n <Segmented\n aria-label=\"Budget mode\"\n options={BUDGET_MODE_OPTIONS.map((o) => ({\n value: o.value,\n label: o.label,\n ...(modeAboveCeiling(o.value, maxMode) ? { ariaLabel: `${o.label} — above your grant` } : {}),\n disabled: readOnly || pending !== null || modeAboveCeiling(o.value, maxMode),\n }))}\n value={view.mode}\n onChange={(next) => { if (next !== view.mode && !modeAboveCeiling(next, maxMode)) onMode(next); }}\n />\n {/* No option is pressed when the server named no mode we know —\n showing Balanced there would claim a setting nobody read. */}\n <p className={styles.modeText}>{knownMode ? mode.description : 'The server did not say which mode is on.'}</p>\n {ceilingLabel ? (\n <p className={styles.modeText} data-ceiling=\"\">\n {aboveNow\n ? `Your grant allows up to ${ceilingLabel}, so autonomy spends as ${ceilingLabel} until this moves down.`\n : `Your grant allows up to ${ceilingLabel}; modes above it are off. Re-approve the grant to raise it.`}\n </p>\n ) : null}\n </div>\n\n {preview ? (\n <p className={styles.preview} aria-live=\"polite\">\n <span className={styles.previewLead}>Next medium task →</span>{' '}\n <strong>{chosen?.label ?? (preview.seatId ?? 'nowhere right now')}</strong>\n <span className={styles.previewWhy}>{preview.why}</span>\n </p>\n ) : null}\n\n {error ? <p className={styles.error} role=\"alert\">{error}</p> : null}\n\n {rows.length === 0 ? (\n <p className={styles.empty}>No seats yet — connect an account or start Ollama, and they appear here.</p>\n ) : (\n <ul className={styles.seats}>\n {rows.map((row) => (\n <SeatRow key={row.seatId} row={row} saving={pending === row.seatId || pending === 'mode'} readOnly={readOnly} onSeat={onSeat} />\n ))}\n </ul>\n )}\n\n <p className={styles.footnote}>\n Reserves apply to autonomous work only — your own chats can always use a seat. Unknown usage is never treated as\n headroom: a seat with no reading, or one {maxAgeMs !== null ? `older than ${Math.round(maxAgeMs / 60_000)} minutes` : 'whose reading is stale'}, is held back.\n </p>\n </section>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Connected panel\n// ---------------------------------------------------------------------------\n\nexport function BudgetControl({ maxMode = null }: { maxMode?: BudgetMode | null } = {}) {\n const budget = useQuery(budgetQuery, { freshMs: 0 });\n const preview = useQuery(budgetPreviewQuery, { freshMs: 0 });\n const refetchBudget = useRefetch(budgetQuery);\n const refetchPreview = useRefetch(budgetPreviewQuery);\n const gate = useTokenGate();\n const [latest, setLatest] = useState<BudgetView | null>(null);\n const [pending, setPending] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [nowMs, setNowMs] = useState(() => Date.now());\n\n // Poll while visible; read immediately on return (useSeatsRefresh's pattern).\n useEffect(() => {\n const tick = (): void => {\n if (typeof document !== 'undefined' && document.visibilityState === 'hidden') return;\n refetchBudget();\n refetchPreview();\n setNowMs(Date.now());\n };\n const timer = window.setInterval(tick, BUDGET_POLL_MS);\n document.addEventListener('visibilitychange', tick);\n return () => {\n window.clearInterval(timer);\n document.removeEventListener('visibilitychange', tick);\n };\n }, [refetchBudget, refetchPreview]);\n\n // The POST response is newer than the cached read until the refetch lands.\n // A cached read with no parseable sampledAt cannot be shown to be newer, so\n // the POST's answer wins (NaN comparisons are always false).\n const cached = budget.data;\n const view = latest && (!cached || !(Date.parse(latest.sampledAt) < Date.parse(cached.sampledAt))) ? latest : cached;\n\n const apply = useCallback(async (key: string, reason: string, update: Parameters<typeof updateBudget>[0]) => {\n setPending(key);\n setError(null);\n try {\n const next = await gate.run(reason, () => updateBudget(update));\n if (next) setLatest(next);\n } catch (err) {\n setError(describeContextError(err));\n } finally {\n setPending(null);\n setNowMs(Date.now());\n }\n }, [gate]);\n\n if (!view) {\n return (\n <section className={styles.panel} aria-label=\"Budget\">\n {budget.status === 'error' ? (\n <p className={styles.error} role=\"alert\">Budget unavailable: {budget.error?.message ?? 'the request failed.'}</p>\n ) : (\n <p className={styles.loading}>Reading seat usage…</p>\n )}\n </section>\n );\n }\n\n return (\n <>\n <BudgetControlView\n view={view}\n preview={preview.data ?? null}\n nowMs={nowMs}\n pending={pending}\n error={error}\n maxMode={maxMode}\n onMode={(mode) => void apply('mode', `Switch the budget to ${mode}`, { mode })}\n onSeat={(seatId, patch) => void apply(seatId, `Change the budget for ${seatId}`, { seatId, policy: patch })}\n />\n <MutationTokenDialog open={gate.dialog.open} reason={gate.dialog.reason} tokenLabel=\"Mutation token\"\n tokenHelp=\"the mutation token ashlr verse printed\" onClose={gate.dialog.onClose} onUnlocked={gate.dialog.onUnlocked} />\n </>\n );\n}\n"],"mappings":"krDCkDa,EAAiB,IAQ9B,SAAS,EAAY,CAAE,OAA2B,CAChD,IAAM,EAAO,EAAI,YACX,EAAU,EAAa,EAAI,cAAc,EAC/C,GAAI,IAAS,KACX,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,EAAO,IAAK,eAAc,EAAI,SAAW,IAAA,GAAzD,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,SAAW,SAAA,EAAI,KAAY,CAAA,GACnD,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAO,aAAc,KAAK,MAAM,aAAY,EAAI,WAAc,CAAA,GAC9E,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,GAAG,EAAO,SAAS,GAAG,EAAO,UAAW,SAAA,YAAgB,CAAA,CACtE,IAGT,IAAM,EAAU,EAAa,CAAI,EAC3B,EAAO,GAAW,EACxB,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,EAAO,IAAK,eAAc,EAAI,SAAW,IAAA,GAAzD,SAAA,EACE,EAAA,EAAA,KAAA,CAAC,OAAD,CAAM,UAAW,EAAO,SAAxB,SAAA,CACG,EAAI,MACJ,EAAI,SAAU,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,YAAa,MAAM,wCAAwC,SAAA,SAAa,CAAA,EAAI,IAC/G,KACN,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,EAAO,MAAO,KAAK,MAAM,aAAY,EAAI,YAAzD,SAAA,CACG,EAAU,KACT,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAO,YAAa,MAAO,CAAE,KAAM,GAAG,EAAQ,GAAI,MAAO,GAAG,IAAM,EAAQ,EAAG,CAAI,CAAA,EAC/F,KACF,EAEE,MADF,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAO,KAAM,MAAO,CAAE,KAAM,GAAG,EAAQ,GAAI,MAAO,GAAG,EAAU,EAAQ,EAAG,CAAI,CAAA,GAEhG,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAO,KAAM,YAAW,GAAQ,IAAA,GAAW,MAAO,CAAE,MAAO,GAAG,EAAQ,EAAG,CAAI,CAAA,EAC5F,EAAU,KAAM,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAO,QAAS,MAAO,CAAE,KAAM,GAAG,EAAQ,EAAG,CAAI,CAAA,EAAI,IACnF,KACL,EAAA,EAAA,KAAA,CAAC,OAAD,CAAM,UAAW,EAAO,SAAxB,SAAA,CACG,EAAQ,SAAO,EAAU,IAAM,eAAe,EAAQ,GAAK,EACxD,GACH,GAET,CAMA,SAAS,EAAkB,EAAqB,EAAgE,CAC9G,GAAM,CAAC,EAAO,IAAA,EAAY,EAAA,SAAA,CAAS,CAAW,EACxC,GAAA,EAAQ,EAAA,OAAA,CAAO,EAAK,EACpB,GAAA,EAAQ,EAAA,OAAA,CAA6C,IAAI,EACzD,GAAA,EAAY,EAAA,OAAA,CAAO,CAAM,EAuB/B,MAtBA,GAAU,QAAU,GAGpB,EAAA,EAAA,UAAA,KAAgB,CACT,EAAM,SAAS,EAAS,CAAW,CAC1C,EAAG,CAAC,CAAW,CAAC,GAEhB,EAAA,EAAA,UAAA,SAAsB,CAChB,EAAM,SAAS,aAAa,EAAM,OAAO,CAC/C,EAAG,CAAC,CAAC,EAaE,CAAC,GAAA,EAXO,EAAA,YAAA,CAAa,GAAkB,CAC5C,EAAS,CAAK,EACd,EAAM,QAAU,GACZ,EAAM,SAAS,aAAa,EAAM,OAAO,EAC7C,EAAM,QAAU,eAAiB,CAC/B,EAAM,QAAU,GAChB,EAAM,QAAU,KAChB,EAAU,QAAQ,CAAK,CACzB,EAAA,GAAyB,CAC3B,EAAG,CAAC,CAEW,CAAM,CACvB,CAaA,SAAS,EAAQ,CAAE,MAAK,SAAQ,WAAU,UAAwB,CAChE,IAAM,GAAA,EAAY,EAAA,MAAA,CAAM,EAClB,EAAgB,EAAI,OAAO,eAC3B,EAAgB,EAAI,OAAO,yBAA2B,IACtD,CAAC,EAAS,GAAc,EAAkB,EAAgB,GAAM,CAChE,IAAM,GAAe,EAAO,EAAI,OAAQ,CAAE,eAAgB,CAAE,CAAC,CACnE,CAAC,EACK,CAAC,EAAS,GAAc,EAAkB,EAAgB,GAAM,CAChE,IAAM,GAAe,EAAO,EAAI,OAAQ,CAAE,wBAAyB,GAAK,IAAM,KAAO,CAAE,CAAC,CAC9F,CAAC,EACK,EAAW,GAAY,EAE7B,OACE,EAAA,EAAA,KAAA,CAAC,KAAD,CAAI,UAAW,EAAO,KAAM,kBAAiB,EAAW,cAAa,EAAI,OAAQ,YAAW,GAAU,IAAA,GAAtG,SAAA,EACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,EAAO,SAAvB,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,EAAD,CAAc,OAAQ,EAAI,OAAQ,UAAW,EAAO,MAAS,CAAA,GAC7D,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,GAAI,EAAW,UAAW,EAAO,SAAW,SAAA,EAAI,KAAY,CAAA,GAClE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,OAAQ,cAAa,EAAI,OAAS,SAAA,EAAa,EAAI,OAAc,CAAA,EACxF,EAAI,MAAO,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,KAAM,SAAA,MAAU,CAAA,EAAI,MACxD,EAAA,EAAA,IAAA,CAAC,EAAD,CACE,UAAW,EAAO,OAClB,QAAS,EAAI,OAAO,QACV,WACV,aAAY,eAAe,EAAI,QAC/B,MAAM,WACN,SAAW,GAAS,EAAO,EAAI,OAAQ,CAAE,QAAS,CAAK,CAAC,CACzD,CAAA,CACE,IAEJ,EAAI,KAAK,OAAS,GACjB,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAO,KACpB,SAAA,EAAI,KAAK,IAAK,IAAQ,EAAA,EAAA,IAAA,CAAC,EAAD,CAAiC,KAAM,EAArB,EAAI,IAAiB,CAAC,CAC5D,CAAA,EACH,EAAI,MACN,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAW,EAAO,SAAU,SAAA,8EAA+E,CAAA,EAC5G,KAEH,CAAC,EAAI,MAAQ,EAAI,OAAO,SACvB,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,EAAO,SAAvB,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,EAAD,CACE,MAAM,eACN,IAAK,EACL,IAAK,IACL,KAAM,EACN,MAAO,EACG,WACV,WAAY,GAAG,EAAQ,GACvB,UAAW,GAAG,EAAQ,kBAAkB,EAAI,SAAW,OAAS,iBAAmB,gBAAgB,eACnG,SAAW,GAAM,EAAW,EAAa,OAAO,EAAE,cAAc,KAAK,CAAC,CAAC,CACxE,CAAA,EACA,EAAI,mBACH,EAAA,EAAA,IAAA,CAAC,EAAD,CACE,MAAM,iBACN,IAAK,GACL,IAAK,IACL,KAAM,EACN,MAAO,EACG,WACV,WAAY,GAAW,IAAM,OAAS,GAAG,EAAQ,GACjD,UAAW,GAAW,IAAM,oBAAsB,qBAAqB,EAAQ,+BAC/E,SAAW,GAAM,EAAW,EAAa,OAAO,EAAE,cAAc,KAAK,EAAG,GAAI,GAAG,CAAC,CACjF,CAAA,EACC,IACD,CACH,CAAA,EAAA,MAEJ,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAW,EAAO,IAAM,SAAA,EAAI,GAAO,CAAA,EACrC,EAAI,KAAK,OAAS,GACjB,EAAA,EAAA,KAAA,CAAC,UAAD,CAAS,UAAW,EAAO,KAA3B,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,UAAD,CAAA,SAAU,EAAI,KAAK,SAAW,EAAI,cAAgB,GAAG,EAAI,KAAK,OAAO,YAAsB,CAAA,GAC3F,EAAA,EAAA,IAAA,CAAC,KAAD,CAAA,SACG,EAAI,KAAK,IAAK,IAAW,EAAA,EAAA,IAAA,CAAC,KAAD,CAAA,SAAkB,CAAW,EAApB,CAAoB,CAAC,CACtD,CAAA,CACG,CACP,CAAA,EAAA,IACF,GAER,CAyBA,SAAgB,EAAkB,CAAE,OAAM,UAAS,QAAO,UAAS,QAAO,WAAW,GAAO,UAAU,KAAM,SAAQ,UAAkC,CACpJ,IAAM,GAAA,EAAU,EAAA,MAAA,CAAM,EAMhB,EAAO,CAAC,GAAG,EAAe,CAAI,CAAC,CAAC,OAAO,CAAC,EACxC,EAAU,EAAc,CAAI,EAC5B,EAAY,EAAoB,KAAM,GAAM,EAAE,QAAU,EAAK,IAAI,GAAK,KACtE,EAAO,GAAa,EAAoB,GACxC,EAAW,OAAO,EAAK,iBAAoB,UAAY,OAAO,SAAS,EAAK,eAAe,EAAI,EAAK,gBAAkB,KACtH,EAAe,EAAU,EAAoB,KAAM,GAAM,EAAE,QAAU,CAAO,CAAC,EAAE,OAAS,EAAU,KAClG,EAAW,EAAiB,EAAK,KAAM,CAAO,EAC9C,EAAS,GAAS,OAAS,EAAK,KAAM,GAAM,EAAE,SAAW,EAAQ,MAAM,EAAI,KAEjF,OACE,EAAA,EAAA,KAAA,CAAC,UAAD,CAAS,UAAW,EAAO,MAAO,kBAAiB,EAAnD,SAAA,EACE,EAAA,EAAA,KAAA,CAAC,SAAD,CAAQ,UAAW,EAAO,OAA1B,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,GAAI,EAAS,UAAW,EAAO,MAAO,SAAA,QAAU,CAAA,GACpD,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAW,EAAO,QAAU,SAAA,EAAQ,QAAY,CAAA,GACnD,EAAA,EAAA,KAAA,CAAC,OAAD,CAAM,UAAW,EAAO,IAAxB,SAAA,CAA6B,YAAU,EAAW,EAAK,UAAW,CAAK,CAAQ,GACzE,KAER,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,EAAO,KAAvB,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,EAAD,CACE,aAAW,cACX,QAAS,EAAoB,IAAK,IAAO,CACvC,MAAO,EAAE,MACT,MAAO,EAAE,MACT,GAAI,EAAiB,EAAE,MAAO,CAAO,EAAI,CAAE,UAAW,GAAG,EAAE,MAAM,oBAAqB,EAAI,CAAC,EAC3F,SAAU,GAAY,IAAY,MAAQ,EAAiB,EAAE,MAAO,CAAO,CAC7E,EAAE,EACF,MAAO,EAAK,KACZ,SAAW,GAAS,CAAM,IAAS,EAAK,MAAQ,CAAC,EAAiB,EAAM,CAAO,GAAG,EAAO,CAAI,CAAG,CACjG,CAAA,GAGD,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAW,EAAO,SAAW,SAAA,EAAY,EAAK,YAAc,0CAA8C,CAAA,EAC5G,GACC,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAW,EAAO,SAAU,eAAa,GACzC,SAAA,EACG,2BAA2B,EAAa,0BAA0B,EAAa,yBAC/E,2BAA2B,EAAa,4DAC3C,CAAA,EACD,IACD,IAEJ,GACC,EAAA,EAAA,KAAA,CAAC,IAAD,CAAG,UAAW,EAAO,QAAS,YAAU,SAAxC,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,YAAa,SAAA,oBAAwB,CAAA,EAAE,KAC/D,EAAA,EAAA,IAAA,CAAC,SAAD,CAAA,SAAS,GAAQ,OAAU,EAAQ,QAAU,mBAA6B,CAAA,GAC1E,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,WAAa,SAAA,EAAQ,GAAU,CAAA,CACtD,CACD,CAAA,EAAA,KAEH,GAAQ,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAW,EAAO,MAAO,KAAK,QAAS,SAAA,CAAS,CAAA,EAAI,KAE/D,EAAK,SAAW,GACf,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAW,EAAO,MAAO,SAAA,0EAA2E,CAAA,GAEvG,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAW,EAAO,MACnB,SAAA,EAAK,IAAK,IACT,EAAA,EAAA,IAAA,CAAC,EAAD,CAA+B,MAAK,OAAQ,IAAY,EAAI,QAAU,IAAY,OAAkB,WAAkB,QAAS,EAAjH,EAAI,MAA6G,CAChI,CACC,CAAA,GAGN,EAAA,EAAA,KAAA,CAAC,IAAD,CAAG,UAAW,EAAO,SAArB,SAAA,CAA+B,6JAEa,IAAa,KAA+D,yBAAxD,cAAc,KAAK,MAAM,EAAW,GAAM,EAAE,UAAqC,iBAC9I,GACI,GAEb,CAMA,SAAgB,EAAc,CAAE,UAAU,MAA0C,CAAC,EAAG,CACtF,IAAM,EAAS,EAAS,EAAa,CAAE,QAAS,CAAE,CAAC,EAC7C,EAAU,EAAS,EAAoB,CAAE,QAAS,CAAE,CAAC,EACrD,EAAgB,EAAW,CAAW,EACtC,EAAiB,EAAW,CAAkB,EAC9C,EAAO,EAAa,EACpB,CAAC,EAAQ,IAAA,EAAa,EAAA,SAAA,CAA4B,IAAI,EACtD,CAAC,EAAS,IAAA,EAAc,EAAA,SAAA,CAAwB,IAAI,EACpD,CAAC,EAAO,IAAA,EAAY,EAAA,SAAA,CAAwB,IAAI,EAChD,CAAC,EAAO,IAAA,EAAY,EAAA,SAAA,KAAe,KAAK,IAAI,CAAC,GAGnD,EAAA,EAAA,UAAA,KAAgB,CACd,IAAM,MAAmB,EACnB,OAAO,SAAa,KAAe,SAAS,kBAAoB,YACpE,EAAc,EACd,EAAe,EACf,EAAS,KAAK,IAAI,CAAC,EACrB,EACM,EAAQ,OAAO,YAAY,EAAM,CAAc,EAErD,OADA,SAAS,iBAAiB,mBAAoB,CAAI,MACrC,CACX,OAAO,cAAc,CAAK,EAC1B,SAAS,oBAAoB,mBAAoB,CAAI,CACvD,CACF,EAAG,CAAC,EAAe,CAAc,CAAC,EAKlC,IAAM,EAAS,EAAO,KAChB,EAAO,IAAW,CAAC,GAAU,EAAE,KAAK,MAAM,EAAO,SAAS,EAAI,KAAK,MAAM,EAAO,SAAS,IAAM,EAAS,EAExG,GAAA,EAAQ,EAAA,YAAA,CAAY,MAAO,EAAa,EAAgB,IAA+C,CAC3G,EAAW,CAAG,EACd,EAAS,IAAI,EACb,GAAI,CACF,IAAM,EAAO,MAAM,EAAK,IAAI,MAAc,EAAa,CAAM,CAAC,EAC1D,GAAM,EAAU,CAAI,CAC1B,OAAS,EAAK,CACZ,EAAS,EAAqB,CAAG,CAAC,CACpC,QAAU,CACR,EAAW,IAAI,EACf,EAAS,KAAK,IAAI,CAAC,CACrB,CACF,EAAG,CAAC,CAAI,CAAC,EAcT,OAZK,GAaH,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,EAAD,CACQ,OACN,QAAS,EAAQ,MAAQ,KAClB,QACE,UACF,QACE,UACT,OAAS,GAAS,KAAK,EAAM,OAAQ,wBAAwB,IAAQ,CAAE,MAAK,CAAC,EAC7E,QAAS,EAAQ,IAAU,KAAK,EAAM,EAAQ,yBAAyB,IAAU,CAAE,SAAQ,OAAQ,CAAM,CAAC,CAC3G,CAAA,GACD,EAAA,EAAA,IAAA,CAAC,EAAD,CAAqB,KAAM,EAAK,OAAO,KAAM,OAAQ,EAAK,OAAO,OAAQ,WAAW,iBAClF,UAAU,yCAAyC,QAAS,EAAK,OAAO,QAAS,WAAY,EAAK,OAAO,UAAa,CAAA,CACxH,CAAA,CAAA,GAxBA,EAAA,EAAA,IAAA,CAAC,UAAD,CAAS,UAAW,EAAO,MAAO,aAAW,SAC1C,SAAA,EAAO,SAAW,SACjB,EAAA,EAAA,KAAA,CAAC,IAAD,CAAG,UAAW,EAAO,MAAO,KAAK,QAAjC,SAAA,CAAyC,uBAAqB,EAAO,OAAO,SAAW,qBAAyB,CAEhH,CAAA,GAAA,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAW,EAAO,QAAS,SAAA,qBAAsB,CAAA,CAE/C,CAAA,CAoBf"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{a as e,n as t,s as n}from"./index-afDA8cwW.js";import{E as r,T as i,c as a,f as o,h as s,k as c,l,n as u,t as d,u as f,v as p,w as m,y as h}from"./useChartWidth-MEXvDxDL.js";import{_ as g,c as _}from"./colors-B-vHsX1S.js";import{n as v}from"./Swimlane-BR40WVcj.js";var y={tile:`_tile_lsnkj_1`,label:`_label_lsnkj_15`,value:`_value_lsnkj_25`,trend:`_trend_lsnkj_36`,meta:`_meta_lsnkj_41`,delta:`_delta_lsnkj_48`,deltaGood:`_deltaGood_lsnkj_54`,deltaBad:`_deltaBad_lsnkj_58`,deltaNeutral:`_deltaNeutral_lsnkj_62`,caption:`_caption_lsnkj_66`},b=t();function x(e){return[e.format?e.format(e.value):c(e.value),e.unit,e.versus].filter(e=>e!==void 0&&e!==``).join(` `)}function S({label:e,value:t,caption:n,delta:r,trend:i,trendLabel:a,describeTrend:o}){let s=r==null||r.goodWhenPositive===void 0||r.value===0?y.deltaNeutral:r.value>0===r.goodWhenPositive?y.deltaGood:y.deltaBad;return(0,b.jsxs)(`div`,{className:y.tile,"data-stat-tile":``,children:[(0,b.jsx)(`span`,{className:y.label,children:e}),(0,b.jsx)(`span`,{className:y.value,children:t}),i?(0,b.jsx)(`span`,{className:y.trend,children:(0,b.jsx)(v,{points:i,width:112,height:24,area:!0,ariaLabel:a??`${e} trend`,describe:o})}):null,r||n?(0,b.jsxs)(`div`,{className:y.meta,children:[r?(0,b.jsx)(`span`,{className:`${y.delta} ${s}`,children:x(r)}):null,n?(0,b.jsx)(`span`,{className:y.caption,children:n}):null]}):null]})}var C=n(e(),1),w=16,T=26,E=14;function D(e){let t=new Date(e);return Number.isNaN(t.getTime())?``:t.toLocaleString(`en-US`,{weekday:`short`,hour:`numeric`,minute:`2-digit`})}function O(e){let t=Math.max(0,Math.round(e/6e4));if(t<60)return`${t}m`;let n=Math.floor(t/60);return n<48?t%60?`${n}h ${t%60}m`:`${n}h`:`${Math.round(n/24)}d`}function k(e,t,n,r,i){return e.from&&e.from.remaining<=0?{text:`Used up — resets ${r(t)}.`,severity:`danger`}:e.from&&i!==void 0&&e.reserveAt!==null&&e.reserveAt<=e.from.t?{text:`Inside ${i.toLowerCase()} — autonomy has stopped using this window until ${r(t)}.`,severity:`warn`}:e.slopePerMs===null?{text:`Not enough readings to project this window yet.`,severity:`unknown`}:e.exhaustAt===null?e.reserveAt===null?{text:`At this pace: about ${n(e.remainingAtReset??0)} left at reset.`,severity:`ok`}:{text:`At this pace: ${i??`reserve`} reached ${r(e.reserveAt)}, ${O(t-e.reserveAt)} before reset.`,severity:`warn`}:{text:`At this pace: runs out ${r(e.exhaustAt)}, ${O(t-e.exhaustAt)} before reset.`,severity:`danger`}}function A({title:e,description:t,caveat:n,status:c,points:v,capacity:y,start:x,resetAt:S,now:O,reserve:A,height:j=200,width:M,formatValue:N=r,formatTime:P=D,ariaLabel:F}){let I=(0,C.useRef)(null),L=d(I,M),R=[...v].sort((e,t)=>e.t-t.t),z=R.some(e=>e.remaining!==null),ee=c??(R.length===0?{kind:`empty`,message:`No readings in this window yet.`}:z?{kind:`ready`}:{kind:`unknown`}),B=o(R,S,{reserve:A?.value??null}),V=k(B,S,N,P,A?.label),H=f(0,Math.max(y,1),4),U=H[H.length-1],W=Math.min(56,Math.max(28,Math.max(...H.map(e=>N(e).length))*7+10)),G=Math.max(40,L-W-E),K=j-w-T,q=Math.max(S,x+1),J=l(x,q,W,W+G),Y=l(0,U,w+K,w),X=e=>Math.min(q,Math.max(x,e)),Z=s(R.map(e=>({x:X(e.t),y:e.remaining}))).map(e=>e.map(e=>({x:J(e.x),y:Y(Math.max(0,e.y))}))),Q=``;if(B.from&&B.slopePerMs!==null){let e=B.exhaustAt??S,t=B.exhaustAt===null?B.remainingAtReset??B.from.remaining:0;e>B.from.t&&(Q=a([{x:J(X(B.from.t)),y:Y(B.from.remaining)},{x:J(X(e)),y:Y(Math.max(0,t))}]))}let $=V.severity===`danger`?g(`danger`):V.severity===`warn`?g(`warning`):`var(--text-tertiary)`,te=F??`${e}: ${B.from?`${N(B.from.remaining)} of ${N(y)} left at ${P(B.from.t)}`:`no readings`}; resets ${P(S)}. ${V.text}`,ne=[{key:`t`,label:`When`,render:e=>P(e.t)},{key:`r`,label:`Remaining`,numeric:!0,render:e=>e.remaining===null?`—`:N(e.remaining)}],re=[{label:`Remaining`,color:_,kind:`line`},{label:`Even pace`,color:`var(--text-tertiary)`,kind:`line`},...Q?[{label:`Projection`,color:$,kind:`line`}]:[]];return(0,b.jsx)(p,{title:e,description:t,caveat:n,status:ee,table:(0,b.jsx)(i,{caption:e,columns:ne,rows:R,rowKey:e=>String(e.t)}),footer:(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(`p`,{className:m.note,"data-severity":V.severity,role:`status`,children:V.text}),(0,b.jsx)(h,{items:re})]}),children:(0,b.jsx)(`div`,{ref:I,className:m.plotWrap,children:(0,b.jsxs)(`svg`,{className:m.svg,width:L,height:j,viewBox:`0 0 ${L} ${j}`,role:`img`,"aria-label":te,children:[H.map(e=>(0,b.jsxs)(`g`,{children:[(0,b.jsx)(`line`,{className:m.grid,x1:W,x2:W+G,y1:Y(e),y2:Y(e)}),(0,b.jsx)(`text`,{className:m.tick,x:W-6,y:Y(e),dy:`0.32em`,textAnchor:`end`,children:N(e)})]},e)),(0,b.jsx)(`line`,{className:m.axis,x1:W,x2:W+G,y1:Y(0),y2:Y(0)}),(0,b.jsx)(`text`,{className:m.tick,x:W,y:j-8,textAnchor:`start`,children:P(x)}),(0,b.jsxs)(`text`,{className:m.tick,x:W+G,y:j-8,textAnchor:`end`,children:[`Resets `,P(S)]}),(0,b.jsx)(`path`,{"data-role":`pace`,className:m.reference,d:a([{x:J(x),y:Y(y)},{x:J(q),y:Y(0)}])}),A?(0,b.jsxs)(`g`,{"data-role":`reserve`,children:[(0,b.jsx)(`line`,{className:m.reference,x1:W,x2:W+G,y1:Y(A.value),y2:Y(A.value)}),(0,b.jsxs)(`text`,{"data-role":`reserve-label`,className:`${m.tick} ${m.halo}`,x:W+4,y:Y(A.value)-5,textAnchor:`start`,children:[A.label,` · `,N(A.value)]})]}):null,O>x&&O<q?(0,b.jsx)(`line`,{className:m.crosshair,x1:J(O),x2:J(O),y1:w,y2:w+K}):null,Z.map((e,t)=>(0,b.jsxs)(`g`,{"data-role":`remaining`,children:[(0,b.jsx)(`path`,{className:m.wash,fill:_,d:u(e,e.map(e=>({x:e.x,y:Y(0)})))}),(0,b.jsx)(`path`,{className:m.line,stroke:_,d:a(e)})]},t)),Q?(0,b.jsx)(`path`,{"data-role":`projection`,className:m.projection,stroke:$,d:Q}):null,B.from?(0,b.jsx)(`circle`,{className:m.marker,cx:J(X(B.from.t)),cy:Y(B.from.remaining),r:4,fill:_}):null]})})})}export{S as n,A as t};
|
|
2
|
-
//# sourceMappingURL=BurnDown-4P1LDoCL.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"BurnDown-4P1LDoCL.js","names":[],"sources":["../../../../../../src/web-ui/components/charts/StatTile.module.css","../../../../../../src/web-ui/components/charts/StatTile.tsx","../../../../../../src/web-ui/components/charts/BurnDown.tsx"],"sourcesContent":[".tile {\n display: flex;\n flex-direction: column;\n gap: var(--space-1);\n min-width: 0;\n padding: var(--card-pad, var(--space-4));\n border-radius: var(--radius-lg);\n border: 1px solid var(--border-subtle);\n background: var(--bg-surface);\n /* Dark: a 4% white top hairline lifts the KPI row off the canvas; light:\n the token is transparent and this draws nothing. */\n box-shadow: inset 0 1px 0 var(--hairline-lift, transparent);\n}\n\n.label {\n font-family: var(--font-display);\n font-size: var(--text-2xs-size);\n line-height: var(--text-2xs-line);\n color: var(--text-tertiary);\n text-transform: uppercase;\n letter-spacing: var(--tracking-label);\n}\n\n/* KPI number: Plex 600, 24/32, tabular numerals (SPEC-310C §6). */\n.value {\n font-family: var(--font-ui);\n font-size: var(--text-2xl-size);\n line-height: var(--text-2xl-line);\n font-weight: var(--font-weight-semibold);\n font-variant-numeric: tabular-nums;\n color: var(--text-primary);\n overflow-wrap: anywhere;\n}\n\n/* The sparkline sits directly under the number it explains. */\n.trend {\n display: block;\n line-height: 0;\n}\n\n.meta {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: var(--space-1) var(--space-2);\n}\n\n.delta {\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n font-variant-numeric: tabular-nums;\n}\n\n.deltaGood {\n color: var(--status-success-fg);\n}\n\n.deltaBad {\n color: var(--status-danger-fg);\n}\n\n.deltaNeutral {\n color: var(--text-tertiary);\n}\n\n.caption {\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n color: var(--text-tertiary);\n}\n","/**\n * components/charts/StatTile.tsx — value + delta + optional sparkline, the\n * figure contract from marks-and-anatomy.md. Use for a single current value\n * (a one-bar bar chart is never the answer — this is). `value` takes a\n * ReactNode (not just a string) so callers can wrap a sourceQuality-bearing\n * field in <Epistemic/> and pass that straight through.\n *\n * V3.10 (SPEC-310C §6 \"StatTile: sparkline goes under the number; deltas show\n * units\"): the 72×24 sparkline used to float top-right, disconnected from the\n * number it explains; it now sits directly under it. A delta reads as a\n * sentence fragment with its unit and its comparison — \"+5 merges vs prior\n * 7d\", never a bare \"-1\". In dark the tile gets the 4% top hairline\n * (`--hairline-lift`, transparent in light) so a KPI row lifts off the canvas.\n */\nimport type { ReactNode } from 'react';\nimport { formatSignedCompact } from './format.js';\nimport { Sparkline } from './Sparkline.js';\nimport styles from './StatTile.module.css';\n\nexport interface StatTileDelta {\n /** Signed raw value, e.g. +12 or -3. */\n value: number;\n /** Whether a positive delta reads as good (green) or bad (red). Omit for\n * a neutral, non-judgmental delta (e.g. \"goals in flight\" — more isn't\n * inherently good or bad). */\n goodWhenPositive?: boolean;\n /** vs which period, e.g. \"vs prior 7d\". */\n versus?: string;\n /** Unit after the number: \"merges\", \"pts\", \"min\". Plural is the caller's call. */\n unit?: string;\n /** Formats the SIGNED value (default: \"+12\" / \"-3\"). Use for percent points, durations, dollars. */\n format?: (signed: number) => string;\n}\n\n/** \"+5 merges vs prior 7d\" — the whole delta as one readable phrase. */\nexport function deltaText(delta: StatTileDelta): string {\n const n = delta.format ? delta.format(delta.value) : formatSignedCompact(delta.value);\n return [n, delta.unit, delta.versus].filter((part) => part !== undefined && part !== '').join(' ');\n}\n\nexport function StatTile({\n label,\n value,\n caption,\n delta,\n trend,\n trendLabel,\n describeTrend,\n}: {\n label: string;\n value: ReactNode;\n caption?: ReactNode;\n delta?: StatTileDelta | null;\n trend?: (number | null)[];\n trendLabel?: string;\n /** Spoken summary formatter for the sparkline (first → latest, range). */\n describeTrend?: (v: number) => string;\n}) {\n const deltaTone =\n delta == null || delta.goodWhenPositive === undefined\n ? styles.deltaNeutral\n : delta.value === 0\n ? styles.deltaNeutral\n : (delta.value > 0) === delta.goodWhenPositive\n ? styles.deltaGood\n : styles.deltaBad;\n\n return (\n <div className={styles.tile} data-stat-tile=\"\">\n <span className={styles.label}>{label}</span>\n <span className={styles.value}>{value}</span>\n {trend ? (\n <span className={styles.trend}>\n <Sparkline points={trend} width={112} height={24} area ariaLabel={trendLabel ?? `${label} trend`} describe={describeTrend} />\n </span>\n ) : null}\n {delta || caption ? (\n <div className={styles.meta}>\n {delta ? <span className={`${styles.delta} ${deltaTone}`}>{deltaText(delta)}</span> : null}\n {caption ? <span className={styles.caption}>{caption}</span> : null}\n </div>\n ) : null}\n </div>\n );\n}\n","/**\n * components/charts/BurnDown.tsx — a quota window burning down to its reset:\n * remaining capacity over time (solid line + wash), the even-pace reference\n * from full at window start to empty at reset (thin dashed), a projection\n * from the recent slope (dashed), an optional reserve line (the headroom kept\n * for interactive use) and the reset marker.\n *\n * The verdict is written in words under the plot — \"At this pace: reserve\n * reached 14:20, 3h 40m before reset\" — so the chart's point never depends on\n * reading slopes. With fewer than two readings it says it cannot project,\n * rather than drawing a guess.\n */\nimport { useRef } from 'react';\nimport { CHART_SEQUENTIAL, toneColor } from './colors.js';\nimport { ChartFrame, type ChartStatus } from './ChartFrame.js';\nimport { ChartLegend } from './ChartParts.js';\nimport { TableView, type TableColumn } from './TableView.js';\nimport { areaPath, linePath, linearScale, niceTicks, projectBurnDown, splitRuns, type BurnPoint } from './chart-math.js';\nimport { formatCompact } from './format.js';\nimport { useChartWidth } from './useChartWidth.js';\nimport plot from './plot.module.css';\n\nexport interface BurnDownProps {\n title: string;\n description?: string;\n caveat?: string;\n status?: ChartStatus;\n points: BurnPoint[];\n /** Full capacity of the window (e.g. 100 for percent). */\n capacity: number;\n /** Window start and reset, epoch ms. */\n start: number;\n resetAt: number;\n now: number;\n /** Capacity to keep in reserve (same units as `remaining`). */\n reserve?: { value: number; label: string };\n height?: number;\n width?: number;\n formatValue?: (v: number) => string;\n formatTime?: (ms: number) => string;\n ariaLabel?: string;\n}\n\nconst PAD_T = 16;\nconst PAD_B = 26;\nconst PAD_R = 14;\n\nfunction defaultFormatTime(ms: number): string {\n const d = new Date(ms);\n return Number.isNaN(d.getTime()) ? '' : d.toLocaleString('en-US', { weekday: 'short', hour: 'numeric', minute: '2-digit' });\n}\n\nexport function formatLead(ms: number): string {\n const m = Math.max(0, Math.round(ms / 60_000));\n if (m < 60) return `${m}m`;\n const h = Math.floor(m / 60);\n if (h < 48) return m % 60 ? `${h}h ${m % 60}m` : `${h}h`;\n return `${Math.round(h / 24)}d`;\n}\n\nexport function burnVerdict(\n projection: ReturnType<typeof projectBurnDown>,\n resetAt: number,\n formatValue: (v: number) => string,\n formatTime: (ms: number) => string,\n reserveLabel?: string,\n): { text: string; severity: 'ok' | 'warn' | 'danger' | 'unknown' } {\n // Already past a line: say where it IS, not a \"projection\" to a moment\n // that has passed (a used-up seat is not \"running out at 3:02\").\n if (projection.from && projection.from.remaining <= 0) {\n return { text: `Used up — resets ${formatTime(resetAt)}.`, severity: 'danger' };\n }\n if (projection.from && reserveLabel !== undefined && projection.reserveAt !== null && projection.reserveAt <= projection.from.t) {\n return { text: `Inside ${reserveLabel.toLowerCase()} — autonomy has stopped using this window until ${formatTime(resetAt)}.`, severity: 'warn' };\n }\n if (projection.slopePerMs === null) return { text: 'Not enough readings to project this window yet.', severity: 'unknown' };\n if (projection.exhaustAt !== null) {\n return {\n text: `At this pace: runs out ${formatTime(projection.exhaustAt)}, ${formatLead(resetAt - projection.exhaustAt)} before reset.`,\n severity: 'danger',\n };\n }\n if (projection.reserveAt !== null) {\n return {\n text: `At this pace: ${reserveLabel ?? 'reserve'} reached ${formatTime(projection.reserveAt)}, ${formatLead(resetAt - projection.reserveAt)} before reset.`,\n severity: 'warn',\n };\n }\n return {\n text: `At this pace: about ${formatValue(projection.remainingAtReset ?? 0)} left at reset.`,\n severity: 'ok',\n };\n}\n\nexport function BurnDown({\n title,\n description,\n caveat,\n status,\n points,\n capacity,\n start,\n resetAt,\n now,\n reserve,\n height = 200,\n width: fixedWidth,\n formatValue = formatCompact,\n formatTime = defaultFormatTime,\n ariaLabel,\n}: BurnDownProps) {\n const wrapRef = useRef<HTMLDivElement>(null);\n const width = useChartWidth(wrapRef, fixedWidth);\n const sorted = [...points].sort((a, b) => a.t - b.t);\n const anyKnown = sorted.some((p) => p.remaining !== null);\n const resolvedStatus: ChartStatus = status ?? (sorted.length === 0 ? { kind: 'empty', message: 'No readings in this window yet.' } : anyKnown ? { kind: 'ready' } : { kind: 'unknown' });\n\n const projection = projectBurnDown(sorted, resetAt, { reserve: reserve?.value ?? null });\n const verdict = burnVerdict(projection, resetAt, formatValue, formatTime, reserve?.label);\n\n const ticks = niceTicks(0, Math.max(capacity, 1), 4);\n const top = ticks[ticks.length - 1]!;\n const padL = Math.min(56, Math.max(28, Math.max(...ticks.map((t) => formatValue(t).length)) * 7 + 10));\n const plotW = Math.max(40, width - padL - PAD_R);\n const plotH = height - PAD_T - PAD_B;\n const xEnd = Math.max(resetAt, start + 1);\n const xs = linearScale(start, xEnd, padL, padL + plotW);\n const ys = linearScale(0, top, PAD_T + plotH, PAD_T);\n const clampX = (t: number) => Math.min(xEnd, Math.max(start, t));\n\n const runs = splitRuns(sorted.map((p) => ({ x: clampX(p.t), y: p.remaining })))\n .map((run) => run.map((p) => ({ x: xs(p.x), y: ys(Math.max(0, p.y)) })));\n\n let projectionPath = '';\n if (projection.from && projection.slopePerMs !== null) {\n const endT = projection.exhaustAt ?? resetAt;\n const endR = projection.exhaustAt !== null ? 0 : projection.remainingAtReset ?? projection.from.remaining;\n if (endT > projection.from.t) {\n projectionPath = linePath([\n { x: xs(clampX(projection.from.t)), y: ys(projection.from.remaining) },\n { x: xs(clampX(endT)), y: ys(Math.max(0, endR)) },\n ]);\n }\n }\n const projectionColor = verdict.severity === 'danger' ? toneColor('danger') : verdict.severity === 'warn' ? toneColor('warning') : 'var(--text-tertiary)';\n\n const summary = ariaLabel ?? `${title}: ${projection.from ? `${formatValue(projection.from.remaining)} of ${formatValue(capacity)} left at ${formatTime(projection.from.t)}` : 'no readings'}; resets ${formatTime(resetAt)}. ${verdict.text}`;\n\n const columns: TableColumn<BurnPoint>[] = [\n { key: 't', label: 'When', render: (p) => formatTime(p.t) },\n { key: 'r', label: 'Remaining', numeric: true, render: (p) => (p.remaining === null ? '—' : formatValue(p.remaining)) },\n ];\n\n const legendItems = [\n { label: 'Remaining', color: CHART_SEQUENTIAL, kind: 'line' as const },\n { label: 'Even pace', color: 'var(--text-tertiary)', kind: 'line' as const },\n ...(projectionPath ? [{ label: 'Projection', color: projectionColor, kind: 'line' as const }] : []),\n ];\n\n return (\n <ChartFrame\n title={title}\n description={description}\n caveat={caveat}\n status={resolvedStatus}\n table={<TableView caption={title} columns={columns} rows={sorted} rowKey={(p) => String(p.t)} />}\n footer={\n <>\n <p className={plot.note} data-severity={verdict.severity} role=\"status\">{verdict.text}</p>\n <ChartLegend items={legendItems} />\n </>\n }\n >\n <div ref={wrapRef} className={plot.plotWrap}>\n <svg className={plot.svg} width={width} height={height} viewBox={`0 0 ${width} ${height}`} role=\"img\" aria-label={summary}>\n {ticks.map((t) => (\n <g key={t}>\n <line className={plot.grid} x1={padL} x2={padL + plotW} y1={ys(t)} y2={ys(t)} />\n <text className={plot.tick} x={padL - 6} y={ys(t)} dy=\"0.32em\" textAnchor=\"end\">{formatValue(t)}</text>\n </g>\n ))}\n <line className={plot.axis} x1={padL} x2={padL + plotW} y1={ys(0)} y2={ys(0)} />\n <text className={plot.tick} x={padL} y={height - 8} textAnchor=\"start\">{formatTime(start)}</text>\n <text className={plot.tick} x={padL + plotW} y={height - 8} textAnchor=\"end\">Resets {formatTime(resetAt)}</text>\n\n <path data-role=\"pace\" className={plot.reference} d={linePath([{ x: xs(start), y: ys(capacity) }, { x: xs(xEnd), y: ys(0) }])} />\n {reserve ? (\n <g data-role=\"reserve\">\n <line className={plot.reference} x1={padL} x2={padL + plotW} y1={ys(reserve.value)} y2={ys(reserve.value)} />\n {/* Above-left of the line, over a surface halo (SPEC-310C §6): the\n window's start is the one place the remaining line is always\n high, and the projection only ever runs to the right, so the\n label never sits on the data. */}\n <text data-role=\"reserve-label\" className={`${plot.tick} ${plot.halo}`} x={padL + 4} y={ys(reserve.value) - 5} textAnchor=\"start\">\n {reserve.label} · {formatValue(reserve.value)}\n </text>\n </g>\n ) : null}\n {now > start && now < xEnd ? (\n <line className={plot.crosshair} x1={xs(now)} x2={xs(now)} y1={PAD_T} y2={PAD_T + plotH} />\n ) : null}\n {runs.map((run, i) => (\n <g key={i} data-role=\"remaining\">\n <path className={plot.wash} fill={CHART_SEQUENTIAL} d={areaPath(run, run.map((p) => ({ x: p.x, y: ys(0) })))} />\n <path className={plot.line} stroke={CHART_SEQUENTIAL} d={linePath(run)} />\n </g>\n ))}\n {projectionPath ? (\n <path data-role=\"projection\" className={plot.projection} stroke={projectionColor} d={projectionPath} />\n ) : null}\n {projection.from ? (\n <circle className={plot.marker} cx={xs(clampX(projection.from.t))} cy={ys(projection.from.remaining)} r={4} fill={CHART_SEQUENTIAL} />\n ) : null}\n </svg>\n </div>\n </ChartFrame>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{a as e,n as t,s as n}from"./index-afDA8cwW.js";import{h as r,m as i}from"./global-DVgMguLr.js";import{x as a}from"./verse-queries-BjQoOTwv.js";import{i as o,r as s}from"./section-visibility-CSrsTcwK.js";import{i as c,n as l,s as u,t as d}from"./capacity-strip-model-BR539Ci8.js";import{r as f}from"./Tag-DEEbDz7T.js";import{n as p}from"./budget-queries-Dacv1VYP.js";import{n as m,t as h}from"./useSeatsRefresh-4Ov9eT1F.js";var g=n(e(),1),_={section:`_section_z7dje_8`,scroll:`_scroll_z7dje_16`,page:`_page_z7dje_34`,header:`_header_z7dje_43`,headerText:`_headerText_z7dje_50`,title:`_title_z7dje_56`,lede:`_lede_z7dje_65`,headerMeta:`_headerMeta_z7dje_71`,banner:`_banner_z7dje_80`,group:`_group_z7dje_97`,groupHead:`_groupHead_z7dje_103`,groupTitle:`_groupTitle_z7dje_110`,caveat:`_caveat_z7dje_127`,inlineCode:`_inlineCode_z7dje_134`,card:`_card_z7dje_143`,rows:`_rows_z7dje_151`,row:`_row_z7dje_151`,rowMain:`_rowMain_z7dje_169`,rowHead:`_rowHead_z7dje_176`,rowName:`_rowName_z7dje_183`,rowVersion:`_rowVersion_z7dje_189`,rowDesc:`_rowDesc_z7dje_194`,rowDetail:`_rowDetail_z7dje_195`,rowAside:`_rowAside_z7dje_206`,health:`_health_z7dje_217`,healthDot:`_healthDot_z7dje_226`,loadingLine:`_loadingLine_z7dje_252`,tile:`_tile_z7dje_262`,pillWrap:`_pillWrap_z7dje_303`,pill:`_pill_z7dje_303`,pillText:`_pillText_z7dje_330`,pillIcon:`_pillIcon_z7dje_338`,visuallyHidden:`_visuallyHidden_z7dje_349`,split:`_split_z7dje_363`,disabledNote:`_disabledNote_z7dje_376`,dialogBody:`_dialogBody_z7dje_386`,commandBlock:`_commandBlock_z7dje_397`,commandLabel:`_commandLabel_z7dje_402`,dialogActions:`_dialogActions_z7dje_410`,fieldset:`_fieldset_z7dje_417`,legend:`_legend_z7dje_425`,radio:`_radio_z7dje_432`,error:`_error_z7dje_442`,textarea:`_textarea_z7dje_448`,fieldLabel:`_fieldLabel_z7dje_465`,hint:`_hint_z7dje_473`,warnings:`_warnings_z7dje_477`,servers:`_servers_z7dje_487`,reasonCode:`_reasonCode_z7dje_493`,scopeLine:`_scopeLine_z7dje_499`},v=t();function y({monogram:e,engine:t,size:n=`md`}){let r=t===null?void 0:{"--tile-hue":f(t)};return(0,v.jsx)(`span`,{className:_.tile,"data-size":n,"data-engine":t??void 0,style:r,"aria-hidden":`true`,children:e.slice(0,2)})}var b={strip:`_strip_elew6_7`,visuallyHidden:`_visuallyHidden_elew6_15`,headline:`_headline_elew6_27`,empty:`_empty_elew6_35`,rows:`_rows_elew6_42`,row:`_row_elew6_42`,main:`_main_elew6_67`,head:`_head_elew6_27`,nameWrap:`_nameWrap_elew6_82`,nameButton:`_nameButton_elew6_83`,name:`_name_elew6_82`,plan:`_plan_elew6_120`,word:`_word_elew6_130`,dot:`_dot_elew6_139`,summary:`_summary_elew6_157`,meta:`_meta_elew6_158`,autonomy:`_autonomy_elew6_168`,bars:`_bars_elew6_178`,bar:`_bar_elew6_178`,barLabel:`_barLabel_elew6_197`,track:`_track_elew6_208`,trackUnknown:`_trackUnknown_elew6_216`,used:`_used_elew6_222`,reserve:`_reserve_elew6_233`,ceiling:`_ceiling_elew6_243`,value:`_value_elew6_252`,reset:`_reset_elew6_265`,actions:`_actions_elew6_272`},x=90;function S(e){return Math.max(0,Math.min(100,Math.round(e)))}function C({row:e,w:t,reservePercent:n,compact:r}){let i=u(e,t,t.binding?n:null),a=t.binding&&n!==null&&n>0?100-S(n):null,o,s;if(t.limitReached)o=(0,v.jsx)(`span`,{className:b.track,role:`img`,"aria-label":i,children:(0,v.jsx)(`span`,{className:b.used,"data-level":`limit`,style:{width:`100%`}})}),s=(0,v.jsx)(`span`,{className:b.value,"data-level":`limit`,children:`limit reached`});else if(t.usedPercent===null)o=(0,v.jsx)(`span`,{className:b.trackUnknown,role:`img`,"aria-label":i}),s=(0,v.jsx)(`span`,{className:b.value,"data-level":`unknown`,children:`no reading`});else{let e=S(t.usedPercent),n=e>=x?`tight`:`ok`;o=(0,v.jsxs)(`span`,{className:b.track,role:`img`,"aria-label":i,children:[a===null?null:(0,v.jsx)(`span`,{className:b.reserve,style:{left:`${a}%`,width:`${100-a}%`}}),(0,v.jsx)(`span`,{className:b.used,"data-level":n,style:{width:`${e}%`}}),a===null?null:(0,v.jsx)(`span`,{className:b.ceiling,style:{left:`${a}%`}})]}),s=(0,v.jsxs)(`span`,{className:b.value,"data-level":n,children:[e,`%`]})}return(0,v.jsxs)(`div`,{className:b.bar,"data-binding":t.binding||void 0,"data-compact":r||void 0,children:[(0,v.jsx)(`span`,{className:b.barLabel,children:t.label.replace(/ window$/,``)}),o,s,!r&&t.resetText!==null?(0,v.jsx)(`span`,{className:b.reset,children:t.resetText}):null]})}function w({row:e,onSelect:t,selected:n}){let r=(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(`span`,{className:b.name,children:e.label}),e.plan===null?null:(0,v.jsx)(`span`,{className:b.plan,children:e.plan})]});return t?(0,v.jsx)(`button`,{type:`button`,className:b.nameButton,"aria-pressed":n,onClick:()=>t(e.seatId),children:r}):(0,v.jsx)(`span`,{className:b.nameWrap,children:r})}function T({row:e,compact:t,renderActions:n,onSelectSeat:r,selected:i}){let a=c(e.cls),o=e.windows.find(e=>e.binding)??null,s=t?o?[o]:[]:e.windows,l=n?n(e):null,u=e.reserve;return(0,v.jsxs)(`li`,{className:b.row,"data-capacity":e.cls,"data-compact":t||void 0,children:[(0,v.jsx)(y,{monogram:e.monogram,engine:e.engine,size:`sm`}),(0,v.jsxs)(`div`,{className:b.main,children:[(0,v.jsxs)(`div`,{className:b.head,children:[(0,v.jsx)(w,{row:e,onSelect:r,selected:i}),(0,v.jsxs)(`span`,{className:b.word,"data-tone":a,children:[(0,v.jsx)(`span`,{className:b.dot,"aria-hidden":`true`}),e.word]}),e.connection!==null&&e.connection.connection!==`connected`&&e.connection.connection!==`unknown`?(0,v.jsxs)(`span`,{className:b.word,"data-tone":e.connection.tone,children:[(0,v.jsx)(`span`,{className:b.dot,"aria-hidden":`true`}),e.connection.word]}):null]}),!t||s.length===0?(0,v.jsx)(`p`,{className:b.summary,children:e.summary}):null,s.length>0?(0,v.jsx)(`div`,{className:b.bars,children:s.map(n=>(0,v.jsx)(C,{row:e,w:n,reservePercent:u?.percent??null,compact:t},n.id))}):null,!t&&(u!==null||e.credits!==null)?(0,v.jsxs)(`p`,{className:b.meta,children:[u===null?null:(0,v.jsxs)(`span`,{title:u.why,children:[u.label,u.autonomy===`off`?null:(0,v.jsxs)(v.Fragment,{children:[` · Autonomy: `,(0,v.jsx)(`span`,{className:b.autonomy,"data-status":u.autonomy,children:u.autonomyWord})]})]}),u!==null&&e.credits!==null?` · `:null,e.credits===null?null:(0,v.jsx)(`span`,{children:e.credits})]}):null]}),l?(0,v.jsx)(`div`,{className:b.actions,children:l}):null]})}function E({seats:e,health:t,budget:n,local:r,seatIds:i,density:a=`full`,headline:o,title:s=`Seat capacity`,labelledBy:c,renderActions:u,onSelectSeat:f,selectedSeatId:p=null,emptyText:m=`No seats yet. Connect an account or start Ollama — an empty roster, not seats at zero.`}){let h=(0,g.useId)(),_=(0,g.useMemo)(()=>d(e,{health:t??null,budget:n??null,...r?{local:r}:{},...i?{seatIds:i}:{}}),[e,t,n,r,i]),y=a===`compact`,x=o??!y;return(0,v.jsxs)(c?`div`:`section`,{className:b.strip,"aria-labelledby":c?void 0:h,"data-density":a,children:[c?null:(0,v.jsx)(`h3`,{id:h,className:b.visuallyHidden,children:s}),x&&_.length>0?(0,v.jsx)(`p`,{className:b.headline,children:l(_)}):null,_.length===0?(0,v.jsx)(`p`,{className:b.empty,children:m}):(0,v.jsx)(`ul`,{className:b.rows,"aria-label":c?void 0:s,"aria-labelledby":c,children:_.map(e=>(0,v.jsx)(T,{row:e,compact:y,renderActions:u,onSelectSeat:f,selected:p===e.seatId},e.seatId))})]})}var D=6e4;function O(e={}){let t=o(),n=e.withBudget??!0,c=e.withHealth??!0,l=i(a);h(t);let u=m(t&&c),d=i(p),f=r(p);s(f,D,{enabled:n});let g=l.data;return{seats:g?.seats??[],health:c?u.data?.seats??null:null,budget:n?d.data??null:null,loading:g===void 0&&(l.status===`loading`||l.status===`idle`)}}function k({seats:e,...t}){let n=O();return e===void 0&&n.loading?(0,v.jsx)(`p`,{className:b.empty,"aria-busy":`true`,children:`Reading seats…`}):(0,v.jsx)(E,{...t,seats:e??n.seats,health:n.health,budget:n.budget})}export{_ as a,y as i,k as n,O as r,E as t};
|
|
2
|
-
//# sourceMappingURL=CapacityStrip-D6Yyg4a1.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"CapacityStrip-D6Yyg4a1.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/apps/Apps.module.css","../../../../../../src/web-ui/routes/verse/apps/MonogramTile.tsx","../../../../../../src/web-ui/routes/verse/usage/CapacityStrip.module.css","../../../../../../src/web-ui/routes/verse/usage/CapacityStrip.tsx"],"sourcesContent":["/*\n * Apps & Accounts (SPEC-310C §4) — grouped rows in the Ollama style, max\n * 880px. Tokens only (DESIGN.md §13; style-scan-310 enforces it): no raw\n * colour, no px font size. The row adapts to its container: at the compact\n * width (480, viewport.ts) the right-hand pill wraps under the description.\n */\n\n.section {\n display: flex;\n flex-direction: column;\n min-height: 0;\n height: 100%;\n background: var(--bg-canvas);\n}\n\n.scroll {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n padding: var(--space-6) var(--space-4) var(--space-12);\n /* Desktop shell (desktop/README.md \"Desktop shell contract\"): this page has\n no 48px strip, so its title sits inside the OS title-bar band. Once the\n window is narrow enough that the 880px column stops centring (minWidth\n is 900), the column's left edge lands at rail + 16px — under the macOS\n traffic lights, which cover the top-left 92px of the WINDOW. Owe the same\n overlap every header strip owes (inset − rail, 36px on a 56px rail);\n the vars are absent in a browser and the expanded rail sits under the\n lights itself, so both floor to --space-4 and nothing moves there. The\n whole column shifts, not just the header, so the title stays aligned\n with the rows under it. */\n padding-left: max(var(--space-4), calc(var(--app-traffic-light-inset, 0px) - var(--rail-width, 56px)));\n}\n\n.page {\n container-type: inline-size;\n max-width: 880px;\n margin: 0 auto;\n display: flex;\n flex-direction: column;\n gap: var(--space-8);\n}\n\n.header {\n display: flex;\n flex-wrap: wrap;\n align-items: flex-end;\n justify-content: space-between;\n gap: var(--space-3) var(--space-4);\n}\n.headerText {\n display: flex;\n flex-direction: column;\n gap: var(--space-1);\n min-width: 0;\n}\n.title {\n margin: 0;\n font-family: var(--font-display);\n font-size: var(--text-xl-size);\n line-height: var(--text-xl-line);\n letter-spacing: var(--tracking-display);\n font-weight: var(--font-weight-semibold);\n color: var(--text-primary);\n}\n.lede {\n margin: 0;\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line);\n color: var(--text-secondary);\n}\n.headerMeta {\n display: flex;\n align-items: center;\n gap: var(--space-2);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n color: var(--text-tertiary);\n}\n\n.banner {\n margin: 0;\n padding: var(--space-3) var(--space-4);\n border: 1px solid var(--border-subtle);\n border-radius: var(--radius-md);\n background: var(--bg-surface);\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line);\n color: var(--text-secondary);\n}\n.banner[data-tone='danger'] {\n border-color: color-mix(in srgb, var(--status-danger-solid) 40%, var(--border-subtle));\n color: var(--status-danger-fg);\n}\n\n/* ── Groups ─────────────────────────────────────────────────────────── */\n\n.group {\n display: flex;\n flex-direction: column;\n gap: var(--space-2);\n scroll-margin-top: var(--space-6);\n}\n.groupHead {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--space-3);\n min-height: var(--control-h-sm);\n}\n.groupTitle {\n margin: 0;\n font-family: var(--font-display);\n font-size: var(--text-2xs-size);\n line-height: var(--text-2xs-line);\n text-transform: uppercase;\n letter-spacing: var(--tracking-label);\n font-weight: var(--font-weight-semibold);\n color: var(--text-tertiary);\n}\n.groupTitle:focus {\n outline: none;\n}\n.groupTitle:focus-visible {\n box-shadow: var(--shadow-focus-ring);\n border-radius: var(--radius-xs);\n}\n.caveat {\n margin: 0;\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n color: var(--text-secondary);\n}\n.caveat code,\n.inlineCode {\n font-family: var(--font-mono);\n font-size: var(--text-xs-size);\n background: var(--bg-code);\n padding: 0 var(--space-1);\n border-radius: var(--radius-xs);\n overflow-wrap: anywhere;\n}\n\n.card {\n border: 1px solid var(--border-subtle);\n border-radius: var(--radius-lg);\n background: var(--bg-surface);\n padding: 0 var(--card-pad);\n box-shadow: inset 0 1px 0 var(--hairline-lift);\n}\n\n.rows {\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n.row {\n display: grid;\n grid-template-columns: auto minmax(0, 1fr) auto;\n align-items: start;\n gap: var(--space-3);\n padding: var(--space-3) 0;\n border-top: 1px solid var(--border-subtle);\n}\n.row:first-child {\n border-top: 0;\n}\n\n.rowMain {\n display: flex;\n flex-direction: column;\n gap: var(--space-1);\n min-width: 0;\n padding-top: var(--space-1);\n}\n.rowHead {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: var(--space-1) var(--space-3);\n min-width: 0;\n}\n.rowName {\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line);\n font-weight: var(--font-weight-semibold);\n color: var(--text-primary);\n}\n.rowVersion {\n font-family: var(--font-mono);\n font-size: var(--text-xs-size);\n color: var(--text-tertiary);\n}\n.rowDesc,\n.rowDetail {\n margin: 0;\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n color: var(--text-secondary);\n overflow-wrap: anywhere;\n}\n.rowDetail {\n color: var(--text-tertiary);\n}\n\n.rowAside {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: flex-end;\n gap: var(--space-2);\n padding-top: var(--space-1);\n max-width: 26rem;\n}\n\n/* A health state is a WORD; the dot reinforces it (DESIGN §13.2). */\n.health {\n display: inline-flex;\n align-items: center;\n gap: var(--space-1);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n color: var(--text-secondary);\n white-space: nowrap;\n}\n.healthDot {\n width: 7px;\n height: 7px;\n border-radius: var(--radius-full);\n background: var(--status-neutral-solid);\n flex: none;\n}\n.health[data-tone='success'] .healthDot { background: var(--status-success-solid); }\n.health[data-tone='warning'] { color: var(--status-warning-fg); }\n.health[data-tone='warning'] .healthDot { background: var(--status-warning-solid); }\n.health[data-tone='danger'] { color: var(--status-danger-fg); }\n.health[data-tone='danger'] .healthDot { background: var(--status-danger-solid); }\n.health[data-tone='off'] { color: var(--text-tertiary); }\n.health[data-tone='off'] .healthDot {\n background: transparent;\n border: 1px solid var(--border-strong);\n}\n.health[data-tone='neutral'] {\n font-style: italic;\n color: var(--status-unknown-fg);\n}\n.health[data-tone='neutral'] .healthDot {\n background: transparent;\n border: 1px dashed var(--status-unknown-solid);\n}\n\n.loadingLine {\n margin: 0;\n padding: var(--space-3) 0;\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line);\n color: var(--text-secondary);\n}\n\n/* ── Monogram tile (32px rows, 24px capacity rows) ───────────────────── */\n\n.tile {\n --tile-hue: var(--text-tertiary);\n display: inline-flex;\n align-items: center;\n justify-content: center;\n flex: none;\n width: 32px;\n height: 32px;\n border-radius: var(--radius-md);\n font-family: var(--font-display);\n font-size: var(--text-sm-size);\n font-weight: var(--font-weight-semibold);\n color: var(--text-primary);\n background: var(--bg-surface-raised);\n border: 1px solid var(--border-subtle);\n position: relative;\n overflow: hidden;\n}\n.tile[data-engine] {\n background: color-mix(in srgb, var(--tile-hue) 12%, var(--bg-surface));\n border-color: color-mix(in srgb, var(--tile-hue) 28%, var(--border-subtle));\n}\n/* The 2px identity tick. */\n.tile[data-engine]::before {\n content: '';\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n width: 2px;\n background: var(--tile-hue);\n}\n.tile[data-size='sm'] {\n width: 24px;\n height: 24px;\n border-radius: var(--radius-sm);\n font-size: var(--text-xs-size);\n}\n\n/* ── Copy pill ───────────────────────────────────────────────────────── */\n\n.pillWrap {\n display: inline-flex;\n min-width: 0;\n max-width: 100%;\n}\n.pill {\n display: inline-flex;\n align-items: center;\n gap: var(--space-2);\n min-width: 0;\n max-width: 100%;\n height: var(--control-h-sm);\n padding: 0 var(--space-2) 0 var(--space-3);\n border: 1px solid var(--border-subtle);\n border-radius: var(--radius-full);\n background: var(--bg-code);\n color: var(--text-primary);\n cursor: pointer;\n transition: border-color var(--duration-fast) var(--ease-standard);\n}\n.pill:hover {\n border-color: var(--border-strong);\n}\n.pill:focus-visible {\n outline: none;\n box-shadow: var(--shadow-focus-ring);\n}\n.pillText {\n font-family: var(--font-mono);\n font-size: var(--text-xs-size);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n min-width: 0;\n}\n.pillIcon {\n display: inline-flex;\n color: var(--text-tertiary);\n}\n.pill[data-state='copied'] .pillIcon {\n color: var(--status-success-fg);\n}\n.pill[data-state='failed'] {\n border-color: var(--status-danger-solid);\n}\n\n.visuallyHidden {\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/* ── Launch split button ─────────────────────────────────────────────── */\n\n.split {\n display: inline-flex;\n align-items: stretch;\n}\n.split > :first-child {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n}\n.split > :last-child {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n margin-left: -1px;\n}\n.disabledNote {\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n color: var(--text-tertiary);\n max-width: 18rem;\n text-align: right;\n}\n\n/* ── Dialog bodies ───────────────────────────────────────────────────── */\n\n.dialogBody {\n display: flex;\n flex-direction: column;\n gap: var(--space-3);\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line);\n color: var(--text-secondary);\n}\n.dialogBody p {\n margin: 0;\n}\n.commandBlock {\n display: flex;\n flex-direction: column;\n gap: var(--space-1);\n}\n.commandLabel {\n font-family: var(--font-display);\n font-size: var(--text-2xs-size);\n line-height: var(--text-2xs-line);\n text-transform: uppercase;\n letter-spacing: var(--tracking-label);\n color: var(--text-tertiary);\n}\n.dialogActions {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-end;\n gap: var(--space-2);\n margin-top: var(--space-2);\n}\n.fieldset {\n border: 0;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n gap: var(--space-2);\n}\n.legend {\n padding: 0;\n margin-bottom: var(--space-1);\n font-size: var(--text-xs-size);\n font-weight: var(--font-weight-semibold);\n color: var(--text-primary);\n}\n.radio {\n display: flex;\n align-items: center;\n gap: var(--space-2);\n font-size: var(--text-sm-size);\n color: var(--text-primary);\n}\n.radio input {\n accent-color: var(--accent-500);\n}\n.error {\n margin: 0;\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n color: var(--status-danger-fg);\n}\n.textarea {\n width: 100%;\n min-height: 5rem;\n resize: vertical;\n padding: var(--space-2);\n border: 1px solid var(--border-default);\n border-radius: var(--radius-sm);\n background: var(--bg-input);\n color: var(--text-primary);\n font-family: var(--font-mono);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n}\n.textarea:focus-visible {\n outline: none;\n box-shadow: var(--shadow-focus-ring);\n}\n.fieldLabel {\n display: flex;\n flex-direction: column;\n gap: var(--space-1);\n font-size: var(--text-xs-size);\n font-weight: var(--font-weight-medium);\n color: var(--text-primary);\n}\n.hint {\n font-weight: var(--font-weight-regular);\n color: var(--text-tertiary);\n}\n.warnings {\n margin: 0;\n padding-left: var(--space-4);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n color: var(--status-warning-fg);\n}\n\n/* ── MCP ─────────────────────────────────────────────────────────────── */\n\n.servers {\n display: flex;\n flex-direction: column;\n gap: var(--space-2);\n margin-top: var(--space-2);\n}\n.reasonCode {\n font-family: var(--font-mono);\n font-size: var(--text-2xs-size);\n color: var(--text-tertiary);\n}\n\n.scopeLine {\n margin: 0;\n padding: 0 0 var(--space-3);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n color: var(--text-tertiary);\n}\n\n/* ── Compact container (a 375 window, or a narrow pane) ──────────────── */\n@container (max-width: 480px) {\n .row {\n grid-template-columns: auto minmax(0, 1fr);\n }\n .rowAside {\n grid-column: 2;\n justify-content: flex-start;\n max-width: none;\n }\n .disabledNote {\n text-align: left;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .pill {\n transition: none;\n }\n}\n","/**\n * routes/verse/apps/MonogramTile.tsx — the square letter tile every seat and\n * app row leads with (SPEC-310C §6: engines are a monogram and a 2px tick,\n * never a vendor logo — no brand impersonation, and one visual grammar for\n * the rail, the sidebar, Apps and the capacity strip).\n *\n * Engine-backed tiles take a 12% tint of the engine hue with an ink letter,\n * so the letter's contrast never depends on the hue; neutral tiles (Aider,\n * Goose, …) sit on the surface with a hairline. Decorative: the row's name\n * carries the meaning.\n */\nimport type { CSSProperties } from 'react';\nimport type { VerseEngine } from '../../../data/api-types.js';\nimport { engineColor } from '../../../components/primitives/Tag.js';\nimport styles from './Apps.module.css';\n\nexport function MonogramTile({\n monogram,\n engine,\n size = 'md',\n}: {\n monogram: string;\n engine: VerseEngine | null;\n /** md = 32px (Apps rows), sm = 24px (capacity rows). */\n size?: 'sm' | 'md';\n}) {\n const style = engine === null ? undefined : ({ '--tile-hue': engineColor(engine) } as CSSProperties);\n return (\n <span\n className={styles.tile}\n data-size={size}\n data-engine={engine ?? undefined}\n style={style}\n aria-hidden=\"true\"\n >\n {monogram.slice(0, 2)}\n </span>\n );\n}\n","/*\n * The shared capacity strip. Tokens only (DESIGN.md §13): no raw colour, no\n * px font size. It adapts to ITS container, not the window — the same strip\n * sits in an 880px Apps column and a 300px Resources panel — so the narrow\n * layout is a container query at the compact breakpoint (480, viewport.ts).\n */\n.strip {\n container-type: inline-size;\n display: flex;\n flex-direction: column;\n gap: var(--space-3);\n min-width: 0;\n}\n\n.visuallyHidden {\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.headline {\n margin: 0;\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line);\n font-weight: var(--font-weight-medium);\n color: var(--text-primary);\n}\n\n.empty {\n margin: 0;\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line);\n color: var(--text-secondary);\n}\n\n.rows {\n list-style: none;\n margin: 0;\n padding: 0;\n display: flex;\n flex-direction: column;\n}\n\n.row {\n display: grid;\n grid-template-columns: auto minmax(0, 1fr) auto;\n align-items: start;\n gap: var(--space-3);\n padding: var(--space-3) 0;\n border-top: 1px solid var(--border-subtle);\n}\n.row:first-child {\n border-top: 0;\n}\n.row[data-compact] {\n padding: var(--space-2) 0;\n gap: var(--space-2);\n align-items: center;\n}\n\n.main {\n display: flex;\n flex-direction: column;\n gap: var(--space-1);\n min-width: 0;\n}\n\n.head {\n display: flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: var(--space-1) var(--space-3);\n min-width: 0;\n}\n\n.nameWrap,\n.nameButton {\n display: inline-flex;\n align-items: baseline;\n gap: var(--space-2);\n min-width: 0;\n}\n.nameButton {\n padding: 0;\n border: 0;\n background: none;\n font: inherit;\n color: inherit;\n cursor: pointer;\n border-radius: var(--radius-xs);\n}\n.nameButton:hover .name {\n text-decoration: underline;\n text-underline-offset: 2px;\n}\n.nameButton:focus-visible {\n outline: none;\n box-shadow: var(--shadow-focus-ring);\n}\n.nameButton[aria-pressed='true'] .name {\n color: var(--text-link);\n}\n\n.name {\n font-size: var(--text-sm-size);\n line-height: var(--text-sm-line);\n font-weight: var(--font-weight-semibold);\n color: var(--text-primary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.plan {\n font-size: var(--text-2xs-size);\n line-height: var(--text-2xs-line);\n text-transform: uppercase;\n letter-spacing: var(--tracking-label);\n font-family: var(--font-display);\n color: var(--text-tertiary);\n}\n\n/* A state is a WORD; the dot only reinforces it. */\n.word {\n display: inline-flex;\n align-items: center;\n gap: var(--space-1);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n color: var(--text-secondary);\n white-space: nowrap;\n}\n.dot {\n width: 7px;\n height: 7px;\n border-radius: var(--radius-full);\n background: var(--status-neutral-solid);\n flex: none;\n}\n.word[data-tone='success'] .dot { background: var(--status-success-solid); }\n.word[data-tone='warning'] { color: var(--status-warning-fg); }\n.word[data-tone='warning'] .dot { background: var(--status-warning-solid); }\n.word[data-tone='danger'] { color: var(--status-danger-fg); }\n.word[data-tone='danger'] .dot { background: var(--status-danger-solid); }\n.word[data-tone='neutral'] { font-style: italic; }\n.word[data-tone='neutral'] .dot {\n background: transparent;\n border: 1px solid var(--status-unknown-solid);\n}\n\n.summary,\n.meta {\n margin: 0;\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line-relaxed);\n color: var(--text-secondary);\n overflow-wrap: anywhere;\n}\n.meta {\n color: var(--text-tertiary);\n}\n.autonomy {\n color: var(--text-secondary);\n font-weight: var(--font-weight-medium);\n}\n.autonomy[data-status='eligible'] { color: var(--status-success-fg); }\n.autonomy[data-status='unknown'] {\n font-style: italic;\n color: var(--status-unknown-fg);\n}\n\n.bars {\n display: flex;\n flex-direction: column;\n gap: var(--space-1);\n margin-top: var(--space-1);\n}\n\n.bar {\n display: grid;\n grid-template-columns: minmax(4.5rem, 7.5rem) minmax(5rem, 1fr) minmax(2.75rem, auto) minmax(0, 12rem);\n align-items: center;\n gap: var(--space-2);\n font-size: var(--text-xs-size);\n line-height: var(--text-xs-line);\n}\n.bar[data-compact] {\n grid-template-columns: minmax(3.5rem, 5.5rem) minmax(3rem, 1fr) auto;\n}\n\n.barLabel {\n color: var(--text-tertiary);\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.bar[data-binding] .barLabel {\n color: var(--text-secondary);\n}\n\n/* used (solid) · room (track) · kept for you (hatched, past the tick). */\n.track {\n position: relative;\n display: block;\n height: 6px;\n border-radius: var(--radius-full);\n background: var(--meter-track);\n overflow: hidden;\n}\n.trackUnknown {\n display: block;\n height: 6px;\n border-radius: var(--radius-full);\n border: 1px dashed var(--border-strong);\n}\n.used {\n position: absolute;\n left: 0;\n top: 0;\n bottom: 0;\n border-radius: var(--radius-full);\n background: var(--data-seq-5);\n transition: width var(--duration-base) var(--ease-standard);\n}\n.used[data-level='tight'] { background: var(--status-warning-solid); }\n.used[data-level='limit'] { background: var(--status-danger-solid); }\n.reserve {\n position: absolute;\n top: 0;\n bottom: 0;\n background: repeating-linear-gradient(\n 135deg,\n color-mix(in srgb, var(--text-tertiary) 34%, transparent) 0 2px,\n transparent 2px 5px\n );\n}\n.ceiling {\n position: absolute;\n top: 0;\n bottom: 0;\n width: 2px;\n margin-left: -1px;\n background: var(--text-secondary);\n}\n\n.value {\n font-variant-numeric: tabular-nums;\n color: var(--text-primary);\n white-space: nowrap;\n text-align: right;\n}\n.value[data-level='tight'] { color: var(--status-warning-fg); }\n.value[data-level='limit'] { color: var(--status-danger-fg); }\n.value[data-level='unknown'] {\n font-style: italic;\n color: var(--status-unknown-fg);\n}\n\n.reset {\n color: var(--text-tertiary);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.actions {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-end;\n gap: var(--space-1);\n}\n\n/* Narrow container (a side panel, or a 375 window): actions and resets wrap. */\n@container (max-width: 480px) {\n .row {\n grid-template-columns: auto minmax(0, 1fr);\n }\n .actions {\n grid-column: 2;\n justify-content: flex-start;\n }\n .bar {\n grid-template-columns: minmax(0, 1fr) auto;\n row-gap: var(--space-1);\n }\n .bar .track,\n .bar .trackUnknown {\n grid-column: 1 / -1;\n grid-row: 2;\n }\n .reset {\n grid-column: 1 / -1;\n grid-row: 3;\n white-space: normal;\n }\n .bar[data-compact] {\n grid-template-columns: minmax(3rem, auto) minmax(3rem, 1fr) auto;\n }\n .bar[data-compact] .track,\n .bar[data-compact] .trackUnknown {\n grid-column: auto;\n grid-row: auto;\n }\n}\n\n@media (prefers-reduced-motion: reduce) {\n .used {\n transition: none;\n }\n}\n","/**\n * routes/verse/usage/CapacityStrip.tsx — THE capacity view (SPEC-310C §4:\n * \"Resources, NewChatDialog and onboarding drop their own capacity views and\n * import usage/CapacityStrip instead\"). Apps & Accounts and Usage render it\n * too, so every surface answers \"how much of each seat is left\" the same way.\n *\n * [C] Claude Max · max ● connected [actions]\n * usable · 62% of 5-hour window used\n * 5-hour window ▇▇▇▇▇▇▇░░░░│▨▨▨ 62% resets 7pm\n * weekly window ▇▇▇░░░░░░░░│▨▨▨ 40% resets Thu\n * Reserved for you 40% · Autonomy: Eligible\n *\n * Each bar reads left to right: used (solid), what autonomy may still use\n * (track), and the band KEPT FOR YOU (hatched) past a tick at 100 − reserve —\n * so \"Reserved for you 40%\" is something you can see, not just read. The\n * reserve applies to the binding window; the other windows carry no tick.\n *\n * Honesty (docs/VERSE-TELEMETRY-V2.md), enforced by the model and kept here:\n * - no reading → a dashed track and the words \"no reading\", never a 0% bar;\n * - a flagged limit → \"limit reached\", never \"100%\";\n * - reset prose is printed verbatim, never turned into a countdown;\n * - every state is a WORD first; colour only reinforces it.\n *\n * Three entry points:\n * <CapacityStrip seats health? budget? …/> pure: props in, markup out;\n * <LiveCapacityStrip …/> reads the shared caches itself\n * (bootstrap seats, /health,\n * /budget) — drop-in for C1/C2;\n * useCapacityRows() the rows, for a custom layout\n * (the rail ring, the seat chip).\n */\nimport { useId, useMemo, type CSSProperties, type ReactNode } from 'react';\nimport type { BudgetView } from '../../../../core/routing/policy.js';\nimport type { SeatHealthReport } from '../../../../core/verse/health-types.js';\nimport type { VerseBootstrap, VerseSeat } from '../../../data/api-types.js';\nimport { useQuery, useRefetch } from '../../../data/hooks.js';\nimport { MonogramTile } from '../apps/MonogramTile.js';\nimport { budgetQuery } from '../budget/budget-queries.js';\nimport { useSeatHealth } from '../health/useSeatHealth.js';\nimport { usePollWhileVisible, useSectionVisible } from '../shell/section-visibility.js';\nimport { useSeatsRefresh } from '../useSeatsRefresh.js';\nimport { verseBootstrapQuery } from '../verse-queries.js';\nimport {\n buildCapacityRows,\n capacityHeadline,\n capacityTone,\n windowSentence,\n type CapacityInputs,\n type CapacityRow,\n type CapacityWindowRow,\n} from './capacity-strip-model.js';\nimport styles from './CapacityStrip.module.css';\n\n/** Above this share of a window the bar turns amber (the word \"tight\" rides with it). */\nconst TIGHT_AT = 90;\n\nexport interface CapacityStripProps {\n seats: readonly VerseSeat[];\n health?: readonly SeatHealthReport[] | null;\n budget?: BudgetView | null;\n local?: CapacityInputs['local'];\n seatIds?: readonly string[];\n /** full: every window with resets and the reserve; compact: one line per seat (pickers, side panels). */\n density?: 'full' | 'compact';\n /** Show the one-sentence summary above the rows. Default true for full, false for compact. */\n headline?: boolean;\n /** Heading for assistive tech (visually hidden). */\n title?: string;\n /**\n * The id of a heading that already names this strip (Apps' \"Accounts\"\n * group). The strip then labels itself by it instead of adding a second,\n * hidden heading — two regions with one name is noise to a screen reader.\n */\n labelledBy?: string;\n /** Per-seat trailing controls (Apps passes Reconnect / Fix / Edit budget). */\n renderActions?: (row: CapacityRow) => ReactNode;\n /** Makes each seat name a toggle (Usage opens the account's detail). */\n onSelectSeat?: (seatId: string) => void;\n selectedSeatId?: string | null;\n /** Shown instead of rows when the roster is empty. */\n emptyText?: string;\n}\n\nfunction pct(n: number): number {\n return Math.max(0, Math.min(100, Math.round(n)));\n}\n\nfunction WindowBar({\n row,\n w,\n reservePercent,\n compact,\n}: {\n row: CapacityRow;\n w: CapacityWindowRow;\n reservePercent: number | null;\n compact: boolean;\n}) {\n const sentence = windowSentence(row, w, w.binding ? reservePercent : null);\n const ceiling = w.binding && reservePercent !== null && reservePercent > 0 ? 100 - pct(reservePercent) : null;\n let track: ReactNode;\n let value: ReactNode;\n if (w.limitReached) {\n track = (\n <span className={styles.track} role=\"img\" aria-label={sentence}>\n <span className={styles.used} data-level=\"limit\" style={{ width: '100%' }} />\n </span>\n );\n value = <span className={styles.value} data-level=\"limit\">limit reached</span>;\n } else if (w.usedPercent === null) {\n // Absence drawn as absence. Never a 0% bar.\n track = <span className={styles.trackUnknown} role=\"img\" aria-label={sentence} />;\n value = <span className={styles.value} data-level=\"unknown\">no reading</span>;\n } else {\n const used = pct(w.usedPercent);\n const level = used >= TIGHT_AT ? 'tight' : 'ok';\n track = (\n <span className={styles.track} role=\"img\" aria-label={sentence}>\n {ceiling !== null ? (\n <span className={styles.reserve} style={{ left: `${ceiling}%`, width: `${100 - ceiling}%` } as CSSProperties} />\n ) : null}\n <span className={styles.used} data-level={level} style={{ width: `${used}%` }} />\n {ceiling !== null ? <span className={styles.ceiling} style={{ left: `${ceiling}%` }} /> : null}\n </span>\n );\n value = <span className={styles.value} data-level={level}>{used}%</span>;\n }\n return (\n <div className={styles.bar} data-binding={w.binding || undefined} data-compact={compact || undefined}>\n <span className={styles.barLabel}>{w.label.replace(/ window$/, '')}</span>\n {track}\n {value}\n {!compact && w.resetText !== null ? <span className={styles.reset}>{w.resetText}</span> : null}\n </div>\n );\n}\n\nfunction SeatName({ row, onSelect, selected }: { row: CapacityRow; onSelect: ((id: string) => void) | undefined; selected: boolean }) {\n const text = (\n <>\n <span className={styles.name}>{row.label}</span>\n {row.plan !== null ? <span className={styles.plan}>{row.plan}</span> : null}\n </>\n );\n // A control only when there is something for it to open.\n if (!onSelect) return <span className={styles.nameWrap}>{text}</span>;\n return (\n <button type=\"button\" className={styles.nameButton} aria-pressed={selected} onClick={() => onSelect(row.seatId)}>\n {text}\n </button>\n );\n}\n\nfunction CapacityRowView({\n row,\n compact,\n renderActions,\n onSelectSeat,\n selected,\n}: {\n row: CapacityRow;\n compact: boolean;\n renderActions: CapacityStripProps['renderActions'];\n onSelectSeat: CapacityStripProps['onSelectSeat'];\n selected: boolean;\n}) {\n const tone = capacityTone(row.cls);\n const binding = row.windows.find((w) => w.binding) ?? null;\n const windows = compact ? (binding ? [binding] : []) : row.windows;\n const actions = renderActions ? renderActions(row) : null;\n const reserve = row.reserve;\n return (\n <li className={styles.row} data-capacity={row.cls} data-compact={compact || undefined}>\n <MonogramTile monogram={row.monogram} engine={row.engine} size=\"sm\" />\n <div className={styles.main}>\n <div className={styles.head}>\n <SeatName row={row} onSelect={onSelectSeat} selected={selected} />\n <span className={styles.word} data-tone={tone}>\n <span className={styles.dot} aria-hidden=\"true\" />\n {row.word}\n </span>\n {row.connection !== null && row.connection.connection !== 'connected' && row.connection.connection !== 'unknown' ? (\n <span className={styles.word} data-tone={row.connection.tone}>\n <span className={styles.dot} aria-hidden=\"true\" />\n {row.connection.word}\n </span>\n ) : null}\n </div>\n {!compact || windows.length === 0 ? <p className={styles.summary}>{row.summary}</p> : null}\n {windows.length > 0 ? (\n <div className={styles.bars}>\n {windows.map((w) => (\n <WindowBar key={w.id} row={row} w={w} reservePercent={reserve?.percent ?? null} compact={compact} />\n ))}\n </div>\n ) : null}\n {!compact && (reserve !== null || row.credits !== null) ? (\n <p className={styles.meta}>\n {reserve !== null ? (\n <span title={reserve.why}>\n {reserve.label}\n {/* \"Autonomy off — all yours\" already says it; no second \"Off\". */}\n {reserve.autonomy === 'off' ? null : (\n <> · Autonomy: <span className={styles.autonomy} data-status={reserve.autonomy}>{reserve.autonomyWord}</span></>\n )}\n </span>\n ) : null}\n {reserve !== null && row.credits !== null ? ' · ' : null}\n {row.credits !== null ? <span>{row.credits}</span> : null}\n </p>\n ) : null}\n </div>\n {actions ? <div className={styles.actions}>{actions}</div> : null}\n </li>\n );\n}\n\nexport function CapacityStrip({\n seats,\n health,\n budget,\n local,\n seatIds,\n density = 'full',\n headline,\n title = 'Seat capacity',\n labelledBy,\n renderActions,\n onSelectSeat,\n selectedSeatId = null,\n emptyText = 'No seats yet. Connect an account or start Ollama — an empty roster, not seats at zero.',\n}: CapacityStripProps) {\n const headingId = useId();\n const rows = useMemo(\n () => buildCapacityRows(seats, {\n health: health ?? null,\n budget: budget ?? null,\n ...(local ? { local } : {}),\n ...(seatIds ? { seatIds } : {}),\n }),\n [seats, health, budget, local, seatIds],\n );\n const compact = density === 'compact';\n const showHeadline = headline ?? !compact;\n // Named by the caller's heading: a plain block inside the caller's region,\n // not a second region with the same name.\n const Wrapper = labelledBy ? 'div' : 'section';\n return (\n <Wrapper className={styles.strip} aria-labelledby={labelledBy ? undefined : headingId} data-density={density}>\n {labelledBy ? null : <h3 id={headingId} className={styles.visuallyHidden}>{title}</h3>}\n {showHeadline && rows.length > 0 ? <p className={styles.headline}>{capacityHeadline(rows)}</p> : null}\n {rows.length === 0 ? (\n <p className={styles.empty}>{emptyText}</p>\n ) : (\n <ul className={styles.rows} aria-label={labelledBy ? undefined : title} aria-labelledby={labelledBy}>\n {rows.map((row) => (\n <CapacityRowView\n key={row.seatId}\n row={row}\n compact={compact}\n renderActions={renderActions}\n onSelectSeat={onSelectSeat}\n selected={selectedSeatId === row.seatId}\n />\n ))}\n </ul>\n )}\n </Wrapper>\n );\n}\n\n// ---------------------------------------------------------------------------\n// Live data\n// ---------------------------------------------------------------------------\n\n/** Budget moves with the collector (30 s); a minute is plenty for a strip. */\nexport const CAPACITY_BUDGET_POLL_MS = 60_000;\n\nexport interface CapacityData {\n seats: readonly VerseSeat[];\n health: readonly SeatHealthReport[] | null;\n budget: BudgetView | null;\n /** True until the seat roster has been read once. */\n loading: boolean;\n}\n\n/**\n * The three shared reads behind the strip, kept live while the surface is on\n * screen: seats (the /seats poll merged into bootstrap), A2's health (30 s)\n * and A9's budget (60 s). Each is the app-wide cache entry — mounting this\n * twice costs no extra request.\n */\nexport function useCapacityData(opts: { withBudget?: boolean; withHealth?: boolean } = {}): CapacityData {\n const visible = useSectionVisible();\n const withBudget = opts.withBudget ?? true;\n const withHealth = opts.withHealth ?? true;\n const bootstrap = useQuery(verseBootstrapQuery);\n useSeatsRefresh(visible);\n const health = useSeatHealth(visible && withHealth);\n const budget = useQuery(budgetQuery);\n const refetchBudget = useRefetch(budgetQuery);\n usePollWhileVisible(refetchBudget, CAPACITY_BUDGET_POLL_MS, { enabled: withBudget });\n const data = bootstrap.data as VerseBootstrap | undefined;\n return {\n seats: data?.seats ?? [],\n health: withHealth ? (health.data?.seats ?? null) : null,\n budget: withBudget ? (budget.data ?? null) : null,\n loading: data === undefined && (bootstrap.status === 'loading' || bootstrap.status === 'idle'),\n };\n}\n\n/** The rows for a custom layout (the rail's capacity ring, the composer's seat chip). */\nexport function useCapacityRows(inputs: Omit<CapacityInputs, 'health' | 'budget'> = {}): CapacityRow[] {\n const data = useCapacityData();\n return useMemo(\n () => buildCapacityRows(data.seats, { health: data.health, budget: data.budget, ...inputs }),\n // eslint-disable-next-line react-hooks/exhaustive-deps -- inputs is a small literal; its fields are the identity.\n [data.seats, data.health, data.budget, inputs.local, inputs.seatIds],\n );\n}\n\nexport interface LiveCapacityStripProps extends Omit<CapacityStripProps, 'seats' | 'health' | 'budget'> {\n /**\n * The roster, when the caller already holds it (the new-chat dialog, whose\n * seat list IS this roster and whose pre-fill works from its own props).\n * The strip then adds only health and budget, and never shows \"Reading\n * seats…\" over a roster that is already on screen.\n */\n seats?: readonly VerseSeat[];\n}\n\n/** Drop-in strip that reads its own data — what NewChatDialog and onboarding mount. */\nexport function LiveCapacityStrip({ seats: given, ...props }: LiveCapacityStripProps) {\n const data = useCapacityData();\n if (given === undefined && data.loading) {\n return <p className={styles.empty} aria-busy=\"true\">Reading seats…</p>;\n }\n return <CapacityStrip {...props} seats={given ?? data.seats} health={data.health} budget={data.budget} />;\n}\n"],"mappings":"k6DCgBA,SAAgB,EAAa,CAC3B,WACA,SACA,OAAO,MAMN,CACD,IAAM,EAAQ,IAAW,KAAO,IAAA,GAAa,CAAE,aAAc,EAAY,CAAM,CAAE,EACjF,OACE,EAAA,EAAA,IAAA,CAAC,OAAD,CACE,UAAW,EAAO,KAClB,YAAW,EACX,cAAa,GAAU,IAAA,GAChB,QACP,cAAY,OAEX,SAAA,EAAS,MAAM,EAAG,CAAC,CAChB,CAAA,CAEV,6uBEgBM,EAAW,GA6BjB,SAAS,EAAI,EAAmB,CAC9B,OAAO,KAAK,IAAI,EAAG,KAAK,IAAI,IAAK,KAAK,MAAM,CAAC,CAAC,CAAC,CACjD,CAEA,SAAS,EAAU,CACjB,MACA,IACA,iBACA,WAMC,CACD,IAAM,EAAW,EAAe,EAAK,EAAG,EAAE,QAAU,EAAiB,IAAI,EACnE,EAAU,EAAE,SAAW,IAAmB,MAAQ,EAAiB,EAAI,IAAM,EAAI,CAAc,EAAI,KACrG,EACA,EACJ,GAAI,EAAE,aACJ,GACE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,MAAO,KAAK,MAAM,aAAY,EACpD,UAAA,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,KAAM,aAAW,QAAQ,MAAO,CAAE,MAAO,MAAO,CAAI,CAAA,CACxE,CAAA,EAER,GAAQ,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,MAAO,aAAW,QAAQ,SAAA,eAAmB,CAAA,OACxE,GAAI,EAAE,cAAgB,KAE3B,GAAQ,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,aAAc,KAAK,MAAM,aAAY,CAAW,CAAA,EAChF,GAAQ,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,MAAO,aAAW,UAAU,SAAA,YAAgB,CAAA,MACvE,CACL,IAAM,EAAO,EAAI,EAAE,WAAW,EACxB,EAAQ,GAAQ,EAAW,QAAU,KAC3C,GACE,EAAA,EAAA,KAAA,CAAC,OAAD,CAAM,UAAW,EAAO,MAAO,KAAK,MAAM,aAAY,EAAtD,SAAA,CACG,IAAY,KAET,MADF,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,QAAS,MAAO,CAAE,KAAM,GAAG,EAAQ,GAAI,MAAO,GAAG,IAAM,EAAQ,EAAG,CAAqB,CAAA,GAEjH,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,KAAM,aAAY,EAAO,MAAO,CAAE,MAAO,GAAG,EAAK,EAAG,CAAI,CAAA,EAC/E,IAAY,KAA6E,MAAtE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,QAAS,MAAO,CAAE,KAAM,GAAG,EAAQ,EAAG,CAAI,CAAA,CAClF,IAER,GAAQ,EAAA,EAAA,KAAA,CAAC,OAAD,CAAM,UAAW,EAAO,MAAO,aAAY,EAA3C,SAAA,CAAmD,EAAK,GAAO,GACzE,CACA,OACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,EAAO,IAAK,eAAc,EAAE,SAAW,IAAA,GAAW,eAAc,GAAW,IAAA,GAA3F,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,SAAW,SAAA,EAAE,MAAM,QAAQ,WAAY,EAAE,CAAQ,CAAA,EACxE,EACA,EACA,CAAC,GAAW,EAAE,YAAc,MAAO,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,MAAQ,SAAA,EAAE,SAAgB,CAAA,EAAI,IACvF,GAET,CAEA,SAAS,EAAS,CAAE,MAAK,WAAU,YAAmG,CACpI,IAAM,GACJ,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,KAAO,SAAA,EAAI,KAAY,CAAA,EAC9C,EAAI,OAAS,KAAyD,MAAlD,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,KAAO,SAAA,EAAI,IAAW,CAAA,CACnE,CAAA,CAAA,EAIJ,OADK,GAEH,EAAA,EAAA,IAAA,CAAC,SAAD,CAAQ,KAAK,SAAS,UAAW,EAAO,WAAY,eAAc,EAAU,YAAe,EAAS,EAAI,MAAM,EAC3G,SAAA,CACK,CAAA,GAJY,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,SAAW,SAAA,CAAW,CAAA,CAMtE,CAEA,SAAS,EAAgB,CACvB,MACA,UACA,gBACA,eACA,YAOC,CACD,IAAM,EAAO,EAAa,EAAI,GAAG,EAC3B,EAAU,EAAI,QAAQ,KAAM,GAAM,EAAE,OAAO,GAAK,KAChD,EAAU,EAAW,EAAU,CAAC,CAAO,EAAI,CAAC,EAAK,EAAI,QACrD,EAAU,EAAgB,EAAc,CAAG,EAAI,KAC/C,EAAU,EAAI,QACpB,OACE,EAAA,EAAA,KAAA,CAAC,KAAD,CAAI,UAAW,EAAO,IAAK,gBAAe,EAAI,IAAK,eAAc,GAAW,IAAA,GAA5E,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,EAAD,CAAc,SAAU,EAAI,SAAU,OAAQ,EAAI,OAAQ,KAAK,IAAM,CAAA,GACrE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,EAAO,KAAvB,SAAA,EACE,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAW,EAAO,KAAvB,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,EAAD,CAAe,MAAK,SAAU,EAAwB,UAAW,CAAA,GACjE,EAAA,EAAA,KAAA,CAAC,OAAD,CAAM,UAAW,EAAO,KAAM,YAAW,EAAzC,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,IAAK,cAAY,MAAQ,CAAA,EAChD,EAAI,IACD,IACL,EAAI,aAAe,MAAQ,EAAI,WAAW,aAAe,aAAe,EAAI,WAAW,aAAe,WACrG,EAAA,EAAA,KAAA,CAAC,OAAD,CAAM,UAAW,EAAO,KAAM,YAAW,EAAI,WAAW,KAAxD,SAAA,EACE,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,IAAK,cAAY,MAAQ,CAAA,EAChD,EAAI,WAAW,IACZ,CACJ,CAAA,EAAA,IACD,IACJ,CAAC,GAAW,EAAQ,SAAW,GAAI,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAW,EAAO,QAAU,SAAA,EAAI,OAAW,CAAA,EAAI,KACrF,EAAQ,OAAS,GAChB,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAO,KACpB,SAAA,EAAQ,IAAK,IACZ,EAAA,EAAA,IAAA,CAAC,EAAD,CAA2B,MAAQ,IAAG,eAAgB,GAAS,SAAW,KAAe,SAAU,EAAnF,EAAE,EAAiF,CACpG,CACE,CAAA,EACH,KACH,CAAC,IAAY,IAAY,MAAQ,EAAI,UAAY,OAChD,EAAA,EAAA,KAAA,CAAC,IAAD,CAAG,UAAW,EAAO,KAArB,SAAA,CACG,IAAY,KAQT,MAPF,EAAA,EAAA,KAAA,CAAC,OAAD,CAAM,MAAO,EAAQ,IAArB,SAAA,CACG,EAAQ,MAER,EAAQ,WAAa,MAAQ,MAC5B,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,CAAE,iBAAa,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAW,EAAO,SAAU,cAAa,EAAQ,SAAW,SAAA,EAAQ,YAAmB,CAAA,CAAG,CAAA,CAAA,CAE7G,CACJ,CAAA,EACH,IAAY,MAAQ,EAAI,UAAY,KAAO,MAAQ,KACnD,EAAI,UAAY,KAAoC,MAA7B,EAAA,EAAA,IAAA,CAAC,OAAD,CAAA,SAAO,EAAI,OAAc,CAAA,CAChD,CACD,CAAA,EAAA,IACD,IACJ,GAAU,EAAA,EAAA,IAAA,CAAC,MAAD,CAAK,UAAW,EAAO,QAAU,SAAA,CAAa,CAAA,EAAI,IAC3D,GAER,CAEA,SAAgB,EAAc,CAC5B,QACA,SACA,SACA,QACA,UACA,UAAU,OACV,WACA,QAAQ,gBACR,aACA,gBACA,eACA,iBAAiB,KACjB,YAAY,0FACS,CACrB,IAAM,GAAA,EAAY,EAAA,MAAA,CAAM,EAClB,GAAA,EAAO,EAAA,QAAA,KACL,EAAkB,EAAO,CAC7B,OAAQ,GAAU,KAClB,OAAQ,GAAU,KAClB,GAAI,EAAQ,CAAE,OAAM,EAAI,CAAC,EACzB,GAAI,EAAU,CAAE,SAAQ,EAAI,CAAC,CAC/B,CAAC,EACD,CAAC,EAAO,EAAQ,EAAQ,EAAO,CAAO,CACxC,EACM,EAAU,IAAY,UACtB,EAAe,GAAY,CAAC,EAIlC,OACE,EAAA,EAAA,KAAA,CAFc,EAAa,MAAQ,UAEnC,CAAS,UAAW,EAAO,MAAO,kBAAiB,EAAa,IAAA,GAAY,EAAW,eAAc,EAArG,SAAA,CACG,EAAa,MAAO,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,GAAI,EAAW,UAAW,EAAO,eAAiB,SAAA,CAAU,CAAA,EACpF,GAAgB,EAAK,OAAS,GAAI,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAW,EAAO,SAAW,SAAA,EAAiB,CAAI,CAAK,CAAA,EAAI,KAChG,EAAK,SAAW,GACf,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAW,EAAO,MAAQ,SAAA,CAAa,CAAA,GAE1C,EAAA,EAAA,IAAA,CAAC,KAAD,CAAI,UAAW,EAAO,KAAM,aAAY,EAAa,IAAA,GAAY,EAAO,kBAAiB,EACtF,SAAA,EAAK,IAAK,IACT,EAAA,EAAA,IAAA,CAAC,EAAD,CAEO,MACI,UACM,gBACD,eACd,SAAU,IAAmB,EAAI,MAClC,EANM,EAAI,MAMV,CACF,CACC,CAAA,CAEC,GAEb,CAOA,IAAa,EAA0B,IAgBvC,SAAgB,EAAgB,EAAuD,CAAC,EAAiB,CACvG,IAAM,EAAU,EAAkB,EAC5B,EAAa,EAAK,YAAc,GAChC,EAAa,EAAK,YAAc,GAChC,EAAY,EAAS,CAAmB,EAC9C,EAAgB,CAAO,EACvB,IAAM,EAAS,EAAc,GAAW,CAAU,EAC5C,EAAS,EAAS,CAAW,EAC7B,EAAgB,EAAW,CAAW,EAC5C,EAAoB,EAAe,EAAyB,CAAE,QAAS,CAAW,CAAC,EACnF,IAAM,EAAO,EAAU,KACvB,MAAO,CACL,MAAO,GAAM,OAAS,CAAC,EACvB,OAAQ,EAAc,EAAO,MAAM,OAAS,KAAQ,KACpD,OAAQ,EAAc,EAAO,MAAQ,KAAQ,KAC7C,QAAS,IAAS,IAAA,KAAc,EAAU,SAAW,WAAa,EAAU,SAAW,OACzF,CACF,CAuBA,SAAgB,EAAkB,CAAE,MAAO,EAAO,GAAG,GAAiC,CACpF,IAAM,EAAO,EAAgB,EAI7B,OAHI,IAAU,IAAA,IAAa,EAAK,SACvB,EAAA,EAAA,IAAA,CAAC,IAAD,CAAG,UAAW,EAAO,MAAO,YAAU,OAAO,SAAA,gBAAiB,CAAA,GAEhE,EAAA,EAAA,IAAA,CAAC,EAAD,CAAe,GAAI,EAAO,MAAO,GAAS,EAAK,MAAO,OAAQ,EAAK,OAAQ,OAAQ,EAAK,MAAS,CAAA,CAC1G"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
._section_z7dje_8{background:var(--bg-canvas);flex-direction:column;height:100%;min-height:0;display:flex}._scroll_z7dje_16{min-height:0;padding:var(--space-6) var(--space-4) var(--space-12);padding-left:max(var(--space-4), calc(var(--app-traffic-light-inset,0px) - var(--rail-width,56px)));flex:1;overflow-y:auto}._page_z7dje_34{gap:var(--space-8);flex-direction:column;max-width:880px;margin:0 auto;display:flex;container-type:inline-size}._header_z7dje_43{justify-content:space-between;align-items:flex-end;gap:var(--space-3) var(--space-4);flex-wrap:wrap;display:flex}._headerText_z7dje_50{gap:var(--space-1);flex-direction:column;min-width:0;display:flex}._title_z7dje_56{font-family:var(--font-display);font-size:var(--text-xl-size);line-height:var(--text-xl-line);letter-spacing:var(--tracking-display);font-weight:var(--font-weight-semibold);color:var(--text-primary);margin:0}._lede_z7dje_65{font-size:var(--text-sm-size);line-height:var(--text-sm-line);color:var(--text-secondary);margin:0}._headerMeta_z7dje_71{align-items:center;gap:var(--space-2);font-size:var(--text-xs-size);line-height:var(--text-xs-line);color:var(--text-tertiary);display:flex}._banner_z7dje_80{padding:var(--space-3) var(--space-4);border:1px solid var(--border-subtle);border-radius:var(--radius-md);background:var(--bg-surface);font-size:var(--text-sm-size);line-height:var(--text-sm-line);color:var(--text-secondary);margin:0}._banner_z7dje_80[data-tone=danger]{border-color:color-mix(in srgb, var(--status-danger-solid) 40%, var(--border-subtle));color:var(--status-danger-fg)}._group_z7dje_97{gap:var(--space-2);scroll-margin-top:var(--space-6);flex-direction:column;display:flex}._groupHead_z7dje_103{justify-content:space-between;align-items:center;gap:var(--space-3);min-height:var(--control-h-sm);display:flex}._groupTitle_z7dje_110{font-family:var(--font-display);font-size:var(--text-2xs-size);line-height:var(--text-2xs-line);text-transform:uppercase;letter-spacing:var(--tracking-label);font-weight:var(--font-weight-semibold);color:var(--text-tertiary);margin:0}._groupTitle_z7dje_110:focus{outline:none}._groupTitle_z7dje_110:focus-visible{box-shadow:var(--shadow-focus-ring);border-radius:var(--radius-xs)}._caveat_z7dje_127{font-size:var(--text-xs-size);line-height:var(--text-xs-line-relaxed);color:var(--text-secondary);margin:0}._caveat_z7dje_127 code,._inlineCode_z7dje_134{font-family:var(--font-mono);font-size:var(--text-xs-size);background:var(--bg-code);padding:0 var(--space-1);border-radius:var(--radius-xs);overflow-wrap:anywhere}._card_z7dje_143{border:1px solid var(--border-subtle);border-radius:var(--radius-lg);background:var(--bg-surface);padding:0 var(--card-pad);box-shadow:inset 0 1px 0 var(--hairline-lift)}._rows_z7dje_151{margin:0;padding:0;list-style:none}._row_z7dje_151{align-items:start;gap:var(--space-3);padding:var(--space-3) 0;border-top:1px solid var(--border-subtle);grid-template-columns:auto minmax(0,1fr) auto;display:grid}._row_z7dje_151:first-child{border-top:0}._rowMain_z7dje_169{gap:var(--space-1);min-width:0;padding-top:var(--space-1);flex-direction:column;display:flex}._rowHead_z7dje_176{align-items:baseline;gap:var(--space-1) var(--space-3);flex-wrap:wrap;min-width:0;display:flex}._rowName_z7dje_183{font-size:var(--text-sm-size);line-height:var(--text-sm-line);font-weight:var(--font-weight-semibold);color:var(--text-primary)}._rowVersion_z7dje_189{font-family:var(--font-mono);font-size:var(--text-xs-size);color:var(--text-tertiary)}._rowDesc_z7dje_194,._rowDetail_z7dje_195{font-size:var(--text-xs-size);line-height:var(--text-xs-line-relaxed);color:var(--text-secondary);overflow-wrap:anywhere;margin:0}._rowDetail_z7dje_195{color:var(--text-tertiary)}._rowAside_z7dje_206{justify-content:flex-end;align-items:center;gap:var(--space-2);padding-top:var(--space-1);flex-wrap:wrap;max-width:26rem;display:flex}._health_z7dje_217{align-items:center;gap:var(--space-1);font-size:var(--text-xs-size);line-height:var(--text-xs-line);color:var(--text-secondary);white-space:nowrap;display:inline-flex}._healthDot_z7dje_226{border-radius:var(--radius-full);background:var(--status-neutral-solid);flex:none;width:7px;height:7px}._health_z7dje_217[data-tone=success] ._healthDot_z7dje_226{background:var(--status-success-solid)}._health_z7dje_217[data-tone=warning]{color:var(--status-warning-fg)}._health_z7dje_217[data-tone=warning] ._healthDot_z7dje_226{background:var(--status-warning-solid)}._health_z7dje_217[data-tone=danger]{color:var(--status-danger-fg)}._health_z7dje_217[data-tone=danger] ._healthDot_z7dje_226{background:var(--status-danger-solid)}._health_z7dje_217[data-tone=off]{color:var(--text-tertiary)}._health_z7dje_217[data-tone=off] ._healthDot_z7dje_226{border:1px solid var(--border-strong);background:0 0}._health_z7dje_217[data-tone=neutral]{color:var(--status-unknown-fg);font-style:italic}._health_z7dje_217[data-tone=neutral] ._healthDot_z7dje_226{border:1px dashed var(--status-unknown-solid);background:0 0}._loadingLine_z7dje_252{padding:var(--space-3) 0;font-size:var(--text-sm-size);line-height:var(--text-sm-line);color:var(--text-secondary);margin:0}._tile_z7dje_262{--tile-hue:var(--text-tertiary);border-radius:var(--radius-md);width:32px;height:32px;font-family:var(--font-display);font-size:var(--text-sm-size);font-weight:var(--font-weight-semibold);color:var(--text-primary);background:var(--bg-surface-raised);border:1px solid var(--border-subtle);flex:none;justify-content:center;align-items:center;display:inline-flex;position:relative;overflow:hidden}._tile_z7dje_262[data-engine]{background:color-mix(in srgb, var(--tile-hue) 12%, var(--bg-surface));border-color:color-mix(in srgb, var(--tile-hue) 28%, var(--border-subtle))}._tile_z7dje_262[data-engine]:before{content:"";background:var(--tile-hue);width:2px;position:absolute;top:0;bottom:0;left:0}._tile_z7dje_262[data-size=sm]{border-radius:var(--radius-sm);width:24px;height:24px;font-size:var(--text-xs-size)}._pillWrap_z7dje_303{min-width:0;max-width:100%;display:inline-flex}._pill_z7dje_303{align-items:center;gap:var(--space-2);min-width:0;max-width:100%;height:var(--control-h-sm);padding:0 var(--space-2) 0 var(--space-3);border:1px solid var(--border-subtle);border-radius:var(--radius-full);background:var(--bg-code);color:var(--text-primary);cursor:pointer;transition:border-color var(--duration-fast) var(--ease-standard);display:inline-flex}._pill_z7dje_303:hover{border-color:var(--border-strong)}._pill_z7dje_303:focus-visible{box-shadow:var(--shadow-focus-ring);outline:none}._pillText_z7dje_330{font-family:var(--font-mono);font-size:var(--text-xs-size);white-space:nowrap;text-overflow:ellipsis;min-width:0;overflow:hidden}._pillIcon_z7dje_338{color:var(--text-tertiary);display:inline-flex}._pill_z7dje_303[data-state=copied] ._pillIcon_z7dje_338{color:var(--status-success-fg)}._pill_z7dje_303[data-state=failed]{border-color:var(--status-danger-solid)}._visuallyHidden_z7dje_349{clip:rect(0 0 0 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}._split_z7dje_363{align-items:stretch;display:inline-flex}._split_z7dje_363>:first-child{border-top-right-radius:0;border-bottom-right-radius:0}._split_z7dje_363>:last-child{border-top-left-radius:0;border-bottom-left-radius:0;margin-left:-1px}._disabledNote_z7dje_376{font-size:var(--text-xs-size);line-height:var(--text-xs-line);color:var(--text-tertiary);text-align:right;max-width:18rem}._dialogBody_z7dje_386{gap:var(--space-3);font-size:var(--text-sm-size);line-height:var(--text-sm-line);color:var(--text-secondary);flex-direction:column;display:flex}._dialogBody_z7dje_386 p{margin:0}._commandBlock_z7dje_397{gap:var(--space-1);flex-direction:column;display:flex}._commandLabel_z7dje_402{font-family:var(--font-display);font-size:var(--text-2xs-size);line-height:var(--text-2xs-line);text-transform:uppercase;letter-spacing:var(--tracking-label);color:var(--text-tertiary)}._dialogActions_z7dje_410{justify-content:flex-end;gap:var(--space-2);margin-top:var(--space-2);flex-wrap:wrap;display:flex}._fieldset_z7dje_417{gap:var(--space-2);border:0;flex-direction:column;margin:0;padding:0;display:flex}._legend_z7dje_425{margin-bottom:var(--space-1);font-size:var(--text-xs-size);font-weight:var(--font-weight-semibold);color:var(--text-primary);padding:0}._radio_z7dje_432{align-items:center;gap:var(--space-2);font-size:var(--text-sm-size);color:var(--text-primary);display:flex}._radio_z7dje_432 input{accent-color:var(--accent-500)}._error_z7dje_442{font-size:var(--text-xs-size);line-height:var(--text-xs-line-relaxed);color:var(--status-danger-fg);margin:0}._textarea_z7dje_448{resize:vertical;width:100%;min-height:5rem;padding:var(--space-2);border:1px solid var(--border-default);border-radius:var(--radius-sm);background:var(--bg-input);color:var(--text-primary);font-family:var(--font-mono);font-size:var(--text-xs-size);line-height:var(--text-xs-line-relaxed)}._textarea_z7dje_448:focus-visible{box-shadow:var(--shadow-focus-ring);outline:none}._fieldLabel_z7dje_465{gap:var(--space-1);font-size:var(--text-xs-size);font-weight:var(--font-weight-medium);color:var(--text-primary);flex-direction:column;display:flex}._hint_z7dje_473{font-weight:var(--font-weight-regular);color:var(--text-tertiary)}._warnings_z7dje_477{padding-left:var(--space-4);font-size:var(--text-xs-size);line-height:var(--text-xs-line-relaxed);color:var(--status-warning-fg);margin:0}._servers_z7dje_487{gap:var(--space-2);margin-top:var(--space-2);flex-direction:column;display:flex}._reasonCode_z7dje_493{font-family:var(--font-mono);font-size:var(--text-2xs-size);color:var(--text-tertiary)}._scopeLine_z7dje_499{padding:0 0 var(--space-3);font-size:var(--text-xs-size);line-height:var(--text-xs-line-relaxed);color:var(--text-tertiary);margin:0}@container (width<=480px){._row_z7dje_151{grid-template-columns:auto minmax(0,1fr)}._rowAside_z7dje_206{grid-column:2;justify-content:flex-start;max-width:none}._disabledNote_z7dje_376{text-align:left}}@media (prefers-reduced-motion:reduce){._pill_z7dje_303{transition:none}}._strip_elew6_7{gap:var(--space-3);flex-direction:column;min-width:0;display:flex;container-type:inline-size}._visuallyHidden_elew6_15{clip:rect(0 0 0 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}._headline_elew6_27{font-size:var(--text-sm-size);line-height:var(--text-sm-line);font-weight:var(--font-weight-medium);color:var(--text-primary);margin:0}._empty_elew6_35{font-size:var(--text-sm-size);line-height:var(--text-sm-line);color:var(--text-secondary);margin:0}._rows_elew6_42{flex-direction:column;margin:0;padding:0;list-style:none;display:flex}._row_elew6_42{align-items:start;gap:var(--space-3);padding:var(--space-3) 0;border-top:1px solid var(--border-subtle);grid-template-columns:auto minmax(0,1fr) auto;display:grid}._row_elew6_42:first-child{border-top:0}._row_elew6_42[data-compact]{padding:var(--space-2) 0;gap:var(--space-2);align-items:center}._main_elew6_67{gap:var(--space-1);flex-direction:column;min-width:0;display:flex}._head_elew6_27{align-items:baseline;gap:var(--space-1) var(--space-3);flex-wrap:wrap;min-width:0;display:flex}._nameWrap_elew6_82,._nameButton_elew6_83{align-items:baseline;gap:var(--space-2);min-width:0;display:inline-flex}._nameButton_elew6_83{font:inherit;color:inherit;cursor:pointer;border-radius:var(--radius-xs);background:0 0;border:0;padding:0}._nameButton_elew6_83:hover ._name_elew6_82{text-underline-offset:2px;text-decoration:underline}._nameButton_elew6_83:focus-visible{box-shadow:var(--shadow-focus-ring);outline:none}._nameButton_elew6_83[aria-pressed=true] ._name_elew6_82{color:var(--text-link)}._name_elew6_82{font-size:var(--text-sm-size);line-height:var(--text-sm-line);font-weight:var(--font-weight-semibold);color:var(--text-primary);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}._plan_elew6_120{font-size:var(--text-2xs-size);line-height:var(--text-2xs-line);text-transform:uppercase;letter-spacing:var(--tracking-label);font-family:var(--font-display);color:var(--text-tertiary)}._word_elew6_130{align-items:center;gap:var(--space-1);font-size:var(--text-xs-size);line-height:var(--text-xs-line);color:var(--text-secondary);white-space:nowrap;display:inline-flex}._dot_elew6_139{border-radius:var(--radius-full);background:var(--status-neutral-solid);flex:none;width:7px;height:7px}._word_elew6_130[data-tone=success] ._dot_elew6_139{background:var(--status-success-solid)}._word_elew6_130[data-tone=warning]{color:var(--status-warning-fg)}._word_elew6_130[data-tone=warning] ._dot_elew6_139{background:var(--status-warning-solid)}._word_elew6_130[data-tone=danger]{color:var(--status-danger-fg)}._word_elew6_130[data-tone=danger] ._dot_elew6_139{background:var(--status-danger-solid)}._word_elew6_130[data-tone=neutral]{font-style:italic}._word_elew6_130[data-tone=neutral] ._dot_elew6_139{border:1px solid var(--status-unknown-solid);background:0 0}._summary_elew6_157,._meta_elew6_158{font-size:var(--text-xs-size);line-height:var(--text-xs-line-relaxed);color:var(--text-secondary);overflow-wrap:anywhere;margin:0}._meta_elew6_158{color:var(--text-tertiary)}._autonomy_elew6_168{color:var(--text-secondary);font-weight:var(--font-weight-medium)}._autonomy_elew6_168[data-status=eligible]{color:var(--status-success-fg)}._autonomy_elew6_168[data-status=unknown]{color:var(--status-unknown-fg);font-style:italic}._bars_elew6_178{gap:var(--space-1);margin-top:var(--space-1);flex-direction:column;display:flex}._bar_elew6_178{align-items:center;gap:var(--space-2);font-size:var(--text-xs-size);line-height:var(--text-xs-line);grid-template-columns:minmax(4.5rem,7.5rem) minmax(5rem,1fr) minmax(2.75rem,auto) minmax(0,12rem);display:grid}._bar_elew6_178[data-compact]{grid-template-columns:minmax(3.5rem,5.5rem) minmax(3rem,1fr) auto}._barLabel_elew6_197{color:var(--text-tertiary);white-space:nowrap;text-overflow:ellipsis;overflow:hidden}._bar_elew6_178[data-binding] ._barLabel_elew6_197{color:var(--text-secondary)}._track_elew6_208{border-radius:var(--radius-full);background:var(--meter-track);height:6px;display:block;position:relative;overflow:hidden}._trackUnknown_elew6_216{border-radius:var(--radius-full);border:1px dashed var(--border-strong);height:6px;display:block}._used_elew6_222{border-radius:var(--radius-full);background:var(--data-seq-5);transition:width var(--duration-base) var(--ease-standard);position:absolute;top:0;bottom:0;left:0}._used_elew6_222[data-level=tight]{background:var(--status-warning-solid)}._used_elew6_222[data-level=limit]{background:var(--status-danger-solid)}._reserve_elew6_233{background:repeating-linear-gradient(135deg, color-mix(in srgb, var(--text-tertiary) 34%, transparent) 0 2px, transparent 2px 5px);position:absolute;top:0;bottom:0}._ceiling_elew6_243{background:var(--text-secondary);width:2px;margin-left:-1px;position:absolute;top:0;bottom:0}._value_elew6_252{font-variant-numeric:tabular-nums;color:var(--text-primary);white-space:nowrap;text-align:right}._value_elew6_252[data-level=tight]{color:var(--status-warning-fg)}._value_elew6_252[data-level=limit]{color:var(--status-danger-fg)}._value_elew6_252[data-level=unknown]{color:var(--status-unknown-fg);font-style:italic}._reset_elew6_265{color:var(--text-tertiary);text-overflow:ellipsis;white-space:nowrap;overflow:hidden}._actions_elew6_272{justify-content:flex-end;gap:var(--space-1);flex-wrap:wrap;display:flex}@container (width<=480px){._row_elew6_42{grid-template-columns:auto minmax(0,1fr)}._actions_elew6_272{grid-column:2;justify-content:flex-start}._bar_elew6_178{row-gap:var(--space-1);grid-template-columns:minmax(0,1fr) auto}._bar_elew6_178 ._track_elew6_208,._bar_elew6_178 ._trackUnknown_elew6_216{grid-area:2/1/auto/-1}._reset_elew6_265{white-space:normal;grid-area:3/1/auto/-1}._bar_elew6_178[data-compact]{grid-template-columns:minmax(3rem,auto) minmax(3rem,1fr) auto}._bar_elew6_178[data-compact] ._track_elew6_208,._bar_elew6_178[data-compact] ._trackUnknown_elew6_216{grid-area:auto}}@media (prefers-reduced-motion:reduce){._used_elew6_222{transition:none}}
|