@ashlr/hub 3.16.0 → 3.16.1
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 +28 -0
- package/README.md +2 -2
- package/dist/authority-surface.json +5 -5
- package/dist/build-identity.json +2 -2
- package/dist/core/daemon/loop.js +1 -0
- package/dist/core/daemon/loop.js.map +1 -1
- package/dist/core/daemon/tick-hooks.d.ts +2 -0
- package/dist/core/daemon/tick-hooks.js.map +1 -1
- package/dist/core/fleet/tick-hooks-live.d.ts +2 -1
- package/dist/core/fleet/tick-hooks-live.js +49 -7
- package/dist/core/fleet/tick-hooks-live.js.map +1 -1
- package/dist/core/web/public/next/assets/ActionMenu-Bv-kQxD4.js +2 -0
- package/dist/core/web/public/next/assets/ActionMenu-Bv-kQxD4.js.map +1 -0
- package/dist/core/web/public/next/assets/Advanced-Be7Frv-G.js +2 -0
- package/dist/core/web/public/next/assets/Advanced-Be7Frv-G.js.map +1 -0
- package/dist/core/web/public/next/assets/AgentDetailScreen-DzqHmufO.js +2 -0
- package/dist/core/web/public/next/assets/AgentDetailScreen-DzqHmufO.js.map +1 -0
- package/dist/core/web/public/next/assets/AgentToolsSheet-D00kLnIq.js +2 -0
- package/dist/core/web/public/next/assets/AgentToolsSheet-D00kLnIq.js.map +1 -0
- package/dist/core/web/public/next/assets/AgentToolsStrip-CSus9Dr3.js +2 -0
- package/dist/core/web/public/next/assets/AgentToolsStrip-CSus9Dr3.js.map +1 -0
- package/dist/core/web/public/next/assets/AgentsScreen-WoR0oSLZ.js +2 -0
- package/dist/core/web/public/next/assets/AgentsScreen-WoR0oSLZ.js.map +1 -0
- package/dist/core/web/public/next/assets/AgentsSection-D5mKoOhH.js +3 -0
- package/dist/core/web/public/next/assets/AgentsSection-D5mKoOhH.js.map +1 -0
- package/dist/core/web/public/next/assets/App-Uy6lDpKw.js +8 -0
- package/dist/core/web/public/next/assets/App-Uy6lDpKw.js.map +1 -0
- package/dist/core/web/public/next/assets/AppsSection-Cfhmc4r3.js +2 -0
- package/dist/core/web/public/next/assets/AppsSection-Cfhmc4r3.js.map +1 -0
- package/dist/core/web/public/next/assets/AreaTrend-Bz3ETKPk.js +2 -0
- package/dist/core/web/public/next/assets/AreaTrend-Bz3ETKPk.js.map +1 -0
- package/dist/core/web/public/next/assets/AutomationsSection-D4K8db0o.js +2 -0
- package/dist/core/web/public/next/assets/AutomationsSection-D4K8db0o.js.map +1 -0
- package/dist/core/web/public/next/assets/AutonomyOffState-DUiNMgr8.js +3 -0
- package/dist/core/web/public/next/assets/AutonomyOffState-DUiNMgr8.js.map +1 -0
- package/dist/core/web/public/next/assets/AutonomySection-wxRZ7vSw.js +2 -0
- package/dist/core/web/public/next/assets/AutonomySection-wxRZ7vSw.js.map +1 -0
- package/dist/core/web/public/next/assets/AutonomyStatus-B-PCVnFO.js +2 -0
- package/dist/core/web/public/next/assets/AutonomyStatus-B-PCVnFO.js.map +1 -0
- package/dist/core/web/public/next/assets/BranchBar-Bs4r_Vh6.js +2 -0
- package/dist/core/web/public/next/assets/BranchBar-Bs4r_Vh6.js.map +1 -0
- package/dist/core/web/public/next/assets/BrowserPanel-BMQcviI1.js +7 -0
- package/dist/core/web/public/next/assets/BrowserPanel-BMQcviI1.js.map +1 -0
- package/dist/core/web/public/next/assets/BudgetControl-A4TEONtT.js +2 -0
- package/dist/core/web/public/next/assets/BudgetControl-A4TEONtT.js.map +1 -0
- package/dist/core/web/public/next/assets/Button-CMR_Op-0.js +2 -0
- package/dist/core/web/public/next/assets/Button-CMR_Op-0.js.map +1 -0
- package/dist/core/web/public/next/assets/CapacityStrip-B-2NDrA5.js +2 -0
- package/dist/core/web/public/next/assets/CapacityStrip-B-2NDrA5.js.map +1 -0
- package/dist/core/web/public/next/assets/ChangesPaneHost-CS5qGjwM.js +16 -0
- package/dist/core/web/public/next/assets/ChangesPaneHost-CS5qGjwM.js.map +1 -0
- package/dist/core/web/public/next/assets/ChartFrame-sZTnZkVd.js +2 -0
- package/dist/core/web/public/next/assets/ChartFrame-sZTnZkVd.js.map +1 -0
- package/dist/core/web/public/next/assets/ChatPanes-CicgTVpN.js +2 -0
- package/dist/core/web/public/next/assets/ChatPanes-CicgTVpN.js.map +1 -0
- package/dist/core/web/public/next/assets/ChatSection-Cc6sudpF.js +3 -0
- package/dist/core/web/public/next/assets/ChatSection-Cc6sudpF.js.map +1 -0
- package/dist/core/web/public/next/assets/ChecksPanel-BGWgv8Zb.js +5 -0
- package/dist/core/web/public/next/assets/ChecksPanel-BGWgv8Zb.js.map +1 -0
- package/dist/core/web/public/next/assets/CloudBudgetForm-CqsidwfU.js +2 -0
- package/dist/core/web/public/next/assets/CloudBudgetForm-CqsidwfU.js.map +1 -0
- package/dist/core/web/public/next/assets/CommandPalette-rwEZ20MN.js +3 -0
- package/dist/core/web/public/next/assets/CommandPalette-rwEZ20MN.js.map +1 -0
- package/dist/core/web/public/next/assets/CommandSection-C2CLkVXN.js +3 -0
- package/dist/core/web/public/next/assets/CommandSection-C2CLkVXN.js.map +1 -0
- package/dist/core/web/public/next/assets/CommandWorkflowForm-DAbPIdI3.js +9 -0
- package/dist/core/web/public/next/assets/CommandWorkflowForm-DAbPIdI3.js.map +1 -0
- package/dist/core/web/public/next/assets/CommandWorkflowPicker-fqHtzYXX.js +3 -0
- package/dist/core/web/public/next/assets/CommandWorkflowPicker-fqHtzYXX.js.map +1 -0
- package/dist/core/web/public/next/assets/CompareDialog-Cwfpaa8I.js +4 -0
- package/dist/core/web/public/next/assets/CompareDialog-Cwfpaa8I.js.map +1 -0
- package/dist/core/web/public/next/assets/ComputerControl-DU0cuVSY.js +2 -0
- package/dist/core/web/public/next/assets/ComputerControl-DU0cuVSY.js.map +1 -0
- package/dist/core/web/public/next/assets/ConfirmDialog-B_wCnbcC.js +2 -0
- package/dist/core/web/public/next/assets/ConfirmDialog-B_wCnbcC.js.map +1 -0
- package/dist/core/web/public/next/assets/DeleteChatDialog-CxMh53yX.js +2 -0
- package/dist/core/web/public/next/assets/DeleteChatDialog-CxMh53yX.js.map +1 -0
- package/dist/core/web/public/next/assets/DevinStopDialog-D9Bziccz.js +2 -0
- package/dist/core/web/public/next/assets/DevinStopDialog-D9Bziccz.js.map +1 -0
- package/dist/core/web/public/next/assets/Dialog-DI5D6Is2.js +2 -0
- package/dist/core/web/public/next/assets/Dialog-DI5D6Is2.js.map +1 -0
- package/dist/core/web/public/next/assets/DiffPane-Buo19Bqr.js +2 -0
- package/dist/core/web/public/next/assets/DiffPane-Buo19Bqr.js.map +1 -0
- package/dist/core/web/public/next/assets/DiffViewer-dO0RQoqA.js +2 -0
- package/dist/core/web/public/next/assets/DiffViewer-dO0RQoqA.js.map +1 -0
- package/dist/core/web/public/next/assets/DockHost-KJUHjoiG.js +2 -0
- package/dist/core/web/public/next/assets/DockHost-KJUHjoiG.js.map +1 -0
- package/dist/core/web/public/next/assets/EmptyState-C3BUt2Ev.js +2 -0
- package/dist/core/web/public/next/assets/EmptyState-C3BUt2Ev.js.map +1 -0
- package/dist/core/web/public/next/assets/Epistemic-DlG2QqKJ.js +2 -0
- package/dist/core/web/public/next/assets/Epistemic-DlG2QqKJ.js.map +1 -0
- package/dist/core/web/public/next/assets/EvidenceTimeline-D1GB9F-f.js +2 -0
- package/dist/core/web/public/next/assets/EvidenceTimeline-D1GB9F-f.js.map +1 -0
- package/dist/core/web/public/next/assets/FilesPane-icSP5vPt.js +2 -0
- package/dist/core/web/public/next/assets/FilesPane-icSP5vPt.js.map +1 -0
- package/dist/core/web/public/next/assets/FleetScreen-V_X8SeD3.js +2 -0
- package/dist/core/web/public/next/assets/FleetScreen-V_X8SeD3.js.map +1 -0
- package/dist/core/web/public/next/assets/FleetSection-xyhfpRJy.js +5 -0
- package/dist/core/web/public/next/assets/FleetSection-xyhfpRJy.js.map +1 -0
- package/dist/core/web/public/next/assets/Funnel-BlzQ5FOU.js +2 -0
- package/dist/core/web/public/next/assets/Funnel-BlzQ5FOU.js.map +1 -0
- package/dist/core/web/public/next/assets/GearTray-Dvu-ee-h.js +2 -0
- package/dist/core/web/public/next/assets/GearTray-Dvu-ee-h.js.map +1 -0
- package/dist/core/web/public/next/assets/GitDialogs-o0eCEqAN.js +2 -0
- package/dist/core/web/public/next/assets/GitDialogs-o0eCEqAN.js.map +1 -0
- package/dist/core/web/public/next/assets/GrowthSection-CyqJOzob.js +3 -0
- package/dist/core/web/public/next/assets/GrowthSection-CyqJOzob.js.map +1 -0
- package/dist/core/web/public/next/assets/HandoffDialog-0uTNyK99.js +2 -0
- package/dist/core/web/public/next/assets/HandoffDialog-0uTNyK99.js.map +1 -0
- package/dist/core/web/public/next/assets/HomeBody-DJjN3GTV.js +3 -0
- package/dist/core/web/public/next/assets/HomeBody-DJjN3GTV.js.map +1 -0
- package/dist/core/web/public/next/assets/HomeSeats-IJvjh9iH.js +2 -0
- package/dist/core/web/public/next/assets/HomeSeats-IJvjh9iH.js.map +1 -0
- package/dist/core/web/public/next/assets/Input-CsSZI8QC.js +2 -0
- package/dist/core/web/public/next/assets/Input-CsSZI8QC.js.map +1 -0
- package/dist/core/web/public/next/assets/LaunchDialog-DReYqlI0.js +9 -0
- package/dist/core/web/public/next/assets/LaunchDialog-DReYqlI0.js.map +1 -0
- package/dist/core/web/public/next/assets/LeaderCard-82indlOE.js +2 -0
- package/dist/core/web/public/next/assets/LeaderCard-82indlOE.js.map +1 -0
- package/dist/core/web/public/next/assets/LeaderConversation-8hDF6Gh3.js +3 -0
- package/dist/core/web/public/next/assets/LeaderConversation-8hDF6Gh3.js.map +1 -0
- package/dist/core/web/public/next/assets/LeaderScreen-BxPiwHcT.js +2 -0
- package/dist/core/web/public/next/assets/LeaderScreen-BxPiwHcT.js.map +1 -0
- package/dist/core/web/public/next/assets/LessonsPanel-BG558qil.js +2 -0
- package/dist/core/web/public/next/assets/LessonsPanel-BG558qil.js.map +1 -0
- package/dist/core/web/public/next/assets/LiveTimer-DUgUBr49.js +2 -0
- package/dist/core/web/public/next/assets/LiveTimer-DUgUBr49.js.map +1 -0
- package/dist/core/web/public/next/assets/LocalSeatBadge-D6U4Q2P3.js +2 -0
- package/dist/core/web/public/next/assets/LocalSeatBadge-D6U4Q2P3.js.map +1 -0
- package/dist/core/web/public/next/assets/MatrixHeatmap-Brn70z84.js +2 -0
- package/dist/core/web/public/next/assets/MatrixHeatmap-Brn70z84.js.map +1 -0
- package/dist/core/web/public/next/assets/McpSection-Dz8Ga2Rg.js +2 -0
- package/dist/core/web/public/next/assets/McpSection-Dz8Ga2Rg.js.map +1 -0
- package/dist/core/web/public/next/assets/MessageMarkdown-CQfYQaXB.js +3 -0
- package/dist/core/web/public/next/assets/MessageMarkdown-CQfYQaXB.js.map +1 -0
- package/dist/core/web/public/next/assets/MessageMarkdownRenderer-DPaNQMj8.js +72 -0
- package/dist/core/web/public/next/assets/MessageMarkdownRenderer-DPaNQMj8.js.map +1 -0
- package/dist/core/web/public/next/assets/Meter-TnD7Ris6.js +2 -0
- package/dist/core/web/public/next/assets/Meter-TnD7Ris6.js.map +1 -0
- package/dist/core/web/public/next/assets/MicButton-Dc9g2Z_E.js +2 -0
- package/dist/core/web/public/next/assets/MicButton-Dc9g2Z_E.js.map +1 -0
- package/dist/core/web/public/next/assets/MindSection-DGpYq8c7.js +3 -0
- package/dist/core/web/public/next/assets/MindSection-DGpYq8c7.js.map +1 -0
- package/dist/core/web/public/next/assets/MobileComposer-DbSZ2rxa.js +2 -0
- package/dist/core/web/public/next/assets/MobileComposer-DbSZ2rxa.js.map +1 -0
- package/dist/core/web/public/next/assets/MobileGuardSheet-qQJev_w3.js +2 -0
- package/dist/core/web/public/next/assets/MobileGuardSheet-qQJev_w3.js.map +1 -0
- package/dist/core/web/public/next/assets/MobileRuntime-BEnY4Uvs.js +3 -0
- package/dist/core/web/public/next/assets/MobileRuntime-BEnY4Uvs.js.map +1 -0
- package/dist/core/web/public/next/assets/MoreScreen-CG0E5S8G.js +2 -0
- package/dist/core/web/public/next/assets/MoreScreen-CG0E5S8G.js.map +1 -0
- package/dist/core/web/public/next/assets/MultiModelBar-DgMyP8IC.js +7 -0
- package/dist/core/web/public/next/assets/MultiModelBar-DgMyP8IC.js.map +1 -0
- package/dist/core/web/public/next/assets/MutationTokenDialog-T3r9EtHi.js +2 -0
- package/dist/core/web/public/next/assets/MutationTokenDialog-T3r9EtHi.js.map +1 -0
- package/dist/core/web/public/next/assets/NeedsYouDrawer-BDAcTlK8.js +3 -0
- package/dist/core/web/public/next/assets/NeedsYouDrawer-BDAcTlK8.js.map +1 -0
- package/dist/core/web/public/next/assets/NeedsYouList-BFubkjzF.js +2 -0
- package/dist/core/web/public/next/assets/NeedsYouList-BFubkjzF.js.map +1 -0
- package/dist/core/web/public/next/assets/NeedsYouScreen-B3Dk15T_.js +2 -0
- package/dist/core/web/public/next/assets/NeedsYouScreen-B3Dk15T_.js.map +1 -0
- package/dist/core/web/public/next/assets/NewAgentScreen-zf1bqGYC.js +2 -0
- package/dist/core/web/public/next/assets/NewAgentScreen-zf1bqGYC.js.map +1 -0
- package/dist/core/web/public/next/assets/NewChatDialog-el95cRTF.js +4 -0
- package/dist/core/web/public/next/assets/NewChatDialog-el95cRTF.js.map +1 -0
- package/dist/core/web/public/next/assets/OnboardingFlow-Bi8gZOuz.js +3 -0
- package/dist/core/web/public/next/assets/OnboardingFlow-Bi8gZOuz.js.map +1 -0
- package/dist/core/web/public/next/assets/OnboardingGate-CRexmMn5.js +3 -0
- package/dist/core/web/public/next/assets/OnboardingGate-CRexmMn5.js.map +1 -0
- package/dist/core/web/public/next/assets/PlaybooksSection-R2_wyVpQ.js +9 -0
- package/dist/core/web/public/next/assets/PlaybooksSection-R2_wyVpQ.js.map +1 -0
- package/dist/core/web/public/next/assets/PreviewPane-Djw_GJ20.js +2 -0
- package/dist/core/web/public/next/assets/PreviewPane-Djw_GJ20.js.map +1 -0
- package/dist/core/web/public/next/assets/ProviderLogo-DIfJXNWf.js +2 -0
- package/dist/core/web/public/next/assets/ProviderLogo-DIfJXNWf.js.map +1 -0
- package/dist/core/web/public/next/assets/RailStatus-B3eI2AaD.js +2 -0
- package/dist/core/web/public/next/assets/RailStatus-B3eI2AaD.js.map +1 -0
- package/dist/core/web/public/next/assets/ReasoningPane-ExT8XgQB.js +2 -0
- package/dist/core/web/public/next/assets/ReasoningPane-ExT8XgQB.js.map +1 -0
- package/dist/core/web/public/next/assets/ReasoningSheet-YF4OS4lM.js +2 -0
- package/dist/core/web/public/next/assets/ReasoningSheet-YF4OS4lM.js.map +1 -0
- package/dist/core/web/public/next/assets/RefreshIndicator-BJoefKSa.js +2 -0
- package/dist/core/web/public/next/assets/RefreshIndicator-BJoefKSa.js.map +1 -0
- package/dist/core/web/public/next/assets/RemoteMobileApp-C2SflRkm.js +2 -0
- package/dist/core/web/public/next/assets/RemoteMobileApp-C2SflRkm.js.map +1 -0
- package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-FkAdn3Sv.js +7 -0
- package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-FkAdn3Sv.js.map +1 -0
- package/dist/core/web/public/next/assets/ResourcesChrome-CFHrLqmA.js +3 -0
- package/dist/core/web/public/next/assets/ResourcesChrome-CFHrLqmA.js.map +1 -0
- package/dist/core/web/public/next/assets/ResourcesDrawer-DtnZgDr_.js +3 -0
- package/dist/core/web/public/next/assets/ResourcesDrawer-DtnZgDr_.js.map +1 -0
- package/dist/core/web/public/next/assets/RouteErrorBoundary-DTz5-ndE.js +2 -0
- package/dist/core/web/public/next/assets/RouteErrorBoundary-DTz5-ndE.js.map +1 -0
- package/dist/core/web/public/next/assets/RunInCloudAction-DvoDMV54.js +2 -0
- package/dist/core/web/public/next/assets/RunInCloudAction-DvoDMV54.js.map +1 -0
- package/dist/core/web/public/next/assets/RunInDevinAction-BwCkFxLX.js +2 -0
- package/dist/core/web/public/next/assets/RunInDevinAction-BwCkFxLX.js.map +1 -0
- package/dist/core/web/public/next/assets/ScreenHost-jdgnt5U2.js +3 -0
- package/dist/core/web/public/next/assets/ScreenHost-jdgnt5U2.js.map +1 -0
- package/dist/core/web/public/next/assets/SeatSelector-DnpH5D_D.js +3 -0
- package/dist/core/web/public/next/assets/SeatSelector-DnpH5D_D.js.map +1 -0
- package/dist/core/web/public/next/assets/Segmented-BECZDbsg.js +2 -0
- package/dist/core/web/public/next/assets/Segmented-BECZDbsg.js.map +1 -0
- package/dist/core/web/public/next/assets/Select-DjQDkPJU.js +2 -0
- package/dist/core/web/public/next/assets/Select-DjQDkPJU.js.map +1 -0
- package/dist/core/web/public/next/assets/SessionGate-CWuI8dDR.js +2 -0
- package/dist/core/web/public/next/assets/SessionGate-CWuI8dDR.js.map +1 -0
- package/dist/core/web/public/next/assets/SessionInsightChip-DRsIQu29.js +2 -0
- package/dist/core/web/public/next/assets/SessionInsightChip-DRsIQu29.js.map +1 -0
- package/dist/core/web/public/next/assets/SessionSearch-Bya3EXJl.js +2 -0
- package/dist/core/web/public/next/assets/SessionSearch-Bya3EXJl.js.map +1 -0
- package/dist/core/web/public/next/assets/SettingsSection-CXjiHNQb.js +2 -0
- package/dist/core/web/public/next/assets/SettingsSection-CXjiHNQb.js.map +1 -0
- package/dist/core/web/public/next/assets/SetupChecklist-YUMOJNbk.js +2 -0
- package/dist/core/web/public/next/assets/SetupChecklist-YUMOJNbk.js.map +1 -0
- package/dist/core/web/public/next/assets/ShadowDecisions-BP2WgGMi.js +3 -0
- package/dist/core/web/public/next/assets/ShadowDecisions-BP2WgGMi.js.map +1 -0
- package/dist/core/web/public/next/assets/Sheet-Czuz3h6A.js +2 -0
- package/dist/core/web/public/next/assets/Sheet-Czuz3h6A.js.map +1 -0
- package/dist/core/web/public/next/assets/ShortcutsOverlay-D_ICte5N.js +2 -0
- package/dist/core/web/public/next/assets/ShortcutsOverlay-D_ICte5N.js.map +1 -0
- package/dist/core/web/public/next/assets/Sidebar-CcI1_B9Y.js +3 -0
- package/dist/core/web/public/next/assets/Sidebar-CcI1_B9Y.js.map +1 -0
- package/dist/core/web/public/next/assets/SkipToContent-B0GAKhYQ.js +2 -0
- package/dist/core/web/public/next/assets/SkipToContent-B0GAKhYQ.js.map +1 -0
- package/dist/core/web/public/next/assets/Slider-Dzv55CNY.js +2 -0
- package/dist/core/web/public/next/assets/Slider-Dzv55CNY.js.map +1 -0
- package/dist/core/web/public/next/assets/SourcesPane-rxRCi7cL.js +2 -0
- package/dist/core/web/public/next/assets/SourcesPane-rxRCi7cL.js.map +1 -0
- package/dist/core/web/public/next/assets/SourcesPanel-LyMp7aLt.js +2 -0
- package/dist/core/web/public/next/assets/SourcesPanel-LyMp7aLt.js.map +1 -0
- package/dist/core/web/public/next/assets/StatTile-1_HPOflX.js +2 -0
- package/dist/core/web/public/next/assets/StatTile-1_HPOflX.js.map +1 -0
- package/dist/core/web/public/next/assets/StatusBadge-zR7YgIa8.js +2 -0
- package/dist/core/web/public/next/assets/StatusBadge-zR7YgIa8.js.map +1 -0
- package/dist/core/web/public/next/assets/StepBand-BGX2RpFV.js +2 -0
- package/dist/core/web/public/next/assets/StepBand-BGX2RpFV.js.map +1 -0
- package/dist/core/web/public/next/assets/Surface-BEToBKC3.js +2 -0
- package/dist/core/web/public/next/assets/Surface-BEToBKC3.js.map +1 -0
- package/dist/core/web/public/next/assets/Swimlane-DAf7u5p3.js +2 -0
- package/dist/core/web/public/next/assets/Swimlane-DAf7u5p3.js.map +1 -0
- package/dist/core/web/public/next/assets/Switch-mvc9lQcT.js +2 -0
- package/dist/core/web/public/next/assets/Switch-mvc9lQcT.js.map +1 -0
- package/dist/core/web/public/next/assets/Tag-Chqolzxz.js +2 -0
- package/dist/core/web/public/next/assets/Tag-Chqolzxz.js.map +1 -0
- package/dist/core/web/public/next/assets/TerminalPane-4wn3AxS0.js +3 -0
- package/dist/core/web/public/next/assets/TerminalPane-4wn3AxS0.js.map +1 -0
- package/dist/core/web/public/next/assets/TerminalPane-D7-O0ssr.js +26 -0
- package/dist/core/web/public/next/assets/TerminalPane-D7-O0ssr.js.map +1 -0
- package/dist/core/web/public/next/assets/ThinkingBlock-gWESdTxs.js +2 -0
- package/dist/core/web/public/next/assets/ThinkingBlock-gWESdTxs.js.map +1 -0
- package/dist/core/web/public/next/assets/UniverseConsoleApp-XqJvgt7b.js +2 -0
- package/dist/core/web/public/next/assets/UniverseConsoleApp-XqJvgt7b.js.map +1 -0
- package/dist/core/web/public/next/assets/UniverseView-D0j9HVku.js +9 -0
- package/dist/core/web/public/next/assets/UniverseView-D0j9HVku.js.map +1 -0
- package/dist/core/web/public/next/assets/UsageSection-DnSPo4Ua.js +3 -0
- package/dist/core/web/public/next/assets/UsageSection-DnSPo4Ua.js.map +1 -0
- package/dist/core/web/public/next/assets/UsePlaybookAction-71M3gO7g.js +2 -0
- package/dist/core/web/public/next/assets/UsePlaybookAction-71M3gO7g.js.map +1 -0
- package/dist/core/web/public/next/assets/VerseConsoleApp-DO84Xscn.js +3 -0
- package/dist/core/web/public/next/assets/VerseConsoleApp-DO84Xscn.js.map +1 -0
- package/dist/core/web/public/next/assets/VerseMobileApp-CrCDQcw5.js +3 -0
- package/dist/core/web/public/next/assets/VerseMobileApp-CrCDQcw5.js.map +1 -0
- package/dist/core/web/public/next/assets/VerseShared-CFE5B-IY.js +2 -0
- package/dist/core/web/public/next/assets/VerseShared-CFE5B-IY.js.map +1 -0
- package/dist/core/web/public/next/assets/VoiceHud-CumHX7If.js +2 -0
- package/dist/core/web/public/next/assets/VoiceHud-CumHX7If.js.map +1 -0
- package/dist/core/web/public/next/assets/VoiceInput-CWTVwTwV.js +2 -0
- package/dist/core/web/public/next/assets/VoiceInput-CWTVwTwV.js.map +1 -0
- package/dist/core/web/public/next/assets/WikiSection-BIGSx4z-.js +2 -0
- package/dist/core/web/public/next/assets/WikiSection-BIGSx4z-.js.map +1 -0
- package/dist/core/web/public/next/assets/Workspace-5sa9Xggd.js +6 -0
- package/dist/core/web/public/next/assets/Workspace-5sa9Xggd.js.map +1 -0
- package/dist/core/web/public/next/assets/actions-BPyW8QC-.js +2 -0
- package/dist/core/web/public/next/assets/actions-BPyW8QC-.js.map +1 -0
- package/dist/core/web/public/next/assets/agent-tools-client-Si2ncqwV.js +2 -0
- package/dist/core/web/public/next/assets/agent-tools-client-Si2ncqwV.js.map +1 -0
- package/dist/core/web/public/next/assets/agent-transcript-model-D-34Ll59.js +7 -0
- package/dist/core/web/public/next/assets/agent-transcript-model-D-34Ll59.js.map +1 -0
- package/dist/core/web/public/next/assets/agents-focus-E_TBTTmZ.js +2 -0
- package/dist/core/web/public/next/assets/agents-focus-E_TBTTmZ.js.map +1 -0
- package/dist/core/web/public/next/assets/app-version-y5sfMXiE.js +2 -0
- package/dist/core/web/public/next/assets/app-version-y5sfMXiE.js.map +1 -0
- package/dist/core/web/public/next/assets/apps-model-BnjwUIUH.js +2 -0
- package/dist/core/web/public/next/assets/apps-model-BnjwUIUH.js.map +1 -0
- package/dist/core/web/public/next/assets/ask-seat-CWE-jY2D.js +2 -0
- package/dist/core/web/public/next/assets/ask-seat-CWE-jY2D.js.map +1 -0
- package/dist/core/web/public/next/assets/authority-model-DVMxkDV4.js +2 -0
- package/dist/core/web/public/next/assets/authority-model-DVMxkDV4.js.map +1 -0
- package/dist/core/web/public/next/assets/automations-focus-B-lklYid.js +2 -0
- package/dist/core/web/public/next/assets/automations-focus-B-lklYid.js.map +1 -0
- package/dist/core/web/public/next/assets/budget-model-Bwv4MZSa.js +2 -0
- package/dist/core/web/public/next/assets/budget-model-Bwv4MZSa.js.map +1 -0
- package/dist/core/web/public/next/assets/budget-queries-t-Bdoly3.js +2 -0
- package/dist/core/web/public/next/assets/budget-queries-t-Bdoly3.js.map +1 -0
- package/dist/core/web/public/next/assets/capacity-strip-model-CJ5F-CtB.js +2 -0
- package/dist/core/web/public/next/assets/capacity-strip-model-CJ5F-CtB.js.map +1 -0
- package/dist/core/web/public/next/assets/charts-Di0_Q980.js +2 -0
- package/dist/core/web/public/next/assets/charts-Di0_Q980.js.map +1 -0
- package/dist/core/web/public/next/assets/chat-pane-data-5MDEsLff.js +2 -0
- package/dist/core/web/public/next/assets/chat-pane-data-5MDEsLff.js.map +1 -0
- package/dist/core/web/public/next/assets/checkpoint-queries-6thqsAiE.js +2 -0
- package/dist/core/web/public/next/assets/checkpoint-queries-6thqsAiE.js.map +1 -0
- package/dist/core/web/public/next/assets/cloud-model-CzKeuxfm.js +2 -0
- package/dist/core/web/public/next/assets/cloud-model-CzKeuxfm.js.map +1 -0
- package/dist/core/web/public/next/assets/cloud-queries-DrR_QeUK.js +2 -0
- package/dist/core/web/public/next/assets/cloud-queries-DrR_QeUK.js.map +1 -0
- package/dist/core/web/public/next/assets/command-catalog-COH2G2xv.js +2 -0
- package/dist/core/web/public/next/assets/command-catalog-COH2G2xv.js.map +1 -0
- package/dist/core/web/public/next/assets/composer-queries-GxFt1UQm.js +2 -0
- package/dist/core/web/public/next/assets/composer-queries-GxFt1UQm.js.map +1 -0
- package/dist/core/web/public/next/assets/composer-state-DTAoie2b.js +2 -0
- package/dist/core/web/public/next/assets/composer-state-DTAoie2b.js.map +1 -0
- package/dist/core/web/public/next/assets/connectivity-zM4_O-XZ.js +2 -0
- package/dist/core/web/public/next/assets/connectivity-zM4_O-XZ.js.map +1 -0
- package/dist/core/web/public/next/assets/context-model-CKXUZd0O.js +2 -0
- package/dist/core/web/public/next/assets/context-model-CKXUZd0O.js.map +1 -0
- package/dist/core/web/public/next/assets/context-model-DYkDKK6C.js +3 -0
- package/dist/core/web/public/next/assets/context-model-DYkDKK6C.js.map +1 -0
- package/dist/core/web/public/next/assets/context-queries-D0Aydl5L.js +2 -0
- package/dist/core/web/public/next/assets/context-queries-D0Aydl5L.js.map +1 -0
- package/dist/core/web/public/next/assets/control-queries-C5uQTzJi.js +2 -0
- package/dist/core/web/public/next/assets/control-queries-C5uQTzJi.js.map +1 -0
- package/dist/core/web/public/next/assets/copy-setup-IHGsNfkz.js +2 -0
- package/dist/core/web/public/next/assets/copy-setup-IHGsNfkz.js.map +1 -0
- package/dist/core/web/public/next/assets/deep-link-DgTIAuc2.js +2 -0
- package/dist/core/web/public/next/assets/deep-link-DgTIAuc2.js.map +1 -0
- package/dist/core/web/public/next/assets/device-permissions-BplZgouU.js +2 -0
- package/dist/core/web/public/next/assets/device-permissions-BplZgouU.js.map +1 -0
- package/dist/core/web/public/next/assets/devin-queries-Bltl6Jz2.js +2 -0
- package/dist/core/web/public/next/assets/devin-queries-Bltl6Jz2.js.map +1 -0
- package/dist/core/web/public/next/assets/dock-icons-DPXFt10d.js +2 -0
- package/dist/core/web/public/next/assets/dock-icons-DPXFt10d.js.map +1 -0
- package/dist/core/web/public/next/assets/dock-panes-DNSv-1Tq.js +2 -0
- package/dist/core/web/public/next/assets/dock-panes-DNSv-1Tq.js.map +1 -0
- package/dist/core/web/public/next/assets/fleet-control-queries-DZEa-aFz.js +2 -0
- package/dist/core/web/public/next/assets/fleet-control-queries-DZEa-aFz.js.map +1 -0
- package/dist/core/web/public/next/assets/fleet-model-D4n8ErhA.js +2 -0
- package/dist/core/web/public/next/assets/fleet-model-D4n8ErhA.js.map +1 -0
- package/dist/core/web/public/next/assets/fleet-queries-BO1MHMFz.js +2 -0
- package/dist/core/web/public/next/assets/fleet-queries-BO1MHMFz.js.map +1 -0
- package/dist/core/web/public/next/assets/fleet-state-yM0mV9_P.js +3 -0
- package/dist/core/web/public/next/assets/fleet-state-yM0mV9_P.js.map +1 -0
- package/dist/core/web/public/next/assets/focus-trap-C2rynI8q.js +2 -0
- package/dist/core/web/public/next/assets/focus-trap-C2rynI8q.js.map +1 -0
- package/dist/core/web/public/next/assets/format-V6IiIMAL.js +2 -0
- package/dist/core/web/public/next/assets/format-V6IiIMAL.js.map +1 -0
- package/dist/core/web/public/next/assets/git-model-rVA0Jd0g.js +5 -0
- package/dist/core/web/public/next/assets/git-model-rVA0Jd0g.js.map +1 -0
- package/dist/core/web/public/next/assets/global-CYfRwH6t.js +3 -0
- package/dist/core/web/public/next/assets/global-CYfRwH6t.js.map +1 -0
- package/dist/core/web/public/next/assets/guarded-action-A9ZsIE8S.js +3 -0
- package/dist/core/web/public/next/assets/guarded-action-A9ZsIE8S.js.map +1 -0
- package/dist/core/web/public/next/assets/guarded-runners-xMakDn92.js +2 -0
- package/dist/core/web/public/next/assets/guarded-runners-xMakDn92.js.map +1 -0
- package/dist/core/web/public/next/assets/headroom-C4dyfw7P.js +2 -0
- package/dist/core/web/public/next/assets/headroom-C4dyfw7P.js.map +1 -0
- package/dist/core/web/public/next/assets/health-queries-BHoSyIcL.js +2 -0
- package/dist/core/web/public/next/assets/health-queries-BHoSyIcL.js.map +1 -0
- package/dist/core/web/public/next/assets/icons-BBm_Cy62.js +2 -0
- package/dist/core/web/public/next/assets/icons-BBm_Cy62.js.map +1 -0
- package/dist/core/web/public/next/assets/index-_izD07R9.js +11 -0
- package/dist/core/web/public/next/assets/index-_izD07R9.js.map +1 -0
- package/dist/core/web/public/next/assets/jev-queries-D-AMM0sw.js +2 -0
- package/dist/core/web/public/next/assets/jev-queries-D-AMM0sw.js.map +1 -0
- package/dist/core/web/public/next/assets/ladder-queries-BIpJVqxu.js +2 -0
- package/dist/core/web/public/next/assets/ladder-queries-BIpJVqxu.js.map +1 -0
- package/dist/core/web/public/next/assets/leader-focus-Dh4gXTSi.js +2 -0
- package/dist/core/web/public/next/assets/leader-focus-Dh4gXTSi.js.map +1 -0
- package/dist/core/web/public/next/assets/live-model-D97AfBFz.js +2 -0
- package/dist/core/web/public/next/assets/live-model-D97AfBFz.js.map +1 -0
- package/dist/core/web/public/next/assets/mind.module-rVKz51LB.js +2 -0
- package/dist/core/web/public/next/assets/mind.module-rVKz51LB.js.map +1 -0
- package/dist/core/web/public/next/assets/mobile-actions-V26-lGbH.js +2 -0
- package/dist/core/web/public/next/assets/mobile-actions-V26-lGbH.js.map +1 -0
- package/dist/core/web/public/next/assets/mobile-toast-9-WQbWQu.js +2 -0
- package/dist/core/web/public/next/assets/mobile-toast-9-WQbWQu.js.map +1 -0
- package/dist/core/web/public/next/assets/multimodel-flows-D309YXSk.js +7 -0
- package/dist/core/web/public/next/assets/multimodel-flows-D309YXSk.js.map +1 -0
- package/dist/core/web/public/next/assets/multimodel-queries-BuslyWtq.js +2 -0
- package/dist/core/web/public/next/assets/multimodel-queries-BuslyWtq.js.map +1 -0
- package/dist/core/web/public/next/assets/mutations-B9AZoqNR.js +2 -0
- package/dist/core/web/public/next/assets/mutations-B9AZoqNR.js.map +1 -0
- package/dist/core/web/public/next/assets/nav-DC0ynjdb.js +2 -0
- package/dist/core/web/public/next/assets/nav-DC0ynjdb.js.map +1 -0
- package/dist/core/web/public/next/assets/needs-you-actions-BOHN9fg7.js +2 -0
- package/dist/core/web/public/next/assets/needs-you-actions-BOHN9fg7.js.map +1 -0
- package/dist/core/web/public/next/assets/needs-you-model-ChGg3r5r.js +2 -0
- package/dist/core/web/public/next/assets/needs-you-model-ChGg3r5r.js.map +1 -0
- package/dist/core/web/public/next/assets/open-terminal-5F1FNUEB.js +2 -0
- package/dist/core/web/public/next/assets/open-terminal-5F1FNUEB.js.map +1 -0
- package/dist/core/web/public/next/assets/open-terminal-request-SjPIZmAt.js +2 -0
- package/dist/core/web/public/next/assets/open-terminal-request-SjPIZmAt.js.map +1 -0
- package/dist/core/web/public/next/assets/overnight-queries-Dc46kMfg.js +2 -0
- package/dist/core/web/public/next/assets/overnight-queries-Dc46kMfg.js.map +1 -0
- package/dist/core/web/public/next/assets/palette-handoff-xkWF9v2M.js +2 -0
- package/dist/core/web/public/next/assets/palette-handoff-xkWF9v2M.js.map +1 -0
- package/dist/core/web/public/next/assets/panes-DOXM13lF.js +3 -0
- package/dist/core/web/public/next/assets/panes-DOXM13lF.js.map +1 -0
- package/dist/core/web/public/next/assets/path-display-C6BmdnBS.js +2 -0
- package/dist/core/web/public/next/assets/path-display-C6BmdnBS.js.map +1 -0
- package/dist/core/web/public/next/assets/percent-text-CSk89zQF.js +2 -0
- package/dist/core/web/public/next/assets/percent-text-CSk89zQF.js.map +1 -0
- package/dist/core/web/public/next/assets/playbook-composer-Bz-fFxXW.js +2 -0
- package/dist/core/web/public/next/assets/playbook-composer-Bz-fFxXW.js.map +1 -0
- package/dist/core/web/public/next/assets/playbook-focus-BXu0yrHF.js +2 -0
- package/dist/core/web/public/next/assets/playbook-focus-BXu0yrHF.js.map +1 -0
- package/dist/core/web/public/next/assets/playbooks-queries-Cpnl3avl.js +2 -0
- package/dist/core/web/public/next/assets/playbooks-queries-Cpnl3avl.js.map +1 -0
- package/dist/core/web/public/next/assets/preloaded-E_jepvvg.js +2 -0
- package/dist/core/web/public/next/assets/preloaded-E_jepvvg.js.map +1 -0
- package/dist/core/web/public/next/assets/primitives-Bynv7bPl.js +1 -0
- package/dist/core/web/public/next/assets/pwa-D2lyCiGV.js +2 -0
- package/dist/core/web/public/next/assets/pwa-D2lyCiGV.js.map +1 -0
- package/dist/core/web/public/next/assets/queries-C0Bs3TOo.js +2 -0
- package/dist/core/web/public/next/assets/queries-C0Bs3TOo.js.map +1 -0
- package/dist/core/web/public/next/assets/reasoning-pref-DDPtfTM3.js +2 -0
- package/dist/core/web/public/next/assets/reasoning-pref-DDPtfTM3.js.map +1 -0
- package/dist/core/web/public/next/assets/remote-session-Dj27m1xb.js +3 -0
- package/dist/core/web/public/next/assets/remote-session-Dj27m1xb.js.map +1 -0
- package/dist/core/web/public/next/assets/resolved-store-B2iJa5C2.js +2 -0
- package/dist/core/web/public/next/assets/resolved-store-B2iJa5C2.js.map +1 -0
- package/dist/core/web/public/next/assets/resources-queries-pVRhOTEt.js +2 -0
- package/dist/core/web/public/next/assets/resources-queries-pVRhOTEt.js.map +1 -0
- package/dist/core/web/public/next/assets/reveal-anchor-BAMmxMeu.js +2 -0
- package/dist/core/web/public/next/assets/reveal-anchor-BAMmxMeu.js.map +1 -0
- package/dist/core/web/public/next/assets/rolldown-runtime-hePW80VL.js +1 -0
- package/dist/core/web/public/next/assets/seat-readiness-a5B9iqP-.js +2 -0
- package/dist/core/web/public/next/assets/seat-readiness-a5B9iqP-.js.map +1 -0
- package/dist/core/web/public/next/assets/seat-subscription-Cut6eC-8.js +2 -0
- package/dist/core/web/public/next/assets/seat-subscription-Cut6eC-8.js.map +1 -0
- package/dist/core/web/public/next/assets/sheet-BxZSmdad.js +2 -0
- package/dist/core/web/public/next/assets/sheet-BxZSmdad.js.map +1 -0
- package/dist/core/web/public/next/assets/sidebar-model-COzIPSiP.js +2 -0
- package/dist/core/web/public/next/assets/sidebar-model-COzIPSiP.js.map +1 -0
- package/dist/core/web/public/next/assets/slots-BJc3RJkV.js +3 -0
- package/dist/core/web/public/next/assets/slots-BJc3RJkV.js.map +1 -0
- package/dist/core/web/public/next/assets/sources-queries-DCKiXNAt.js +4 -0
- package/dist/core/web/public/next/assets/sources-queries-DCKiXNAt.js.map +1 -0
- package/dist/core/web/public/next/assets/sse-It4xa040.js +2 -0
- package/dist/core/web/public/next/assets/sse-It4xa040.js.map +1 -0
- package/dist/core/web/public/next/assets/surface-data-NFl_uS--.js +2 -0
- package/dist/core/web/public/next/assets/surface-data-NFl_uS--.js.map +1 -0
- package/dist/core/web/public/next/assets/surface-prefetch-jMaLNI6z.js +2 -0
- package/dist/core/web/public/next/assets/surface-prefetch-jMaLNI6z.js.map +1 -0
- package/dist/core/web/public/next/assets/tasks-model-CbmPgWL8.js +2 -0
- package/dist/core/web/public/next/assets/tasks-model-CbmPgWL8.js.map +1 -0
- package/dist/core/web/public/next/assets/terminal-client-DTXAf2-x.js +2 -0
- package/dist/core/web/public/next/assets/terminal-client-DTXAf2-x.js.map +1 -0
- package/dist/core/web/public/next/assets/terminal-icons-qBCOwqu-.js +2 -0
- package/dist/core/web/public/next/assets/terminal-icons-qBCOwqu-.js.map +1 -0
- package/dist/core/web/public/next/assets/terminal-view-CksH3CsK.js +6 -0
- package/dist/core/web/public/next/assets/terminal-view-CksH3CsK.js.map +1 -0
- package/dist/core/web/public/next/assets/thread-data-C8z55msn.js +2 -0
- package/dist/core/web/public/next/assets/thread-data-C8z55msn.js.map +1 -0
- package/dist/core/web/public/next/assets/ui-parts-CcpmRBwj.js +2 -0
- package/dist/core/web/public/next/assets/ui-parts-CcpmRBwj.js.map +1 -0
- package/dist/core/web/public/next/assets/usage-queries-BxrTLCaJ.js +2 -0
- package/dist/core/web/public/next/assets/usage-queries-BxrTLCaJ.js.map +1 -0
- package/dist/core/web/public/next/assets/use-chat-activity-O8I0Ho0m.js +2 -0
- package/dist/core/web/public/next/assets/use-chat-activity-O8I0Ho0m.js.map +1 -0
- package/dist/core/web/public/next/assets/use-guarded-action-BZ6Bye9l.js +2 -0
- package/dist/core/web/public/next/assets/use-guarded-action-BZ6Bye9l.js.map +1 -0
- package/dist/core/web/public/next/assets/use-ticker-CUsNALmP.js +2 -0
- package/dist/core/web/public/next/assets/use-ticker-CUsNALmP.js.map +1 -0
- package/dist/core/web/public/next/assets/use-token-gate-DgnO9fbv.js +2 -0
- package/dist/core/web/public/next/assets/use-token-gate-DgnO9fbv.js.map +1 -0
- package/dist/core/web/public/next/assets/useAutoSeat-CIEXM-Q5.js +2 -0
- package/dist/core/web/public/next/assets/useAutoSeat-CIEXM-Q5.js.map +1 -0
- package/dist/core/web/public/next/assets/useOnboarding-BAmRBxkI.js +2 -0
- package/dist/core/web/public/next/assets/useOnboarding-BAmRBxkI.js.map +1 -0
- package/dist/core/web/public/next/assets/useSeatHealth-DPkSSddF.js +2 -0
- package/dist/core/web/public/next/assets/useSeatHealth-DPkSSddF.js.map +1 -0
- package/dist/core/web/public/next/assets/useSeatsRefresh-CpsRhfmt.js +2 -0
- package/dist/core/web/public/next/assets/useSeatsRefresh-CpsRhfmt.js.map +1 -0
- package/dist/core/web/public/next/assets/useVerseSession-DeW1iFpw.js +2 -0
- package/dist/core/web/public/next/assets/useVerseSession-DeW1iFpw.js.map +1 -0
- package/dist/core/web/public/next/assets/useVerseTranscript-CvUqjRmZ.js +2 -0
- package/dist/core/web/public/next/assets/useVerseTranscript-CvUqjRmZ.js.map +1 -0
- package/dist/core/web/public/next/assets/verse-bootstrap-query-ANtL2OPN.js +2 -0
- package/dist/core/web/public/next/assets/verse-bootstrap-query-ANtL2OPN.js.map +1 -0
- package/dist/core/web/public/next/assets/verse-icons-C92Qt7rh.js +2 -0
- package/dist/core/web/public/next/assets/verse-icons-C92Qt7rh.js.map +1 -0
- package/dist/core/web/public/next/assets/verse-model-DAOz9LrY.js +2 -0
- package/dist/core/web/public/next/assets/verse-model-DAOz9LrY.js.map +1 -0
- package/dist/core/web/public/next/assets/warmup-B2DWWeeC.js +3 -0
- package/dist/core/web/public/next/assets/warmup-B2DWWeeC.js.map +1 -0
- package/dist/core/web/public/next/assets/why-seat-model-Bn6O26JJ.js +2 -0
- package/dist/core/web/public/next/assets/why-seat-model-Bn6O26JJ.js.map +1 -0
- package/dist/core/web/public/next/assets/wiki-focus-CwC-yoT9.js +2 -0
- package/dist/core/web/public/next/assets/wiki-focus-CwC-yoT9.js.map +1 -0
- package/dist/core/web/public/next/assets/workspace-model-C-q_I8xN.js +2 -0
- package/dist/core/web/public/next/assets/workspace-model-C-q_I8xN.js.map +1 -0
- package/dist/core/web/public/next/index.html +2 -1
- package/dist/core/web/remote-gateway-policy.js +5 -0
- package/dist/core/web/remote-gateway-policy.js.map +1 -1
- package/dist/core/web/static.d.ts +4 -3
- package/dist/core/web/static.js +8 -5
- package/dist/core/web/static.js.map +1 -1
- package/dist/release-dependency-inventory.json +1 -1
- package/node_modules/fast-uri/index.js +20 -5
- package/node_modules/fast-uri/lib/utils.js +8 -1
- package/node_modules/fast-uri/package.json +1 -1
- package/node_modules/fast-uri/test/component-safe-serialization.test.js +58 -0
- package/node_modules/fast-uri/test/ipv6-validation.test.js +34 -0
- package/node_modules/ip-address/README.md +134 -134
- package/node_modules/ip-address/dist/address-error.d.ts +11 -0
- package/node_modules/ip-address/dist/address-error.js.map +1 -1
- package/node_modules/ip-address/dist/ipv4.d.ts +22 -6
- package/node_modules/ip-address/dist/ipv4.js +22 -6
- package/node_modules/ip-address/dist/ipv4.js.map +1 -1
- package/node_modules/ip-address/dist/ipv6.d.ts +26 -8
- package/node_modules/ip-address/dist/ipv6.js +46 -29
- package/node_modules/ip-address/dist/ipv6.js.map +1 -1
- package/node_modules/ip-address/dist/v6/constants.js +1 -0
- package/node_modules/ip-address/dist/v6/constants.js.map +1 -1
- package/node_modules/ip-address/package.json +1 -1
- package/package.json +5 -4
- package/dist/core/web/public/next/assets/ActionMenu-Bia8Re6u.js +0 -2
- package/dist/core/web/public/next/assets/ActionMenu-Bia8Re6u.js.map +0 -1
- package/dist/core/web/public/next/assets/Advanced-C1LtnA8c.js +0 -2
- package/dist/core/web/public/next/assets/Advanced-C1LtnA8c.js.map +0 -1
- package/dist/core/web/public/next/assets/AgentDetailScreen-DuoXrbol.js +0 -2
- package/dist/core/web/public/next/assets/AgentDetailScreen-DuoXrbol.js.map +0 -1
- package/dist/core/web/public/next/assets/AgentToolsSheet-Bdfk4SF-.js +0 -2
- package/dist/core/web/public/next/assets/AgentToolsSheet-Bdfk4SF-.js.map +0 -1
- package/dist/core/web/public/next/assets/AgentToolsStrip-BN1otiqC.js +0 -2
- package/dist/core/web/public/next/assets/AgentToolsStrip-BN1otiqC.js.map +0 -1
- package/dist/core/web/public/next/assets/AgentsScreen-BxHFaI48.js +0 -2
- package/dist/core/web/public/next/assets/AgentsScreen-BxHFaI48.js.map +0 -1
- package/dist/core/web/public/next/assets/AgentsSection-mYIA8Lyk.js +0 -3
- package/dist/core/web/public/next/assets/AgentsSection-mYIA8Lyk.js.map +0 -1
- package/dist/core/web/public/next/assets/App-DebYuj1v.js +0 -8
- package/dist/core/web/public/next/assets/App-DebYuj1v.js.map +0 -1
- package/dist/core/web/public/next/assets/AppsSection-W30duGQA.js +0 -2
- package/dist/core/web/public/next/assets/AppsSection-W30duGQA.js.map +0 -1
- package/dist/core/web/public/next/assets/AreaTrend-ZnnIjBGU.js +0 -2
- package/dist/core/web/public/next/assets/AreaTrend-ZnnIjBGU.js.map +0 -1
- package/dist/core/web/public/next/assets/AutomationsSection-B4N0V-vz.js +0 -2
- package/dist/core/web/public/next/assets/AutomationsSection-B4N0V-vz.js.map +0 -1
- package/dist/core/web/public/next/assets/AutonomyOffState-C9S_FXc0.js +0 -3
- package/dist/core/web/public/next/assets/AutonomyOffState-C9S_FXc0.js.map +0 -1
- package/dist/core/web/public/next/assets/AutonomySection-oMQfNEQN.js +0 -2
- package/dist/core/web/public/next/assets/AutonomySection-oMQfNEQN.js.map +0 -1
- package/dist/core/web/public/next/assets/AutonomyStatus-CdHOyhrV.js +0 -2
- package/dist/core/web/public/next/assets/AutonomyStatus-CdHOyhrV.js.map +0 -1
- package/dist/core/web/public/next/assets/BranchBar-Bo5b8-hr.js +0 -2
- package/dist/core/web/public/next/assets/BranchBar-Bo5b8-hr.js.map +0 -1
- package/dist/core/web/public/next/assets/BrowserPanel-D02omBK0.js +0 -7
- package/dist/core/web/public/next/assets/BrowserPanel-D02omBK0.js.map +0 -1
- package/dist/core/web/public/next/assets/BudgetControl-BtPTi8qI.js +0 -2
- package/dist/core/web/public/next/assets/BudgetControl-BtPTi8qI.js.map +0 -1
- package/dist/core/web/public/next/assets/Button-DP2ImS5n.js +0 -2
- package/dist/core/web/public/next/assets/Button-DP2ImS5n.js.map +0 -1
- package/dist/core/web/public/next/assets/CapacityStrip-ChYPcr23.js +0 -2
- package/dist/core/web/public/next/assets/CapacityStrip-ChYPcr23.js.map +0 -1
- package/dist/core/web/public/next/assets/ChangesPaneHost-C53_94Kn.js +0 -16
- package/dist/core/web/public/next/assets/ChangesPaneHost-C53_94Kn.js.map +0 -1
- package/dist/core/web/public/next/assets/ChartFrame-CtFLETWA.js +0 -2
- package/dist/core/web/public/next/assets/ChartFrame-CtFLETWA.js.map +0 -1
- package/dist/core/web/public/next/assets/ChatPanes-CyAK9VAi.js +0 -2
- package/dist/core/web/public/next/assets/ChatPanes-CyAK9VAi.js.map +0 -1
- package/dist/core/web/public/next/assets/ChatSection-DV9smoPe.js +0 -3
- package/dist/core/web/public/next/assets/ChatSection-DV9smoPe.js.map +0 -1
- package/dist/core/web/public/next/assets/ChecksPanel-B6T2sjc_.js +0 -5
- package/dist/core/web/public/next/assets/ChecksPanel-B6T2sjc_.js.map +0 -1
- package/dist/core/web/public/next/assets/CloudBudgetForm-D8RbdAC7.js +0 -2
- package/dist/core/web/public/next/assets/CloudBudgetForm-D8RbdAC7.js.map +0 -1
- package/dist/core/web/public/next/assets/CommandPalette-C04gGTES.js +0 -3
- package/dist/core/web/public/next/assets/CommandPalette-C04gGTES.js.map +0 -1
- package/dist/core/web/public/next/assets/CommandSection-Be8VFAEU.js +0 -3
- package/dist/core/web/public/next/assets/CommandSection-Be8VFAEU.js.map +0 -1
- package/dist/core/web/public/next/assets/CommandWorkflowForm-D5A7c2PE.js +0 -9
- package/dist/core/web/public/next/assets/CommandWorkflowForm-D5A7c2PE.js.map +0 -1
- package/dist/core/web/public/next/assets/CommandWorkflowPicker-CGrRWfzQ.js +0 -3
- package/dist/core/web/public/next/assets/CommandWorkflowPicker-CGrRWfzQ.js.map +0 -1
- package/dist/core/web/public/next/assets/CompareDialog-C2ryiEtF.js +0 -4
- package/dist/core/web/public/next/assets/CompareDialog-C2ryiEtF.js.map +0 -1
- package/dist/core/web/public/next/assets/ComputerControl-C4oW7Zim.js +0 -2
- package/dist/core/web/public/next/assets/ComputerControl-C4oW7Zim.js.map +0 -1
- package/dist/core/web/public/next/assets/ConfirmDialog-J8CszPmj.js +0 -2
- package/dist/core/web/public/next/assets/ConfirmDialog-J8CszPmj.js.map +0 -1
- package/dist/core/web/public/next/assets/DeleteChatDialog-BT5y9cR2.js +0 -2
- package/dist/core/web/public/next/assets/DeleteChatDialog-BT5y9cR2.js.map +0 -1
- package/dist/core/web/public/next/assets/DevinStopDialog-CADdSqha.js +0 -2
- package/dist/core/web/public/next/assets/DevinStopDialog-CADdSqha.js.map +0 -1
- package/dist/core/web/public/next/assets/Dialog-BYIKNPcH.js +0 -2
- package/dist/core/web/public/next/assets/Dialog-BYIKNPcH.js.map +0 -1
- package/dist/core/web/public/next/assets/DiffPane-D_CC9a5x.js +0 -2
- package/dist/core/web/public/next/assets/DiffPane-D_CC9a5x.js.map +0 -1
- package/dist/core/web/public/next/assets/DiffViewer-DjtLl7ro.js +0 -2
- package/dist/core/web/public/next/assets/DiffViewer-DjtLl7ro.js.map +0 -1
- package/dist/core/web/public/next/assets/DockHost-BHbosAjM.js +0 -2
- package/dist/core/web/public/next/assets/DockHost-BHbosAjM.js.map +0 -1
- package/dist/core/web/public/next/assets/EmptyState-BEXDoNZd.js +0 -2
- package/dist/core/web/public/next/assets/EmptyState-BEXDoNZd.js.map +0 -1
- package/dist/core/web/public/next/assets/Epistemic-BPBAmLNh.js +0 -2
- package/dist/core/web/public/next/assets/Epistemic-BPBAmLNh.js.map +0 -1
- package/dist/core/web/public/next/assets/EvidenceTimeline-D2nuo6Oo.js +0 -2
- package/dist/core/web/public/next/assets/EvidenceTimeline-D2nuo6Oo.js.map +0 -1
- package/dist/core/web/public/next/assets/FilesPane-BQBcWyxr.js +0 -2
- package/dist/core/web/public/next/assets/FilesPane-BQBcWyxr.js.map +0 -1
- package/dist/core/web/public/next/assets/FleetScreen-YXDuVwKd.js +0 -2
- package/dist/core/web/public/next/assets/FleetScreen-YXDuVwKd.js.map +0 -1
- package/dist/core/web/public/next/assets/FleetSection-D2M7u9zG.js +0 -5
- package/dist/core/web/public/next/assets/FleetSection-D2M7u9zG.js.map +0 -1
- package/dist/core/web/public/next/assets/Funnel-rnPUaoN7.js +0 -2
- package/dist/core/web/public/next/assets/Funnel-rnPUaoN7.js.map +0 -1
- package/dist/core/web/public/next/assets/GearTray-Cc14h572.js +0 -2
- package/dist/core/web/public/next/assets/GearTray-Cc14h572.js.map +0 -1
- package/dist/core/web/public/next/assets/GitDialogs-BSTlyNJR.js +0 -2
- package/dist/core/web/public/next/assets/GitDialogs-BSTlyNJR.js.map +0 -1
- package/dist/core/web/public/next/assets/GrowthSection-BK63EJn9.js +0 -3
- package/dist/core/web/public/next/assets/GrowthSection-BK63EJn9.js.map +0 -1
- package/dist/core/web/public/next/assets/HandoffDialog-DD4M-C7v.js +0 -2
- package/dist/core/web/public/next/assets/HandoffDialog-DD4M-C7v.js.map +0 -1
- package/dist/core/web/public/next/assets/HomeBody-OEhTpkk9.js +0 -3
- package/dist/core/web/public/next/assets/HomeBody-OEhTpkk9.js.map +0 -1
- package/dist/core/web/public/next/assets/HomeSeats-CJCxRUlD.js +0 -2
- package/dist/core/web/public/next/assets/HomeSeats-CJCxRUlD.js.map +0 -1
- package/dist/core/web/public/next/assets/Input-BEF-ScuG.js +0 -2
- package/dist/core/web/public/next/assets/Input-BEF-ScuG.js.map +0 -1
- package/dist/core/web/public/next/assets/LaunchDialog-CERI717u.js +0 -9
- package/dist/core/web/public/next/assets/LaunchDialog-CERI717u.js.map +0 -1
- package/dist/core/web/public/next/assets/LeaderCard-3P95vgVU.js +0 -2
- package/dist/core/web/public/next/assets/LeaderCard-3P95vgVU.js.map +0 -1
- package/dist/core/web/public/next/assets/LeaderConversation-DjZS2PrX.js +0 -3
- package/dist/core/web/public/next/assets/LeaderConversation-DjZS2PrX.js.map +0 -1
- package/dist/core/web/public/next/assets/LeaderScreen-Dw5jDfWv.js +0 -2
- package/dist/core/web/public/next/assets/LeaderScreen-Dw5jDfWv.js.map +0 -1
- package/dist/core/web/public/next/assets/LessonsPanel-Wy6TVWEv.js +0 -2
- package/dist/core/web/public/next/assets/LessonsPanel-Wy6TVWEv.js.map +0 -1
- package/dist/core/web/public/next/assets/LiveTimer-c18lVIBC.js +0 -2
- package/dist/core/web/public/next/assets/LiveTimer-c18lVIBC.js.map +0 -1
- package/dist/core/web/public/next/assets/LocalSeatBadge-BfUUuXE5.js +0 -2
- package/dist/core/web/public/next/assets/LocalSeatBadge-BfUUuXE5.js.map +0 -1
- package/dist/core/web/public/next/assets/MatrixHeatmap-DTOumwCS.js +0 -2
- package/dist/core/web/public/next/assets/MatrixHeatmap-DTOumwCS.js.map +0 -1
- package/dist/core/web/public/next/assets/McpSection-D9eJislZ.js +0 -2
- package/dist/core/web/public/next/assets/McpSection-D9eJislZ.js.map +0 -1
- package/dist/core/web/public/next/assets/MessageMarkdown-Dkw4V24c.js +0 -3
- package/dist/core/web/public/next/assets/MessageMarkdown-Dkw4V24c.js.map +0 -1
- package/dist/core/web/public/next/assets/MessageMarkdownRenderer-VOSfkJpd.js +0 -72
- package/dist/core/web/public/next/assets/MessageMarkdownRenderer-VOSfkJpd.js.map +0 -1
- package/dist/core/web/public/next/assets/Meter-dMqKBaVV.js +0 -2
- package/dist/core/web/public/next/assets/Meter-dMqKBaVV.js.map +0 -1
- package/dist/core/web/public/next/assets/MicButton-92I_NsaT.js +0 -2
- package/dist/core/web/public/next/assets/MicButton-92I_NsaT.js.map +0 -1
- package/dist/core/web/public/next/assets/MindSection-CaGckJiR.js +0 -3
- package/dist/core/web/public/next/assets/MindSection-CaGckJiR.js.map +0 -1
- package/dist/core/web/public/next/assets/MobileComposer-BOFWmkku.js +0 -2
- package/dist/core/web/public/next/assets/MobileComposer-BOFWmkku.js.map +0 -1
- package/dist/core/web/public/next/assets/MobileGuardSheet-CY3Iulte.js +0 -2
- package/dist/core/web/public/next/assets/MobileGuardSheet-CY3Iulte.js.map +0 -1
- package/dist/core/web/public/next/assets/MobileRuntime-C-GtV4jT.js +0 -3
- package/dist/core/web/public/next/assets/MobileRuntime-C-GtV4jT.js.map +0 -1
- package/dist/core/web/public/next/assets/MoreScreen-BaH8iEnb.js +0 -2
- package/dist/core/web/public/next/assets/MoreScreen-BaH8iEnb.js.map +0 -1
- package/dist/core/web/public/next/assets/MultiModelBar-7DHuXGht.js +0 -7
- package/dist/core/web/public/next/assets/MultiModelBar-7DHuXGht.js.map +0 -1
- package/dist/core/web/public/next/assets/MutationTokenDialog-D522NXsm.js +0 -2
- package/dist/core/web/public/next/assets/MutationTokenDialog-D522NXsm.js.map +0 -1
- package/dist/core/web/public/next/assets/NeedsYouDrawer-6ud1RHOU.js +0 -3
- package/dist/core/web/public/next/assets/NeedsYouDrawer-6ud1RHOU.js.map +0 -1
- package/dist/core/web/public/next/assets/NeedsYouList-E-yy-xKE.js +0 -2
- package/dist/core/web/public/next/assets/NeedsYouList-E-yy-xKE.js.map +0 -1
- package/dist/core/web/public/next/assets/NeedsYouScreen-D13Q7iU8.js +0 -2
- package/dist/core/web/public/next/assets/NeedsYouScreen-D13Q7iU8.js.map +0 -1
- package/dist/core/web/public/next/assets/NewAgentScreen-BLtU1u-d.js +0 -2
- package/dist/core/web/public/next/assets/NewAgentScreen-BLtU1u-d.js.map +0 -1
- package/dist/core/web/public/next/assets/NewChatDialog-BL15LCaj.js +0 -4
- package/dist/core/web/public/next/assets/NewChatDialog-BL15LCaj.js.map +0 -1
- package/dist/core/web/public/next/assets/OnboardingFlow-7LRC7FlX.js +0 -3
- package/dist/core/web/public/next/assets/OnboardingFlow-7LRC7FlX.js.map +0 -1
- package/dist/core/web/public/next/assets/OnboardingGate-DRlv8QZ5.js +0 -3
- package/dist/core/web/public/next/assets/OnboardingGate-DRlv8QZ5.js.map +0 -1
- package/dist/core/web/public/next/assets/PlaybooksSection-D_uQ-NB3.js +0 -9
- package/dist/core/web/public/next/assets/PlaybooksSection-D_uQ-NB3.js.map +0 -1
- package/dist/core/web/public/next/assets/PreviewPane-DubyNi8H.js +0 -2
- package/dist/core/web/public/next/assets/PreviewPane-DubyNi8H.js.map +0 -1
- package/dist/core/web/public/next/assets/ProviderLogo-CWrojWjI.js +0 -2
- package/dist/core/web/public/next/assets/ProviderLogo-CWrojWjI.js.map +0 -1
- package/dist/core/web/public/next/assets/RailStatus-xjOcjL0v.js +0 -2
- package/dist/core/web/public/next/assets/RailStatus-xjOcjL0v.js.map +0 -1
- package/dist/core/web/public/next/assets/ReasoningPane-M7ZfvEc5.js +0 -2
- package/dist/core/web/public/next/assets/ReasoningPane-M7ZfvEc5.js.map +0 -1
- package/dist/core/web/public/next/assets/ReasoningSheet-RLLj2oys.js +0 -2
- package/dist/core/web/public/next/assets/ReasoningSheet-RLLj2oys.js.map +0 -1
- package/dist/core/web/public/next/assets/RefreshIndicator-CEMRNruu.js +0 -2
- package/dist/core/web/public/next/assets/RefreshIndicator-CEMRNruu.js.map +0 -1
- package/dist/core/web/public/next/assets/RemoteMobileApp-BcXsVw0z.js +0 -2
- package/dist/core/web/public/next/assets/RemoteMobileApp-BcXsVw0z.js.map +0 -1
- package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-BC_Q_i0I.js +0 -7
- package/dist/core/web/public/next/assets/ResourcePoolConsoleApp-BC_Q_i0I.js.map +0 -1
- package/dist/core/web/public/next/assets/ResourcesChrome-CPcTYvZR.js +0 -3
- package/dist/core/web/public/next/assets/ResourcesChrome-CPcTYvZR.js.map +0 -1
- package/dist/core/web/public/next/assets/ResourcesDrawer-C6VzGCSv.js +0 -3
- package/dist/core/web/public/next/assets/ResourcesDrawer-C6VzGCSv.js.map +0 -1
- package/dist/core/web/public/next/assets/RouteErrorBoundary-Cc9GsjZz.js +0 -2
- package/dist/core/web/public/next/assets/RouteErrorBoundary-Cc9GsjZz.js.map +0 -1
- package/dist/core/web/public/next/assets/RunInCloudAction-P_hDsqjX.js +0 -2
- package/dist/core/web/public/next/assets/RunInCloudAction-P_hDsqjX.js.map +0 -1
- package/dist/core/web/public/next/assets/RunInDevinAction-CfNpQCP3.js +0 -2
- package/dist/core/web/public/next/assets/RunInDevinAction-CfNpQCP3.js.map +0 -1
- package/dist/core/web/public/next/assets/ScreenHost-BBYihlNQ.js +0 -3
- package/dist/core/web/public/next/assets/ScreenHost-BBYihlNQ.js.map +0 -1
- package/dist/core/web/public/next/assets/SeatSelector-DSd_pxg2.js +0 -3
- package/dist/core/web/public/next/assets/SeatSelector-DSd_pxg2.js.map +0 -1
- package/dist/core/web/public/next/assets/Segmented-CtwuFlbY.js +0 -2
- package/dist/core/web/public/next/assets/Segmented-CtwuFlbY.js.map +0 -1
- package/dist/core/web/public/next/assets/Select-zXMdgblm.js +0 -2
- package/dist/core/web/public/next/assets/Select-zXMdgblm.js.map +0 -1
- package/dist/core/web/public/next/assets/SessionGate-88QiSoXo.js +0 -2
- package/dist/core/web/public/next/assets/SessionGate-88QiSoXo.js.map +0 -1
- package/dist/core/web/public/next/assets/SessionInsightChip-CaPvisvI.js +0 -2
- package/dist/core/web/public/next/assets/SessionInsightChip-CaPvisvI.js.map +0 -1
- package/dist/core/web/public/next/assets/SessionSearch-Ch3veGxY.js +0 -2
- package/dist/core/web/public/next/assets/SessionSearch-Ch3veGxY.js.map +0 -1
- package/dist/core/web/public/next/assets/SettingsSection-DLSYZEFc.js +0 -2
- package/dist/core/web/public/next/assets/SettingsSection-DLSYZEFc.js.map +0 -1
- package/dist/core/web/public/next/assets/SetupChecklist-DFAVVLpJ.js +0 -2
- package/dist/core/web/public/next/assets/SetupChecklist-DFAVVLpJ.js.map +0 -1
- package/dist/core/web/public/next/assets/ShadowDecisions-Gtrbo4US.js +0 -3
- package/dist/core/web/public/next/assets/ShadowDecisions-Gtrbo4US.js.map +0 -1
- package/dist/core/web/public/next/assets/Sheet-D72WH4mP.js +0 -2
- package/dist/core/web/public/next/assets/Sheet-D72WH4mP.js.map +0 -1
- package/dist/core/web/public/next/assets/ShortcutsOverlay-DKetDlCR.js +0 -2
- package/dist/core/web/public/next/assets/ShortcutsOverlay-DKetDlCR.js.map +0 -1
- package/dist/core/web/public/next/assets/Sidebar-CqOJle0q.js +0 -3
- package/dist/core/web/public/next/assets/Sidebar-CqOJle0q.js.map +0 -1
- package/dist/core/web/public/next/assets/SkipToContent-C7UObcP2.js +0 -2
- package/dist/core/web/public/next/assets/SkipToContent-C7UObcP2.js.map +0 -1
- package/dist/core/web/public/next/assets/Slider-Bi5q-21C.js +0 -2
- package/dist/core/web/public/next/assets/Slider-Bi5q-21C.js.map +0 -1
- package/dist/core/web/public/next/assets/SourcesPane-D7Raaor0.js +0 -2
- package/dist/core/web/public/next/assets/SourcesPane-D7Raaor0.js.map +0 -1
- package/dist/core/web/public/next/assets/SourcesPanel-CCSdY5Os.js +0 -2
- package/dist/core/web/public/next/assets/SourcesPanel-CCSdY5Os.js.map +0 -1
- package/dist/core/web/public/next/assets/StatTile-BS_dzInS.js +0 -2
- package/dist/core/web/public/next/assets/StatTile-BS_dzInS.js.map +0 -1
- package/dist/core/web/public/next/assets/StatusBadge-CJbb9DhR.js +0 -2
- package/dist/core/web/public/next/assets/StatusBadge-CJbb9DhR.js.map +0 -1
- package/dist/core/web/public/next/assets/StepBand-Bfj1YYTl.js +0 -2
- package/dist/core/web/public/next/assets/StepBand-Bfj1YYTl.js.map +0 -1
- package/dist/core/web/public/next/assets/Surface-CV-NXGIM.js +0 -2
- package/dist/core/web/public/next/assets/Surface-CV-NXGIM.js.map +0 -1
- package/dist/core/web/public/next/assets/Swimlane-DbUp4tjD.js +0 -2
- package/dist/core/web/public/next/assets/Swimlane-DbUp4tjD.js.map +0 -1
- package/dist/core/web/public/next/assets/Switch-BtEo9Cku.js +0 -2
- package/dist/core/web/public/next/assets/Switch-BtEo9Cku.js.map +0 -1
- package/dist/core/web/public/next/assets/Tag-CMFqY2MP.js +0 -2
- package/dist/core/web/public/next/assets/Tag-CMFqY2MP.js.map +0 -1
- package/dist/core/web/public/next/assets/TerminalPane-BCjlhc3t.js +0 -26
- package/dist/core/web/public/next/assets/TerminalPane-BCjlhc3t.js.map +0 -1
- package/dist/core/web/public/next/assets/TerminalPane-DIwGSCA9.js +0 -3
- package/dist/core/web/public/next/assets/TerminalPane-DIwGSCA9.js.map +0 -1
- package/dist/core/web/public/next/assets/ThinkingBlock-Db8qnuKz.js +0 -2
- package/dist/core/web/public/next/assets/ThinkingBlock-Db8qnuKz.js.map +0 -1
- package/dist/core/web/public/next/assets/UniverseConsoleApp-ksreONXM.js +0 -2
- package/dist/core/web/public/next/assets/UniverseConsoleApp-ksreONXM.js.map +0 -1
- package/dist/core/web/public/next/assets/UniverseView-CfT9Dsl7.js +0 -9
- package/dist/core/web/public/next/assets/UniverseView-CfT9Dsl7.js.map +0 -1
- package/dist/core/web/public/next/assets/UsageSection-DypcdQys.js +0 -3
- package/dist/core/web/public/next/assets/UsageSection-DypcdQys.js.map +0 -1
- package/dist/core/web/public/next/assets/UsePlaybookAction-Bxwqrpwe.js +0 -2
- package/dist/core/web/public/next/assets/UsePlaybookAction-Bxwqrpwe.js.map +0 -1
- package/dist/core/web/public/next/assets/VerseConsoleApp-kFOEmnGC.js +0 -3
- package/dist/core/web/public/next/assets/VerseConsoleApp-kFOEmnGC.js.map +0 -1
- package/dist/core/web/public/next/assets/VerseMobileApp-BTGF5yuZ.js +0 -3
- package/dist/core/web/public/next/assets/VerseMobileApp-BTGF5yuZ.js.map +0 -1
- package/dist/core/web/public/next/assets/VerseShared-_pMXKs8m.js +0 -2
- package/dist/core/web/public/next/assets/VerseShared-_pMXKs8m.js.map +0 -1
- package/dist/core/web/public/next/assets/VoiceHud-B_hiHfnQ.js +0 -2
- package/dist/core/web/public/next/assets/VoiceHud-B_hiHfnQ.js.map +0 -1
- package/dist/core/web/public/next/assets/VoiceInput-B7yrGchr.js +0 -2
- package/dist/core/web/public/next/assets/VoiceInput-B7yrGchr.js.map +0 -1
- package/dist/core/web/public/next/assets/WikiSection-BXu4aZyr.js +0 -2
- package/dist/core/web/public/next/assets/WikiSection-BXu4aZyr.js.map +0 -1
- package/dist/core/web/public/next/assets/Workspace-BYT3iuNM.js +0 -6
- package/dist/core/web/public/next/assets/Workspace-BYT3iuNM.js.map +0 -1
- package/dist/core/web/public/next/assets/actions-CyO4R-IO.js +0 -2
- package/dist/core/web/public/next/assets/actions-CyO4R-IO.js.map +0 -1
- package/dist/core/web/public/next/assets/agent-tools-client-FgVNokGh.js +0 -2
- package/dist/core/web/public/next/assets/agent-tools-client-FgVNokGh.js.map +0 -1
- package/dist/core/web/public/next/assets/agent-transcript-model-CRa_I3eR.js +0 -7
- package/dist/core/web/public/next/assets/agent-transcript-model-CRa_I3eR.js.map +0 -1
- package/dist/core/web/public/next/assets/agents-focus-D2hd-RNJ.js +0 -2
- package/dist/core/web/public/next/assets/agents-focus-D2hd-RNJ.js.map +0 -1
- package/dist/core/web/public/next/assets/app-version-DDlXX8-W.js +0 -2
- package/dist/core/web/public/next/assets/app-version-DDlXX8-W.js.map +0 -1
- package/dist/core/web/public/next/assets/apps-model-DLQgiczq.js +0 -2
- package/dist/core/web/public/next/assets/apps-model-DLQgiczq.js.map +0 -1
- package/dist/core/web/public/next/assets/ask-seat-zMpqJABI.js +0 -2
- package/dist/core/web/public/next/assets/ask-seat-zMpqJABI.js.map +0 -1
- package/dist/core/web/public/next/assets/authority-model-BvLFgPaX.js +0 -2
- package/dist/core/web/public/next/assets/authority-model-BvLFgPaX.js.map +0 -1
- package/dist/core/web/public/next/assets/automations-focus-zqI9oIl8.js +0 -2
- package/dist/core/web/public/next/assets/automations-focus-zqI9oIl8.js.map +0 -1
- package/dist/core/web/public/next/assets/budget-model-CKd0d1Cj.js +0 -2
- package/dist/core/web/public/next/assets/budget-model-CKd0d1Cj.js.map +0 -1
- package/dist/core/web/public/next/assets/budget-queries-q7mCG9Ek.js +0 -2
- package/dist/core/web/public/next/assets/budget-queries-q7mCG9Ek.js.map +0 -1
- package/dist/core/web/public/next/assets/capacity-strip-model-pdIEweaZ.js +0 -2
- package/dist/core/web/public/next/assets/capacity-strip-model-pdIEweaZ.js.map +0 -1
- package/dist/core/web/public/next/assets/charts-D3I0q4hG.js +0 -2
- package/dist/core/web/public/next/assets/charts-D3I0q4hG.js.map +0 -1
- package/dist/core/web/public/next/assets/chat-pane-data-DIDV7uIU.js +0 -2
- package/dist/core/web/public/next/assets/chat-pane-data-DIDV7uIU.js.map +0 -1
- package/dist/core/web/public/next/assets/checkpoint-queries-DjrDEsN-.js +0 -2
- package/dist/core/web/public/next/assets/checkpoint-queries-DjrDEsN-.js.map +0 -1
- package/dist/core/web/public/next/assets/cloud-model-DuboHWPT.js +0 -2
- package/dist/core/web/public/next/assets/cloud-model-DuboHWPT.js.map +0 -1
- package/dist/core/web/public/next/assets/cloud-queries-DQF1a_R-.js +0 -2
- package/dist/core/web/public/next/assets/cloud-queries-DQF1a_R-.js.map +0 -1
- package/dist/core/web/public/next/assets/command-catalog-BzHSIzIS.js +0 -2
- package/dist/core/web/public/next/assets/command-catalog-BzHSIzIS.js.map +0 -1
- package/dist/core/web/public/next/assets/composer-queries-BEYuD6Qr.js +0 -2
- package/dist/core/web/public/next/assets/composer-queries-BEYuD6Qr.js.map +0 -1
- package/dist/core/web/public/next/assets/composer-state-B4KVc2ZZ.js +0 -2
- package/dist/core/web/public/next/assets/composer-state-B4KVc2ZZ.js.map +0 -1
- package/dist/core/web/public/next/assets/connectivity-Svn7iy2K.js +0 -2
- package/dist/core/web/public/next/assets/connectivity-Svn7iy2K.js.map +0 -1
- package/dist/core/web/public/next/assets/context-model-C9EIuPJ_.js +0 -2
- package/dist/core/web/public/next/assets/context-model-C9EIuPJ_.js.map +0 -1
- package/dist/core/web/public/next/assets/context-model-DU3OPiBC.js +0 -3
- package/dist/core/web/public/next/assets/context-model-DU3OPiBC.js.map +0 -1
- package/dist/core/web/public/next/assets/context-queries-Cgb_XvRv.js +0 -2
- package/dist/core/web/public/next/assets/context-queries-Cgb_XvRv.js.map +0 -1
- package/dist/core/web/public/next/assets/control-queries-Clgsy_eH.js +0 -2
- package/dist/core/web/public/next/assets/control-queries-Clgsy_eH.js.map +0 -1
- package/dist/core/web/public/next/assets/copy-setup-C-hDt9sS.js +0 -2
- package/dist/core/web/public/next/assets/copy-setup-C-hDt9sS.js.map +0 -1
- package/dist/core/web/public/next/assets/deep-link-Cgvchdy7.js +0 -2
- package/dist/core/web/public/next/assets/deep-link-Cgvchdy7.js.map +0 -1
- package/dist/core/web/public/next/assets/device-permissions-JmqkyrDw.js +0 -2
- package/dist/core/web/public/next/assets/device-permissions-JmqkyrDw.js.map +0 -1
- package/dist/core/web/public/next/assets/devin-queries-DKgeD4_S.js +0 -2
- package/dist/core/web/public/next/assets/devin-queries-DKgeD4_S.js.map +0 -1
- package/dist/core/web/public/next/assets/dock-icons-CRHjXBWm.js +0 -2
- package/dist/core/web/public/next/assets/dock-icons-CRHjXBWm.js.map +0 -1
- package/dist/core/web/public/next/assets/dock-panes-C98u13Bi.js +0 -2
- package/dist/core/web/public/next/assets/dock-panes-C98u13Bi.js.map +0 -1
- package/dist/core/web/public/next/assets/fleet-control-queries-BLoc5Gza.js +0 -2
- package/dist/core/web/public/next/assets/fleet-control-queries-BLoc5Gza.js.map +0 -1
- package/dist/core/web/public/next/assets/fleet-model-CPTadBFK.js +0 -2
- package/dist/core/web/public/next/assets/fleet-model-CPTadBFK.js.map +0 -1
- package/dist/core/web/public/next/assets/fleet-queries-69WuY-dt.js +0 -2
- package/dist/core/web/public/next/assets/fleet-queries-69WuY-dt.js.map +0 -1
- package/dist/core/web/public/next/assets/fleet-state-CCdBRK-m.js +0 -3
- package/dist/core/web/public/next/assets/fleet-state-CCdBRK-m.js.map +0 -1
- package/dist/core/web/public/next/assets/focus-trap-C8MiYlLZ.js +0 -2
- package/dist/core/web/public/next/assets/focus-trap-C8MiYlLZ.js.map +0 -1
- package/dist/core/web/public/next/assets/format-CcEKjUou.js +0 -2
- package/dist/core/web/public/next/assets/format-CcEKjUou.js.map +0 -1
- package/dist/core/web/public/next/assets/git-model-DL3MwN93.js +0 -5
- package/dist/core/web/public/next/assets/git-model-DL3MwN93.js.map +0 -1
- package/dist/core/web/public/next/assets/global-BWc2NPzv.js +0 -3
- package/dist/core/web/public/next/assets/global-BWc2NPzv.js.map +0 -1
- package/dist/core/web/public/next/assets/guarded-action-BK2_U5ho.js +0 -3
- package/dist/core/web/public/next/assets/guarded-action-BK2_U5ho.js.map +0 -1
- package/dist/core/web/public/next/assets/guarded-runners-Q0UkoY3H.js +0 -2
- package/dist/core/web/public/next/assets/guarded-runners-Q0UkoY3H.js.map +0 -1
- package/dist/core/web/public/next/assets/headroom-CP99UxyV.js +0 -2
- package/dist/core/web/public/next/assets/headroom-CP99UxyV.js.map +0 -1
- package/dist/core/web/public/next/assets/health-queries-D8TwNTDQ.js +0 -2
- package/dist/core/web/public/next/assets/health-queries-D8TwNTDQ.js.map +0 -1
- package/dist/core/web/public/next/assets/icons-U34oiN9M.js +0 -2
- package/dist/core/web/public/next/assets/icons-U34oiN9M.js.map +0 -1
- package/dist/core/web/public/next/assets/index-BbDqdepe.js +0 -11
- package/dist/core/web/public/next/assets/index-BbDqdepe.js.map +0 -1
- package/dist/core/web/public/next/assets/jev-queries-CiQDnM5r.js +0 -2
- package/dist/core/web/public/next/assets/jev-queries-CiQDnM5r.js.map +0 -1
- package/dist/core/web/public/next/assets/ladder-queries-Cf64JB04.js +0 -2
- package/dist/core/web/public/next/assets/ladder-queries-Cf64JB04.js.map +0 -1
- package/dist/core/web/public/next/assets/leader-focus-azN19kfO.js +0 -2
- package/dist/core/web/public/next/assets/leader-focus-azN19kfO.js.map +0 -1
- package/dist/core/web/public/next/assets/live-model-DHX_2gOu.js +0 -2
- package/dist/core/web/public/next/assets/live-model-DHX_2gOu.js.map +0 -1
- package/dist/core/web/public/next/assets/mind.module-BJpuH2JT.js +0 -2
- package/dist/core/web/public/next/assets/mind.module-BJpuH2JT.js.map +0 -1
- package/dist/core/web/public/next/assets/mobile-actions-CvGouAAH.js +0 -2
- package/dist/core/web/public/next/assets/mobile-actions-CvGouAAH.js.map +0 -1
- package/dist/core/web/public/next/assets/mobile-toast-C_UP13GQ.js +0 -2
- package/dist/core/web/public/next/assets/mobile-toast-C_UP13GQ.js.map +0 -1
- package/dist/core/web/public/next/assets/multimodel-flows-C377w9oZ.js +0 -7
- package/dist/core/web/public/next/assets/multimodel-flows-C377w9oZ.js.map +0 -1
- package/dist/core/web/public/next/assets/multimodel-queries-_Y1QXAqq.js +0 -2
- package/dist/core/web/public/next/assets/multimodel-queries-_Y1QXAqq.js.map +0 -1
- package/dist/core/web/public/next/assets/mutations-DL4u2kRQ.js +0 -2
- package/dist/core/web/public/next/assets/mutations-DL4u2kRQ.js.map +0 -1
- package/dist/core/web/public/next/assets/nav-CM-mJcSq.js +0 -2
- package/dist/core/web/public/next/assets/nav-CM-mJcSq.js.map +0 -1
- package/dist/core/web/public/next/assets/needs-you-actions-DF2zEltF.js +0 -2
- package/dist/core/web/public/next/assets/needs-you-actions-DF2zEltF.js.map +0 -1
- package/dist/core/web/public/next/assets/needs-you-model-DqmU5YOe.js +0 -2
- package/dist/core/web/public/next/assets/needs-you-model-DqmU5YOe.js.map +0 -1
- package/dist/core/web/public/next/assets/open-terminal-BAnwAOoA.js +0 -2
- package/dist/core/web/public/next/assets/open-terminal-BAnwAOoA.js.map +0 -1
- package/dist/core/web/public/next/assets/open-terminal-request-f5_ItEpF.js +0 -2
- package/dist/core/web/public/next/assets/open-terminal-request-f5_ItEpF.js.map +0 -1
- package/dist/core/web/public/next/assets/overnight-queries-BP6viiM5.js +0 -2
- package/dist/core/web/public/next/assets/overnight-queries-BP6viiM5.js.map +0 -1
- package/dist/core/web/public/next/assets/palette-handoff-Bmq98lDl.js +0 -2
- package/dist/core/web/public/next/assets/palette-handoff-Bmq98lDl.js.map +0 -1
- package/dist/core/web/public/next/assets/panes-BjUzIDw6.js +0 -3
- package/dist/core/web/public/next/assets/panes-BjUzIDw6.js.map +0 -1
- package/dist/core/web/public/next/assets/path-display-HyxETV-f.js +0 -2
- package/dist/core/web/public/next/assets/path-display-HyxETV-f.js.map +0 -1
- package/dist/core/web/public/next/assets/playbook-composer-DwuBBP4I.js +0 -2
- package/dist/core/web/public/next/assets/playbook-composer-DwuBBP4I.js.map +0 -1
- package/dist/core/web/public/next/assets/playbook-focus-B9xzeUMw.js +0 -2
- package/dist/core/web/public/next/assets/playbook-focus-B9xzeUMw.js.map +0 -1
- package/dist/core/web/public/next/assets/playbooks-queries-C8j1Aswo.js +0 -2
- package/dist/core/web/public/next/assets/playbooks-queries-C8j1Aswo.js.map +0 -1
- package/dist/core/web/public/next/assets/preloaded-CLDUOHXJ.js +0 -2
- package/dist/core/web/public/next/assets/preloaded-CLDUOHXJ.js.map +0 -1
- package/dist/core/web/public/next/assets/primitives-BEXDE-HP.js +0 -1
- package/dist/core/web/public/next/assets/pwa-lVT_VRkK.js +0 -2
- package/dist/core/web/public/next/assets/pwa-lVT_VRkK.js.map +0 -1
- package/dist/core/web/public/next/assets/queries-T7ZUVqyA.js +0 -2
- package/dist/core/web/public/next/assets/queries-T7ZUVqyA.js.map +0 -1
- package/dist/core/web/public/next/assets/reasoning-pref-CWEri5xB.js +0 -2
- package/dist/core/web/public/next/assets/reasoning-pref-CWEri5xB.js.map +0 -1
- package/dist/core/web/public/next/assets/remote-session-BPULIfdG.js +0 -3
- package/dist/core/web/public/next/assets/remote-session-BPULIfdG.js.map +0 -1
- package/dist/core/web/public/next/assets/resolved-store-Ba-W6Uhy.js +0 -2
- package/dist/core/web/public/next/assets/resolved-store-Ba-W6Uhy.js.map +0 -1
- package/dist/core/web/public/next/assets/resources-queries-CKyXyaDY.js +0 -2
- package/dist/core/web/public/next/assets/resources-queries-CKyXyaDY.js.map +0 -1
- package/dist/core/web/public/next/assets/reveal-anchor-Djk1vGLl.js +0 -2
- package/dist/core/web/public/next/assets/reveal-anchor-Djk1vGLl.js.map +0 -1
- package/dist/core/web/public/next/assets/seat-readiness-CvEmMBol.js +0 -2
- package/dist/core/web/public/next/assets/seat-readiness-CvEmMBol.js.map +0 -1
- package/dist/core/web/public/next/assets/seat-subscription-BClqZwau.js +0 -2
- package/dist/core/web/public/next/assets/seat-subscription-BClqZwau.js.map +0 -1
- package/dist/core/web/public/next/assets/sheet-D0ciShoy.js +0 -2
- package/dist/core/web/public/next/assets/sheet-D0ciShoy.js.map +0 -1
- package/dist/core/web/public/next/assets/sidebar-model-BZ9Wh1lR.js +0 -2
- package/dist/core/web/public/next/assets/sidebar-model-BZ9Wh1lR.js.map +0 -1
- package/dist/core/web/public/next/assets/slots-m3L6Ints.js +0 -3
- package/dist/core/web/public/next/assets/slots-m3L6Ints.js.map +0 -1
- package/dist/core/web/public/next/assets/sources-queries-DeIlxb3A.js +0 -4
- package/dist/core/web/public/next/assets/sources-queries-DeIlxb3A.js.map +0 -1
- package/dist/core/web/public/next/assets/sse-CK65-Cun.js +0 -2
- package/dist/core/web/public/next/assets/sse-CK65-Cun.js.map +0 -1
- package/dist/core/web/public/next/assets/surface-data-DoN8peNV.js +0 -2
- package/dist/core/web/public/next/assets/surface-data-DoN8peNV.js.map +0 -1
- package/dist/core/web/public/next/assets/surface-prefetch-CVNIptSl.js +0 -2
- package/dist/core/web/public/next/assets/surface-prefetch-CVNIptSl.js.map +0 -1
- package/dist/core/web/public/next/assets/tasks-model-BueAhEAf.js +0 -2
- package/dist/core/web/public/next/assets/tasks-model-BueAhEAf.js.map +0 -1
- package/dist/core/web/public/next/assets/terminal-client-DO0eRhRi.js +0 -2
- package/dist/core/web/public/next/assets/terminal-client-DO0eRhRi.js.map +0 -1
- package/dist/core/web/public/next/assets/terminal-icons-COMoAiDd.js +0 -2
- package/dist/core/web/public/next/assets/terminal-icons-COMoAiDd.js.map +0 -1
- package/dist/core/web/public/next/assets/terminal-view-DkVXx7Xk.js +0 -6
- package/dist/core/web/public/next/assets/terminal-view-DkVXx7Xk.js.map +0 -1
- package/dist/core/web/public/next/assets/thread-data-Dq7QugaD.js +0 -2
- package/dist/core/web/public/next/assets/thread-data-Dq7QugaD.js.map +0 -1
- package/dist/core/web/public/next/assets/ui-parts-2JLq2ZSq.js +0 -2
- package/dist/core/web/public/next/assets/ui-parts-2JLq2ZSq.js.map +0 -1
- package/dist/core/web/public/next/assets/usage-queries-CDKUE4e0.js +0 -2
- package/dist/core/web/public/next/assets/usage-queries-CDKUE4e0.js.map +0 -1
- package/dist/core/web/public/next/assets/use-chat-activity-BaNWmI2A.js +0 -2
- package/dist/core/web/public/next/assets/use-chat-activity-BaNWmI2A.js.map +0 -1
- package/dist/core/web/public/next/assets/use-guarded-action-D4m4Mlzr.js +0 -2
- package/dist/core/web/public/next/assets/use-guarded-action-D4m4Mlzr.js.map +0 -1
- package/dist/core/web/public/next/assets/use-ticker-PQ_oYxn5.js +0 -2
- package/dist/core/web/public/next/assets/use-ticker-PQ_oYxn5.js.map +0 -1
- package/dist/core/web/public/next/assets/use-token-gate-_JPjMD5z.js +0 -2
- package/dist/core/web/public/next/assets/use-token-gate-_JPjMD5z.js.map +0 -1
- package/dist/core/web/public/next/assets/useAutoSeat-CkyqgwX9.js +0 -2
- package/dist/core/web/public/next/assets/useAutoSeat-CkyqgwX9.js.map +0 -1
- package/dist/core/web/public/next/assets/useOnboarding-3r8T1GBP.js +0 -2
- package/dist/core/web/public/next/assets/useOnboarding-3r8T1GBP.js.map +0 -1
- package/dist/core/web/public/next/assets/useSeatHealth-C08b9zut.js +0 -2
- package/dist/core/web/public/next/assets/useSeatHealth-C08b9zut.js.map +0 -1
- package/dist/core/web/public/next/assets/useSeatsRefresh-BGsdylUl.js +0 -2
- package/dist/core/web/public/next/assets/useSeatsRefresh-BGsdylUl.js.map +0 -1
- package/dist/core/web/public/next/assets/useVerseSession-0MnfpcHg.js +0 -2
- package/dist/core/web/public/next/assets/useVerseSession-0MnfpcHg.js.map +0 -1
- package/dist/core/web/public/next/assets/useVerseTranscript-B6wLDOv8.js +0 -2
- package/dist/core/web/public/next/assets/useVerseTranscript-B6wLDOv8.js.map +0 -1
- package/dist/core/web/public/next/assets/verse-bootstrap-query-BR5ypA8b.js +0 -2
- package/dist/core/web/public/next/assets/verse-bootstrap-query-BR5ypA8b.js.map +0 -1
- package/dist/core/web/public/next/assets/verse-icons-BQxBZk9k.js +0 -2
- package/dist/core/web/public/next/assets/verse-icons-BQxBZk9k.js.map +0 -1
- package/dist/core/web/public/next/assets/verse-model-CkF3q2IH.js +0 -2
- package/dist/core/web/public/next/assets/verse-model-CkF3q2IH.js.map +0 -1
- package/dist/core/web/public/next/assets/warmup-CqTK8yIn.js +0 -3
- package/dist/core/web/public/next/assets/warmup-CqTK8yIn.js.map +0 -1
- package/dist/core/web/public/next/assets/why-seat-model-Dh4-Ty9n.js +0 -2
- package/dist/core/web/public/next/assets/why-seat-model-Dh4-Ty9n.js.map +0 -1
- package/dist/core/web/public/next/assets/wiki-focus-CisQb_pM.js +0 -2
- package/dist/core/web/public/next/assets/wiki-focus-CisQb_pM.js.map +0 -1
- package/dist/core/web/public/next/assets/workspace-model-DRGckE8q.js +0 -2
- package/dist/core/web/public/next/assets/workspace-model-DRGckE8q.js.map +0 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{_ as e,c as t}from"./format-V6IiIMAL.js";function n(e){return typeof e==`object`&&e&&!Array.isArray(e)?e:null}function r(e,t){let n=e[t];return typeof n==`string`&&n.length>0?n:null}function i(e,t){let n=e[t];return typeof n==`number`&&Number.isFinite(n)?n:null}function a(e,t){let n=i(e,t);return n===null?null:Math.max(0,Math.round(n))}function o(e,t){let n=e[t];return typeof n==`boolean`?n:null}function s(e,t){let n=e[t];return Array.isArray(n)?n.filter(e=>typeof e==`string`):[]}var c=[`llama-server`,`ollama`,`vllm`,`unknown`],l=[`running`,`starting`,`stopping`,`stopped`,`unknown`],u=[`queued`,`running`,`finishing`],d=[`off`,`config`,`env`,`config+env`,`latch`,`unknown`];function f(e,t,n,r){let i=e[t];return typeof i==`string`&&n.includes(i)?i:r}function p(e){let t=n(e);return t?{capable:o(t,`capable`),refusal:r(t,`refusal`),slots:a(t,`slots`)}:{capable:null,refusal:null,slots:null}}var m={up:`running`,down:`stopped`,loading:`starting`,unknown:`unknown`};function h(e){let t=e.state;if(typeof t!=`string`||!(t in m))return null;let i=n(e.slots),s=r(e,`host`),c=a(e,`port`),l=i?a(i,`configured`):null,u=i?a(i,`busy`):null,d=i?r(i,`source`):null,f=d!==null&&d!==`unknown`,p=f?l:null,h=r(e,`parallelRefusal`),_=r(e,`runtimeKind`),v=a(e,`contextPerSlot`),y=a(e,`contextTotal`);return{kind:_===`ollama`?`ollama`:_===`unknown`?`unknown`:`llama-server`,state:m[t]??`unknown`,endpoint:s!==null&&c!==null?`${s}:${c}`:r(e,`origin`)??null,model:g(r(e,`modelName`))??g(r(e,`model`)),slotsTotal:p,slotsBusy:f?u:null,contextTokens:v??(p!==null&&p>0&&y!==null&&y>0?Math.floor(y/p):null),startedAt:r(e,`startedAt`),parallel:{capable:h===null?f&&p!==null?!0:null:!1,refusal:h,slots:p},reason:r(e,`lastError`),supervised:o(e,`managed`)??!1,sampledAt:r(e,`checkedAt`)}}function g(e){if(e===null||e.length===0)return null;let t=e.split(`/`).pop()??e;return t.length===0||/^sha256[-:][0-9a-f]{16,}$/i.test(t)?null:t}function _(e){let t=n(e);if(!t)return null;if(!(`kind`in t)&&`slots`in t&&`state`in t){let e=h(t);if(e!==null)return e}return{kind:f(t,`kind`,c,`unknown`),state:f(t,`state`,l,`unknown`),endpoint:r(t,`endpoint`),model:r(t,`model`),slotsTotal:a(t,`slotsTotal`),slotsBusy:a(t,`slotsBusy`),contextTokens:a(t,`contextTokens`),startedAt:r(t,`startedAt`),parallel:p(t.parallel),reason:r(t,`reason`),supervised:o(t,`supervised`)??!1,sampledAt:r(t,`sampledAt`)}}function v(e){let t=n(e);if(!t)return null;let i=r(t,`id`);return i===null?null:{id:i,task:r(t,`task`),repo:r(t,`repo`),engine:r(t,`engine`),model:r(t,`model`),state:f(t,`state`,u,`running`),startedAt:r(t,`startedAt`),slot:a(t,`slot`)}}function y(e){let t=n(e);return t?{agents:(Array.isArray(t.agents)?t.agents:[]).map(v).filter(e=>e!==null),queueDepth:a(t,`queueDepth`),slotsTotal:a(t,`slotsTotal`),slotsBusy:a(t,`slotsBusy`),notes:s(t,`notes`),sampledAt:r(t,`sampledAt`)}:null}function b(e){let t=n(e);if(!t)return null;let i=r(t,`engine`);return i===null?null:{engine:i,reason:r(t,`reason`)??`The dispatcher refuses this engine while local-only is on.`}}var x=new Set([`env`,`config+env`,`latch`,`unknown`]);function S(e){let t=n(e);if(!t)return null;let i=Array.isArray(t.refuses)?t.refuses:[],a=f(t,`source`,d,`unknown`);return{enabled:o(t,`enabled`)??!1,source:a,refuses:i.map(b).filter(e=>e!==null),mutable:x.has(a)?!1:o(t,`mutable`)??!1,detail:r(t,`detail`),sampledAt:r(t,`sampledAt`)??r(t,`checkedAt`)}}function C(e){switch(e){case`llama-server`:return`llama-server`;case`ollama`:return`Ollama`;case`vllm`:return`vLLM`;default:return`the serving runtime`}}function w(e){if(e===null)return{verdict:`unknown`,effectiveConcurrency:null,configuredSlots:null,overstated:!1,headline:`No serving runtime reported`,detail:`Serving runtime unavailable — concurrency unknown.`,tone:`unknown`};let t=e.slotsTotal??e.parallel.slots,n=C(e.kind);if(e.state!==`running`)return{verdict:`offline`,effectiveConcurrency:null,configuredSlots:t,overstated:!1,headline:e.state===`stopped`?`Not serving`:`Serving runtime is ${e.state}`,detail:e.state===`stopped`?`${n} is not running, so no local agent can take a turn. Start it before dispatching a fleet.`:`${n} is ${e.state}; capacity is not settled until it reports running.`,tone:e.state===`stopped`?`neutral`:`warning`};if(e.parallel.capable===!1){let e=t!==null&&t>1;return{verdict:`serialized`,effectiveConcurrency:1,configuredSlots:t,overstated:e,headline:`${n} serializes requests`,detail:e?`${n} has ${t} slots configured but runs one request at a time for this model, so the real capacity is one agent. The other ${t-1} would queue, and a queue looks like slowness rather than a wait.`:`${n} runs one request at a time for this model. A second agent waits for the first to finish.`,tone:`danger`}}return e.parallel.capable===null?{verdict:`unknown`,effectiveConcurrency:null,configuredSlots:t,overstated:!1,headline:`Batching not confirmed`,detail:`${n} is running${t===null?``:` with ${t} slots configured`}, but it has not reported whether it batches concurrent requests for this model. Until it does, this panel will not quote a concurrency it cannot stand behind.`,tone:`unknown`}:t===null?{verdict:`batched`,effectiveConcurrency:null,configuredSlots:null,overstated:!1,headline:`${n} batches concurrent requests`,detail:`${n} batches, but reported no slot count, so the ceiling on concurrent agents is unknown.`,tone:`unknown`}:{verdict:`batched`,effectiveConcurrency:t,configuredSlots:t,overstated:!1,headline:`${t} agent${t===1?``:`s`} in parallel`,detail:`${n} batches across ${t} slot${t===1?``:`s`} sharing one copy of the weights, so ${t} agent${t===1?``:`s`} can be mid-turn at once.`,tone:`success`}}var T=[{runtime:`Ollama`,perRequestSeconds:[3.7,7.6,11.4,15.2],wallSeconds:15.2,verdict:`staggered — the requests queued`},{runtime:`llama-server`,perRequestSeconds:[8.6,8.9,9,9],wallSeconds:9.1,verdict:`together — the requests batched`}];function E(t,n){if(t===null||n===null||n<=0)return{busy:t,total:n,percent:null,percentText:null,saturated:!1,label:t===null?`Slot occupancy is not reported.`:`${t} in flight; the number of slots is not known, so occupancy cannot be drawn.`};let r=Math.min(t,n)/n*100,i=Math.round(r),a=t>=n;return{busy:t,total:n,percent:i,percentText:e(r),saturated:a,label:a?`All ${n} slot${n===1?``:`s`} busy — new turns wait for one to free up.`:`${t} of ${n} slot${n===1?``:`s`} busy.`}}function D(e,t,n){if(e===null)return{state:`unknown`,headline:`Fleet not reported`,detail:`Fleet status unavailable.`,tone:`unknown`};let r=e.agents.filter(e=>e.state!==`queued`).length,i=e.queueDepth??e.agents.filter(e=>e.state===`queued`).length;return i>0?{state:`queued`,headline:`${i} waiting for a slot`,detail:n.verdict===`serialized`?`${r} turn${r===1?``:`s`} in flight and ${i} queued. This runtime serializes, so the queue drains one at a time — the wait is a wait, not slow inference.`:`${r} turn${r===1?``:`s`} in flight and ${i} queued behind ${t.total===null?`the available slots`:`${t.total} slots`}. Queued turns have not started; their wall time is queueing, not work.`,tone:`warning`}:r===0?{state:`idle`,headline:`Nothing in flight`,detail:`No agent is mid-turn.`,tone:`neutral`}:t.saturated?{state:`saturated`,headline:`All slots busy · ${r} in flight`,detail:`Every slot is working and nothing is queued behind them. The next turn will wait, but none is waiting yet.`,tone:`running`}:{state:`working`,headline:`${r} in flight`,detail:t.label,tone:`running`}}var O=`Refused: local-only is on and this engine is not local.`;function k(e,t){let n=t.filter(e=>e.engine!==`local`),r=t.filter(e=>e.engine===`local`),i=new Map;for(let t of e?.refuses??[])i.set(t.engine,t.reason);return{blocked:n,allowed:r,refusalFor:e=>i.get(e)??O,summary:t.length===0?`No seats are configured, so there is nothing for this policy to block yet.`:n.length===0?`Every one of your ${t.length} seat${t.length===1?``:`s`} is local, so this policy would block nothing today.`:`${n.length} of ${t.length} seat${t.length===1?``:`s`} would become unreachable; ${r.length} local seat${r.length===1?``:`s`} would keep working.`}}function A(e){if(e===null)return null;if(e.detail!==null)return e.detail;switch(e.source){case`env`:case`config+env`:return`This policy is pinned by an environment variable on the server process, so it cannot be changed from here — restart the server without it to take the switch back.`;case`latch`:return`This process already observed a persisted local-only and has pinned it for its own lifetime, so turning it off takes effect for new dispatches but not for the seams that latched. Restart the server to clear it.`;case`config`:return`Stored in the hub config and applied on the next dispatch.`;case`off`:return`Not configured; cloud engines are reachable.`;default:return`The server did not say where this setting came from.`}}function j(e,n){if(!e)return`—`;let r=Date.parse(e);return Number.isNaN(r)?`—`:t(Math.max(0,n-r))}function M(e,n){if(!e)return`—`;let r=Date.parse(e);return Number.isNaN(r)?`—`:`up ${t(Math.max(0,n-r))}`}function N(e){let t={running:0,finishing:1,queued:2};return[...e].sort((e,n)=>{let r=t[e.state]-t[n.state];if(r!==0)return r;let i=e.startedAt?Date.parse(e.startedAt):NaN,a=n.startedAt?Date.parse(n.startedAt):NaN;return Number.isNaN(i)&&Number.isNaN(a)?e.id.localeCompare(n.id):Number.isNaN(i)?1:Number.isNaN(a)?-1:i-a})}export{k as a,y as c,w as d,C as f,M as i,S as l,j as n,A as o,E as p,D as r,N as s,T as t,_ as u};
|
|
2
|
+
//# sourceMappingURL=fleet-model-D4n8ErhA.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fleet-model-D4n8ErhA.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/autonomy/fleet-model.ts"],"sourcesContent":["/**\n * routes/verse/autonomy/fleet-model.ts — every derivation the local-fleet\n * surfaces make, as pure functions. No React, no I/O, so the rules that decide\n * what the operator is told are unit-testable without a DOM.\n *\n * The one rule this file exists to enforce:\n *\n * **A concurrency number the runtime will not honour is a lie, and the UI\n * must print the truth instead of the configuration.**\n *\n * That is not a hypothetical. Measured on this machine (docs/LOCAL-FLEET.md),\n * four concurrent Qwen3.8 requests to Ollama returned at 3.7 / 7.6 / 11.4 /\n * 15.2s — a four-second stagger, which is a queue. The same weights on\n * llama-server returned at 8.6 / 8.9 / 9.0 / 9.0s: continuous batching across\n * four slots sharing one 27 GB copy. Ollama's log calls it a refusal\n * (`model architecture does not currently support parallel requests`) and\n * `OLLAMA_NUM_PARALLEL` does not move it.\n *\n * So `runtimeCapacity()` never reports `slotsTotal` as capacity unless the\n * runtime says it batches. When a runtime that serializes is configured with\n * four slots, the capacity is ONE and `overstated` is true, and the panel says\n * so in words. A queue that looks like slowness is the exact failure this\n * surface is here to prevent.\n *\n * The bodies these functions narrow come from routes that are landing in\n * parallel (see fleet-contract.ts), so everything is projected STRUCTURALLY\n * rather than cast: a field-name drift degrades to an honest \"unknown\" at\n * render time instead of throwing.\n */\nimport { UNKNOWN, formatDuration, percentText } from './format.js';\nimport type {\n FleetAgent,\n FleetAgentState,\n FleetSnapshot,\n LocalOnlyPolicy,\n LocalOnlyRefusal,\n LocalOnlySource,\n ServingRuntimeKind,\n ServingRuntimeParallelism,\n ServingRuntimeSnapshot,\n ServingRuntimeState,\n} from './fleet-contract.js';\n\n// ---------------------------------------------------------------------------\n// Structural narrowing\n// ---------------------------------------------------------------------------\n\nfunction record(value: unknown): Record<string, unknown> | null {\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : null;\n}\n\nfunction str(source: Record<string, unknown>, key: string): string | null {\n const v = source[key];\n return typeof v === 'string' && v.length > 0 ? v : null;\n}\n\nfunction num(source: Record<string, unknown>, key: string): number | null {\n const v = source[key];\n return typeof v === 'number' && Number.isFinite(v) ? v : null;\n}\n\n/** A count that is meaningful at zero — so 0 stays 0 and absent stays null. */\nfunction count(source: Record<string, unknown>, key: string): number | null {\n const v = num(source, key);\n return v === null ? null : Math.max(0, Math.round(v));\n}\n\nfunction bool(source: Record<string, unknown>, key: string): boolean | null {\n const v = source[key];\n return typeof v === 'boolean' ? v : null;\n}\n\nfunction strings(source: Record<string, unknown>, key: string): string[] {\n const v = source[key];\n return Array.isArray(v) ? v.filter((entry): entry is string => typeof entry === 'string') : [];\n}\n\nconst RUNTIME_KINDS: readonly ServingRuntimeKind[] = ['llama-server', 'ollama', 'vllm', 'unknown'];\nconst RUNTIME_STATES: readonly ServingRuntimeState[] = [\n 'running',\n 'starting',\n 'stopping',\n 'stopped',\n 'unknown',\n];\nconst AGENT_STATES: readonly FleetAgentState[] = ['queued', 'running', 'finishing'];\nconst LOCAL_ONLY_SOURCES: readonly LocalOnlySource[] = [\n 'off',\n 'config',\n 'env',\n 'config+env',\n 'latch',\n 'unknown',\n];\n\nfunction oneOf<T extends string>(\n source: Record<string, unknown>,\n key: string,\n allowed: readonly T[],\n fallback: T,\n): T {\n const v = source[key];\n return typeof v === 'string' && (allowed as readonly string[]).includes(v) ? (v as T) : fallback;\n}\n\nfunction projectParallelism(raw: unknown): ServingRuntimeParallelism {\n const r = record(raw);\n if (!r) return { capable: null, refusal: null, slots: null };\n return { capable: bool(r, 'capable'), refusal: str(r, 'refusal'), slots: count(r, 'slots') };\n}\n\n/**\n * Owner R's `LlamaRuntimeSnapshot` (`src/core/local-runtime/llama/types.ts`)\n * spells the same facts differently, and the route that serves it is not\n * written yet — so rather than betting on one envelope, this reads both.\n *\n * The mapping, with the two judgement calls stated:\n *\n * - `state: 'up' | 'down' | 'loading' | 'unknown'` → running / stopped /\n * starting / unknown.\n * - `contextPerSlot` wins over `contextTotal`. `-c 65536 --parallel 4` gives\n * each slot 16k, and the number an agent's turn actually runs in is the\n * per-slot one. Quoting the total would overstate every agent's context\n * fourfold — the same class of error as quoting slots as concurrency.\n * - `managed` → `supervised`. R is explicit that an unmanaged server may be\n * adopted but is \"never killed on a guess\", which is exactly the condition\n * under which this panel must not offer a stop button.\n */\nconst LLAMA_STATE: Readonly<Record<string, ServingRuntimeState>> = {\n up: 'running',\n down: 'stopped',\n loading: 'starting',\n unknown: 'unknown',\n};\n\nfunction projectLlamaShape(r: Record<string, unknown>): ServingRuntimeSnapshot | null {\n const rawState = r['state'];\n if (typeof rawState !== 'string' || !(rawState in LLAMA_STATE)) return null;\n const slots = record(r['slots']);\n const host = str(r, 'host');\n const port = count(r, 'port');\n const configured = slots ? count(slots, 'configured') : null;\n const busy = slots ? count(slots, 'busy') : null;\n // `slots.source` is R's own trust marker: 'unknown' means \"do not trust a\n // number\", so a slot count carrying it is dropped rather than quoted.\n const slotSource = slots ? str(slots, 'source') : null;\n const trusted = slotSource !== null && slotSource !== 'unknown';\n const total = trusted ? configured : null;\n\n const refusal = str(r, 'parallelRefusal');\n const identity = str(r, 'runtimeKind');\n const contextPerSlot = count(r, 'contextPerSlot');\n const contextTotal = count(r, 'contextTotal');\n\n return {\n // IDENTIFIED where the producer says so. A base URL pointed at Ollama's\n // /v1 answers /v1/models — enough to keep the engine routable — while\n // 404ing /health and /props, and asserting 'llama-server' for it would\n // hide the one fact that matters: that runtime serialises this model.\n kind: identity === 'ollama' ? 'ollama' : identity === 'unknown' ? 'unknown' : 'llama-server',\n state: LLAMA_STATE[rawState] ?? 'unknown',\n endpoint: host !== null && port !== null ? `${host}:${port}` : (str(r, 'origin') ?? null),\n // A digest is not a name. `modelName` falls back to `model_path`'s basename\n // at the producer, which for a blob out of Ollama's content-addressed store\n // is `sha256-…`: it identifies the machine's storage layout and names\n // nothing. Null renders as \"unknown\", which is the honest answer.\n model: humaneModelName(str(r, 'modelName')) ?? humaneModelName(str(r, 'model')),\n slotsTotal: total,\n slotsBusy: trusted ? busy : null,\n // PER-SLOT, or nothing. `-c 65536 --parallel 4` gives each agent 16k, so\n // the `-c` total is usable only divided by a slot count we trust.\n contextTokens:\n contextPerSlot ??\n (total !== null && total > 0 && contextTotal !== null && contextTotal > 0\n ? Math.floor(contextTotal / total)\n : null),\n startedAt: str(r, 'startedAt'),\n parallel: {\n // llama-server's slots ARE its continuous-batching slots: a count read\n // back off the live server (`/props.total_slots`, `/slots`) is a count\n // of requests it will run at the same time, which is what the\n // measurement in docs/LOCAL-FLEET.md showed. An untrusted or absent\n // reading claims nothing — `null`, not `true`.\n capable: refusal !== null ? false : trusted && total !== null ? true : null,\n // The runtime's own words when it refuses, carried verbatim as evidence.\n refusal,\n slots: total,\n },\n reason: str(r, 'lastError'),\n supervised: bool(r, 'managed') ?? false,\n sampledAt: str(r, 'checkedAt'),\n };\n}\n\n/** A displayable model name, or null for an absent or digest-shaped one. */\nfunction humaneModelName(raw: string | null): string | null {\n if (raw === null || raw.length === 0) return null;\n const base = raw.split('/').pop() ?? raw;\n if (base.length === 0) return null;\n if (/^sha256[-:][0-9a-f]{16,}$/i.test(base)) return null;\n return base;\n}\n\nexport function projectServingRuntime(raw: unknown): ServingRuntimeSnapshot | null {\n const r = record(raw);\n if (!r) return null;\n // A body already in this surface's own shape wins; otherwise try owner R's.\n if (!('kind' in r) && 'slots' in r && 'state' in r) {\n const llama = projectLlamaShape(r);\n if (llama !== null) return llama;\n }\n return {\n kind: oneOf(r, 'kind', RUNTIME_KINDS, 'unknown'),\n state: oneOf(r, 'state', RUNTIME_STATES, 'unknown'),\n endpoint: str(r, 'endpoint'),\n model: str(r, 'model'),\n slotsTotal: count(r, 'slotsTotal'),\n slotsBusy: count(r, 'slotsBusy'),\n contextTokens: count(r, 'contextTokens'),\n startedAt: str(r, 'startedAt'),\n parallel: projectParallelism(r['parallel']),\n reason: str(r, 'reason'),\n // A runtime this server cannot supervise must not be offered buttons, so\n // an unreported flag reads as NOT supervised. The conservative default is\n // \"no controls\" rather than controls that 404 on the first click.\n supervised: bool(r, 'supervised') ?? false,\n sampledAt: str(r, 'sampledAt'),\n };\n}\n\nfunction projectAgent(raw: unknown): FleetAgent | null {\n const r = record(raw);\n if (!r) return null;\n const id = str(r, 'id');\n if (id === null) return null;\n return {\n id,\n task: str(r, 'task'),\n repo: str(r, 'repo'),\n engine: str(r, 'engine'),\n model: str(r, 'model'),\n state: oneOf(r, 'state', AGENT_STATES, 'running'),\n startedAt: str(r, 'startedAt'),\n slot: count(r, 'slot'),\n };\n}\n\nexport function projectFleet(raw: unknown): FleetSnapshot | null {\n const r = record(raw);\n if (!r) return null;\n const rawAgents = Array.isArray(r['agents']) ? (r['agents'] as unknown[]) : [];\n return {\n agents: rawAgents.map(projectAgent).filter((a): a is FleetAgent => a !== null),\n queueDepth: count(r, 'queueDepth'),\n slotsTotal: count(r, 'slotsTotal'),\n slotsBusy: count(r, 'slotsBusy'),\n notes: strings(r, 'notes'),\n sampledAt: str(r, 'sampledAt'),\n };\n}\n\nfunction projectRefusal(raw: unknown): LocalOnlyRefusal | null {\n const r = record(raw);\n if (!r) return null;\n const engine = str(r, 'engine');\n if (engine === null) return null;\n return { engine, reason: str(r, 'reason') ?? 'The dispatcher refuses this engine while local-only is on.' };\n}\n\n/**\n * `source` is carried through as the resolver's own value — it is no longer\n * flattened onto a smaller union here.\n *\n * The flattening this replaced mapped `'latch'` onto `'config'`, which tells\n * an operator the mode is stored in the config and editable when in fact the\n * process has pinned it for its own lifetime. Only the separate `mutable`\n * flag kept that from reaching the screen as a working switch that silently\n * does nothing. An unrecognised value lands on `'unknown'`, which makes no\n * claim at all.\n */\n/** Sources that pin the mode to this server process, whatever the config says. */\nconst PINNED_SOURCES: ReadonlySet<LocalOnlySource> = new Set<LocalOnlySource>([\n 'env',\n 'config+env',\n 'latch',\n 'unknown',\n]);\n\nexport function projectLocalOnly(raw: unknown): LocalOnlyPolicy | null {\n const r = record(raw);\n if (!r) return null;\n const rawRefusals = Array.isArray(r['refuses']) ? (r['refuses'] as unknown[]) : [];\n const source = oneOf(r, 'source', LOCAL_ONLY_SOURCES, 'unknown');\n return {\n // An unreported `enabled` is NOT \"on\": claiming cloud is unreachable when\n // the server never said so is the one error this policy cannot afford.\n enabled: bool(r, 'enabled') ?? false,\n source,\n refuses: rawRefusals.map(projectRefusal).filter((x): x is LocalOnlyRefusal => x !== null),\n // A policy pinned by the server's own process — an env var, or a latch\n // this process already took — is never editable from here, whatever the\n // body claims: a write would be silently overridden on the next read.\n // `'unknown'` is treated as pinned too, because offering a switch for a\n // policy this client cannot identify is the more expensive mistake.\n mutable: PINNED_SOURCES.has(source) ? false : (bool(r, 'mutable') ?? false),\n detail: str(r, 'detail'),\n sampledAt: str(r, 'sampledAt') ?? str(r, 'checkedAt'),\n };\n}\n\n// ---------------------------------------------------------------------------\n// The capacity verdict — the point of this whole file\n// ---------------------------------------------------------------------------\n\nexport type CapacityVerdict = 'batched' | 'serialized' | 'unknown' | 'offline';\n\nexport interface RuntimeCapacity {\n verdict: CapacityVerdict;\n /**\n * How many agents can genuinely be in flight at once. `null` means it\n * cannot be known from this reading — which is NOT the same as 0 and must\n * never render as a number.\n */\n effectiveConcurrency: number | null;\n /** What the runtime was configured with, honoured or not. */\n configuredSlots: number | null;\n /**\n * True when the configured slot count is larger than what the runtime will\n * actually run in parallel. While this is true, the configured number must\n * not be presented as capacity anywhere on the screen.\n */\n overstated: boolean;\n headline: string;\n detail: string;\n tone: 'success' | 'warning' | 'danger' | 'neutral' | 'unknown';\n}\n\n/** Human name for a runtime, used in sentences. */\nexport function runtimeLabel(kind: ServingRuntimeKind): string {\n switch (kind) {\n case 'llama-server':\n return 'llama-server';\n case 'ollama':\n return 'Ollama';\n case 'vllm':\n return 'vLLM';\n default:\n return 'the serving runtime';\n }\n}\n\nexport function runtimeCapacity(runtime: ServingRuntimeSnapshot | null): RuntimeCapacity {\n if (runtime === null) {\n return {\n verdict: 'unknown',\n effectiveConcurrency: null,\n configuredSlots: null,\n overstated: false,\n headline: 'No serving runtime reported',\n detail:\n 'Serving runtime unavailable — concurrency unknown.',\n tone: 'unknown',\n };\n }\n\n const configured = runtime.slotsTotal ?? runtime.parallel.slots;\n const name = runtimeLabel(runtime.kind);\n\n if (runtime.state !== 'running') {\n return {\n verdict: 'offline',\n effectiveConcurrency: null,\n configuredSlots: configured,\n overstated: false,\n headline: runtime.state === 'stopped' ? 'Not serving' : `Serving runtime is ${runtime.state}`,\n detail:\n runtime.state === 'stopped'\n ? `${name} is not running, so no local agent can take a turn. Start it before dispatching a fleet.`\n : `${name} is ${runtime.state}; capacity is not settled until it reports running.`,\n tone: runtime.state === 'stopped' ? 'neutral' : 'warning',\n };\n }\n\n if (runtime.parallel.capable === false) {\n // The measured case. The configured number is real — it is simply not a\n // concurrency, and printing it as one is the failure mode this exists for.\n const overstated = configured !== null && configured > 1;\n return {\n verdict: 'serialized',\n effectiveConcurrency: 1,\n configuredSlots: configured,\n overstated,\n headline: `${name} serializes requests`,\n detail: overstated\n ? `${name} has ${configured} slots configured but runs one request at a time for this model, so the real capacity is one agent. The other ${configured - 1} would queue, and a queue looks like slowness rather than a wait.`\n : `${name} runs one request at a time for this model. A second agent waits for the first to finish.`,\n tone: 'danger',\n };\n }\n\n if (runtime.parallel.capable === null) {\n return {\n verdict: 'unknown',\n effectiveConcurrency: null,\n configuredSlots: configured,\n overstated: false,\n headline: 'Batching not confirmed',\n detail: `${name} is running${\n configured === null ? '' : ` with ${configured} slots configured`\n }, but it has not reported whether it batches concurrent requests for this model. Until it does, this panel will not quote a concurrency it cannot stand behind.`,\n tone: 'unknown',\n };\n }\n\n if (configured === null) {\n return {\n verdict: 'batched',\n effectiveConcurrency: null,\n configuredSlots: null,\n overstated: false,\n headline: `${name} batches concurrent requests`,\n detail: `${name} batches, but reported no slot count, so the ceiling on concurrent agents is unknown.`,\n tone: 'unknown',\n };\n }\n\n return {\n verdict: 'batched',\n effectiveConcurrency: configured,\n configuredSlots: configured,\n overstated: false,\n headline: `${configured} agent${configured === 1 ? '' : 's'} in parallel`,\n detail: `${name} batches across ${configured} slot${\n configured === 1 ? '' : 's'\n } sharing one copy of the weights, so ${configured} agent${\n configured === 1 ? '' : 's'\n } can be mid-turn at once.`,\n tone: 'success',\n };\n}\n\n/**\n * The measured comparison, kept as data so the panel renders it as evidence\n * rather than as an assertion in prose. Source: docs/LOCAL-FLEET.md, four\n * concurrent requests against the same Qwen3.8 GGUF on this machine.\n */\nexport interface ConcurrencyEvidenceRow {\n runtime: string;\n /** Per-request completion times, in seconds, in the order they returned. */\n perRequestSeconds: readonly number[];\n wallSeconds: number;\n verdict: string;\n}\n\nexport const CONCURRENCY_EVIDENCE: readonly ConcurrencyEvidenceRow[] = [\n {\n runtime: 'Ollama',\n perRequestSeconds: [3.7, 7.6, 11.4, 15.2],\n wallSeconds: 15.2,\n verdict: 'staggered — the requests queued',\n },\n {\n runtime: 'llama-server',\n perRequestSeconds: [8.6, 8.9, 9.0, 9.0],\n wallSeconds: 9.1,\n verdict: 'together — the requests batched',\n },\n] as const;\n\n// ---------------------------------------------------------------------------\n// Utilisation\n// ---------------------------------------------------------------------------\n\nexport interface SlotUtilisation {\n busy: number | null;\n total: number | null;\n /** 0–100, or null when either half is unknown. */\n percent: number | null;\n /** The share in words, by the one percent rule (\"<1%\", \"99%\"); null when unknown. */\n percentText: string | null;\n /** Every slot is taken: the next turn waits. */\n saturated: boolean;\n /** One line, safe to render on its own. */\n label: string;\n}\n\n/**\n * Slot occupancy.\n *\n * `total` is the EFFECTIVE concurrency, not the configured slot count — on a\n * runtime that serializes, one busy slot out of four configured is full, and\n * drawing it as 25% would tell the operator there is room when there is none.\n */\nexport function slotUtilisation(busy: number | null, effectiveTotal: number | null): SlotUtilisation {\n if (busy === null || effectiveTotal === null || effectiveTotal <= 0) {\n return {\n busy,\n total: effectiveTotal,\n percent: null,\n percentText: null,\n saturated: false,\n label:\n busy === null\n ? 'Slot occupancy is not reported.'\n : `${busy} in flight; the number of slots is not known, so occupancy cannot be drawn.`,\n };\n }\n const clamped = Math.min(busy, effectiveTotal);\n const share = (clamped / effectiveTotal) * 100;\n const percent = Math.round(share);\n const saturated = busy >= effectiveTotal;\n return {\n busy,\n total: effectiveTotal,\n percent,\n percentText: percentText(share),\n saturated,\n label: saturated\n ? `All ${effectiveTotal} slot${effectiveTotal === 1 ? '' : 's'} busy — new turns wait for one to free up.`\n : `${busy} of ${effectiveTotal} slot${effectiveTotal === 1 ? '' : 's'} busy.`,\n };\n}\n\n/**\n * What the operator is actually waiting on.\n *\n * Saturation alone is not bad news — a fleet at full occupancy is a fleet\n * working. Saturation WITH a queue is the thing to say plainly, because from\n * the outside it is indistinguishable from the machine being slow.\n */\nexport interface FleetPressure {\n state: 'idle' | 'working' | 'saturated' | 'queued' | 'unknown';\n headline: string;\n detail: string;\n tone: 'success' | 'running' | 'warning' | 'neutral' | 'unknown';\n}\n\nexport function fleetPressure(\n fleet: FleetSnapshot | null,\n utilisation: SlotUtilisation,\n capacity: RuntimeCapacity,\n): FleetPressure {\n if (fleet === null) {\n return {\n state: 'unknown',\n headline: 'Fleet not reported',\n // A missing reading — never shown as an empty fleet.\n detail: 'Fleet status unavailable.',\n tone: 'unknown',\n };\n }\n\n const running = fleet.agents.filter((a) => a.state !== 'queued').length;\n const queued = fleet.queueDepth ?? fleet.agents.filter((a) => a.state === 'queued').length;\n\n if (queued > 0) {\n return {\n state: 'queued',\n headline: `${queued} waiting for a slot`,\n detail:\n capacity.verdict === 'serialized'\n ? `${running} turn${running === 1 ? '' : 's'} in flight and ${queued} queued. This runtime serializes, so the queue drains one at a time — the wait is a wait, not slow inference.`\n : `${running} turn${running === 1 ? '' : 's'} in flight and ${queued} queued behind ${\n utilisation.total === null ? 'the available slots' : `${utilisation.total} slots`\n }. Queued turns have not started; their wall time is queueing, not work.`,\n tone: 'warning',\n };\n }\n\n if (running === 0) {\n return {\n state: 'idle',\n headline: 'Nothing in flight',\n detail: 'No agent is mid-turn.',\n tone: 'neutral',\n };\n }\n\n if (utilisation.saturated) {\n return {\n state: 'saturated',\n headline: `All slots busy · ${running} in flight`,\n detail: `Every slot is working and nothing is queued behind them. The next turn will wait, but none is waiting yet.`,\n tone: 'running',\n };\n }\n\n return {\n state: 'working',\n headline: `${running} in flight`,\n detail: utilisation.label,\n tone: 'running',\n };\n}\n\n// ---------------------------------------------------------------------------\n// Local-only impact\n// ---------------------------------------------------------------------------\n\nexport interface SeatLike {\n id: string;\n engine: string;\n label: string;\n}\n\nexport interface LocalOnlyImpact {\n /** Seats that become unreachable while the policy is on. */\n blocked: SeatLike[];\n /** Seats unaffected — the local ones. */\n allowed: SeatLike[];\n /** The named refusal per blocked engine, from the server when it sent one. */\n refusalFor: (engine: string) => string;\n /** One line summarising the blast radius against the CURRENT seat roster. */\n summary: string;\n}\n\nconst DEFAULT_REFUSAL = 'Refused: local-only is on and this engine is not local.';\n\n/**\n * What local-only would block, measured against the seats that actually exist\n * on this machine right now.\n *\n * Deliberately computed from the live roster rather than from a fixed list of\n * cloud engines: the sentence \"this would block 3 of your 5 seats\" is only\n * trustworthy if the 5 is the operator's own number.\n */\nexport function localOnlyImpact(\n policy: LocalOnlyPolicy | null,\n seats: readonly SeatLike[],\n): LocalOnlyImpact {\n const blocked = seats.filter((s) => s.engine !== 'local');\n const allowed = seats.filter((s) => s.engine === 'local');\n const byEngine = new Map<string, string>();\n for (const refusal of policy?.refuses ?? []) byEngine.set(refusal.engine, refusal.reason);\n\n const summary =\n seats.length === 0\n ? 'No seats are configured, so there is nothing for this policy to block yet.'\n : blocked.length === 0\n ? `Every one of your ${seats.length} seat${seats.length === 1 ? '' : 's'} is local, so this policy would block nothing today.`\n : `${blocked.length} of ${seats.length} seat${seats.length === 1 ? '' : 's'} would become unreachable; ${allowed.length} local seat${allowed.length === 1 ? '' : 's'} would keep working.`;\n\n return {\n blocked,\n allowed,\n refusalFor: (engine: string) => byEngine.get(engine) ?? DEFAULT_REFUSAL,\n summary,\n };\n}\n\n/** Where the policy came from, as a sentence an operator can act on. */\nexport function localOnlySourceNote(policy: LocalOnlyPolicy | null): string | null {\n if (policy === null) return null;\n // The policy's own sentence, when it wrote one. It knows things this client\n // does not — e.g. that an env var tried and failed to clear a persisted\n // local-only — and a template would erase exactly that.\n if (policy.detail !== null) return policy.detail;\n switch (policy.source) {\n case 'env':\n case 'config+env':\n return 'This policy is pinned by an environment variable on the server process, so it cannot be changed from here — restart the server without it to take the switch back.';\n case 'latch':\n return 'This process already observed a persisted local-only and has pinned it for its own lifetime, so turning it off takes effect for new dispatches but not for the seams that latched. Restart the server to clear it.';\n case 'config':\n return 'Stored in the hub config and applied on the next dispatch.';\n case 'off':\n return 'Not configured; cloud engines are reachable.';\n default:\n return 'The server did not say where this setting came from.';\n }\n}\n\n// ---------------------------------------------------------------------------\n// Small formatters\n// ---------------------------------------------------------------------------\n\n/** \"4m 12s\" since an ISO instant, against a live clock. Absent stays absent. */\nexport function elapsedSince(iso: string | null, now: number): string {\n if (!iso) return UNKNOWN;\n const at = Date.parse(iso);\n if (Number.isNaN(at)) return UNKNOWN;\n return formatDuration(Math.max(0, now - at));\n}\n\n/** Uptime for the runtime header. Same rules, different words. */\nexport function formatUptime(startedAt: string | null, now: number): string {\n if (!startedAt) return UNKNOWN;\n const at = Date.parse(startedAt);\n if (Number.isNaN(at)) return UNKNOWN;\n return `up ${formatDuration(Math.max(0, now - at))}`;\n}\n\n/** Agent rows, ordered so the reader's first question is answered first. */\nexport function orderAgents(agents: readonly FleetAgent[]): FleetAgent[] {\n const rank: Record<FleetAgentState, number> = { running: 0, finishing: 1, queued: 2 };\n return [...agents].sort((a, b) => {\n const byState = rank[a.state] - rank[b.state];\n if (byState !== 0) return byState;\n // Longest-running first: the one most likely to be stuck is the one an\n // operator scanning this table is looking for.\n const at = a.startedAt ? Date.parse(a.startedAt) : Number.NaN;\n const bt = b.startedAt ? Date.parse(b.startedAt) : Number.NaN;\n if (Number.isNaN(at) && Number.isNaN(bt)) return a.id.localeCompare(b.id);\n if (Number.isNaN(at)) return 1;\n if (Number.isNaN(bt)) return -1;\n return at - bt;\n });\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{s as t}from"./index-_izD07R9.js";import{C as n,M as r,V as i,a,i as o,t as s,u as c}from"./global-CYfRwH6t.js";import{n as l,t as u}from"./control-queries-C5uQTzJi.js";import{c as d,l as f,u as p}from"./fleet-model-D4n8ErhA.js";var m=e(t(),1),h=`verse-runtime`,g=`verse-fleet`,_=`verse-local-only`;function v(e,t){return t instanceof s?t.status===404?`This server doesn't have ${e}.`:`${e} answered HTTP ${t.status}.`:`${e} could not be reached.`}function y(e,t){return async n=>{try{let r=t(await o(e,n));return r===null?{value:null,available:!0,reason:`Unrecognized response — update Ashlr.`}:{value:r,available:!0,reason:null}}catch(t){if(t instanceof s&&t.status===401||t instanceof DOMException&&t.name===`AbortError`)throw t;return{value:null,available:!1,reason:v(e,t)}}}}var b={key:h,fetch:y(`/api/verse/runtime`,p)},x={key:g,fetch:y(`/api/verse/fleet`,d)},S={key:_,fetch:y(`/api/verse/local-only`,f)};async function C(e,t){let i=n();if(!i)throw new l;let o=await a(e,t,i);return r(),o}async function w(e){let t=await C(`/api/verse/runtime`,{action:e});return i(h),i(g),i(u),t}async function T(e){let t=await C(`/api/verse/local-only`,{enabled:e});return i(_),i(u),t}var E=4e3;function D(e=E){let t=c(b),n=c(x);(0,m.useEffect)(()=>{let r=null,i=()=>{t(),n()},a=()=>{r===null&&(r=setInterval(i,e))},o=()=>{r!==null&&(clearInterval(r),r=null)},s=()=>{if(document.visibilityState===`hidden`){o();return}i(),a()};return document.visibilityState!==`hidden`&&a(),document.addEventListener(`visibilitychange`,s),()=>{o(),document.removeEventListener(`visibilitychange`,s)}},[e,t,n])}export{b as a,w as i,x as n,T as o,S as r,D as s,g as t};
|
|
2
|
+
//# sourceMappingURL=fleet-queries-BO1MHMFz.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fleet-queries-BO1MHMFz.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/autonomy/fleet-queries.ts"],"sourcesContent":["/**\n * routes/verse/autonomy/fleet-queries.ts — the reads and writes behind the\n * local-fleet surfaces: `GET/POST /api/verse/runtime`,\n * `GET/POST /api/verse/local-only`, and `GET /api/verse/fleet`.\n *\n * Same contract as control-queries.ts — reads are QueryDefs consumed through\n * useQuery, writes go through the mutation-token gate and invalidate exactly\n * the keys they affect — with two differences that both come from these three\n * routes landing in parallel with this surface (owners R, L, F):\n *\n * 1. **The reads do not throw on absence.** A server without these routes\n * answers 404, and a 404 means \"this panel has no source yet\", not\n * \"Autonomy is broken\". The panels render a designed degraded state from\n * `OptionalFleetRead.reason`. 401 still propagates: an expired read\n * session is an unauthorized state for the whole surface.\n * 2. **The bodies are narrowed structurally, not cast.** `fleet-model.ts`\n * projects every field, so a name drift between the route and this client\n * degrades to \"unknown\" rather than throwing at render time.\n *\n * Polling: the fleet and the runtime are the two things on this screen that\n * change while nobody clicks anything, and neither has an SSE event yet, so\n * `useFleetPolling` re-reads them on an interval — pausing while the tab is\n * hidden, because a background tab polling a runtime probe is pure waste.\n */\nimport { useEffect } from 'react';\nimport { ApiError, apiGet, apiPost } from '../../../data/client.js';\nimport { getMutationToken, touchMutationHold } from '../../../data/auth-store.js';\nimport { invalidate } from '../../../data/cache.js';\nimport type { QueryDef } from '../../../data/queries.js';\nimport { useRefetch } from '../../../data/hooks.js';\nimport { VERSE_CONTROL_KEY, VerseControlLockedError } from './control-queries.js';\nimport type {\n FleetSnapshot,\n LocalOnlyPolicy,\n LocalOnlyUpdateResult,\n OptionalFleetRead,\n RuntimeAction,\n RuntimeActionResult,\n ServingRuntimeSnapshot,\n} from './fleet-contract.js';\nimport { projectFleet, projectLocalOnly, projectServingRuntime } from './fleet-model.js';\n\nexport const VERSE_RUNTIME_KEY = 'verse-runtime';\nexport const VERSE_FLEET_KEY = 'verse-fleet';\nexport const VERSE_LOCAL_ONLY_KEY = 'verse-local-only';\n\nfunction describeAbsence(path: string, err: unknown): string {\n if (err instanceof ApiError) {\n if (err.status === 404) {\n // A missing route — never read as an idle machine.\n return `This server doesn't have ${path}.`;\n }\n return `${path} answered HTTP ${err.status}.`;\n }\n return `${path} could not be reached.`;\n}\n\n/**\n * One optional read, projected. `value` is null both when the route was absent\n * and when it answered something this client could not narrow — `available`\n * and `reason` are what tell the two apart.\n */\nfunction optionalRead<T>(\n path: string,\n project: (raw: unknown) => T | null,\n): (signal?: AbortSignal) => Promise<OptionalFleetRead<T>> {\n return async (signal) => {\n try {\n const raw = await apiGet<unknown>(path, signal);\n const value = project(raw);\n if (value === null) {\n return {\n value: null,\n available: true,\n // Nothing is shown rather than guessed from an unknown shape.\n reason: 'Unrecognized response — update Ashlr.',\n };\n }\n return { value, available: true, reason: null };\n } catch (err) {\n if (err instanceof ApiError && err.status === 401) throw err;\n if (err instanceof DOMException && err.name === 'AbortError') throw err;\n return { value: null, available: false, reason: describeAbsence(path, err) };\n }\n };\n}\n\n/** GET /api/verse/runtime — is the serving runtime up, and what can it do. */\nexport const servingRuntimeQuery: QueryDef<OptionalFleetRead<ServingRuntimeSnapshot>> = {\n key: VERSE_RUNTIME_KEY,\n fetch: optionalRead('/api/verse/runtime', projectServingRuntime),\n};\n\n/** GET /api/verse/fleet — the agents in flight right now. */\nexport const fleetQuery: QueryDef<OptionalFleetRead<FleetSnapshot>> = {\n key: VERSE_FLEET_KEY,\n fetch: optionalRead('/api/verse/fleet', projectFleet),\n};\n\n/** GET /api/verse/local-only — the refusal policy and what it refuses. */\nexport const localOnlyQuery: QueryDef<OptionalFleetRead<LocalOnlyPolicy>> = {\n key: VERSE_LOCAL_ONLY_KEY,\n fetch: optionalRead('/api/verse/local-only', projectLocalOnly),\n};\n\n// ---------------------------------------------------------------------------\n// Writes\n// ---------------------------------------------------------------------------\n\nasync function post<T>(path: string, body: unknown): Promise<T> {\n const token = getMutationToken();\n if (!token) throw new VerseControlLockedError();\n const result = await apiPost<T>(path, body, token);\n touchMutationHold();\n return result;\n}\n\n/**\n * Start / stop / restart the serving runtime.\n *\n * Every one of these changes what the fleet can do, so all three fleet keys\n * and the control snapshot are invalidated together — a restarted runtime\n * with a stale slot count beside it is exactly the disagreement this surface\n * exists to prevent.\n */\nexport async function runRuntimeAction(action: RuntimeAction): Promise<RuntimeActionResult> {\n const result = await post<RuntimeActionResult>('/api/verse/runtime', { action });\n invalidate(VERSE_RUNTIME_KEY);\n invalidate(VERSE_FLEET_KEY);\n invalidate(VERSE_CONTROL_KEY);\n return result;\n}\n\n/** Turn the local-only refusal on or off. */\nexport async function setLocalOnly(enabled: boolean): Promise<LocalOnlyUpdateResult> {\n const result = await post<LocalOnlyUpdateResult>('/api/verse/local-only', { enabled });\n invalidate(VERSE_LOCAL_ONLY_KEY);\n invalidate(VERSE_CONTROL_KEY);\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Polling\n// ---------------------------------------------------------------------------\n\n/** Fast enough that \"is it working\" is answered live; slow enough to be free. */\nexport const FLEET_POLL_MS = 4000;\n\n/**\n * Keep the runtime and fleet reads live while this section is mounted and the\n * tab is visible.\n *\n * Both routes probe a local process, so this is cheap — but only while someone\n * is looking. `visibilitychange` stops the timer when the tab is hidden and\n * takes one immediate reading when it comes back, so a fleet view returned to\n * after lunch is current on the first frame rather than up to an interval old.\n */\nexport function useFleetPolling(intervalMs: number = FLEET_POLL_MS): void {\n const refetchRuntime = useRefetch(servingRuntimeQuery);\n const refetchFleet = useRefetch(fleetQuery);\n\n useEffect(() => {\n let timer: ReturnType<typeof setInterval> | null = null;\n\n const tick = (): void => {\n refetchRuntime();\n refetchFleet();\n };\n\n const start = (): void => {\n if (timer !== null) return;\n timer = setInterval(tick, intervalMs);\n };\n\n const stop = (): void => {\n if (timer === null) return;\n clearInterval(timer);\n timer = null;\n };\n\n const onVisibility = (): void => {\n if (document.visibilityState === 'hidden') {\n stop();\n return;\n }\n tick();\n start();\n };\n\n if (document.visibilityState !== 'hidden') start();\n document.addEventListener('visibilitychange', onVisibility);\n return () => {\n stop();\n document.removeEventListener('visibilitychange', onVisibility);\n };\n }, [intervalMs, refetchRuntime, refetchFleet]);\n}\n"],"mappings":"6SA0Ca,EAAoB,gBACpB,EAAkB,cAClB,EAAuB,mBAEpC,SAAS,EAAgB,EAAc,EAAsB,CAQ3D,OAPI,aAAe,EACb,EAAI,SAAW,IAEV,4BAA4B,EAAK,GAEnC,GAAG,EAAK,iBAAiB,EAAI,OAAO,GAEtC,GAAG,EAAK,uBACjB,CAOA,SAAS,EACP,EACA,EACyD,CACzD,OAAO,KAAO,IAAW,CACvB,GAAI,CAEF,IAAM,EAAQ,EAAQ,MADJ,EAAgB,EAAM,CAAM,CACrB,EASzB,OARI,IAAU,KACL,CACL,MAAO,KACP,UAAW,GAEX,OAAQ,uCACV,EAEK,CAAE,QAAO,UAAW,GAAM,OAAQ,IAAK,CAChD,OAAS,EAAK,CAEZ,GADI,aAAe,GAAY,EAAI,SAAW,KAC1C,aAAe,cAAgB,EAAI,OAAS,aAAc,MAAM,EACpE,MAAO,CAAE,MAAO,KAAM,UAAW,GAAO,OAAQ,EAAgB,EAAM,CAAG,CAAE,CAC7E,CACF,CACF,CAGA,IAAa,EAA2E,CACtF,IAAK,EACL,MAAO,EAAa,qBAAsB,CAAqB,CACjE,EAGa,EAAyD,CACpE,IAAK,EACL,MAAO,EAAa,mBAAoB,CAAY,CACtD,EAGa,EAA+D,CAC1E,IAAK,EACL,MAAO,EAAa,wBAAyB,CAAgB,CAC/D,EAMA,eAAe,EAAQ,EAAc,EAA2B,CAC9D,IAAM,EAAQ,EAAiB,EAC/B,GAAI,CAAC,EAAO,MAAM,IAAI,EACtB,IAAM,EAAS,MAAM,EAAW,EAAM,EAAM,CAAK,EAEjD,OADA,EAAkB,EACX,CACT,CAUA,eAAsB,EAAiB,EAAqD,CAC1F,IAAM,EAAS,MAAM,EAA0B,qBAAsB,CAAE,QAAO,CAAC,EAI/E,OAHA,EAAW,CAAiB,EAC5B,EAAW,CAAe,EAC1B,EAAW,CAAiB,EACrB,CACT,CAGA,eAAsB,EAAa,EAAkD,CACnF,IAAM,EAAS,MAAM,EAA4B,wBAAyB,CAAE,SAAQ,CAAC,EAGrF,OAFA,EAAW,CAAoB,EAC/B,EAAW,CAAiB,EACrB,CACT,CAOA,IAAa,EAAgB,IAW7B,SAAgB,EAAgB,EAAqB,EAAqB,CACxE,IAAM,EAAiB,EAAW,CAAmB,EAC/C,EAAe,EAAW,CAAU,GAE1C,EAAA,EAAA,UAAA,KAAgB,CACd,IAAI,EAA+C,KAE7C,MAAmB,CACvB,EAAe,EACf,EAAa,CACf,EAEM,MAAoB,CACpB,IAAU,OACd,EAAQ,YAAY,EAAM,CAAU,EACtC,EAEM,MAAmB,CACnB,IAAU,OACd,cAAc,CAAK,EACnB,EAAQ,KACV,EAEM,MAA2B,CAC/B,GAAI,SAAS,kBAAoB,SAAU,CACzC,EAAK,EACL,MACF,CACA,EAAK,EACL,EAAM,CACR,EAIA,OAFI,SAAS,kBAAoB,UAAU,EAAM,EACjD,SAAS,iBAAiB,mBAAoB,CAAY,MAC7C,CACX,EAAK,EACL,SAAS,oBAAoB,mBAAoB,CAAY,CAC/D,CACF,EAAG,CAAC,EAAY,EAAgB,CAAY,CAAC,CAC/C"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/global-1SED_aTT.css","assets/budget-queries-t-Bdoly3.js"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{t as e}from"./index-_izD07R9.js";import{V as t}from"./global-CYfRwH6t.js";import{O as n}from"./VerseShared-CFE5B-IY.js";import{n as r}from"./surface-data-NFl_uS--.js";import{n as i}from"./mobile-toast-9-WQbWQu.js";import{t as a}from"./mobile-actions-V26-lGbH.js";var o={async daemon(t){let{runDaemonAction:n}=await e(async()=>{let{runDaemonAction:e}=await import(`./control-queries-C5uQTzJi.js`).then(e=>e.r);return{runDaemonAction:e}},__vite__mapDeps([0])),r=await n(t);return{note:typeof r?.note==`string`&&r.note?r.note:null}},async setBudgetMode(t){let{updateBudget:n}=await e(async()=>{let{updateBudget:e}=await import(`./budget-queries-t-Bdoly3.js`).then(e=>e.r);return{updateBudget:e}},__vite__mapDeps([1,0]));return await n({mode:t}),{note:null}}};function s(){return o}var c=`verse-control`,l={start:`Fleet starting`,stop:`Fleet stopped`,pause:`Fleet paused`,resume:`Fleet resumed`};function u(){t(c),t(r.fleetLive),n()}function d(e){let t=null;return a({title:e.confirm?.title??`${e.label} the fleet`,consequences:e.confirm?.body??``,confirmLabel:e.confirm?.confirmLabel??e.label,destructive:e.destructive,confirm:e.confirm!==null,run:async()=>{t=(await s().daemon(e.verb)).note},onDone:()=>{u(),i(t??l[e.verb],`success`)}})}var f={running:`Running`,paused:`Paused`,stopped:`Stopped`,blocked:`Blocked`,unknown:`Unknown`},p={start:{title:`Start the fleet?`,body:`Starts the autonomous daemon on your Mac. It picks up work in your enrolled repos and spends from your seats under the current budget mode.`,confirmLabel:`Start fleet`},resume:{title:`Resume the fleet?`,body:`The daemon starts dispatching again: queued work runs and spends from your seats under the current budget mode.`,confirmLabel:`Resume`},stop:{title:`Stop the fleet?`,body:"Stops the daemon by engaging the kill switch. Runs in flight are cut off and the agents’ own write tools refuse too. Only your Mac can release it (`ashlr fleet resume`).",confirmLabel:`Stop fleet`}},m={kind:`daemon`,verb:`pause`,label:`Pause`,confirm:null,destructive:!1},h={kind:`daemon`,verb:`resume`,label:`Resume`,confirm:p.resume,destructive:!1},g={kind:`daemon`,verb:`start`,label:`Start`,confirm:p.start,destructive:!1},_={kind:`daemon`,verb:`stop`,label:`Stop`,confirm:p.stop,destructive:!0};function v(e,t,n){return`${e} ${e===1?t:n}`}function y({control:e,live:t,badge:n}){let r=t?.summary.building??null;if(e?.killSwitch.state===`active`||n?.stopped===!0)return{headline:`stopped`,label:f.stopped,detail:e?.killSwitch.reason||"The kill switch is engaged. Release it on your Mac with `ashlr fleet resume`.",building:r,action:{kind:`open-fleet`,label:`Details`},killEngaged:!0};if(e?.pause.state===`paused`||t?.state===`paused`)return{headline:`paused`,label:f.paused,detail:e?.pause.reason||t?.stateReason||`Dispatch is paused. Nothing new starts until you resume.`,building:r,action:h,killEngaged:!1};if(e?.daemon.running===!1||t?.state===`stopped`)return{headline:`stopped`,label:f.stopped,detail:t?.stateReason||`The fleet daemon is not running on your Mac.`,building:r,action:g,killEngaged:!1};if(t?.state===`dark`||n?.mode===`off`||n?.paused===!0)return{headline:`blocked`,label:f.blocked,detail:t?.stateReason||n?.label||`No standing grant is in force, so the fleet cannot land work.`,building:r,action:{kind:`open-fleet`,label:`See why`},killEngaged:!1};if(t?.state===`running`||t?.state===`idle`||e?.daemon.running===!0){let e=r&&r>0?`${v(r,`run`,`runs`)} building${t?.summary.queued?` · ${t.summary.queued} queued`:``}`:t?.stateReason||`Idle between tasks.`;return{headline:`running`,label:f.running,detail:e,building:r,action:m,killEngaged:!1}}return{headline:`unknown`,label:f.unknown,detail:`Your Mac has not reported the fleet yet.`,building:r,action:null,killEngaged:!1}}function b(e){return!e.killEngaged&&(e.headline===`running`||e.headline===`paused`||e.headline===`blocked`)}export{s as a,d as i,b as n,y as r,_ as t};
|
|
3
|
+
//# sourceMappingURL=fleet-state-yM0mV9_P.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"mappings":";8QA2CA,IAAI,EAA4B,CAZ9B,MAAM,OAAO,EAAM,CACjB,GAAM,CAAE,qCAAF,IAAE,mBAAoB,MAAM,OAAO,+FACnC,EAAS,MAAM,EAAgB,CAAI,EACzC,MAAO,CAAE,KAAM,OAAO,GAAQ,MAAS,UAAY,EAAO,KAAO,EAAO,KAAO,IAAK,CACtF,EACA,MAAM,cAAc,EAAM,CACxB,GAAM,CAAE,kCAAF,IAAE,gBAAiB,MAAM,OAAO,6FAEtC,OADA,MAAM,EAAa,CAAE,MAAK,CAAC,EACpB,CAAE,KAAM,IAAK,CACtB,CAG8B,EAEhC,SAAgB,GAA0C,CACxD,OAAO,CACT,CC/BA,IAAa,EAAc,gBAErB,EAAkD,CACtD,MAAO,iBACP,KAAM,gBACN,MAAO,eACP,OAAQ,eACV,EAEA,SAAgB,GAA0B,CACxC,EAAW,CAAW,EACtB,EAAW,EAAa,SAAS,EACjC,EAAqB,CACvB,CAEA,SAAgB,EAAe,EAAkE,CAC/F,IAAI,EAAsB,KAC1B,OAAO,EAAgB,CACrB,MAAO,EAAO,SAAS,OAAS,GAAG,EAAO,MAAM,YAChD,aAAc,EAAO,SAAS,MAAQ,GACtC,aAAc,EAAO,SAAS,cAAgB,EAAO,MACrD,YAAa,EAAO,YACpB,QAAS,EAAO,UAAY,KAC5B,IAAK,SAAY,CACf,GAAQ,MAAM,EAAqB,CAAC,CAAC,OAAO,EAAO,IAAI,GAAG,IAC5D,EACA,WAAc,CACZ,EAAkB,EAClB,EAAgB,GAAQ,EAAU,EAAO,MAAO,SAAS,CAC3D,CACF,CAAC,CACH,CCjBA,IAAa,EAA0D,CACrE,QAAS,UACT,OAAQ,SACR,QAAS,UACT,QAAS,UACT,QAAS,SACX,EAuCa,EAA8E,CACzF,MAAO,CACL,MAAO,mBACP,KAAM,8IACN,aAAc,aAChB,EACA,OAAQ,CACN,MAAO,oBACP,KAAM,kHACN,aAAc,QAChB,EACA,KAAM,CACJ,MAAO,kBACP,KAAM,4KACN,aAAc,YAChB,CACF,EAEa,EAAmC,CAAE,KAAM,SAAU,KAAM,QAAS,MAAO,QAAS,QAAS,KAAM,YAAa,EAAM,EAC7H,EAAoC,CAAE,KAAM,SAAU,KAAM,SAAU,MAAO,SAAU,QAAS,EAAe,OAAQ,YAAa,EAAM,EAC1I,EAAmC,CAAE,KAAM,SAAU,KAAM,QAAS,MAAO,QAAS,QAAS,EAAe,MAAO,YAAa,EAAM,EAC/H,EAAkC,CAAE,KAAM,SAAU,KAAM,OAAQ,MAAO,OAAQ,QAAS,EAAe,KAAM,YAAa,EAAK,EAE9I,SAAS,EAAO,EAAW,EAAa,EAAsB,CAC5D,MAAO,GAAG,EAAE,GAAG,IAAM,EAAI,EAAM,GACjC,CAEA,SAAgB,EAAe,CAAE,UAAS,OAAM,SAA0C,CACxF,IAAM,EAAW,GAAM,QAAQ,UAAY,KAG3C,GAFoB,GAAS,WAAW,QAAU,UAAY,GAAO,UAAY,GAG/E,MAAO,CACL,SAAU,UACV,MAAO,EAAe,QACtB,OAAQ,GAAS,WAAW,QAAU,gFACtC,WACA,OAAQ,CAAE,KAAM,aAAc,MAAO,SAAU,EAC/C,YAAa,EACf,EAEF,GAAI,GAAS,MAAM,QAAU,UAAY,GAAM,QAAU,SACvD,MAAO,CACL,SAAU,SACV,MAAO,EAAe,OACtB,OAAQ,GAAS,MAAM,QAAU,GAAM,aAAe,2DACtD,WACA,OAAQ,EACR,YAAa,EACf,EAEF,GAAI,GAAS,OAAO,UAAY,IAAS,GAAM,QAAU,UACvD,MAAO,CACL,SAAU,UACV,MAAO,EAAe,QACtB,OAAQ,GAAM,aAAe,+CAC7B,WACA,OAAQ,EACR,YAAa,EACf,EAEF,GAAI,GAAM,QAAU,QAAU,GAAO,OAAS,OAAS,GAAO,SAAW,GACvE,MAAO,CACL,SAAU,UACV,MAAO,EAAe,QACtB,OAAQ,GAAM,aAAe,GAAO,OAAS,gEAC7C,WACA,OAAQ,CAAE,KAAM,aAAc,MAAO,SAAU,EAC/C,YAAa,EACf,EAEF,GAAI,GAAM,QAAU,WAAa,GAAM,QAAU,QAAU,GAAS,OAAO,UAAY,GAAM,CAC3F,IAAM,EAAS,GAAY,EAAW,EAClC,GAAG,EAAO,EAAU,MAAO,MAAM,EAAE,WAAW,GAAM,QAAQ,OAAS,MAAM,EAAK,QAAQ,OAAO,SAAW,KAC1G,GAAM,aAAe,sBACzB,MAAO,CAAE,SAAU,UAAW,MAAO,EAAe,QAAS,SAAQ,WAAU,OAAQ,EAAc,YAAa,EAAM,CAC1H,CACA,MAAO,CACL,SAAU,UACV,MAAO,EAAe,QACtB,OAAQ,2CACR,WACA,OAAQ,KACR,YAAa,EACf,CACF,CAGA,SAAgB,EAAQ,EAA+B,CACrD,MAAO,CAAC,EAAK,cAAgB,EAAK,WAAa,WAAa,EAAK,WAAa,UAAY,EAAK,WAAa,UAC9G","names":[],"ignoreList":[],"sources":["../../../../../../src/web-ui/routes/verse/mobile/fleet-client.ts","../../../../../../src/web-ui/routes/verse/mobile/fleet-actions.ts","../../../../../../src/web-ui/routes/verse/mobile/fleet-state.ts"],"sourcesContent":["/**\n * routes/verse/mobile/fleet-client.ts — the fleet WRITES the phone makes,\n * behind one small interface.\n *\n * Today every verb is an existing route the workbench already uses:\n *\n * start / stop / pause / resume POST /api/verse/daemon (autonomy/control-queries.ts runDaemonAction)\n * budget mode POST /api/verse/budget (budget/budget-queries.ts updateBudget)\n *\n * The Fleet tab's own control routes are being built alongside this app; when\n * they land, `setMobileFleetClient` swaps the implementation in one place and\n * no screen changes. Reads stay on the shared query cache (the same keys the\n * workbench uses), so a write here refreshes the Mac's own view too.\n *\n * The implementations are dynamic imports: a Pause from Home is rare, and the\n * control and budget modules have no business in the first-paint bundle.\n */\nimport type { BudgetMode } from '../../../../core/routing/types.js';\nimport type { DaemonVerb } from './fleet-state.js';\n\nexport interface FleetActionResult {\n /** The server's own sentence about what happened (\"Paused dispatch.\"), or null. */\n note: string | null;\n}\n\nexport interface MobileFleetClient {\n daemon(verb: DaemonVerb): Promise<FleetActionResult>;\n setBudgetMode(mode: BudgetMode): Promise<FleetActionResult>;\n}\n\nexport const defaultFleetClient: MobileFleetClient = {\n async daemon(verb) {\n const { runDaemonAction } = await import('../autonomy/control-queries.js');\n const result = await runDaemonAction(verb);\n return { note: typeof result?.note === 'string' && result.note ? result.note : null };\n },\n async setBudgetMode(mode) {\n const { updateBudget } = await import('../budget/budget-queries.js');\n await updateBudget({ mode });\n return { note: null };\n },\n};\n\nlet client: MobileFleetClient = defaultFleetClient;\n\nexport function getMobileFleetClient(): MobileFleetClient {\n return client;\n}\n\n/** Swap the implementation (the Fleet tab's routes, or a test fake). Null restores the default. */\nexport function setMobileFleetClient(next: MobileFleetClient | null): void {\n client = next ?? defaultFleetClient;\n}\n","/**\n * routes/verse/mobile/fleet-actions.ts — pressing a fleet button on the phone\n * (Home's one button, the Fleet screen's controls): the guarded path\n * (mobile-actions.ts), the swappable client (fleet-client.ts), then a refresh\n * of every read that shows the fleet — the control aggregate, the live view\n * and activity's autonomy badge — so the new state shows at once.\n */\nimport { invalidate } from '../../../data/cache.js';\nimport { SURFACE_KEYS } from '../command/surface-data.js';\nimport { refreshActivity } from '../shell/useActivity.js';\nimport { getMobileFleetClient } from './fleet-client.js';\nimport type { DaemonVerb, FleetPrimaryAction } from './fleet-state.js';\nimport { runMobileAction } from './mobile-actions.js';\nimport { showMobileToast } from './mobile-toast.js';\n\n/** The workbench's control aggregate key (autonomy/control-queries.ts VERSE_CONTROL_KEY). */\nexport const CONTROL_KEY = 'verse-control';\n\nconst DONE_TEXT: Readonly<Record<DaemonVerb, string>> = {\n start: 'Fleet starting',\n stop: 'Fleet stopped',\n pause: 'Fleet paused',\n resume: 'Fleet resumed',\n};\n\nexport function refreshFleetReads(): void {\n invalidate(CONTROL_KEY);\n invalidate(SURFACE_KEYS.fleetLive);\n void refreshActivity();\n}\n\nexport function runFleetAction(action: Extract<FleetPrimaryAction, { kind: 'daemon' }>): boolean {\n let note: string | null = null;\n return runMobileAction({\n title: action.confirm?.title ?? `${action.label} the fleet`,\n consequences: action.confirm?.body ?? '',\n confirmLabel: action.confirm?.confirmLabel ?? action.label,\n destructive: action.destructive,\n confirm: action.confirm !== null,\n run: async () => {\n note = (await getMobileFleetClient().daemon(action.verb)).note;\n },\n onDone: () => {\n refreshFleetReads();\n showMobileToast(note ?? DONE_TEXT[action.verb], 'success');\n },\n });\n}\n","/**\n * routes/verse/mobile/fleet-state.ts — the fleet in one word and one button,\n * for a phone (Home's top card and the Fleet screen's header). Pure.\n *\n * Four words, from three reads the workbench already makes:\n *\n * control GET /api/verse/control daemon, the narrow pause, the kill switch\n * live GET /api/verse/fleet/live the fleet's own state and reason\n * badge GET /api/verse/activity the autonomy switch (off/propose/autonomous)\n *\n * Stopped the kill switch is engaged, or no daemon is running\n * Paused the daemon-scoped pause is set\n * Blocked the daemon runs but nothing may move: no standing grant, the\n * switch is off, the grant is paused (\"Fleet dark\")\n * Running the daemon runs under a grant (building, or idle between tasks)\n *\n * THE ONE BUTTON only ever does what is safe to do from a pocket:\n * Running → Pause (narrow, instant to undo — no confirmation)\n * Paused → Resume (confirmed: work and spend start again)\n * Stopped, no kill switch → Start (confirmed: starts an autonomous agent)\n * Stopped BY the kill switch → no button. Releasing an emergency stop stays\n * on the Mac (`ashlr fleet resume`); the phone can engage one, never undo it.\n * Blocked → \"See why\" (opens Fleet; a grant is signed on the Mac).\n */\nimport type { FleetLiveSnapshotV1 } from '../../../../core/fleet/fleet-types.js';\nimport type { VerseControlSnapshot } from '../../../../core/verse/control-types.js';\nimport type { VerseAutonomyBadge } from '../../../../core/verse/workbench-types.js';\n\nexport type FleetHeadline = 'running' | 'paused' | 'stopped' | 'blocked' | 'unknown';\n\nexport const HEADLINE_LABEL: Readonly<Record<FleetHeadline, string>> = {\n running: 'Running',\n paused: 'Paused',\n stopped: 'Stopped',\n blocked: 'Blocked',\n unknown: 'Unknown',\n};\n\nexport type DaemonVerb = 'start' | 'stop' | 'pause' | 'resume';\n\nexport interface ConfirmText {\n title: string;\n body: string;\n confirmLabel: string;\n}\n\nexport type FleetPrimaryAction =\n | {\n kind: 'daemon';\n verb: DaemonVerb;\n label: string;\n /** Null = runs without a confirmation sheet (Pause). */\n confirm: ConfirmText | null;\n destructive: boolean;\n }\n | { kind: 'open-fleet'; label: string };\n\nexport interface FleetStateView {\n headline: FleetHeadline;\n label: string;\n /** One sentence: why it is in this state, or what it is doing. */\n detail: string;\n /** Runs building right now; null = unknown. */\n building: number | null;\n action: FleetPrimaryAction | null;\n /** The kill switch is engaged (only the Mac can release it). */\n killEngaged: boolean;\n}\n\nexport interface FleetStateInput {\n control: VerseControlSnapshot | null;\n live: FleetLiveSnapshotV1 | null;\n badge: VerseAutonomyBadge | null;\n}\n\nexport const DAEMON_CONFIRM: Readonly<Record<Exclude<DaemonVerb, 'pause'>, ConfirmText>> = {\n start: {\n title: 'Start the fleet?',\n body: 'Starts the autonomous daemon on your Mac. It picks up work in your enrolled repos and spends from your seats under the current budget mode.',\n confirmLabel: 'Start fleet',\n },\n resume: {\n title: 'Resume the fleet?',\n body: 'The daemon starts dispatching again: queued work runs and spends from your seats under the current budget mode.',\n confirmLabel: 'Resume',\n },\n stop: {\n title: 'Stop the fleet?',\n body: 'Stops the daemon by engaging the kill switch. Runs in flight are cut off and the agents’ own write tools refuse too. Only your Mac can release it (`ashlr fleet resume`).',\n confirmLabel: 'Stop fleet',\n },\n};\n\nexport const PAUSE_ACTION: FleetPrimaryAction = { kind: 'daemon', verb: 'pause', label: 'Pause', confirm: null, destructive: false };\nconst RESUME_ACTION: FleetPrimaryAction = { kind: 'daemon', verb: 'resume', label: 'Resume', confirm: DAEMON_CONFIRM.resume, destructive: false };\nconst START_ACTION: FleetPrimaryAction = { kind: 'daemon', verb: 'start', label: 'Start', confirm: DAEMON_CONFIRM.start, destructive: false };\nexport const STOP_ACTION: FleetPrimaryAction = { kind: 'daemon', verb: 'stop', label: 'Stop', confirm: DAEMON_CONFIRM.stop, destructive: true };\n\nfunction plural(n: number, one: string, many: string): string {\n return `${n} ${n === 1 ? one : many}`;\n}\n\nexport function fleetStateView({ control, live, badge }: FleetStateInput): FleetStateView {\n const building = live?.summary.building ?? null;\n const killEngaged = control?.killSwitch.state === 'active' || badge?.stopped === true;\n\n if (killEngaged) {\n return {\n headline: 'stopped',\n label: HEADLINE_LABEL.stopped,\n detail: control?.killSwitch.reason || 'The kill switch is engaged. Release it on your Mac with `ashlr fleet resume`.',\n building,\n action: { kind: 'open-fleet', label: 'Details' },\n killEngaged: true,\n };\n }\n if (control?.pause.state === 'paused' || live?.state === 'paused') {\n return {\n headline: 'paused',\n label: HEADLINE_LABEL.paused,\n detail: control?.pause.reason || live?.stateReason || 'Dispatch is paused. Nothing new starts until you resume.',\n building,\n action: RESUME_ACTION,\n killEngaged: false,\n };\n }\n if (control?.daemon.running === false || live?.state === 'stopped') {\n return {\n headline: 'stopped',\n label: HEADLINE_LABEL.stopped,\n detail: live?.stateReason || 'The fleet daemon is not running on your Mac.',\n building,\n action: START_ACTION,\n killEngaged: false,\n };\n }\n if (live?.state === 'dark' || badge?.mode === 'off' || badge?.paused === true) {\n return {\n headline: 'blocked',\n label: HEADLINE_LABEL.blocked,\n detail: live?.stateReason || badge?.label || 'No standing grant is in force, so the fleet cannot land work.',\n building,\n action: { kind: 'open-fleet', label: 'See why' },\n killEngaged: false,\n };\n }\n if (live?.state === 'running' || live?.state === 'idle' || control?.daemon.running === true) {\n const detail = building && building > 0\n ? `${plural(building, 'run', 'runs')} building${live?.summary.queued ? ` · ${live.summary.queued} queued` : ''}`\n : live?.stateReason || 'Idle between tasks.';\n return { headline: 'running', label: HEADLINE_LABEL.running, detail, building, action: PAUSE_ACTION, killEngaged: false };\n }\n return {\n headline: 'unknown',\n label: HEADLINE_LABEL.unknown,\n detail: 'Your Mac has not reported the fleet yet.',\n building,\n action: null,\n killEngaged: false,\n };\n}\n\n/** Whether the Fleet screen may offer Stop: never twice, never when nothing runs. */\nexport function canStop(view: FleetStateView): boolean {\n return !view.killEngaged && (view.headline === 'running' || view.headline === 'paused' || view.headline === 'blocked');\n}\n"],"file":"fleet-state-yM0mV9_P.js"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{s as t}from"./index-_izD07R9.js";var n=e(t(),1),r=[`a[href]`,`button:not([disabled])`,`input:not([disabled])`,`select:not([disabled])`,`textarea:not([disabled])`,`[tabindex]:not([tabindex="-1"])`].join(`,`);function i(e){return Array.from(e.querySelectorAll(r)).filter(e=>e.offsetParent!==null)}function a({open:e,containerRef:t,onClose:r,initialFocusRef:a}){(0,n.useEffect)(()=>{if(!e)return;let n=document.activeElement;return(a?.current??t.current)?.focus({preventScroll:!0}),()=>{n?.focus?.({preventScroll:!0})}},[e]),(0,n.useEffect)(()=>{if(!e)return;function n(e){if(e.key===`Escape`){e.stopPropagation(),r();return}if(e.key!==`Tab`)return;let n=t.current;if(!n)return;let a=i(n);if(a.length===0)return;let o=a[0],s=a[a.length-1];e.shiftKey&&document.activeElement===o?(e.preventDefault(),s.focus()):!e.shiftKey&&document.activeElement===s&&(e.preventDefault(),o.focus())}return document.addEventListener(`keydown`,n,!0),()=>document.removeEventListener(`keydown`,n,!0)},[e,r])}export{a as t};
|
|
2
|
+
//# sourceMappingURL=focus-trap-C2rynI8q.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"focus-trap-C2rynI8q.js","names":[],"sources":["../../../../../../src/web-ui/components/primitives/focus-trap.ts"],"sourcesContent":["/**\n * components/primitives/focus-trap.ts — the modal focus contract, extracted\n * from Dialog.tsx so Sheet.tsx (the slide-over overlay) gets exactly the same\n * behavior instead of a second, subtly different implementation:\n *\n * - focus moves into the overlay (or `initialFocusRef`) on open\n * - focus is trapped inside while open (Tab/Shift+Tab wrap)\n * - focus returns to the element that opened it on close\n * - Escape closes\n *\n * Dialog.tsx is unchanged in behavior — it now calls this instead of\n * inlining it. Any future overlay MUST use this rather than hand-rolling a\n * trap (DESIGN.md §3, \"primitives own their accessibility\").\n */\nimport { useEffect, type RefObject } from 'react';\n\nexport const FOCUSABLE_SELECTOR = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([tabindex=\"-1\"])',\n].join(',');\n\n/** Focusable descendants that are actually rendered (offsetParent is null for hidden nodes). */\nexport function focusableWithin(node: HTMLElement): HTMLElement[] {\n return Array.from(node.querySelectorAll<HTMLElement>(FOCUSABLE_SELECTOR)).filter((el) => el.offsetParent !== null);\n}\n\nexport interface FocusTrapOptions {\n open: boolean;\n containerRef: RefObject<HTMLElement | null>;\n onClose: () => void;\n initialFocusRef?: RefObject<HTMLElement | null>;\n}\n\nexport function useFocusTrap({ open, containerRef, onClose, initialFocusRef }: FocusTrapOptions): void {\n useEffect(() => {\n if (!open) return;\n const previouslyFocused = document.activeElement as HTMLElement | null;\n const target = initialFocusRef?.current ?? containerRef.current;\n target?.focus({ preventScroll: true });\n\n return () => {\n previouslyFocused?.focus?.({ preventScroll: true });\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- the refs are refs (stable identity is not the point); only `open` should re-run this.\n }, [open]);\n\n useEffect(() => {\n if (!open) return;\n function onKeyDown(e: KeyboardEvent) {\n if (e.key === 'Escape') {\n e.stopPropagation();\n onClose();\n return;\n }\n if (e.key !== 'Tab') return;\n const node = containerRef.current;\n if (!node) return;\n const focusable = focusableWithin(node);\n if (focusable.length === 0) return;\n const first = focusable[0]!;\n const last = focusable[focusable.length - 1]!;\n if (e.shiftKey && document.activeElement === first) {\n e.preventDefault();\n last.focus();\n } else if (!e.shiftKey && document.activeElement === last) {\n e.preventDefault();\n first.focus();\n }\n }\n document.addEventListener('keydown', onKeyDown, true);\n return () => document.removeEventListener('keydown', onKeyDown, true);\n // eslint-disable-next-line react-hooks/exhaustive-deps -- containerRef is a ref; re-binding on every render would drop in-flight key handling.\n }, [open, onClose]);\n}\n"],"mappings":"0GAgBa,EAAqB,CAChC,UACA,yBACA,wBACA,yBACA,2BACA,iCACF,CAAC,CAAC,KAAK,GAAG,EAGV,SAAgB,EAAgB,EAAkC,CAChE,OAAO,MAAM,KAAK,EAAK,iBAA8B,CAAkB,CAAC,CAAC,CAAC,OAAQ,GAAO,EAAG,eAAiB,IAAI,CACnH,CASA,SAAgB,EAAa,CAAE,OAAM,eAAc,UAAS,mBAA2C,EACrG,EAAA,EAAA,UAAA,KAAgB,CACd,GAAI,CAAC,EAAM,OACX,IAAM,EAAoB,SAAS,cAInC,OAHe,GAAiB,SAAW,EAAa,QAAA,EAChD,MAAM,CAAE,cAAe,EAAK,CAAC,MAExB,CACX,GAAmB,QAAQ,CAAE,cAAe,EAAK,CAAC,CACpD,CAEF,EAAG,CAAC,CAAI,CAAC,GAET,EAAA,EAAA,UAAA,KAAgB,CACd,GAAI,CAAC,EAAM,OACX,SAAS,EAAU,EAAkB,CACnC,GAAI,EAAE,MAAQ,SAAU,CACtB,EAAE,gBAAgB,EAClB,EAAQ,EACR,MACF,CACA,GAAI,EAAE,MAAQ,MAAO,OACrB,IAAM,EAAO,EAAa,QAC1B,GAAI,CAAC,EAAM,OACX,IAAM,EAAY,EAAgB,CAAI,EACtC,GAAI,EAAU,SAAW,EAAG,OAC5B,IAAM,EAAQ,EAAU,GAClB,EAAO,EAAU,EAAU,OAAS,GACtC,EAAE,UAAY,SAAS,gBAAkB,GAC3C,EAAE,eAAe,EACjB,EAAK,MAAM,GACF,CAAC,EAAE,UAAY,SAAS,gBAAkB,IACnD,EAAE,eAAe,EACjB,EAAM,MAAM,EAEhB,CAEA,OADA,SAAS,iBAAiB,UAAW,EAAW,EAAI,MACvC,SAAS,oBAAoB,UAAW,EAAW,EAAI,CAEtE,EAAG,CAAC,EAAM,CAAO,CAAC,CACpB"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{i as e,n as t}from"./format-D7nBg2bn.js";import{t as n}from"./percent-text-CSk89zQF.js";import{b as r,p as i}from"./verse-model-DAOz9LrY.js";import{t as a}from"./seat-readiness-a5B9iqP-.js";function o(t){return typeof t!=`number`||!Number.isFinite(t)?`—`:t>0&&t<.01?`<1%`:e(t)}function s(e){return n(e)}var c=/\b\d{4}-\d{2}-\d{2}T\d{2}:\d{2}(?::\d{2}(?:\.\d{1,9})?)?(?:Z|[+-]\d{2}:?\d{2})?(?![\w:])/g,l=String.raw`[\p{L}\p{N}%…)\]"'’”\x60]`,u=RegExp(`(${l})\\.{1,2}\\s*;`,`gu`),d=RegExp(`(${l})\\.\\.(?=\\s|$)`,`gu`);function f(e,t=Date.now()){return e.replace(c,e=>a(e,t)??e).replace(u,`$1;`).replace(d,`$1.`)}function p(e){let t=e.trim();return t.endsWith(`...`)||t.endsWith(`…`)?t:t.replace(/\.+$/,``)}function m(e){let t=e.trim().replace(/[\s;,:]+$/,``);return t?/[.!?…]$/.test(t)?t:`${t}.`:``}function h(e){return i(e)?r(e):e}function g(e){return typeof e!=`number`||!Number.isFinite(e)?`—`:`$${e.toFixed(2)}`}function _(e){return typeof e!=`number`||!Number.isFinite(e)?`—`:String(e)}function v(e){let t=Math.max(0,Math.round(e/1e3));if(t<60)return`${t}s`;let n=Math.floor(t/60),r=t%60;return n<60?`${n}m ${String(r).padStart(2,`0`)}s`:`${Math.floor(n/60)}h ${String(n%60).padStart(2,`0`)}m`}function y(e){if(!e)return`—`;let t=Date.parse(e);if(Number.isNaN(t))return`—`;let n=Math.max(0,Math.round((Date.now()-t)/1e3));if(n<60)return`${n}s`;let r=Math.round(n/60);if(r<60)return`${r}m`;let i=Math.round(r/60);return i<24?`${i}h`:`${Math.round(i/24)}d`}function b(e){let t=y(e);return t===`—`?`—`:`${t} ago`}function x(e=new Date){return`${e.getFullYear()}-${String(e.getMonth()+1).padStart(2,`0`)}-${String(e.getDate()).padStart(2,`0`)}`}function S(e,t=new Date){return e===x(t)||e===t.toISOString().slice(0,10)}function C(e,t=new Date){if(!e)return`—`;let n=Date.parse(e);if(Number.isNaN(n))return`—`;let r=new Date(n),i=r.toLocaleTimeString(void 0,{hour:`2-digit`,minute:`2-digit`,second:`2-digit`});return x(r)===x(t)?i:`${r.toLocaleDateString(void 0,{month:`short`,day:`numeric`})} ${i}`}function w(e){return typeof e!=`number`||!Number.isFinite(e)||e<=0?`—`:`every ${v(e).replace(/ 00[ms]$/,``)}`}var T=70;function E(e,n,r,i=new Date){let a=typeof e==`number`&&Number.isFinite(e)?Math.max(0,e):null,o=typeof n==`number`&&Number.isFinite(n)?n:null,c=typeof r==`string`&&!S(r,i);if(o===0)return{state:`stopped`,percent:100,label:`${g(a)} spent today · budget $0.00`,note:`Daily budget is $0 — the loop is stopped.`};if(c)return{state:`unknown`,percent:null,label:`— spent today · budget ${g(o)}`,note:`Nothing has been recorded today — the last ledger day is ${t(r)}.`};if(o===null||a===null)return{state:`unknown`,percent:null,label:o===null?`${g(a)} spent today · budget —`:`— spent today · budget ${g(o)}`,note:o===null?`Daily budget is not configured.`:`Today's spend is not observable right now.`};let l=a/o*100,u=Math.min(100,Math.round(l)),d=l>=100?`over`:l>=T?`warn`:`ok`;return{state:d,percent:u,label:`${g(a)} of ${g(o)} today · ${s(a/o*100)}`,note:d===`over`?`Daily budget reached — the loop idles until the date rolls over.`:d===`warn`?`${g(o-a)} left before the loop idles today.`:`${g(o-a)} left today.`}}function D(e,t){if(!e)return null;let n=Date.parse(e);return Number.isNaN(n)||typeof t!=`number`||!Number.isFinite(t)||t<=0?null:n+t}function O(e,t){if(e===null)return`—`;let n=e-t;return n>1e3?`in ${v(n)}`:n>-1e3?`due now`:`overdue by ${v(-n)}`}function k(e){if(!e)return{label:`no tick recorded`,tone:`unknown`};switch(e){case`ok`:return{label:`ok`,tone:`success`};case`kill-switch`:return{label:`refused — emergency stop engaged`,tone:`danger`};case`budget-exhausted`:return{label:`stopped — daily budget spent`,tone:`warning`};case`no-enrolled-repos`:return{label:`nothing to do — no repos enrolled`,tone:`warning`};case`no-backlog`:return{label:`nothing to do — backlog empty`,tone:`neutral`};case`dry-run`:return{label:`dry run`,tone:`neutral`};default:return{label:e,tone:`neutral`}}}export{s as _,k as a,v as c,C as d,g as f,D as g,x as h,O as i,w as l,S as m,m as n,y as o,o as p,E as r,_ as s,p as t,b as u,h as v,f as y};
|
|
2
|
+
//# sourceMappingURL=format-V6IiIMAL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-V6IiIMAL.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/autonomy/format.ts"],"sourcesContent":["/**\n * routes/verse/autonomy/format.ts — the small pure functions the cockpit's\n * numerals go through. Kept framework-free so they unit-test without a DOM,\n * and kept in ONE place so \"unknown\" never renders as 0 in one panel and as\n * an em-dash in the next.\n *\n * The rule every function here obeys: absent is not zero. A null spend is\n * \"—\", a null budget is \"not configured\", and a budget of exactly 0 is\n * \"stopped\" — which is the single most misread number in the whole product.\n */\nimport { describeResetAt } from '../../../../core/verse/seat-readiness.js';\nimport { formatDayLabel, formatPercent } from '../../../components/charts/format.js';\nimport { isAbsolutePath, projectName } from '../verse-model.js';\nimport { usedPercentText } from '../percent-text.js';\n\n/** What we render when a value genuinely is not known. */\nexport const UNKNOWN = '—';\n\n/**\n * A share as a whole percentage — \"18%\" — except a non-zero share under one\n * percent, which reads \"<1%\". One precision per panel: \"0%\" for a sliver of\n * real spend or progress would state that nothing happened.\n */\nexport function formatWholePercent(fraction: number | null | undefined): string {\n if (typeof fraction !== 'number' || !Number.isFinite(fraction)) return UNKNOWN;\n if (fraction > 0 && fraction < 0.01) return '<1%';\n return formatPercent(fraction);\n}\n\n/**\n * THE ONE PERCENT RULE — a measured share of a window (or of anything capped\n * at 100), printed the same way on every panel: a whole percent, except that a\n * real reading under 1% is \"<1%\" (never \"0%\", which would read as \"untouched\")\n * and one just short of 100 is \"99%\" (never a rounded \"100%\", which would read\n * as \"spent\"). `used` is 0–100 and is clamped; not a number is \"—\".\n *\n * Every place that prints a used percent goes through this — a bar reading\n * \"99%\" beside a summary reading \"100% of 5-hour window used\" is one seat\n * described two ways. Bar WIDTHS stay numeric; only the words use this.\n */\nexport function percentText(used: number): string {\n return usedPercentText(used);\n}\n\n/** An ISO-8601 instant (a date WITH a time) anywhere inside a sentence. */\nconst ISO_INSTANT_IN_TEXT = /\\b\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(?::\\d{2}(?:\\.\\d{1,9})?)?(?:Z|[+-]\\d{2}:?\\d{2})?(?![\\w:])/g;\n\n/**\n * What may end a sentence right before its full stop: a letter, a digit, a\n * percent sign, an ellipsis, or a closing quote / bracket / backtick. NOT a\n * dot, a slash or a space — so a path segment (`../x`, `cd ..;`) never looks\n * like doubled punctuation.\n */\nconst SENTENCE_END = String.raw`[\\p{L}\\p{N}%…)\\]\"'’”\\x60]`;\n/** \"failed.; next\" / \"failed..; next\" → \"failed; next\". */\nconst STOP_BEFORE_SEMICOLON = new RegExp(`(${SENTENCE_END})\\\\.{1,2}\\\\s*;`, 'gu');\n/**\n * \"failed.. Next\" / \"exhausted..\" → one stop. The pair must be FOLLOWED by\n * whitespace or the end, so a git range (`a1b2c3d..e4f5a6b`, `HEAD~1..HEAD`)\n * and a traversal (`x/../y`) pass through untouched; a third dot (`...`) is\n * an ellipsis, not a doubled stop.\n */\nconst DOUBLED_STOP = new RegExp(`(${SENTENCE_END})\\\\.\\\\.(?=\\\\s|$)`, 'gu');\n\n/**\n * Server prose made fit to print: every ISO instant becomes the viewer's\n * local time (\"today 11:46 PM\", \"Fri 11:46 PM\", \"Sep 26, 11:46 PM\" — the\n * wording `describeResetAt` gives resets everywhere else), and the \".;\" / \"..\"\n * that a sentence joined onto another sentence leaves behind is collapsed.\n *\n * For text the server wrote for a person (`ApiError.detail`, action notes,\n * audit summaries, fleet notes): it is shown verbatim otherwise. That matters\n * on the trust surfaces this runs on (approval summaries, the audit trail):\n * a `../../.ssh/authorized_keys` rewritten to `././.ssh/…` would hide the very\n * traversal the operator is deciding about, so only sentence punctuation is\n * ever touched.\n */\nexport function tidyProse(text: string, now: number = Date.now()): string {\n return text\n .replace(ISO_INSTANT_IN_TEXT, (iso) => describeResetAt(iso, now) ?? iso)\n .replace(STOP_BEFORE_SEMICOLON, '$1;')\n .replace(DOUBLED_STOP, '$1.');\n}\n\n/**\n * A sentence ready to be embedded in another one: trimmed, with its own\n * closing period dropped so \"… unavailable: quota exhausted.\" does not become\n * \"quota exhausted..\". An ellipsis is kept — it is not a full stop.\n */\nexport function asClause(text: string): string {\n const trimmed = text.trim();\n if (trimmed.endsWith('...') || trimmed.endsWith('…')) return trimmed;\n return trimmed.replace(/\\.+$/, '');\n}\n\n/**\n * One sentence: trimmed and closed by exactly one full stop — added only when\n * the text does not already end in `.`, `!`, `?` or `…` (a trailing \";\", \",\"\n * or \":\" is dropped first). The fix for \"local Qwen offline..\" when a server\n * reason already carries its own stop. Never re-cased — a sentence may open on\n * a seat id.\n */\nexport function asSentence(text: string): string {\n const t = text.trim().replace(/[\\s;,:]+$/, '');\n if (!t) return '';\n return /[.!?…]$/.test(t) ? t : `${t}.`;\n}\n\n/**\n * What a repo cell shows: the folder's own name for an absolute checkout path\n * (the full path belongs in the cell's `title`), and a `owner/name` slug or a\n * bare name as it came — cutting a slug to its last segment would drop the\n * owner, which is half of what identifies it.\n */\nexport function repoDisplayName(repo: string): string {\n return isAbsolutePath(repo) ? projectName(repo) : repo;\n}\n\nexport function formatUsd(value: number | null | undefined): string {\n if (typeof value !== 'number' || !Number.isFinite(value)) return UNKNOWN;\n return `$${value.toFixed(2)}`;\n}\n\nexport function formatCount(value: number | null | undefined): string {\n if (typeof value !== 'number' || !Number.isFinite(value)) return UNKNOWN;\n return String(value);\n}\n\n/** \"4m 12s\" / \"1h 06m\" / \"12s\" — for durations and countdowns alike. */\nexport function formatDuration(ms: number): string {\n const total = Math.max(0, Math.round(ms / 1000));\n if (total < 60) return `${total}s`;\n const minutes = Math.floor(total / 60);\n const seconds = total % 60;\n if (minutes < 60) return `${minutes}m ${String(seconds).padStart(2, '0')}s`;\n const hours = Math.floor(minutes / 60);\n return `${hours}h ${String(minutes % 60).padStart(2, '0')}m`;\n}\n\n/** Compact age for dense table cells: \"42s\", \"7m\", \"3h\", \"5d\". */\nexport function formatAge(iso: string | null | undefined): string {\n if (!iso) return UNKNOWN;\n const ms = Date.parse(iso);\n if (Number.isNaN(ms)) return UNKNOWN;\n const seconds = Math.max(0, Math.round((Date.now() - ms) / 1000));\n if (seconds < 60) return `${seconds}s`;\n const minutes = Math.round(seconds / 60);\n if (minutes < 60) return `${minutes}m`;\n const hours = Math.round(minutes / 60);\n if (hours < 24) return `${hours}h`;\n return `${Math.round(hours / 24)}d`;\n}\n\nexport function formatRelative(iso: string | null | undefined): string {\n const age = formatAge(iso);\n return age === UNKNOWN ? UNKNOWN : `${age} ago`;\n}\n\n/** Local wall-clock time, for the audit table's second column. */\nexport function formatClock(iso: string | null | undefined): string {\n if (!iso) return UNKNOWN;\n const ms = Date.parse(iso);\n if (Number.isNaN(ms)) return UNKNOWN;\n return new Date(ms).toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit', second: '2-digit' });\n}\n\n/** The viewer's local calendar day as `YYYY-MM-DD` — NOT the UTC slice. */\nexport function localDateKey(at: Date = new Date()): string {\n const y = at.getFullYear();\n const m = String(at.getMonth() + 1).padStart(2, '0');\n const d = String(at.getDate()).padStart(2, '0');\n return `${y}-${m}-${d}`;\n}\n\n/**\n * Is `todayDate` still the current ledger day?\n *\n * The daemon stamps it in UTC (`resetDayIfNeeded` in core/daemon/state.ts is\n * `new Date().toISOString().slice(0, 10)`) but the operator reads the screen\n * in local time, and the two disagree for part of every day at any offset but\n * zero. Comparing against the local day alone would announce \"nothing has been\n * recorded today\" every evening west of UTC — a false alarm on the meter whose\n * whole purpose is to be trustworthy.\n *\n * So either spelling counts as current. That is deliberately conservative: it\n * can call a day current for a few hours after the UTC rollover, and it will\n * never call a genuinely current day stale. The case this exists for is a\n * ledger day weeks old, which neither spelling matches.\n */\nexport function isCurrentLedgerDay(todayDate: string, now: Date = new Date()): boolean {\n return todayDate === localDateKey(now) || todayDate === now.toISOString().slice(0, 10);\n}\n\n/**\n * Time-of-day for a row from today; date + time for anything older.\n *\n * `formatClock` alone is only honest inside a single-day window, and the\n * tables that use it are not one: the audit trail defaults to 200 rows and\n * offers 500, which on a real machine spans days. Two rows reading \"03:12:44\"\n * could be last night and last week, and the only date was in a hover title\n * that a touch viewport never fires.\n */\nexport function formatStamp(iso: string | null | undefined, now: Date = new Date()): string {\n if (!iso) return UNKNOWN;\n const ms = Date.parse(iso);\n if (Number.isNaN(ms)) return UNKNOWN;\n const at = new Date(ms);\n const clock = at.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit', second: '2-digit' });\n if (localDateKey(at) === localDateKey(now)) return clock;\n const day = at.toLocaleDateString(undefined, { month: 'short', day: 'numeric' });\n return `${day} ${clock}`;\n}\n\n/** Human tick interval, e.g. \"every 15m\". */\nexport function formatInterval(intervalMs: number | null | undefined): string {\n if (typeof intervalMs !== 'number' || !Number.isFinite(intervalMs) || intervalMs <= 0) return UNKNOWN;\n // A configured interval is a round number far more often than not; \"every\n // 15m\" reads better than \"every 15m 00s\" and loses nothing when it isn't.\n return `every ${formatDuration(intervalMs).replace(/ 00[ms]$/, '')}`;\n}\n\nexport type BudgetState = 'stopped' | 'unknown' | 'ok' | 'warn' | 'over';\n\nexport interface BudgetMeter {\n state: BudgetState;\n /** 0-100, clamped. Null when there is nothing honest to draw. */\n percent: number | null;\n /** One line: \"$4.50 of $25.00 today · 18%\". */\n label: string;\n /** The plain-language verdict shown next to the meter. */\n note: string;\n}\n\nconst BUDGET_WARN_PERCENT = 70;\n\n/**\n * Today's spend against the configured daily cap, as ONE line.\n *\n * A cap of exactly 0 is the contract's guard rail: it means the loop is\n * stopped, and it must never render as an empty (i.e. \"plenty left\") meter.\n *\n * `todayDate` is the ledger day `spend.todayUsd` was counted for. It is NOT\n * optional decoration: the daemon writes the figure once per day and leaves it\n * there, so a machine that last ticked three weeks ago answers\n * `{todayUsd: 0, todayDate: \"2026-09-01\"}`. Rendering that as \"$0.00 of $50.00\n * today\" is a fabricated statement about today on the one number an operator\n * checks before walking away from an autonomous loop. Pass `null` only when\n * the source genuinely has no date to offer (the legacy daemon observation).\n */\nexport function budgetMeter(\n spentUsd: number | null | undefined,\n capUsd: number | null | undefined,\n todayDate?: string | null,\n now: Date = new Date(),\n): BudgetMeter {\n const spend = typeof spentUsd === 'number' && Number.isFinite(spentUsd) ? Math.max(0, spentUsd) : null;\n const cap = typeof capUsd === 'number' && Number.isFinite(capUsd) ? capUsd : null;\n // A cap of 0 is a statement about configuration, not about the ledger, so\n // it still reads true on a stale day and is checked first.\n const stale = typeof todayDate === 'string' && !isCurrentLedgerDay(todayDate, now);\n\n if (cap === 0) {\n return {\n state: 'stopped',\n percent: 100,\n label: `${formatUsd(spend)} spent today · budget $0.00`,\n note: 'Daily budget is $0 — the loop is stopped.',\n };\n }\n if (stale) {\n return {\n state: 'unknown',\n percent: null,\n label: `${UNKNOWN} spent today · budget ${formatUsd(cap)}`,\n // \"Sep 1\", not \"2026-09-01\": the ledger day is a calendar date, so it is\n // read as one (formatDayLabel parses it in UTC and cannot shift a day).\n note: `Nothing has been recorded today — the last ledger day is ${formatDayLabel(todayDate)}.`,\n };\n }\n if (cap === null || spend === null) {\n return {\n state: 'unknown',\n percent: null,\n label: cap === null ? `${formatUsd(spend)} spent today · budget ${UNKNOWN}` : `${UNKNOWN} spent today · budget ${formatUsd(cap)}`,\n note: cap === null ? 'Daily budget is not configured.' : \"Today's spend is not observable right now.\",\n };\n }\n\n const raw = (spend / cap) * 100;\n const percent = Math.min(100, Math.round(raw));\n const state: BudgetState = raw >= 100 ? 'over' : raw >= BUDGET_WARN_PERCENT ? 'warn' : 'ok';\n return {\n state,\n percent,\n // The text follows the one percent rule (\"<1%\", \"99%\" short of the cap); `percent` (the bar) stays numeric.\n label: `${formatUsd(spend)} of ${formatUsd(cap)} today · ${percentText((spend / cap) * 100)}`,\n note:\n state === 'over'\n ? 'Daily budget reached — the loop idles until the date rolls over.'\n : state === 'warn'\n ? `${formatUsd(cap - spend)} left before the loop idles today.`\n : `${formatUsd(cap - spend)} left today.`,\n };\n}\n\n/** Epoch ms of the next expected tick, or null when it cannot be derived. */\nexport function nextTickAt(lastTickAt: string | null | undefined, intervalMs: number | null | undefined): number | null {\n if (!lastTickAt) return null;\n const last = Date.parse(lastTickAt);\n if (Number.isNaN(last)) return null;\n if (typeof intervalMs !== 'number' || !Number.isFinite(intervalMs) || intervalMs <= 0) return null;\n return last + intervalMs;\n}\n\n/** \"in 4m 12s\" / \"due now\" / \"overdue by 2m 03s\". */\nexport function countdownLabel(nextAt: number | null, now: number): string {\n if (nextAt === null) return UNKNOWN;\n const delta = nextAt - now;\n if (delta > 1000) return `in ${formatDuration(delta)}`;\n if (delta > -1000) return 'due now';\n return `overdue by ${formatDuration(-delta)}`;\n}\n\n/** Last tick outcome, phrased the way a person would say it out loud. */\nexport function describeTickOutcome(reason: string | null | undefined): { label: string; tone: 'success' | 'warning' | 'danger' | 'neutral' | 'unknown' } {\n if (!reason) return { label: 'no tick recorded', tone: 'unknown' };\n switch (reason) {\n case 'ok':\n return { label: 'ok', tone: 'success' };\n case 'kill-switch':\n return { label: 'refused — emergency stop engaged', tone: 'danger' };\n case 'budget-exhausted':\n return { label: 'stopped — daily budget spent', tone: 'warning' };\n case 'no-enrolled-repos':\n return { label: 'nothing to do — no repos enrolled', tone: 'warning' };\n case 'no-backlog':\n return { label: 'nothing to do — backlog empty', tone: 'neutral' };\n case 'dry-run':\n return { label: 'dry run', tone: 'neutral' };\n default:\n return { label: reason, tone: 'neutral' };\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{C as e,M as t,O as n,a as r,t as i,w as a}from"./global-CYfRwH6t.js";import{r as o}from"./VerseShared-CFE5B-IY.js";var s=`/api/verse/git`,c=new Set([`VERSE_GIT_NOT_A_REPO`,`VERSE_GIT_REFUSED`]);async function l(e,t){let r=await fetch(e,{method:`GET`,credentials:`same-origin`,headers:{"x-ashlr-read-client":a()},signal:t});if(r.status===401)throw n(),new i(`Read session expired.`,401,e);if(!r.ok){let t=null,n=null;try{let e=await r.json();t=typeof e.error==`string`&&e.error?e.error:null,n=typeof e.code==`string`&&e.code?e.code:null}catch{}throw new i(`GET ${e} failed (HTTP ${r.status}).`,r.status,e,t,n)}return await r.json()}function u(e,t){return l(`${s}/status?root=${encodeURIComponent(e)}`,t)}function d(e,t,n,r){let i=new URLSearchParams({root:e,scope:t});return n!==null&&i.set(`file`,n),l(`${s}/diff?${i.toString()}`,r)}async function f(n,i){let a=e();if(!a)throw new o;let s=await r(n,i,a);return t(),s}function p(e){return f(`${s}/commit`,e)}function m(e){return f(`${s}/push`,{root:e})}function h(e){return f(`${s}/pr`,e)}function g(e){return f(`${s}/pr/merge`,e)}function _(e,t){return f(`${s}/worktree`,{root:e,name:t})}function v(e){return e instanceof i&&e.code!==null&&c.has(e.code)}var y=new Intl.NumberFormat(`en-US`);function b(e){return y.format(Math.max(0,Math.round(e)))}function x(e,t){return`+${b(e)} −${b(t)}`}function S(e,t,n){return`${b(e)} ${e===1?`file`:`files`} changed, ${b(t)} added, ${b(n)} removed`}function C(e){return!!(e.dirty>0||e.ahead>0||e.diffstat.files>0||e.pr&&(e.pr.state===`open`||e.pr.state===`draft`))}function w(e){let t=new Set,n=[];for(let r of e){let e=r.gitRoot??r.root;t.has(e)||(t.add(e),n.push(r))}return n}function T(e){let t=e.branch??`HEAD`,n=e.base??`the default branch`;switch(e.suggested){case`commit`:return{action:`commit`,label:`Commit`,disclosure:`Commit ${b(e.dirty)} changed ${e.dirty===1?`file`:`files`} on ${t}.`};case`push`:return{action:`push`,label:`Push`,disclosure:e.upstream?`Push ${b(e.ahead)} ${e.ahead===1?`commit`:`commits`} on ${t} to ${e.upstream}.`:`Publish ${t} to origin.`};case`create-pr`:return{action:`create-pr`,label:`Create PR`,disclosure:`Open a pull request from ${t} into ${n}${e.upstream===null||e.ahead>0?`, pushing it first`:``}.`};case`merge`:return e.pr?{action:`merge`,label:`Merge`,disclosure:`Squash-merge #${e.pr.number} into ${e.pr.baseRef||n}. Checks passed.`}:null;case`view-pr`:return e.pr?{action:`view-pr`,label:`View PR`,disclosure:`Open #${e.pr.number} on GitHub.`}:null;default:return null}}function E(e){let t=e.branch===null,n=e.branch!==null&&e.base!==null&&e.branch===e.base,r=(e.conflicts??0)>0,i=e.pr!==null&&(e.pr.state===`open`||e.pr.state===`draft`);return[{id:`draft-pr`,label:`Create draft PR…`,disabledReason:t?`HEAD is detached`:n?`You are on ${e.base}`:i?`#${e.pr.number} is already open`:e.prLookup===`unavailable`?"GitHub is not reachable (is `gh` signed in?)":null},{id:`commit`,label:`Commit…`,disabledReason:t?`HEAD is detached`:r?`Resolve the conflicts first`:e.dirty===0?`Nothing to commit`:null},{id:`push`,label:e.upstream?`Push`:`Publish branch`,disabledReason:t?`HEAD is detached`:e.upstream!==null&&e.ahead===0?`Already pushed`:e.headSha===null?`No commits yet`:null},{id:`open-github`,label:`Open on GitHub`,disabledReason:e.pr?null:`No pull request for this branch`},{id:`copy-branch`,label:`Copy branch name`,disabledReason:t?`HEAD is detached`:null},{id:`review`,label:`Review changes`,disabledReason:e.diffstat.files===0&&e.dirty===0?`No changes`:null}]}function D(e,t){let n=e.state===`open`?`Open`:e.state===`draft`?`Draft`:e.state===`merged`?`Merged`:`Closed`,r=null,i=`neutral`;if(e.state===`merged`)i=`merged`;else if(e.state===`closed`)i=`neutral`;else{switch(e.checks){case`passing`:r=t&&t.total>0?`${t.passed}/${t.total} checks passed`:`checks passed`,i=e.mergeable===!1?`danger`:`success`;break;case`failing`:r=t?`${t.failed} of ${t.total} checks failing`:`checks failing`,i=`danger`;break;case`pending`:r=t?`${t.pending} of ${t.total} checks running`:`checks running`,i=`running`;break;case`none`:r=`no checks`;break;default:r=`checks —`}e.mergeable===!1&&(r=r?`${r}, conflicts`:`conflicts`)}let a=[`Pull request #${e.number}`,e.title,n,r].filter(Boolean).join(`, `);return{number:`#${e.number}`,title:e.title,state:n,checks:r,tone:i,label:a}}function O(e){let t=e.headSubject?.trim();if(t)return t;let n=((e.branch??``).split(`/`).pop()??``).replace(/[-_]+/g,` `).trim();return n?n[0].toUpperCase()+n.slice(1):``}function k(e){let t=e.pr;return t?{number:t.number,title:t.title,headSha:t.headSha,headRef:t.headRef||e.branch||``,baseRef:t.baseRef||e.base||``,checks:t.checks,mergeable:t.mergeable,counts:e.prCheckCounts??null}:null}function A(e){let t=e.headSha?e.headSha.slice(0,7):`—`,n=e.counts,r;switch(e.checks){case`passing`:r=n&&n.total>0?`${n.passed}/${n.total} checks passed`:`checks passed`;break;case`failing`:r=n&&n.total>0?`${n.failed} of ${n.total} checks failing`:`checks failing`;break;case`pending`:r=n&&n.total>0?`${n.pending} of ${n.total} checks still running`:`checks still running`;break;case`none`:r=`no checks reported`;break;default:r=`checks not known`}let i=e.mergeable===!0?`no conflicts`:e.mergeable===!1?`has conflicts`:`GitHub has not finished checking for conflicts`,a=`${r}, ${i}.`;return{sha:t,detail:a,text:`Head ${t}, ${a}`,verified:e.checks===`passing`&&e.mergeable===!0&&e.headSha!==null}}function j(e,t){let n=t?.pr??null;return!n||n.number!==e.number||n.state!==`open`?`#${e.number} is no longer an open, ready pull request — close this and check the branch bar.`:n.headSha===e.headSha?n.checks===`passing`?n.mergeable===!0?null:`GitHub no longer reports this head as mergeable — close and reopen to review.`:`Checks on this head are no longer passing — close and reopen once they are.`:`The PR changed since you opened this — new commits landed. Close and reopen to review the new head.`}function M(e){let t=new Map,n=[...e].sort((e,t)=>e.path<t.path?-1:+(e.path>t.path));for(let e of n){let n=e.path.lastIndexOf(`/`),r=n===-1?``:e.path.slice(0,n),i=n===-1?e.path:e.path.slice(n+1),a=t.get(r);a||(a={dir:r,files:[]},t.set(r,a)),a.files.push({...e,name:i})}return[...t.values()]}var N={M:`modified`,A:`added`,D:`deleted`,R:`renamed`,U:`conflicted`};function P(e){return[...e].sort((e,t)=>e.path===t.path?e.line-t.line:e.path<t.path?-1:1).map(e=>{let[t,...n]=e.note.trim().split(`
|
|
2
|
+
`);return[`${`${e.path}:${e.line}${e.side===`old`?` (removed line)`:``}`}: ${t??``}`,...n.map(e=>` ${e}`)].join(`
|
|
3
|
+
`)}).join(`
|
|
4
|
+
`)}function F(e){if(e&&typeof e==`object`){let t=e;if(t.name===`DispatchDisabledError`)return`This server is read-only (started without dispatch), so git actions are off.`;if(t.name===`VerseMutationLockedError`)return`Unlock actions with the mutation token first.`;if(t.status===401)return"The mutation token was rejected. Unlock again with the token `ashlr verse` printed.";if(t.detail)return t.detail;if(t.status===404)return"This server has no git routes yet. Update Ashlr and restart `ashlr verse`.";if(t.status===409)return`Git is busy in this repository. Try again in a moment.`}return`The git action failed. The terminal will show why.`}export{h as C,g as S,p as _,F as a,u as b,b as c,E as d,j as f,T as g,D as h,O as i,M as l,k as m,P as n,S as o,A as p,w as r,x as s,N as t,C as u,_ as v,m as w,v as x,d as y};
|
|
5
|
+
//# sourceMappingURL=git-model-rVA0Jd0g.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-model-rVA0Jd0g.js","names":[],"sources":["../../../../../../src/web-ui/routes/verse/git/git-queries.ts","../../../../../../src/web-ui/routes/verse/git/git-model.ts"],"sourcesContent":["/**\n * routes/verse/git/git-queries.ts — the page's side of `/api/verse/git*`\n * (unit C5; server: core/verse/git-api.ts).\n *\n * Reads are plain fetches, not cache entries: a branch's state is stale the\n * moment a turn commits, and the bar and pane each own their own freshness\n * (poll while visible; re-read after every action).\n *\n * WHY a GET helper of its own instead of data/client.ts `apiGet`: the git\n * routes answer \"not a repository\" (404) and \"not a folder Verse knows\"\n * (409) with a CODE the bar acts on — it drops that root instead of showing\n * an error — and apiGet discards the body of a failed read.\n *\n * Mutations go through the held mutation token exactly like every other\n * Verse write (verse-queries.ts): no token → VerseMutationLockedError, which\n * the caller's token gate turns into the unlock dialog.\n */\nimport { ApiError, apiPost } from '../../../data/client.js';\nimport { getMutationToken, getReadClientProof, reportSessionExpired, touchMutationHold } from '../../../data/auth-store.js';\nimport type {\n VerseGitActionResponse,\n VerseGitCommitRequest,\n VerseGitDiffResponse,\n VerseGitDiffScope,\n VerseGitMergeRequest,\n VerseGitPrRequest,\n VerseGitWorktreeResponse,\n} from '../../../data/api-types.js';\nimport { VerseMutationLockedError } from '../verse-queries.js';\nimport type { GitStatusView } from './git-model.js';\n\nexport const GIT_API = '/api/verse/git';\n\n/** Codes that mean \"this root has no bar\", not \"something broke\". */\nexport const GIT_ROOT_UNAVAILABLE_CODES: ReadonlySet<string> = new Set(['VERSE_GIT_NOT_A_REPO', 'VERSE_GIT_REFUSED']);\n\nasync function gitGet<T>(path: string, signal?: AbortSignal): Promise<T> {\n const res = await fetch(path, {\n method: 'GET',\n credentials: 'same-origin',\n headers: { 'x-ashlr-read-client': getReadClientProof() },\n signal,\n });\n if (res.status === 401) {\n reportSessionExpired();\n throw new ApiError('Read session expired.', 401, path);\n }\n if (!res.ok) {\n let detail: string | null = null;\n let code: string | null = null;\n try {\n const body = (await res.json()) as { error?: unknown; code?: unknown };\n detail = typeof body.error === 'string' && body.error ? body.error : null;\n code = typeof body.code === 'string' && body.code ? body.code : null;\n } catch {\n /* not JSON */\n }\n throw new ApiError(`GET ${path} failed (HTTP ${res.status}).`, res.status, path, detail, code);\n }\n return (await res.json()) as T;\n}\n\nexport function fetchGitStatus(root: string, signal?: AbortSignal): Promise<GitStatusView> {\n return gitGet<GitStatusView>(`${GIT_API}/status?root=${encodeURIComponent(root)}`, signal);\n}\n\nexport interface GitDiffView extends VerseGitDiffResponse {\n /** Size of the whole patch before the 256 KB cut; null when no file was asked. */\n patchBytes?: number | null;\n}\n\nexport function fetchGitDiff(root: string, scope: VerseGitDiffScope, file: string | null, signal?: AbortSignal): Promise<GitDiffView> {\n const params = new URLSearchParams({ root, scope });\n if (file !== null) params.set('file', file);\n return gitGet<GitDiffView>(`${GIT_API}/diff?${params.toString()}`, signal);\n}\n\nasync function post<T>(path: string, body: unknown): Promise<T> {\n const token = getMutationToken();\n if (!token) throw new VerseMutationLockedError();\n const result = await apiPost<T>(path, body, token);\n touchMutationHold();\n return result;\n}\n\nexport function commitGit(req: VerseGitCommitRequest): Promise<VerseGitActionResponse> {\n return post(`${GIT_API}/commit`, req);\n}\n\nexport function pushGit(root: string): Promise<VerseGitActionResponse> {\n return post(`${GIT_API}/push`, { root });\n}\n\nexport function openGitPr(req: VerseGitPrRequest): Promise<VerseGitActionResponse> {\n return post(`${GIT_API}/pr`, req);\n}\n\nexport function mergeGitPr(req: VerseGitMergeRequest): Promise<VerseGitActionResponse> {\n return post(`${GIT_API}/pr/merge`, req);\n}\n\nexport function createGitWorktree(root: string, name: string): Promise<VerseGitWorktreeResponse> {\n return post(`${GIT_API}/worktree`, { root, name });\n}\n\n/** True for a failed read that means \"no bar for this root\" rather than an error to show. */\nexport function isRootUnavailable(err: unknown): boolean {\n return err instanceof ApiError && err.code !== null && GIT_ROOT_UNAVAILABLE_CODES.has(err.code);\n}\n","/**\n * routes/verse/git/git-model.ts — the branch bar's and Review pane's words\n * and decisions, as pure functions (unit C5; SPEC-310C §2, §3).\n *\n * Kept apart from the components so the copy, the suggested-action labels and\n * the menu's disabled reasons are tested as a table, and so the bar's chunk\n * stays small (no React here, no DOM).\n *\n * Copy rules (DESIGN §13.8): operator language with units; \"—\" for a value\n * that was not measured; a state is always a WORD beside any colour or icon.\n */\nimport type {\n VerseGitDiffFile,\n VerseGitPr,\n VerseGitStatus,\n VerseGitSuggestedAction,\n} from '../../../data/api-types.js';\nimport type { VerseGitCheckCounts, VerseGitPrLookup, VerseGitStatusDetail } from '../../../../core/verse/workbench-types.js';\n\n// ---------------------------------------------------------------------------\n// Wire additions the server sends beyond the frozen VerseGitStatus — contract\n// now (workbench-types.ts §7 VerseGitStatusDetail). Optional HERE, so an\n// older server that omits them still renders; the names alias the contract\n// so the two can never drift.\n// ---------------------------------------------------------------------------\n\nexport type GitPrLookup = VerseGitPrLookup;\nexport type GitCheckCounts = VerseGitCheckCounts;\n\nexport interface GitStatusView extends VerseGitStatus, Partial<Omit<VerseGitStatusDetail, keyof VerseGitStatus>> {}\n\n// ---------------------------------------------------------------------------\n// Numbers\n// ---------------------------------------------------------------------------\n\nconst NUMBER = new Intl.NumberFormat('en-US');\n\n/** 35079 → \"35,079\". */\nexport function formatCount(n: number): string {\n return NUMBER.format(Math.max(0, Math.round(n)));\n}\n\n/** \"+35,079 −1,074\" — a real minus sign, grouped digits. */\nexport function diffstatText(additions: number, deletions: number): string {\n return `+${formatCount(additions)} −${formatCount(deletions)}`;\n}\n\n/** The ± counts as a screen reader should hear them. */\nexport function diffstatLabel(files: number, additions: number, deletions: number): string {\n return `${formatCount(files)} ${files === 1 ? 'file' : 'files'} changed, ${formatCount(additions)} added, ${formatCount(deletions)} removed`;\n}\n\n// ---------------------------------------------------------------------------\n// Rows\n// ---------------------------------------------------------------------------\n\n/** A root earns a bar row when there is something to do or to see. */\nexport function hasBranchActivity(s: GitStatusView): boolean {\n if (s.dirty > 0 || s.ahead > 0 || s.diffstat.files > 0) return true;\n if (s.pr && (s.pr.state === 'open' || s.pr.state === 'draft')) return true;\n return false;\n}\n\n/**\n * One row per repository: two chat roots inside the same repo would show the\n * same branch twice. The first root (the chat's priority order) keeps the row.\n */\nexport function dedupeByRepo<T extends GitStatusView>(statuses: readonly T[]): T[] {\n const seen = new Set<string>();\n const out: T[] = [];\n for (const s of statuses) {\n const key = s.gitRoot ?? s.root;\n if (seen.has(key)) continue;\n seen.add(key);\n out.push(s);\n }\n return out;\n}\n\n// ---------------------------------------------------------------------------\n// The primary button\n// ---------------------------------------------------------------------------\n\nexport interface PrimaryAction {\n action: Exclude<VerseGitSuggestedAction, 'none'>;\n label: string;\n /** What the click will do, in one sentence (tooltip + accessible description). */\n disclosure: string;\n}\n\nexport function primaryAction(s: GitStatusView): PrimaryAction | null {\n const branch = s.branch ?? 'HEAD';\n const base = s.base ?? 'the default branch';\n switch (s.suggested) {\n case 'commit':\n return { action: 'commit', label: 'Commit', disclosure: `Commit ${formatCount(s.dirty)} changed ${s.dirty === 1 ? 'file' : 'files'} on ${branch}.` };\n case 'push':\n return {\n action: 'push',\n label: 'Push',\n disclosure: s.upstream\n ? `Push ${formatCount(s.ahead)} ${s.ahead === 1 ? 'commit' : 'commits'} on ${branch} to ${s.upstream}.`\n : `Publish ${branch} to origin.`,\n };\n case 'create-pr':\n return {\n action: 'create-pr',\n label: 'Create PR',\n disclosure: `Open a pull request from ${branch} into ${base}${s.upstream === null || s.ahead > 0 ? ', pushing it first' : ''}.`,\n };\n case 'merge':\n return s.pr\n ? { action: 'merge', label: 'Merge', disclosure: `Squash-merge #${s.pr.number} into ${s.pr.baseRef || base}. Checks passed.` }\n : null;\n case 'view-pr':\n return s.pr ? { action: 'view-pr', label: 'View PR', disclosure: `Open #${s.pr.number} on GitHub.` } : null;\n default:\n return null;\n }\n}\n\n// ---------------------------------------------------------------------------\n// The ▾ menu (every item present; disabled WITH a reason, never hidden)\n// ---------------------------------------------------------------------------\n\nexport type MenuActionId = 'draft-pr' | 'commit' | 'push' | 'open-github' | 'copy-branch' | 'review';\n\nexport interface MenuItem {\n id: MenuActionId;\n label: string;\n disabledReason: string | null;\n}\n\nexport function menuItems(s: GitStatusView): MenuItem[] {\n const detached = s.branch === null;\n const onBase = s.branch !== null && s.base !== null && s.branch === s.base;\n const conflicts = (s.conflicts ?? 0) > 0;\n const openPr = s.pr !== null && (s.pr.state === 'open' || s.pr.state === 'draft');\n const draftReason = detached\n ? 'HEAD is detached'\n : onBase\n ? `You are on ${s.base}`\n : openPr\n ? `#${s.pr!.number} is already open`\n : s.prLookup === 'unavailable'\n ? 'GitHub is not reachable (is `gh` signed in?)'\n : null;\n return [\n { id: 'draft-pr', label: 'Create draft PR…', disabledReason: draftReason },\n {\n id: 'commit',\n label: 'Commit…',\n disabledReason: detached ? 'HEAD is detached' : conflicts ? 'Resolve the conflicts first' : s.dirty === 0 ? 'Nothing to commit' : null,\n },\n {\n id: 'push',\n label: s.upstream ? 'Push' : 'Publish branch',\n disabledReason: detached ? 'HEAD is detached' : s.upstream !== null && s.ahead === 0 ? 'Already pushed' : s.headSha === null ? 'No commits yet' : null,\n },\n { id: 'open-github', label: 'Open on GitHub', disabledReason: s.pr ? null : 'No pull request for this branch' },\n { id: 'copy-branch', label: 'Copy branch name', disabledReason: detached ? 'HEAD is detached' : null },\n { id: 'review', label: 'Review changes', disabledReason: s.diffstat.files === 0 && s.dirty === 0 ? 'No changes' : null },\n ];\n}\n\n// ---------------------------------------------------------------------------\n// PR chip\n// ---------------------------------------------------------------------------\n\nexport type PrTone = 'success' | 'danger' | 'warning' | 'running' | 'neutral' | 'merged';\n\nexport interface PrChipModel {\n /** \"#463\" */\n number: string;\n title: string;\n /** \"Open\", \"Draft\", \"Merged\", \"Closed\". */\n state: string;\n /** \"checks passing\", \"2 of 9 checks failing\", \"checks running\", \"no checks\", null. */\n checks: string | null;\n tone: PrTone;\n /** Everything above in one sentence, for the accessible name. */\n label: string;\n}\n\nexport function prChip(pr: VerseGitPr, counts: GitCheckCounts | null | undefined): PrChipModel {\n const state = pr.state === 'open' ? 'Open' : pr.state === 'draft' ? 'Draft' : pr.state === 'merged' ? 'Merged' : 'Closed';\n let checks: string | null = null;\n let tone: PrTone = 'neutral';\n if (pr.state === 'merged') {\n tone = 'merged';\n } else if (pr.state === 'closed') {\n tone = 'neutral';\n } else {\n switch (pr.checks) {\n case 'passing':\n checks = counts && counts.total > 0 ? `${counts.passed}/${counts.total} checks passed` : 'checks passed';\n tone = pr.mergeable === false ? 'danger' : 'success';\n break;\n case 'failing':\n checks = counts ? `${counts.failed} of ${counts.total} checks failing` : 'checks failing';\n tone = 'danger';\n break;\n case 'pending':\n checks = counts ? `${counts.pending} of ${counts.total} checks running` : 'checks running';\n tone = 'running';\n break;\n case 'none':\n checks = 'no checks';\n break;\n default:\n checks = 'checks —';\n }\n if (pr.mergeable === false) checks = checks ? `${checks}, conflicts` : 'conflicts';\n }\n const label = [`Pull request #${pr.number}`, pr.title, state, checks].filter(Boolean).join(', ');\n return { number: `#${pr.number}`, title: pr.title, state, checks, tone, label };\n}\n\n// ---------------------------------------------------------------------------\n// PR dialog defaults\n// ---------------------------------------------------------------------------\n\n/**\n * A PR title from the branch: the last commit's subject when there is one\n * (it is usually the best one-line summary), else the branch name made\n * readable (`feat/branch-bar` → \"Branch bar\").\n */\nexport function defaultPrTitle(s: GitStatusView): string {\n const subject = s.headSubject?.trim();\n if (subject) return subject;\n const leaf = (s.branch ?? '').split('/').pop() ?? '';\n const words = leaf.replace(/[-_]+/g, ' ').trim();\n return words ? words[0]!.toUpperCase() + words.slice(1) : '';\n}\n\n// ---------------------------------------------------------------------------\n// Merge: the head the operator confirmed\n// ---------------------------------------------------------------------------\n\n/**\n * What the Merge dialog showed when it opened. WHY a snapshot: the bar\n * re-polls git status every 10 s, and the server's `--match-head-commit`\n * guard only protects the SHA the CLIENT sends. If the dialog followed the\n * live poll, a commit pushed while it was open (and whose CI went green\n * before the click) would be merged under a confirmation the operator gave\n * for a different head. So the dialog pins the PR at open, asserts only what\n * that pin verified, and submits the pinned SHA — never the latest poll's.\n */\nexport interface PinnedMerge {\n number: number;\n title: string;\n headSha: string | null;\n headRef: string;\n baseRef: string;\n checks: VerseGitPr['checks'];\n mergeable: boolean | null;\n counts: GitCheckCounts | null;\n}\n\nexport function pinMerge(s: GitStatusView): PinnedMerge | null {\n const pr = s.pr;\n if (!pr) return null;\n return {\n number: pr.number,\n title: pr.title,\n headSha: pr.headSha,\n headRef: pr.headRef || s.branch || '',\n baseRef: pr.baseRef || s.base || '',\n checks: pr.checks,\n mergeable: pr.mergeable,\n counts: s.prCheckCounts ?? null,\n };\n}\n\n/**\n * The \"Head abc1234, 9/9 checks passed, no conflicts.\" fact, built ONLY from\n * what the pinned read verified for that SHA: \"checks passed\" needs\n * `checks === 'passing'`, \"no conflicts\" needs `mergeable === true`. Anything\n * else says what is actually known (running, failing, not reported, GitHub\n * still computing mergeability) instead of the reassuring default.\n */\nexport function mergeHeadFact(pin: PinnedMerge): { sha: string; detail: string; text: string; verified: boolean } {\n const sha = pin.headSha ? pin.headSha.slice(0, 7) : '—';\n const c = pin.counts;\n let checks: string;\n switch (pin.checks) {\n case 'passing':\n checks = c && c.total > 0 ? `${c.passed}/${c.total} checks passed` : 'checks passed';\n break;\n case 'failing':\n checks = c && c.total > 0 ? `${c.failed} of ${c.total} checks failing` : 'checks failing';\n break;\n case 'pending':\n checks = c && c.total > 0 ? `${c.pending} of ${c.total} checks still running` : 'checks still running';\n break;\n case 'none':\n checks = 'no checks reported';\n break;\n default:\n checks = 'checks not known';\n }\n const conflicts = pin.mergeable === true ? 'no conflicts' : pin.mergeable === false ? 'has conflicts' : 'GitHub has not finished checking for conflicts';\n const detail = `${checks}, ${conflicts}.`;\n return { sha, detail, text: `Head ${sha}, ${detail}`, verified: pin.checks === 'passing' && pin.mergeable === true && pin.headSha !== null };\n}\n\n/**\n * Why Merge must stay disabled for this pin against the latest poll, or null\n * when the live PR is still exactly what the dialog showed. A different head\n * (or PR, or a PR that is gone/closed) means the operator has not reviewed\n * what would merge; a regression in checks or mergeability on the SAME head\n * means the server's own suggestion no longer stands.\n */\nexport function mergeDrift(pin: PinnedMerge, live: GitStatusView | null): string | null {\n const pr = live?.pr ?? null;\n // A draft cannot be merged (the server refuses it), so \"open\" is the only live state that keeps the pin valid.\n if (!pr || pr.number !== pin.number || pr.state !== 'open') {\n return `#${pin.number} is no longer an open, ready pull request — close this and check the branch bar.`;\n }\n if (pr.headSha !== pin.headSha) return 'The PR changed since you opened this — new commits landed. Close and reopen to review the new head.';\n if (pr.checks !== 'passing') return 'Checks on this head are no longer passing — close and reopen once they are.';\n if (pr.mergeable !== true) return 'GitHub no longer reports this head as mergeable — close and reopen to review.';\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Review pane: file tree\n// ---------------------------------------------------------------------------\n\nexport interface FileGroup {\n /** \"src/core/verse\", or \"\" for the repository root. */\n dir: string;\n files: Array<VerseGitDiffFile & { name: string }>;\n}\n\n/** Files grouped by directory, in path order — a flat, scannable tree. */\nexport function groupFiles(files: readonly VerseGitDiffFile[]): FileGroup[] {\n const groups = new Map<string, FileGroup>();\n const sorted = [...files].sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0));\n for (const f of sorted) {\n const cut = f.path.lastIndexOf('/');\n const dir = cut === -1 ? '' : f.path.slice(0, cut);\n const name = cut === -1 ? f.path : f.path.slice(cut + 1);\n let g = groups.get(dir);\n if (!g) {\n g = { dir, files: [] };\n groups.set(dir, g);\n }\n g.files.push({ ...f, name });\n }\n return [...groups.values()];\n}\n\nexport const FILE_STATUS_WORD: Record<VerseGitDiffFile['status'], string> = {\n M: 'modified',\n A: 'added',\n D: 'deleted',\n R: 'renamed',\n U: 'conflicted',\n};\n\n// ---------------------------------------------------------------------------\n// Review comments → a message draft\n// ---------------------------------------------------------------------------\n\nexport interface ReviewComment {\n id: string;\n path: string;\n /** The file's line number (new side; old side for a deleted line). */\n line: number;\n side: 'new' | 'old';\n note: string;\n}\n\n/**\n * `path:line: note`, one per line (SPEC-310C §3), in file then line order so\n * the agent reads them top to bottom. A multi-line note keeps its line breaks,\n * indented under its anchor so each comment stays one visual block. A comment\n * on a deleted line says so — its number is the OLD file's.\n */\nexport function commentsToMessage(comments: readonly ReviewComment[]): string {\n const sorted = [...comments].sort((a, b) => (a.path === b.path ? a.line - b.line : a.path < b.path ? -1 : 1));\n return sorted\n .map((c) => {\n const [first, ...rest] = c.note.trim().split('\\n');\n const anchor = `${c.path}:${c.line}${c.side === 'old' ? ' (removed line)' : ''}`;\n return [`${anchor}: ${first ?? ''}`, ...rest.map((l) => ` ${l}`)].join('\\n');\n })\n .join('\\n');\n}\n\n// ---------------------------------------------------------------------------\n// Errors → one sentence\n// ---------------------------------------------------------------------------\n\n/** What the page says when a git action fails. The server's sentence when it wrote one. */\nexport function describeGitError(err: unknown): string {\n if (err && typeof err === 'object') {\n const e = err as { name?: string; status?: number; detail?: string | null; code?: string | null; message?: string };\n if (e.name === 'DispatchDisabledError') return 'This server is read-only (started without dispatch), so git actions are off.';\n if (e.name === 'VerseMutationLockedError') return 'Unlock actions with the mutation token first.';\n if (e.status === 401) return 'The mutation token was rejected. Unlock again with the token `ashlr verse` printed.';\n if (e.detail) return e.detail;\n if (e.status === 404) return 'This server has no git routes yet. Update Ashlr and restart `ashlr verse`.';\n if (e.status === 409) return 'Git is busy in this repository. Try again in a moment.';\n }\n return 'The git action failed. The terminal will show why.';\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/remote-session-Dj27m1xb.js"])))=>i.map(i=>d[i]);
|
|
2
|
+
import{n as e,r as t}from"./rolldown-runtime-hePW80VL.js";import{s as n,t as r}from"./index-_izD07R9.js";var i=t(n(),1),a={data:void 0,error:void 0,status:`idle`,updatedAt:null},o=new Map,s=0,c=[],l=0,u=0;function ee(){--s;let e=c.shift();e&&e()}function te(e){let t=()=>{let t=u;s+=1,s>l&&(l=s);let n=()=>{t===u&&ee()},r;try{r=e()}catch(e){return n(),Promise.reject(e instanceof Error?e:Error(String(e)))}return r.then(e=>(n(),e),e=>{throw n(),e})};return s<4?t():new Promise((e,n)=>{c.push(()=>{t().then(e,n)})})}function ne(){u+=1,s=0,l=0;for(let e of c.splice(0))e()}function re(){return{active:s,queued:c.length,peak:l}}function d(e){let t=o.get(e);return t||(t={snapshot:a,inFlight:null,fetcher:null,subscribers:new Set,issued:0,issuedAt:0,applied:0},o.set(e,t)),t}function ie(e,t){e.snapshot={...e.snapshot,...t}}function ae(e){let t=o.get(e);if(t)for(let e of t.subscribers)e()}function f(e,t){if(Object.is(e,t))return!0;if(typeof e!=typeof t||e===null||t===null||typeof e!=`object`||Array.isArray(e)!==Array.isArray(t))return!1;if(Array.isArray(e)&&Array.isArray(t))return e.length===t.length&&e.every((e,n)=>f(e,t[n]));let n=e,r=t,i=Object.keys(n);return i.length===Object.keys(r).length&&i.every(e=>Object.prototype.hasOwnProperty.call(r,e)&&f(n[e],r[e]))}function oe(e,t){let n=d(e);return n.subscribers.add(t),()=>{n.subscribers.delete(t)}}function p(e){return d(e).snapshot}function se(e,t){return e.snapshot.updatedAt===null||e.snapshot.status===`error`?!1:Date.now()-e.snapshot.updatedAt<t}function ce(e,t){return e.inFlight===null?!1:t.joinWindowMs===void 0||Date.now()-e.issuedAt<t.joinWindowMs}function m(e,t,n){let r=d(e);if(r.fetcher=t,!n.force){if(ce(r,n))return r.inFlight;if(n.maxAgeMs!==void 0&&se(r,n.maxAgeMs))return Promise.resolve()}let i=r.issued+=1;r.issuedAt=Date.now(),ie(r,{status:r.snapshot.data===void 0?`loading`:`refreshing`}),ae(e);let a=te(t).then(e=>{if(i<r.applied)return;r.applied=i;let t=r.snapshot.data!==void 0&&f(r.snapshot.data,e);ie(r,{data:t?r.snapshot.data:e,error:void 0,status:`success`,updatedAt:Date.now()})}).catch(e=>{i<r.applied||(r.applied=i,ie(r,{error:e instanceof Error?e:Error(String(e)),status:`error`}))}).finally(()=>{r.issued===i&&(r.inFlight=null),ae(e)});return r.inFlight=a,a}function le(e,t){return m(e,t,{})}function ue(e,t,n){return m(e,t,{maxAgeMs:n})}function h(e,t,n=!1){return m(e,t,n?{force:!0}:{joinWindowMs:250})}function g(e){let t=o.get(e);t&&t.fetcher&&le(e,t.fetcher)}function de(e){for(let t of o.keys())t.startsWith(e)&&g(t)}function fe(e){for(let[t,n]of o)n.subscribers.size>0&&t.startsWith(e)&&g(t)}function pe(e,t){t.snapshot=a,t.fetcher=null,t.inFlight=null,t.issued+=1,t.applied=t.issued,ae(e)}function me(){ne();for(let[e,t]of[...o]){if(t.subscribers.size===0){o.delete(e);continue}pe(e,t)}}var _=`ashlr.verse.drafts.v1`,v=`ashlr.verse.sent.v1`,he=40,y=65536;function b(e,t){let n={};try{let r=localStorage.getItem(e),i=r?JSON.parse(r):null;if(i&&typeof i==`object`&&!Array.isArray(i))for(let[e,r]of Object.entries(i)){let i=t(r);i!==null&&(n[e]=i)}}catch{}return n}function x(e,t){let n=Object.keys(t);for(let e of n.slice(0,Math.max(0,n.length-he)))delete t[e];try{return localStorage.setItem(e,JSON.stringify(t)),!0}catch{return!1}}var S=e=>typeof e==`string`&&e.length>0?e.slice(0,y):null,C=e=>{if(!Array.isArray(e))return null;let t=e.filter(e=>typeof e==`string`&&e.length>0).slice(-25).map(e=>e.slice(0,y));return t.length>0?t:null},w=new Map;function ge(e){if(!e)return``;let t=w.get(e);return t===void 0?b(_,S)[e]??``:t}function _e(e,t){if(!e)return;let n=t.trim().length>0?t.slice(0,y):``,r=b(_,S);if(delete r[e],n&&(r[e]=n),w.delete(e),!x(_,r)){w.set(e,n);for(let e of[...w.keys()].slice(0,Math.max(0,w.size-he)))w.delete(e)}}function ve(e){return e?b(v,C)[e]??[]:[]}function ye(e,t){if(!e||t.trim().length===0)return;let n=b(v,C),r=n[e]??[];delete n[e],n[e]=(r[r.length-1]===t?r:[...r,t.slice(0,y)]).slice(-25),x(v,n)}function be(e){if(e){w.delete(e);for(let[t,n]of[[_,S],[v,C]]){let r=b(t,n);e in r&&(delete r[e],x(t,r))}}}function xe(){w.clear();for(let e of[_,v])try{localStorage.removeItem(e)}catch{}}function T(){return typeof document<`u`&&document.head.querySelector(`meta[name="ashlr-remote-gateway"][content="v1"]`)!==null}var Se=e({adoptInjectedTokens:()=>je,clearMutationToken:()=>Y,clearReadSession:()=>Oe,establishReadSession:()=>V,getAuthSnapshot:()=>z,getMutationToken:()=>G,getReadClientProof:()=>B,hasMutationHold:()=>K,markCheckComplete:()=>ke,renewReadSession:()=>W,reportSessionExpired:()=>U,setMutationToken:()=>q,setRemoteActGranted:()=>Me,subscribeAuth:()=>R,takeInjectedTokens:()=>Ae,touchMutationHold:()=>J}),Ce=`ashlr.readClientProof.v1`,we=/^[a-f0-9]{64}$/,E=12e5;function Te(){let e=new Uint8Array(32);return crypto.getRandomValues(e),Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``)}function Ee(){if(T())return``;try{let e=sessionStorage.getItem(Ce);if(e&&we.test(e))return e}catch{}let e=Te();try{sessionStorage.setItem(Ce,e)}catch{}return e}var D=Ee(),O=null,k=null,A=!1,j=!1,M=null,N=null,P=null,F={phase:`checking`,checked:!1,mutationTokenHeldUntil:null},I=new Set;function De(){for(let e of I)e()}function L(e){F={...F,...e},De()}function R(e){return I.add(e),()=>I.delete(e)}function z(){return F}function B(){if(T())throw Error(`Local read-client proof is unavailable on the phone gateway.`);return D}async function V(e){if(T())throw Error(`Hub read tokens are unavailable on the phone gateway.`);let t=e.trim();if(!/^[a-f0-9]{64}$/.test(t))throw Error(`That does not look like a read token — expected 64 hex characters.`);let n=await fetch(`/api/session`,{method:`POST`,credentials:`same-origin`,headers:{"x-ashlr-token":t,"x-ashlr-read-client":D}});if(n.status===204){M=t,L({phase:`authenticated`,checked:!0});return}throw n.status===401?Error(`Server rejected that token. Double-check the read token printed by this server at startup.`):Error(`Unexpected response establishing session (HTTP ${n.status}).`)}async function Oe(){if(T()){try{await(await r(async()=>{let{logoutRemoteDevice:e}=await import(`./remote-session-Dj27m1xb.js`);return{logoutRemoteDevice:e}},__vite__mapDeps([0]))).logoutRemoteDevice()}finally{H()}return}try{await fetch(`/api/session`,{method:`DELETE`,credentials:`same-origin`,headers:{"x-ashlr-read-client":D}})}catch{}M=null,P=null,H()}function H(){Y(),me(),xe(),L({phase:`unauthenticated`,checked:!0})}function U(){if(F.phase===`authenticated`){if(T()){H();return}if(M){W();return}H()}}function W(){if(N)return N;let e=M;return e?(N=(async()=>{try{return await V(e),fe(``),!0}catch{return M=null,P=null,H(),!1}finally{N=null}})(),N):Promise.resolve(!1)}function ke(e){L({phase:e?`authenticated`:`unauthenticated`,checked:!0})}function Ae(){let e=window.__ASHLR_TOKENS__;if(e&&typeof e==`object`){try{delete window.__ASHLR_TOKENS__}catch{window.__ASHLR_TOKENS__=void 0}typeof e.readToken==`string`&&(P={readToken:e.readToken,...typeof e.token==`string`?{token:e.token}:{}})}return P?{...P}:null}async function je(){if(T())return!1;let e=Ae();if(!e)return!1;try{await V(e.readToken)}catch{return P=null,!1}return e.token&&/^[a-f0-9]{64}$/.test(e.token.trim())&&q(e.token.trim(),{host:!0}),!0}function G(){return T()?j?`*`:null:O}function K(){return T()?j:O!==null}function Me(e){j=e,De()}function Ne(){k&&clearTimeout(k),k=setTimeout(()=>{A&&O!==null?J():Y()},E)}function q(e,t={}){if(T())throw Error(`Hub mutation tokens are unavailable on the phone gateway.`);O=e,A=t.host===!0,L({mutationTokenHeldUntil:Date.now()+E}),Ne()}function J(){O!==null&&(L({mutationTokenHeldUntil:Date.now()+E}),Ne())}function Y(){j=!1,O=null,A=!1,k&&=(clearTimeout(k),null),L({mutationTokenHeldUntil:null})}var Pe=`ashlr.theme.v1`;function Fe(e){let t=document.documentElement;e===`system`?t.removeAttribute(`data-theme`):t.setAttribute(`data-theme`,e)}function Ie(){try{let e=localStorage.getItem(Pe);if(e===`light`||e===`dark`||e===`system`)return e}catch{}return`system`}var X=Ie();Fe(X);var Z=new Set;function Le(){for(let e of Z)e()}function Re(e){return Z.add(e),()=>Z.delete(e)}function ze(){return X}function Be(e){X=e,Fe(X);try{localStorage.setItem(Pe,X)}catch{}Le()}function Ve(){Be(X===`system`?`light`:X===`light`?`dark`:`system`)}function He(e,t){let n=t?.freshMs??1e4,r=(0,i.useSyncExternalStore)((0,i.useCallback)(t=>oe(e.key,t),[e.key]),()=>p(e.key),()=>p(e.key));return(0,i.useEffect)(()=>{ue(e.key,()=>e.fetch(),n)},[e.key,n]),r}function Ue(e){return(0,i.useCallback)(()=>{h(e.key,()=>e.fetch())},[e])}function We(e){return(0,i.useCallback)(()=>{h(e.key,()=>e.fetch(),!0)},[e])}function Ge(){return(0,i.useSyncExternalStore)(R,()=>z().phase,()=>z().phase)}function Ke(){let e=(0,i.useSyncExternalStore)(R,()=>z().mutationTokenHeldUntil,()=>z().mutationTokenHeldUntil);return{hasHold:K(),token:G(),heldUntil:e,setToken:q,touch:J,clear:Y}}function qe(){return{theme:(0,i.useSyncExternalStore)(Re,ze,ze),set:Be,cycle:Ve}}var Q=class extends Error{status;path;detail;code;constructor(e,t,n,r=null,i=null){super(e),this.status=t,this.path=n,this.detail=r,this.code=i,this.name=`ApiError`}},Je=class extends Q{constructor(e){super(`This server was started without --allow-dispatch, so mutations are disabled.`,404,e),this.name=`DispatchDisabledError`}};function Ye(e){return e instanceof Q?e.detail??`The server answered HTTP ${e.status}.`:e instanceof TypeError?`The server did not answer.`:`The request failed.`}async function Xe(e,t){if(T())return(await r(async()=>{let{remoteApiGet:e}=await import(`./remote-session-Dj27m1xb.js`);return{remoteApiGet:e}},__vite__mapDeps([0]))).remoteApiGet(e,t);let n=await fetch(e,{method:`GET`,credentials:`same-origin`,headers:{"x-ashlr-read-client":B()},signal:t});if(n.status===401)throw U(),new Q(`Read session expired.`,401,e);if(!n.ok){let{detail:t,code:r}=await $(n);throw new Q(`GET ${e} failed (HTTP ${n.status}).`,n.status,e,t||null,r)}return await n.json()}async function Ze(e,t,n,i){if(T())return(await r(async()=>{let{remoteMutate:e}=await import(`./remote-session-Dj27m1xb.js`);return{remoteMutate:e}},__vite__mapDeps([0]))).remoteMutate(`POST`,e,t);let a=await fetch(e,{method:`POST`,credentials:`same-origin`,headers:{"Content-Type":`application/json`,"x-ashlr-token":n},body:JSON.stringify(t??{}),signal:i});if(a.status===401)throw new Q(`Mutation token was rejected.`,401,e);if(!a.ok){let{detail:t,code:n}=await $(a);throw a.status===404&&n===null?new Je(e):new Q(`POST ${e} failed (HTTP ${a.status})${t?`: ${t}`:``}.`,a.status,e,t||null,n)}if(a.status!==204)return await a.json()}async function Qe(e,t,n){if(T())return(await r(async()=>{let{remoteMutate:e}=await import(`./remote-session-Dj27m1xb.js`);return{remoteMutate:e}},__vite__mapDeps([0]))).remoteMutate(`DELETE`,e,{});let i=await fetch(e,{method:`DELETE`,credentials:`same-origin`,headers:{"x-ashlr-token":t},signal:n});if(i.status===401)throw new Q(`Mutation token was rejected.`,401,e);if(!i.ok){let{detail:t,code:n}=await $(i);throw i.status===404&&n===null?new Je(e):new Q(`DELETE ${e} failed (HTTP ${i.status})${t?`: ${t}`:``}.`,i.status,e,t||null,n)}if(i.status===204)return;let a=await i.text();return a?JSON.parse(a):void 0}async function $(e){try{let t=await e.json();return{detail:typeof t.error==`string`&&t.error?t.error:typeof t.note==`string`&&t.note?t.note:typeof t.message==`string`?t.message:``,code:typeof t.code==`string`&&t.code?t.code:null}}catch{return{detail:``,code:null}}}export{Me as A,p as B,G as C,W as D,ke as E,ge as F,le as G,de as H,ve as I,oe as K,ye as L,J as M,T as N,U as O,be as P,_e as R,z as S,K as T,re as U,g as V,h as W,je as _,Ze as a,Oe as b,Ke as c,We as d,qe as f,Re as g,Be as h,Xe as i,R as j,q as k,He as l,ze as m,Je as n,Ye as o,Ve as p,Qe as r,Ge as s,Q as t,Ue as u,Se as v,B as w,V as x,Y as y,ue as z};
|
|
3
|
+
//# sourceMappingURL=global-CYfRwH6t.js.map
|